summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bridle <bridle.benjamin@gmail.com>2025-01-22 13:47:57 +1300
committerBen Bridle <bridle.benjamin@gmail.com>2025-01-22 13:47:57 +1300
commitd1afb61329bdd6b263fc3c8f81533c7d8a71877a (patch)
treec1db17858702ba0d6fab06ee2212b23fc8e6237a
parent7933e285f9df67141094935ed4d1e525a920315b (diff)
downloadmarkdown-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.rs27
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)
}