diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/line.rs | 11 | ||||
| -rw-r--r-- | src/table.rs | 39 | ||||
| -rw-r--r-- | src/token.rs | 13 |
3 files changed, 46 insertions, 17 deletions
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, }, } } |
