Skip to content

Commit 3bec4eb

Browse files
authored
markdown: Add initial support for tables (#25954)
This PR adds initial support for displaying tables to the `markdown` crate. This allows us to render tables in Assistant 2: | Before | After | | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | <img width="1309" alt="Screenshot 2025-03-03 at 1 39 39 PM" src="https://github.com/user-attachments/assets/ad7ada01-f35d-4fcf-a20c-deb42b55b34e" /> | <img width="1297" alt="Screenshot 2025-03-03 at 3 38 21 PM" src="https://github.com/user-attachments/assets/9b771126-30a0-479b-8c29-f5f572936f56" /> | There are a few known issues that should be addressed as follow-ups: - The horizontal scrolling within a table is linked with the scrolling of the parent container (e.g., the Assistant 2 thread) - Cells are currently cut off entirely when they are too wide, would be nice to truncate them with an ellipsis Release Notes: - N/A
1 parent bf6cc26 commit 3bec4eb

File tree

1 file changed

+78
-3
lines changed

1 file changed

+78
-3
lines changed

crates/markdown/src/markdown.rs

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
pub mod parser;
22

3-
use crate::parser::CodeBlockKind;
3+
use std::collections::HashMap;
4+
use std::iter;
5+
use std::mem;
6+
use std::ops::Range;
7+
use std::rc::Rc;
8+
use std::sync::Arc;
9+
410
use gpui::{
511
actions, point, quad, AnyElement, App, Bounds, ClipboardItem, CursorStyle, DispatchPhase,
612
Edges, Entity, FocusHandle, Focusable, FontStyle, FontWeight, GlobalElementId, Hitbox, Hsla,
@@ -10,12 +16,13 @@ use gpui::{
1016
};
1117
use language::{Language, LanguageRegistry, Rope};
1218
use parser::{parse_links_only, parse_markdown, MarkdownEvent, MarkdownTag, MarkdownTagEnd};
13-
14-
use std::{collections::HashMap, iter, mem, ops::Range, rc::Rc, sync::Arc};
19+
use pulldown_cmark::Alignment;
1520
use theme::SyntaxTheme;
1621
use ui::{prelude::*, Tooltip};
1722
use util::{ResultExt, TryFutureExt};
1823

24+
use crate::parser::CodeBlockKind;
25+
1926
#[derive(Clone)]
2027
pub struct MarkdownStyle {
2128
pub base_text_style: TextStyle,
@@ -654,6 +661,57 @@ impl Element for MarkdownElement {
654661
}
655662
}
656663
MarkdownTag::MetadataBlock(_) => {}
664+
MarkdownTag::Table(alignments) => {
665+
builder.table_alignments = alignments.clone();
666+
builder.push_div(
667+
div()
668+
.id(("table", range.start))
669+
.flex()
670+
.border_1()
671+
.border_color(cx.theme().colors().border)
672+
.rounded_md()
673+
.overflow_x_scroll(),
674+
range,
675+
markdown_end,
676+
);
677+
// This inner `v_flex` is so the table rows will stack vertically without disrupting the `overflow_x_scroll`.
678+
builder.push_div(div().v_flex().flex_grow(), range, markdown_end);
679+
}
680+
MarkdownTag::TableHead => {
681+
builder.push_div(
682+
div()
683+
.flex()
684+
.justify_between()
685+
.border_b_1()
686+
.border_color(cx.theme().colors().border),
687+
range,
688+
markdown_end,
689+
);
690+
builder.push_text_style(TextStyleRefinement {
691+
font_weight: Some(FontWeight::BOLD),
692+
..Default::default()
693+
});
694+
}
695+
MarkdownTag::TableRow => {
696+
builder.push_div(
697+
div().h_flex().justify_between().px_1().py_0p5(),
698+
range,
699+
markdown_end,
700+
);
701+
}
702+
MarkdownTag::TableCell => {
703+
let column_count = builder.table_alignments.len();
704+
705+
builder.push_div(
706+
div()
707+
.flex()
708+
.px_1()
709+
.w(relative(1. / column_count as f32))
710+
.truncate(),
711+
range,
712+
markdown_end,
713+
);
714+
}
657715
_ => log::error!("unsupported markdown tag {:?}", tag),
658716
}
659717
}
@@ -723,6 +781,21 @@ impl Element for MarkdownElement {
723781
builder.pop_text_style()
724782
}
725783
}
784+
MarkdownTagEnd::Table => {
785+
builder.pop_div();
786+
builder.pop_div();
787+
builder.table_alignments.clear();
788+
}
789+
MarkdownTagEnd::TableHead => {
790+
builder.pop_div();
791+
builder.pop_text_style();
792+
}
793+
MarkdownTagEnd::TableRow => {
794+
builder.pop_div();
795+
}
796+
MarkdownTagEnd::TableCell => {
797+
builder.pop_div();
798+
}
726799
_ => log::error!("unsupported markdown tag end: {:?}", tag),
727800
},
728801
MarkdownEvent::Text(parsed) => {
@@ -869,6 +942,7 @@ struct MarkdownElementBuilder {
869942
text_style_stack: Vec<TextStyleRefinement>,
870943
code_block_stack: Vec<Option<Arc<Language>>>,
871944
list_stack: Vec<ListStackEntry>,
945+
table_alignments: Vec<Alignment>,
872946
syntax_theme: Arc<SyntaxTheme>,
873947
}
874948

@@ -895,6 +969,7 @@ impl MarkdownElementBuilder {
895969
text_style_stack: Vec::new(),
896970
code_block_stack: Vec::new(),
897971
list_stack: Vec::new(),
972+
table_alignments: Vec::new(),
898973
syntax_theme,
899974
}
900975
}

0 commit comments

Comments
 (0)