diff options
author | Ben Bridle <bridle.benjamin@gmail.com> | 2025-01-22 13:47:57 +1300 |
---|---|---|
committer | Ben Bridle <bridle.benjamin@gmail.com> | 2025-01-22 13:47:57 +1300 |
commit | d1afb61329bdd6b263fc3c8f81533c7d8a71877a (patch) | |
tree | c1db17858702ba0d6fab06ee2212b23fc8e6237a | |
parent | 7933e285f9df67141094935ed4d1e525a920315b (diff) | |
download | markdown-d1afb61329bdd6b263fc3c8f81533c7d8a71877a.zip |
Double-thickness table walls represent a vertical separator
Consecutive pipe characters in a table row are parsed as a single
separator, with the 'border-right' attribute being given to the column
on the left of the separator. Only the first alignments line is used
when determining this attribute for columns.
This is useful for tables with row labels running down the left-most
cell column, to visually separate labels from data.
-rw-r--r-- | src/table.rs | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/src/table.rs b/src/table.rs index 071bd1a..ecc4f45 100644 --- a/src/table.rs +++ b/src/table.rs @@ -16,7 +16,7 @@ impl Table { let names = split_cells(lines.next()?)?; let alignments = parse_alignments(lines.next()?)?; if names.len() != alignments.len() { return None } - let make_column = |(n, a)| Column { name: n, alignment: a }; + let make_column = |(n, (a, b))| Column { name: n, alignment: a, border_right: b }; std::iter::zip(names, alignments).map(make_column).collect() }; let mut sections = Vec::new(); @@ -42,6 +42,7 @@ impl Table { pub struct Column { pub name: Line, pub alignment: Alignment, + pub border_right: bool, } pub enum Alignment { @@ -63,23 +64,35 @@ impl Alignment { } } -fn split_columns(line: &str) -> Option<Vec<&str>> { +/// Returns the contents of each cell in the row, and whether the right edge +/// is a vertical border. +fn split_columns(line: &str) -> Option<Vec<(&str, bool)>> { if let Some(("", tail)) = line.split_once('|') { if let Some((head, "")) = tail.rsplit_once('|') { - return Some(head.split('|').map(str::trim).collect()); + let mut output: Vec<(&str, bool)> = Vec::new(); + for cell in head.split('|') { + if cell.is_empty () { + if let Some(last) = output.last_mut() { + last.1 = true; + } + } else { + output.push((cell.trim(), false)); + } + } + return Some(output); } } return None; } fn split_cells(line: &str) -> Option<Vec<Line>> { - Some(split_columns(line)?.into_iter().map(Line::from_str).collect()) + Some(split_columns(line)?.into_iter().map(|(cell, _)| Line::from_str(cell)).collect()) } -fn parse_alignments(line: &str) -> Option<Vec<Alignment>> { +fn parse_alignments(line: &str) -> Option<Vec<(Alignment, bool)>> { let mut alignments = Vec::new(); - for cell in split_columns(line)? { - alignments.push(Alignment::from_str(cell)?); + for (cell, border_right) in split_columns(line)? { + alignments.push((Alignment::from_str(cell)?, border_right)); } Some(alignments) } |