diff --git a/crates/markdown_preview/src/markdown_elements.rs b/crates/markdown_preview/src/markdown_elements.rs index b0a36a4cf2..993c52910e 100644 --- a/crates/markdown_preview/src/markdown_elements.rs +++ b/crates/markdown_preview/src/markdown_elements.rs @@ -106,7 +106,6 @@ pub struct ParsedMarkdownTable { pub source_range: Range, pub header: Vec, pub body: Vec, - pub column_alignments: Vec, } #[derive(Debug, Clone, Copy, Default)] @@ -126,6 +125,7 @@ pub struct ParsedMarkdownTableColumn { pub row_span: usize, pub is_header: bool, pub children: MarkdownParagraph, + pub alignment: ParsedMarkdownTableAlignment, } #[derive(Debug)] diff --git a/crates/markdown_preview/src/markdown_parser.rs b/crates/markdown_preview/src/markdown_parser.rs index 28388923a7..fd3e212726 100644 --- a/crates/markdown_preview/src/markdown_parser.rs +++ b/crates/markdown_preview/src/markdown_parser.rs @@ -466,7 +466,10 @@ impl<'a> MarkdownParser<'a> { let mut body = vec![]; let mut row_columns = vec![]; let mut in_header = true; - let column_alignments = alignment.iter().map(Self::convert_alignment).collect(); + let column_alignments = alignment + .iter() + .map(Self::convert_alignment) + .collect::>(); loop { if self.eof() { @@ -489,6 +492,10 @@ impl<'a> MarkdownParser<'a> { row_span: 1, is_header: in_header, children: cell_contents, + alignment: column_alignments + .get(row_columns.len()) + .copied() + .unwrap_or_default(), }); } Event::End(TagEnd::TableHead) | Event::End(TagEnd::TableRow) => { @@ -515,7 +522,6 @@ impl<'a> MarkdownParser<'a> { source_range, header, body, - column_alignments, } } @@ -988,6 +994,8 @@ impl<'a> MarkdownParser<'a> { let mut children = MarkdownParagraph::new(); self.consume_paragraph(source_range, node, &mut children); + let is_header = matches!(name.local, local_name!("th")); + Some(ParsedMarkdownTableColumn { col_span: std::cmp::max( Self::attr_value(attrs, local_name!("colspan")) @@ -1001,8 +1009,22 @@ impl<'a> MarkdownParser<'a> { .unwrap_or(1), 1, ), - is_header: matches!(name.local, local_name!("th")), + is_header, children, + alignment: Self::attr_value(attrs, local_name!("align")) + .and_then(|align| match align.as_str() { + "left" => Some(ParsedMarkdownTableAlignment::Left), + "center" => Some(ParsedMarkdownTableAlignment::Center), + "right" => Some(ParsedMarkdownTableAlignment::Right), + _ => None, + }) + .unwrap_or_else(|| { + if is_header { + ParsedMarkdownTableAlignment::Center + } else { + ParsedMarkdownTableAlignment::default() + } + }), }) } _ => None, @@ -1155,7 +1177,6 @@ impl<'a> MarkdownParser<'a> { Some(ParsedMarkdownTable { source_range, body: body_rows, - column_alignments: Vec::default(), header: header_rows, }) } else { @@ -1653,17 +1674,53 @@ mod tests { children: vec![ParsedMarkdownElement::Table(table( 0..366, vec![row(vec![ - column(1, 1, true, text("Id", 0..366)), - column(1, 1, true, text("Name ", 0..366)) + column( + 1, + 1, + true, + text("Id", 0..366), + ParsedMarkdownTableAlignment::Center + ), + column( + 1, + 1, + true, + text("Name ", 0..366), + ParsedMarkdownTableAlignment::Center + ) ])], vec![ row(vec![ - column(1, 1, false, text("1", 0..366)), - column(1, 1, false, text("Chris", 0..366)) + column( + 1, + 1, + false, + text("1", 0..366), + ParsedMarkdownTableAlignment::None + ), + column( + 1, + 1, + false, + text("Chris", 0..366), + ParsedMarkdownTableAlignment::None + ) ]), row(vec![ - column(1, 1, false, text("2", 0..366)), - column(1, 1, false, text("Dennis", 0..366)) + column( + 1, + 1, + false, + text("2", 0..366), + ParsedMarkdownTableAlignment::None + ), + column( + 1, + 1, + false, + text("Dennis", 0..366), + ParsedMarkdownTableAlignment::None + ) ]), ], ))], @@ -1697,12 +1754,36 @@ mod tests { vec![], vec![ row(vec![ - column(1, 1, false, text("1", 0..240)), - column(1, 1, false, text("Chris", 0..240)) + column( + 1, + 1, + false, + text("1", 0..240), + ParsedMarkdownTableAlignment::None + ), + column( + 1, + 1, + false, + text("Chris", 0..240), + ParsedMarkdownTableAlignment::None + ) ]), row(vec![ - column(1, 1, false, text("2", 0..240)), - column(1, 1, false, text("Dennis", 0..240)) + column( + 1, + 1, + false, + text("2", 0..240), + ParsedMarkdownTableAlignment::None + ), + column( + 1, + 1, + false, + text("Dennis", 0..240), + ParsedMarkdownTableAlignment::None + ) ]), ], ))], @@ -1730,8 +1811,20 @@ mod tests { children: vec![ParsedMarkdownElement::Table(table( 0..150, vec![row(vec![ - column(1, 1, true, text("Id", 0..150)), - column(1, 1, true, text("Name", 0..150)) + column( + 1, + 1, + true, + text("Id", 0..150), + ParsedMarkdownTableAlignment::Center + ), + column( + 1, + 1, + true, + text("Name", 0..150), + ParsedMarkdownTableAlignment::Center + ) ])], vec![], ))], @@ -1915,8 +2008,20 @@ Some other content let expected_table = table( 0..48, vec![row(vec![ - column(1, 1, true, text("Header 1", 1..11)), - column(1, 1, true, text("Header 2", 12..22)), + column( + 1, + 1, + true, + text("Header 1", 1..11), + ParsedMarkdownTableAlignment::None, + ), + column( + 1, + 1, + true, + text("Header 2", 12..22), + ParsedMarkdownTableAlignment::None, + ), ])], vec![], ); @@ -1938,17 +2043,53 @@ Some other content let expected_table = table( 0..95, vec![row(vec![ - column(1, 1, true, text("Header 1", 1..11)), - column(1, 1, true, text("Header 2", 12..22)), + column( + 1, + 1, + true, + text("Header 1", 1..11), + ParsedMarkdownTableAlignment::None, + ), + column( + 1, + 1, + true, + text("Header 2", 12..22), + ParsedMarkdownTableAlignment::None, + ), ])], vec![ row(vec![ - column(1, 1, false, text("Cell 1", 49..59)), - column(1, 1, false, text("Cell 2", 60..70)), + column( + 1, + 1, + false, + text("Cell 1", 49..59), + ParsedMarkdownTableAlignment::None, + ), + column( + 1, + 1, + false, + text("Cell 2", 60..70), + ParsedMarkdownTableAlignment::None, + ), ]), row(vec![ - column(1, 1, false, text("Cell 3", 73..83)), - column(1, 1, false, text("Cell 4", 84..94)), + column( + 1, + 1, + false, + text("Cell 3", 73..83), + ParsedMarkdownTableAlignment::None, + ), + column( + 1, + 1, + false, + text("Cell 4", 84..94), + ParsedMarkdownTableAlignment::None, + ), ]), ], ); @@ -2410,7 +2551,6 @@ fn main() { body: Vec, ) -> ParsedMarkdownTable { ParsedMarkdownTable { - column_alignments: Vec::new(), source_range, header, body, @@ -2426,12 +2566,14 @@ fn main() { row_span: usize, is_header: bool, children: MarkdownParagraph, + alignment: ParsedMarkdownTableAlignment, ) -> ParsedMarkdownTableColumn { ParsedMarkdownTableColumn { col_span, row_span, is_header, children, + alignment, } } diff --git a/crates/markdown_preview/src/markdown_renderer.rs b/crates/markdown_preview/src/markdown_renderer.rs index c6f4354423..0996e40811 100644 --- a/crates/markdown_preview/src/markdown_renderer.rs +++ b/crates/markdown_preview/src/markdown_renderer.rs @@ -497,7 +497,7 @@ fn render_markdown_table(parsed: &ParsedMarkdownTable, cx: &mut RenderContext) - for (row_idx, row) in parsed.header.iter().chain(parsed.body.iter()).enumerate() { let mut col_idx = 0; - for (cell_idx, cell) in row.columns.iter().enumerate() { + for cell in row.columns.iter() { // Skip columns occupied by row-spanning cells from previous rows while col_idx < max_column_count && grid_occupied[row_idx][col_idx] { col_idx += 1; @@ -507,19 +507,7 @@ fn render_markdown_table(parsed: &ParsedMarkdownTable, cx: &mut RenderContext) - break; } - let alignment = parsed - .column_alignments - .get(cell_idx) - .copied() - .unwrap_or_else(|| { - if cell.is_header { - ParsedMarkdownTableAlignment::Center - } else { - ParsedMarkdownTableAlignment::None - } - }); - - let container = match alignment { + let container = match cell.alignment { ParsedMarkdownTableAlignment::Left | ParsedMarkdownTableAlignment::None => div(), ParsedMarkdownTableAlignment::Center => v_flex().items_center(), ParsedMarkdownTableAlignment::Right => v_flex().items_end(), @@ -917,6 +905,7 @@ mod tests { row_span, is_header: false, children, + alignment: ParsedMarkdownTableAlignment::None, } } @@ -930,6 +919,7 @@ mod tests { row_span, is_header: false, children, + alignment: ParsedMarkdownTableAlignment::None, } }