markdown: Support alignment for table cells (#7201)

Bennet Bo Fenner created

Just a small improvement as a follow up to @kierangilliam great work on
#6958

Rendering a table specified like this:
```markdown
| Left columns  | Center columns | Right columns |
| ------------- |:--------------:| -------------:|
| left foo      | center foo     | right foo     |
| left bar      | center bar     | right bar     |
| left baz      | center baz     | right baz     |
```
Does now look like this (notice the cell alignments):

![image](https://github.com/zed-industries/zed/assets/53836821/0f5b6a1e-a3c2-4fe9-bdcb-8654dbae7980)

Release Notes:
- N/A

Change summary

crates/markdown_preview/src/markdown_renderer.rs | 30 ++++++++++++++---
1 file changed, 24 insertions(+), 6 deletions(-)

Detailed changes

crates/markdown_preview/src/markdown_renderer.rs 🔗

@@ -5,7 +5,7 @@ use gpui::{
     Styled, StyledText, WindowContext,
 };
 use language::LanguageRegistry;
-use pulldown_cmark::{CodeBlockKind, Event, HeadingLevel, Options, Parser, Tag};
+use pulldown_cmark::{Alignment, CodeBlockKind, Event, HeadingLevel, Options, Parser, Tag};
 use rich_text::render_rich_text;
 use theme::{ActiveTheme, Theme};
 use ui::{h_flex, v_flex};
@@ -16,6 +16,7 @@ enum TableState {
 }
 
 struct MarkdownTable {
+    column_alignments: Vec<Alignment>,
     header: Vec<Div>,
     body: Vec<Vec<Div>>,
     current_row: Vec<Div>,
@@ -24,8 +25,9 @@ struct MarkdownTable {
 }
 
 impl MarkdownTable {
-    fn new(border_color: Hsla) -> Self {
+    fn new(border_color: Hsla, column_alignments: Vec<Alignment>) -> Self {
         Self {
+            column_alignments,
             header: Vec::new(),
             body: Vec::new(),
             current_row: Vec::new(),
@@ -47,9 +49,15 @@ impl MarkdownTable {
     }
 
     fn add_cell(&mut self, contents: AnyElement) {
-        let cell = div()
-            .child(contents)
+        let container = match self.alignment_for_next_cell() {
+            Alignment::Left | Alignment::None => div(),
+            Alignment::Center => v_flex().items_center(),
+            Alignment::Right => v_flex().items_end(),
+        };
+
+        let cell = container
             .w_full()
+            .child(contents)
             .px_2()
             .py_1()
             .border_color(self.border_color);
@@ -79,6 +87,13 @@ impl MarkdownTable {
         }
         table
     }
+
+    fn alignment_for_next_cell(&self) -> Alignment {
+        self.column_alignments
+            .get(self.current_row.len())
+            .copied()
+            .unwrap_or(Alignment::None)
+    }
 }
 
 struct Renderer<I> {
@@ -141,8 +156,11 @@ where
             Tag::BlockQuote => {
                 self.block_quote_depth += 1;
             }
-            Tag::Table(_text_alignments) => {
-                self.table = Some(MarkdownTable::new(self.theme.colors().border));
+            Tag::Table(column_alignments) => {
+                self.table = Some(MarkdownTable::new(
+                    self.theme.colors().border,
+                    column_alignments,
+                ));
             }
             _ => {}
         }