Skip to content

Commit

Permalink
Fix individual table cells being split
Browse files Browse the repository at this point in the history
Each cell must be wrapped in ui.horizontal. This unfortunately requires
parsing the table before drawing the events.
  • Loading branch information
lampsitter committed Mar 20, 2024
1 parent 733df51 commit cb84930
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 15 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Fixed

- A single table cell split into multiple cells ([#35](https://github.com/lampsitter/egui_commonmark/pull/35))

## 0.13.0 - 2024-02-20

### Added
Expand Down
4 changes: 4 additions & 0 deletions examples/book.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ fn main() {
name: "Block Quotes ".to_owned(),
content: include_str!("markdown/blockquotes.md").to_owned(),
},
Page {
name: "Tables ".to_owned(),
content: include_str!("markdown/tables.md").to_owned(),
},
],
})
}),
Expand Down
9 changes: 9 additions & 0 deletions examples/markdown/tables.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Tables

Column A | Column B
-----------|----------
`item` `a1` | item b1
item a2 | item b2
item a3 | item b3
item a4 | item b4

97 changes: 82 additions & 15 deletions src/parsers/pulldown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,59 @@ fn delayed_events<'e>(
}
}

struct Column<'e>(Vec<pulldown_cmark::Event<'e>>);
struct Row<'e>(Vec<Column<'e>>);

struct Table<'e> {
header: Row<'e>,
rows: Vec<Row<'e>>,
}

fn parse_row<'e>(events: &mut impl Iterator<Item = pulldown_cmark::Event<'e>>) -> Vec<Column<'e>> {
let mut row = Vec::new();
let mut column = Vec::new();

for e in events.by_ref() {
if let pulldown_cmark::Event::End(pulldown_cmark::TagEnd::TableCell) = e {
row.push(Column(column));
column = Vec::new();
}

if let pulldown_cmark::Event::End(pulldown_cmark::TagEnd::TableHead) = e {
break;
}

if let pulldown_cmark::Event::End(pulldown_cmark::TagEnd::TableRow) = e {
break;
}

column.push(e);
}

row
}

fn parse_table<'e>(
events: &mut impl Iterator<Item = (usize, pulldown_cmark::Event<'e>)>,
) -> Table<'e> {
let mut all_events = delayed_events(events, pulldown_cmark::TagEnd::Table)
.into_iter()
.peekable();

let header = parse_row(&mut all_events);

let mut rows = Vec::new();
while all_events.peek().is_some() {
let row = parse_row(&mut all_events);
rows.push(Row(row));
}

Table {
header: Row(header),
rows,
}
}

/// try to parse events as an alert quote block. This ill modify the events
/// to remove the parsed text that should not be rendered.
/// Assumes that the first element is a Paragraph
Expand Down Expand Up @@ -352,17 +405,35 @@ impl CommonMarkViewerInternal {
if self.is_table {
newline(ui);

egui::Frame::group(ui.style()).show(ui, |ui| {
let id = self.source_id.with(self.curr_table);
self.curr_table += 1;
let id = self.source_id.with(self.curr_table);
self.curr_table += 1;

ui.push_id(id, |ui| {
let Table { header, rows } = parse_table(events);

egui::Grid::new(id).striped(true).show(ui, |ui| {
while self.is_table {
if let Some((_, e)) = events.next() {
self.should_insert_newline = false;
self.event(ui, e, cache, options, max_width);
} else {
break;
for col in header.0 {
ui.horizontal(|ui| {
for e in col.0 {
self.should_insert_newline = false;
self.event(ui, e, cache, options, max_width);
}
});
}

ui.end_row();

for row in rows {
for col in row.0 {
ui.horizontal(|ui| {
for e in col.0 {
self.should_insert_newline = false;
self.event(ui, e, cache, options, max_width);
}
});
}

ui.end_row();
}
});
});
Expand Down Expand Up @@ -535,12 +606,8 @@ impl CommonMarkViewerInternal {
pulldown_cmark::TagEnd::Table => {
self.is_table = false;
}
pulldown_cmark::TagEnd::TableHead => {
ui.end_row();
}
pulldown_cmark::TagEnd::TableRow => {
ui.end_row();
}
pulldown_cmark::TagEnd::TableHead => {}
pulldown_cmark::TagEnd::TableRow => {}
pulldown_cmark::TagEnd::TableCell => {
// Ensure space between cells
ui.label(" ");
Expand Down

0 comments on commit cb84930

Please sign in to comment.