diff --git a/cracked_md/src/ast.rs b/cracked_md/src/ast.rs index 964cd54..466938a 100644 --- a/cracked_md/src/ast.rs +++ b/cracked_md/src/ast.rs @@ -16,15 +16,10 @@ pub enum Block { language: Option, content: String, }, - List(Vec), + List(Vec), Quote(Vec), } -#[derive(Debug, Clone, PartialEq)] -pub struct ListItem { - pub blocks: Vec, -} - #[derive(Debug, Clone, PartialEq)] pub enum Inline { Text(String), diff --git a/cracked_md/src/parser/block.rs b/cracked_md/src/parser/block.rs index d6e000c..93f7f19 100644 --- a/cracked_md/src/parser/block.rs +++ b/cracked_md/src/parser/block.rs @@ -48,6 +48,11 @@ pub fn parse_blocks(input: &str) -> Result, MdParseError> { } */ + // unordered list TODO + if line_chars.parse_str("- ") { + todo!() + } + // code if line_chars.parse_str("```") { let lang_line: String = line_chars.collect(); diff --git a/cracked_md/src/parser/inline.rs b/cracked_md/src/parser/inline.rs index 7c8ad78..8cb28e8 100644 --- a/cracked_md/src/parser/inline.rs +++ b/cracked_md/src/parser/inline.rs @@ -36,12 +36,18 @@ pub fn parse_inlines(input: &str) -> Result, MdParseError> { _ => { let mut text = String::new(); text.push(c); + let mut escaped = false; while let Some(&nc) = chars.peek() { - if matches!(nc, '*' | '_' | '`' | '[') { + if matches!(nc, '*' | '_' | '`' | '[') && !escaped { break; } - let c = chars.next().ok_or(MdParseError::new("a character", ""))?; - text.push(c); + let next_c = chars.next().ok_or(MdParseError::new("a character", ""))?; + if next_c == '\\' && !escaped { + escaped = true; + } else { + escaped = false; + text.push(next_c); + } } inlines.push(Inline::Text(text)); } @@ -138,15 +144,18 @@ mod test { #[test] fn single_hyperlink() { - let md = "[my site](https://example.com)"; + let md = "a link to [my site](https://example.com)"; let inl = parse_inlines(md).unwrap(); assert_eq!( inl, - vec![Inline::Link { - text: vec![Inline::Text("my site".to_string())], - href: "https://example.com".to_string() - }] + vec![ + Inline::Text("a link to ".to_string()), + Inline::Link { + text: vec![Inline::Text("my site".to_string())], + href: "https://example.com".to_string() + } + ] ); } @@ -157,4 +166,18 @@ mod test { assert!(inl.is_err()); } + + #[test] + fn escape_brackets() { + let md = r"some \[text\]"; + let inl = parse_inlines(md).unwrap(); + assert_eq!(inl, vec![Inline::Text("some [text]".to_string())]); + } + + #[test] + fn escape_escape() { + let md = r"backslash \\"; + let inl = parse_inlines(md).unwrap(); + assert_eq!(inl, vec![Inline::Text(r"backslash \".to_string())]); + } }