From eb9fd62a90d9b8825e7280f1e27775f6892c3924 Mon Sep 17 00:00:00 2001 From: Andrey Arutiunian <110744283+andarut@users.noreply.github.com> Date: Tue, 1 Oct 2024 01:50:30 +0300 Subject: [PATCH] Fix rendering of markdown tables (#18315) - Closes: https://github.com/zed-industries/zed/issues/11024 ## Release Notes: - Improved Markdown Preview rendering of tables ## Before: ![image](https://github.com/user-attachments/assets/25f05604-38a9-4bde-901c-6d53a5d9d94d) Screenshot 2024-09-25 at 05 47 19 ## Now: ![image](https://github.com/user-attachments/assets/ce06f045-d0db-4b8c-a1fc-2811d35f2683) Screenshot 2024-09-25 at 05 47 48 ## Note: I'm not a Rust programmer and this is my first PR in Zed (because i just want to fix this, so i can view my notes in Markdown in Zed, not slow Visual Studio Code) - so there may be errors. I'm open for critic a --- .../markdown_preview/src/markdown_renderer.rs | 56 ++++++++++++++++--- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/crates/markdown_preview/src/markdown_renderer.rs b/crates/markdown_preview/src/markdown_renderer.rs index ad169f036b..8bab51b2c3 100644 --- a/crates/markdown_preview/src/markdown_renderer.rs +++ b/crates/markdown_preview/src/markdown_renderer.rs @@ -6,8 +6,8 @@ use crate::markdown_elements::{ }; use gpui::{ div, px, rems, AbsoluteLength, AnyElement, DefiniteLength, Div, Element, ElementId, - HighlightStyle, Hsla, InteractiveText, IntoElement, Keystroke, Modifiers, ParentElement, - SharedString, Styled, StyledText, TextStyle, WeakView, WindowContext, + HighlightStyle, Hsla, InteractiveText, IntoElement, Keystroke, Length, Modifiers, + ParentElement, SharedString, Styled, StyledText, TextStyle, WeakView, WindowContext, }; use settings::Settings; use std::{ @@ -16,7 +16,7 @@ use std::{ }; use theme::{ActiveTheme, SyntaxTheme, ThemeSettings}; use ui::{ - h_flex, v_flex, Checkbox, FluentBuilder, InteractiveElement, LinkPreview, Selection, + h_flex, relative, v_flex, Checkbox, FluentBuilder, InteractiveElement, LinkPreview, Selection, StatefulInteractiveElement, Tooltip, }; use workspace::Workspace; @@ -231,12 +231,48 @@ fn render_markdown_list_item( } fn render_markdown_table(parsed: &ParsedMarkdownTable, cx: &mut RenderContext) -> AnyElement { - let header = render_markdown_table_row(&parsed.header, &parsed.column_alignments, true, cx); + let mut max_lengths: Vec = vec![0; parsed.header.children.len()]; + + for (index, cell) in parsed.header.children.iter().enumerate() { + let length = cell.contents.len(); + max_lengths[index] = length; + } + + for row in &parsed.body { + for (index, cell) in row.children.iter().enumerate() { + let length = cell.contents.len(); + if length > max_lengths[index] { + max_lengths[index] = length; + } + } + } + + let total_max_length: usize = max_lengths.iter().sum(); + let max_column_widths: Vec = max_lengths + .iter() + .map(|&length| length as f32 / total_max_length as f32) + .collect(); + + let header = render_markdown_table_row( + &parsed.header, + &parsed.column_alignments, + &max_column_widths, + true, + cx, + ); let body: Vec = parsed .body .iter() - .map(|row| render_markdown_table_row(row, &parsed.column_alignments, false, cx)) + .map(|row| { + render_markdown_table_row( + row, + &parsed.column_alignments, + &max_column_widths, + false, + cx, + ) + }) .collect(); cx.with_common_p(v_flex()) @@ -249,14 +285,15 @@ fn render_markdown_table(parsed: &ParsedMarkdownTable, cx: &mut RenderContext) - fn render_markdown_table_row( parsed: &ParsedMarkdownTableRow, alignments: &Vec, + max_column_widths: &Vec, is_header: bool, cx: &mut RenderContext, ) -> AnyElement { let mut items = vec![]; - for cell in &parsed.children { + for (index, cell) in parsed.children.iter().enumerate() { let alignment = alignments - .get(items.len()) + .get(index) .copied() .unwrap_or(ParsedMarkdownTableAlignment::None); @@ -268,8 +305,11 @@ fn render_markdown_table_row( ParsedMarkdownTableAlignment::Right => v_flex().items_end(), }; + let max_width = max_column_widths.get(index).unwrap_or(&0.0); + let mut cell = container - .w_full() + .w(Length::Definite(relative(*max_width))) + .h_full() .child(contents) .px_2() .py_1()