mirror of
https://github.com/openai/codex.git
synced 2026-10-26 18:38:47 +00:00
fix(tui): tighten spillover and fence-close table parsing
This commit is contained in:
committed by
Felipe Coury
parent
14d66912f3
commit
8a94c65989
@@ -1308,10 +1308,9 @@ where
|
||||
// Keep common intro + html-block spillover together:
|
||||
// "HTML block:" followed by "<div ...>".
|
||||
first_text.trim_end().ends_with(':')
|
||||
&& (next_row
|
||||
&& next_row
|
||||
.and_then(|row| Self::first_non_empty_only_text(row))
|
||||
.is_some_and(|text| Self::looks_like_html_content(&text))
|
||||
|| Self::looks_like_label_line(&first_text))
|
||||
}
|
||||
|
||||
fn first_non_empty_only_text(row: &[TableCell]) -> Option<String> {
|
||||
@@ -1329,10 +1328,6 @@ where
|
||||
text.contains('<') && text.contains('>')
|
||||
}
|
||||
|
||||
fn looks_like_label_line(text: &str) -> bool {
|
||||
text.trim_end().ends_with(':') && text.split_whitespace().count() <= 3
|
||||
}
|
||||
|
||||
fn spans_display_width(spans: &[Span<'_>]) -> usize {
|
||||
spans.iter().map(|span| span.content.width()).sum()
|
||||
}
|
||||
|
||||
@@ -1505,6 +1505,28 @@ fn table_keeps_sparse_sentence_row_inside_grid() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_keeps_label_only_sparse_row_inside_grid() {
|
||||
let md = "| A | B | C |\n|---|---|---|\n| Status: | | |\n| ok | | |\n";
|
||||
let text = render_markdown_text(md);
|
||||
let lines: Vec<String> = text
|
||||
.lines
|
||||
.iter()
|
||||
.map(|line| line.spans.iter().map(|span| span.content.clone()).collect())
|
||||
.collect();
|
||||
|
||||
assert!(
|
||||
lines
|
||||
.iter()
|
||||
.any(|line| line.contains("│ Status:") && line.ends_with('│')),
|
||||
"expected label-only sparse row to remain inside table grid: {lines:?}"
|
||||
);
|
||||
assert!(
|
||||
!lines.iter().any(|line| line.trim() == "Status:"),
|
||||
"did not expect label-only sparse row to spill outside table: {lines:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_preserves_structured_leading_columns_when_last_column_is_long() {
|
||||
let md = "| Milestone | Planned Date | Outcome | Retrospective Summary |\n|---|---|---|---|\n| Canary rollout | 2026-01-10 | Completed | Canary
|
||||
|
||||
+6
-6
@@ -29,13 +29,13 @@ Image: alt text
|
||||
|
||||
Table below (alignment test):
|
||||
|
||||
┌──────┬────────┬───────┐
|
||||
│ Left │ Center │ Right │
|
||||
├──────┼────────┼───────┤
|
||||
│ a │ b │ c │
|
||||
└──────┴────────┴───────┘
|
||||
┌─────────────┬────────┬───────┐
|
||||
│ Left │ Center │ Right │
|
||||
├─────────────┼────────┼───────┤
|
||||
│ a │ b │ c │
|
||||
│ HTML block: │ │ │
|
||||
└─────────────┴────────┴───────┘
|
||||
Inline HTML: <sup>sup</sup> and <sub>sub</sub>.
|
||||
HTML block:
|
||||
<div style="border:1px solid #ccc;padding:2px">inline block</div>
|
||||
Escapes: \_underscores\_, backslash \\, ticks ``code with `backtick` inside``.
|
||||
Emoji shortcodes: :sparkles: :tada: (if supported).
|
||||
|
||||
@@ -585,6 +585,7 @@ fn is_markdown_fence(trimmed_line: &str, marker_len: usize) -> bool {
|
||||
fn parse_lines_with_fence_state(source: &str) -> Vec<ParsedLine<'_>> {
|
||||
let mut in_fence = false;
|
||||
let mut fence_char = '\0';
|
||||
let mut fence_len = 0usize;
|
||||
let mut fence_context = FenceContext::Other;
|
||||
let mut lines = Vec::new();
|
||||
|
||||
@@ -603,13 +604,15 @@ fn parse_lines_with_fence_state(source: &str) -> Vec<ParsedLine<'_>> {
|
||||
if !in_fence {
|
||||
in_fence = true;
|
||||
fence_char = marker;
|
||||
fence_len = len;
|
||||
fence_context = if is_markdown_fence(trimmed, len) {
|
||||
FenceContext::Markdown
|
||||
} else {
|
||||
FenceContext::Other
|
||||
};
|
||||
} else if marker == fence_char && len >= 3 {
|
||||
} else if marker == fence_char && len >= fence_len && trimmed[len..].trim().is_empty() {
|
||||
in_fence = false;
|
||||
fence_len = 0;
|
||||
fence_context = FenceContext::Other;
|
||||
}
|
||||
}
|
||||
@@ -1347,6 +1350,15 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_holdback_state_ignores_table_like_lines_inside_unclosed_long_fence() {
|
||||
let source = "````sh\n```cmd\n| Key | Description |\n| --- | --- |\n````\n";
|
||||
assert!(
|
||||
matches!(table_holdback_state(source), TableHoldbackState::None),
|
||||
"table holdback should ignore pipe lines inside an open non-markdown fence",
|
||||
);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// source_bytes_for_rendered_count — prefix-stability tests
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user