summaryrefslogtreecommitdiff
path: root/src/table.rs
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-12-12 19:40:59 +1300
committerBen Bridle <ben@derelict.engineering>2025-12-12 19:45:04 +1300
commitd8124660ca49d1f335c71c258f455cb88492e706 (patch)
treeaed98709358a9110e0c67ae67efc7b9252b8e58d /src/table.rs
parentdf45ffb3affb7cb1d53b567b70fef721353ccffe (diff)
downloadmarkdown-d8124660ca49d1f335c71c258f455cb88492e706.zip
Ignore pipe characters inside styled tokens in tables
Diffstat (limited to 'src/table.rs')
-rw-r--r--src/table.rs35
1 files changed, 24 insertions, 11 deletions
diff --git a/src/table.rs b/src/table.rs
index ecc4f45..f4a0573 100644
--- a/src/table.rs
+++ b/src/table.rs
@@ -66,33 +66,46 @@ impl Alignment {
/// 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)>> {
+fn split_columns(line: &str) -> Option<Vec<(String, bool)>> {
if let Some(("", tail)) = line.split_once('|') {
if let Some((head, "")) = tail.rsplit_once('|') {
- 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;
+ let mut cells: Vec<(String, bool)> = Vec::new();
+ let mut cell = String::new();
+ let mut context = None;
+ for c in head.chars() {
+ if Some(c) == context {
+ context = None;
+ } else if "$`*_".contains(c) {
+ context = Some(c);
+ } else if c == '|' && context.is_none() {
+ if !cell.is_empty() {
+ cells.push((std::mem::take(&mut cell), false));
+ } else if let Some(prev_cell) = cells.last_mut() {
+ prev_cell.1 = true;
}
- } else {
- output.push((cell.trim(), false));
+ continue;
}
+ cell.push(c);
}
- return Some(output);
+ if !cell.is_empty() {
+ cells.push((std::mem::take(&mut cell), false));
+ } else if let Some(prev_cell) = cells.last_mut() {
+ prev_cell.1 = true;
+ }
+ return Some(cells);
}
}
return None;
}
fn split_cells(line: &str) -> Option<Vec<Line>> {
- Some(split_columns(line)?.into_iter().map(|(cell, _)| Line::from_str(cell)).collect())
+ Some(split_columns(line)?.into_iter().map(|(cell, _)| Line::from_str(&cell)).collect())
}
fn parse_alignments(line: &str) -> Option<Vec<(Alignment, bool)>> {
let mut alignments = Vec::new();
for (cell, border_right) in split_columns(line)? {
- alignments.push((Alignment::from_str(cell)?, border_right));
+ alignments.push((Alignment::from_str(&cell)?, border_right));
}
Some(alignments)
}