parity(7): table cell alignment markers (|:--|--:|:--:|)
The Markdown-style alignment anchors on a table's header-separator row now propagate from the lexer through the parser into the AST, and the HTML renderer emits a `style="text-align: …;"` attribute on each affected `<th>` / `<td>`. |:--| → left |--:| → right |:--:| → center |---| → default (no style attr) Encoding choice: rather than threading the source string into the parser, the lexer now extracts per-cell alignment when it recognises the separator row and carries the `Vec<TableAlign>` inline on the `TableHeaderRow` token. The parser unpacks it into `TableNode`'s new `alignments: Vec<TableAlign>` field. Cells past the end of the vector render with the default alignment. `TableAlign` lives in `nuwiki_core::ast::block` alongside the table nodes and is re-exported via `nuwiki_core::ast`. Tests: 4 new in crates/nuwiki-core/tests/vimwiki_table_alignment.rs covering plain dashes, all three anchor flavours, the HTML output shape, and the no-style-attr case. The existing `vimwiki_lexer::table_header_separator_row` was updated to assert the new payload shape. Gates: 425 Rust / 39 Neovim / 12 Vim. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -210,7 +210,7 @@ impl<'a> ParseState<'a> {
|
||||
K::HorizontalRule => self.parse_horizontal_rule(),
|
||||
K::ListMarker { .. } => self.parse_list(),
|
||||
K::BlockquoteMarker | K::BlockquoteIndent => self.parse_blockquote(),
|
||||
K::TableSep | K::TableHeaderRow => self.parse_table(),
|
||||
K::TableSep | K::TableHeaderRow(_) => self.parse_table(),
|
||||
K::PreformattedOpen { .. } => self.parse_preformatted(),
|
||||
K::MathBlockOpen { .. } => self.parse_math_block(),
|
||||
K::CommentLine(_) => self.parse_single_comment(),
|
||||
@@ -620,11 +620,15 @@ impl<'a> ParseState<'a> {
|
||||
let mut rows: Vec<TableRowNode> = Vec::new();
|
||||
let mut next_is_header = false;
|
||||
let mut has_header = false;
|
||||
let mut alignments: Vec<crate::ast::TableAlign> = Vec::new();
|
||||
|
||||
while let Some(t) = self.peek() {
|
||||
match &t.kind {
|
||||
K::TableHeaderRow => {
|
||||
K::TableHeaderRow(aligns) => {
|
||||
has_header = true;
|
||||
if alignments.is_empty() {
|
||||
alignments = aligns.clone();
|
||||
}
|
||||
if let Some(last) = rows.last_mut() {
|
||||
last.is_header = true;
|
||||
}
|
||||
@@ -638,7 +642,6 @@ impl<'a> ParseState<'a> {
|
||||
span_end = row.span.end;
|
||||
rows.push(row);
|
||||
if next_is_header {
|
||||
// Header sep applies to the *previous* row, not this one.
|
||||
next_is_header = false;
|
||||
}
|
||||
}
|
||||
@@ -649,6 +652,7 @@ impl<'a> ParseState<'a> {
|
||||
span: Span::new(span_start, span_end),
|
||||
rows,
|
||||
has_header,
|
||||
alignments,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -870,7 +874,7 @@ fn starts_new_block(kind: &K) -> bool {
|
||||
| K::BlockquoteMarker
|
||||
| K::BlockquoteIndent
|
||||
| K::TableSep
|
||||
| K::TableHeaderRow
|
||||
| K::TableHeaderRow(_)
|
||||
| K::PreformattedOpen { .. }
|
||||
| K::MathBlockOpen { .. }
|
||||
| K::CommentLine(_)
|
||||
|
||||
Reference in New Issue
Block a user