mdview: blank-row block separation; tables nowrap; fix continuation marker
- Paragraph scanning no longer swallows the blank line separating it from the next block; runs of blank lines collapse to one row. Restores blank separation between paragraphs, headers and horizontal rules. - Detect table rows (first non-space char '|') as nowrap segments; they are no longer merged into surrounding text or each other. - Continuation (wrapped) rows render content as plain text and are no longer re-classified, so a wrapped word starting with '-'/'#'/'>' is not mis-drawn as a list/heading/quote marker. Co-Authored-By: Oz <oz-agent@warp.dev>
This commit is contained in:
@@ -668,6 +668,18 @@ static uint8_t is_hr_raw(uint32_t p)
|
||||
return ok && count >= 3;
|
||||
}
|
||||
|
||||
/* A table row: the first non-space character on the line is '|'. Leading
|
||||
* spaces are allowed. Table rows are nowrap and never merged. */
|
||||
static uint8_t is_table_raw(uint32_t p)
|
||||
{
|
||||
while (p < file_size) {
|
||||
char c = fb(p);
|
||||
if (c == ' ' || c == '\t') { p++; continue; }
|
||||
return (uint8_t)(c == '|');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Shared inline-emphasis / wrap scanner for a single line or paragraph stream.
|
||||
* Starts at `q`, processes until `q_end` (or paragraph break for plain text),
|
||||
* emits continuation segs as needed. `col` is the starting visible column
|
||||
@@ -770,7 +782,8 @@ static void index_lines(void)
|
||||
if (is_line_blank(p)) {
|
||||
while (p < file_size && fb(p) != '\n') p++;
|
||||
if (p < file_size) p++;
|
||||
if (n_lines == 0 || cur_seg_off != p) {
|
||||
/* Collapse a run of blank lines to a single blank row. */
|
||||
if (n_lines == 0 || !(cur_rec.flags & IF_BLANK)) {
|
||||
emit_seg(p, INIT_STYLE_PLAIN, CK_PLAIN, 0);
|
||||
set_blank_cur();
|
||||
}
|
||||
@@ -804,6 +817,15 @@ static void index_lines(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ---- table row (| ... |): one nowrap seg per source line ---- */
|
||||
if (is_table_raw(p)) {
|
||||
emit_seg(p, INIT_STYLE_PLAIN, CK_OTHER, 0);
|
||||
set_nowrap_cur();
|
||||
while (p < file_size && fb(p) != '\n') p++;
|
||||
if (p < file_size) p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ---- classify current line ---- */
|
||||
uint32_t content_off = p;
|
||||
uint8_t kind = classify_line(p, &content_off);
|
||||
@@ -864,6 +886,7 @@ static void index_lines(void)
|
||||
uint32_t next = q + 1;
|
||||
if (is_fence_raw(next)) break;
|
||||
if (is_hr_raw(next)) break;
|
||||
if (is_table_raw(next)) break;
|
||||
uint32_t dummy;
|
||||
if (classify_line(next, &dummy) != LK_PLAIN) break;
|
||||
if (is_line_blank(next)) break;
|
||||
@@ -984,9 +1007,12 @@ static void index_lines(void)
|
||||
if (q >= file_size) {
|
||||
p = file_size;
|
||||
} else {
|
||||
/* q sits on the paragraph's trailing newline; resume at the
|
||||
* next line so the outer loop classifies it. A following
|
||||
* blank line then becomes the single separating blank row
|
||||
* (previously it was swallowed, gluing paragraphs together). */
|
||||
while (q < file_size && fb(q) != '\n') q++;
|
||||
if (q + 1 < file_size && fb(q + 1) == '\n') q += 2;
|
||||
else if (q < file_size) q++;
|
||||
if (q < file_size) q++;
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
@@ -1062,6 +1088,12 @@ static void render_line(uint16_t line_idx, uint8_t row)
|
||||
cur_attr = ATTR_TEXT_CODE;
|
||||
parse_inline = 0;
|
||||
kind = LK_PLAIN;
|
||||
} else if (cont) {
|
||||
/* Continuation row: the parent prefix/indent is already drawn
|
||||
* above. Render the wrapped content as plain text — do NOT
|
||||
* re-classify it, or a wrapped word beginning with '-', '#',
|
||||
* '>' etc. would be mis-drawn as a new marker. */
|
||||
kind = LK_PLAIN;
|
||||
} else {
|
||||
kind = classify_line(p, &content_off);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user