summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--src/line.rs11
-rw-r--r--src/table.rs39
-rw-r--r--src/token.rs13
4 files changed, 47 insertions, 18 deletions
diff --git a/Cargo.toml b/Cargo.toml
index a3671b5..3112b1e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "markdown"
-version = "3.1.0"
+version = "3.3.2"
authors = ["Ben Bridle <ben@derelict.engineering>"]
edition = "2021"
diff --git a/src/line.rs b/src/line.rs
index b60b55c..5ef940f 100644
--- a/src/line.rs
+++ b/src/line.rs
@@ -81,6 +81,15 @@ impl ToString for Line {
}
}
+fn internal_link(inside: String) -> Option<Token> {
+ if let Some((label, path)) = inside.split_once("::") {
+ let label = label.trim().to_string();
+ let path = path.trim().to_string();
+ Some( Token::InternalLink { label, path } )
+ } else {
+ Some( Token::InternalLink { label: String::new(), path: inside })
+ }
+}
fn external_link(inside: String) -> Option<Token> {
if let Some((label, path)) = inside.split_once("::") {
@@ -101,7 +110,7 @@ const DELIMITERS: [(fn(String)->Option<Token>, &str, &str, &str); 6] = [
( make!(Token::Italic), "_", "_", "_" ),
( make!(Token::Monospace), "`", "`", "`" ),
( make!(Token::Math), "$", "$", "$" ),
- ( make!(Token::InternalLink), "{", "}", "{}" ),
+ ( internal_link, "{", "}", "{}" ),
( external_link, "<", ">", "<>" ),
];
diff --git a/src/table.rs b/src/table.rs
index ecc4f45..bfd9177 100644
--- a/src/table.rs
+++ b/src/table.rs
@@ -66,33 +66,50 @@ 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 Some(c) == context {
+ context = None;
+ } else if context.is_none() {
+ 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;
+ }
+ continue;
}
- } else {
- output.push((cell.trim(), false));
}
+ 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)
}
diff --git a/src/token.rs b/src/token.rs
index f1f8288..0f44dc2 100644
--- a/src/token.rs
+++ b/src/token.rs
@@ -5,7 +5,7 @@ pub enum Token {
Italic(String),
Monospace(String),
Math(String),
- InternalLink(String),
+ InternalLink { label: String, path: String },
ExternalLink { label: String, path: String },
}
@@ -17,10 +17,13 @@ impl AsRef<str> for Token {
Token::Italic(text) => text,
Token::Monospace(text) => text,
Token::Math(text) => text,
- Token::InternalLink(name) => name,
- Token::ExternalLink { label, path } => match !label.is_empty() {
- true => label,
- false => path,
+ Token::InternalLink { label, path } => match label.is_empty() {
+ true => path,
+ false => label,
+ },
+ Token::ExternalLink { label, path } => match label.is_empty() {
+ true => path,
+ false => label,
},
}
}