diff --git a/crates/markdown/src/markdown.rs b/crates/markdown/src/markdown.rs index d31d768c303412..ad936489ab1350 100644 --- a/crates/markdown/src/markdown.rs +++ b/crates/markdown/src/markdown.rs @@ -1,6 +1,12 @@ pub mod parser; -use crate::parser::CodeBlockKind; +use std::collections::HashMap; +use std::iter; +use std::mem; +use std::ops::Range; +use std::rc::Rc; +use std::sync::Arc; + use gpui::{ actions, point, quad, AnyElement, App, Bounds, ClipboardItem, CursorStyle, DispatchPhase, Edges, Entity, FocusHandle, Focusable, FontStyle, FontWeight, GlobalElementId, Hitbox, Hsla, @@ -10,12 +16,13 @@ use gpui::{ }; use language::{Language, LanguageRegistry, Rope}; use parser::{parse_links_only, parse_markdown, MarkdownEvent, MarkdownTag, MarkdownTagEnd}; - -use std::{collections::HashMap, iter, mem, ops::Range, rc::Rc, sync::Arc}; +use pulldown_cmark::Alignment; use theme::SyntaxTheme; use ui::{prelude::*, Tooltip}; use util::{ResultExt, TryFutureExt}; +use crate::parser::CodeBlockKind; + #[derive(Clone)] pub struct MarkdownStyle { pub base_text_style: TextStyle, @@ -654,6 +661,57 @@ impl Element for MarkdownElement { } } MarkdownTag::MetadataBlock(_) => {} + MarkdownTag::Table(alignments) => { + builder.table_alignments = alignments.clone(); + builder.push_div( + div() + .id(("table", range.start)) + .flex() + .border_1() + .border_color(cx.theme().colors().border) + .rounded_md() + .overflow_x_scroll(), + range, + markdown_end, + ); + // This inner `v_flex` is so the table rows will stack vertically without disrupting the `overflow_x_scroll`. + builder.push_div(div().v_flex().flex_grow(), range, markdown_end); + } + MarkdownTag::TableHead => { + builder.push_div( + div() + .flex() + .justify_between() + .border_b_1() + .border_color(cx.theme().colors().border), + range, + markdown_end, + ); + builder.push_text_style(TextStyleRefinement { + font_weight: Some(FontWeight::BOLD), + ..Default::default() + }); + } + MarkdownTag::TableRow => { + builder.push_div( + div().h_flex().justify_between().px_1().py_0p5(), + range, + markdown_end, + ); + } + MarkdownTag::TableCell => { + let column_count = builder.table_alignments.len(); + + builder.push_div( + div() + .flex() + .px_1() + .w(relative(1. / column_count as f32)) + .truncate(), + range, + markdown_end, + ); + } _ => log::error!("unsupported markdown tag {:?}", tag), } } @@ -723,6 +781,21 @@ impl Element for MarkdownElement { builder.pop_text_style() } } + MarkdownTagEnd::Table => { + builder.pop_div(); + builder.pop_div(); + builder.table_alignments.clear(); + } + MarkdownTagEnd::TableHead => { + builder.pop_div(); + builder.pop_text_style(); + } + MarkdownTagEnd::TableRow => { + builder.pop_div(); + } + MarkdownTagEnd::TableCell => { + builder.pop_div(); + } _ => log::error!("unsupported markdown tag end: {:?}", tag), }, MarkdownEvent::Text(parsed) => { @@ -869,6 +942,7 @@ struct MarkdownElementBuilder { text_style_stack: Vec, code_block_stack: Vec>>, list_stack: Vec, + table_alignments: Vec, syntax_theme: Arc, } @@ -895,6 +969,7 @@ impl MarkdownElementBuilder { text_style_stack: Vec::new(), code_block_stack: Vec::new(), list_stack: Vec::new(), + table_alignments: Vec::new(), syntax_theme, } }