added support for parsing lists
All checks were successful
Test the running changes / Test (push) Successful in 32s

This commit is contained in:
2025-12-26 16:36:57 +02:00
parent 03b5360ec5
commit 34304546ad
3 changed files with 121 additions and 2 deletions

View File

@@ -31,4 +31,6 @@ pub enum Block {
Code { content: String, lang: String },
Quote { inner: Box<Block> },
Paragraph { inner: Vec<Inline> },
UnorderedList { items: Vec<Block> },
OrderedList { items: Vec<Block> },
}

View File

@@ -15,12 +15,28 @@ impl ToHtml for Vec<Block> {
impl ToHtml for Block {
fn to_html(&self) -> String {
match self {
Block::Paragraph { inner } => format!("<p>{}</p><br>", inner.to_html()),
Block::Paragraph { inner } => format!("<p>{}</p>", inner.to_html()),
Block::Heading { inner, level } => {
format!("<h{}>{}</h{}>", level, inner.to_html(), level)
}
Block::Code { content, lang: _ } => format!("<pre><code>{content}</code></pre>"),
Block::Quote { inner } => format!("<div class=\"quote\">{}</div>", inner.to_html()),
Block::UnorderedList { items } => {
let mut html = "<ul>".to_string();
for item in items {
html.push_str(&format!("<li>{}</li>", &item.to_html()));
}
html.push_str("</ul>");
html
}
Block::OrderedList { items } => {
let mut html = "<ol>".to_string();
for item in items {
html.push_str(&format!("<li>{}</li>", &item.to_html()));
}
html.push_str("</ol>");
html
}
}
}
}

View File

@@ -17,7 +17,14 @@ pub fn blocks(input: &str) -> IResult<&str, Vec<Block>, MarkdownParseError> {
pub fn block(input: &str) -> IResult<&str, Block, MarkdownParseError> {
//alt((heading_block, code_block, quote_block, paragraph_block)).parse(input)
terminated(
alt((heading_block, code_block, quote_block, paragraph_block)),
alt((
heading_block,
code_block,
quote_block,
paragraph_block,
ordered_list,
unordered_list,
)),
tag("\n"),
)
.parse(input)
@@ -74,6 +81,20 @@ fn quote_block(input: &str) -> IResult<&str, Block, MarkdownParseError> {
})
}
fn unordered_list(input: &str) -> IResult<&str, Block, MarkdownParseError> {
many1((tag("- "), block)).parse(input).map(|(rem, v)| {
let items = v.into_iter().map(|(_, b)| b).collect();
(rem, Block::UnorderedList { items })
})
}
fn ordered_list(input: &str) -> IResult<&str, Block, MarkdownParseError> {
many1((tag("1. "), block)).parse(input).map(|(rem, v)| {
let items = v.into_iter().map(|(_, b)| b).collect();
(rem, Block::OrderedList { items })
})
}
//|-------------------------------------------------------------------------------|
//| TESTS TESTS TESTS TESTS TESTS TESTS TESTS TESTS TESTS TESTS TESTS TESTS TESTS |
//|-------------------------------------------------------------------------------|
@@ -235,4 +256,84 @@ Hello MD
]
);
}
#[test]
fn simple_unordered_list() {
let md = "- a\n- b\n- c\n- b again with some `code`\n\n";
let (rem, block) = unordered_list(md).unwrap();
assert_eq!(rem, "\n");
assert_eq!(
block,
Block::UnorderedList {
items: vec![
Block::Paragraph {
inner: vec![Inline::Text {
content: "a".to_string()
}]
},
Block::Paragraph {
inner: vec![Inline::Text {
content: "b".to_string()
}]
},
Block::Paragraph {
inner: vec![Inline::Text {
content: "c".to_string()
}]
},
Block::Paragraph {
inner: vec![
Inline::Text {
content: "b again with some ".to_string()
},
Inline::Code {
content: "code".to_string()
}
]
},
]
}
);
}
#[test]
fn simple_ordered_list() {
let md = "1. a\n1. b\n1. c\n1. b again with some `code`\n\n";
let (rem, block) = ordered_list(md).unwrap();
assert_eq!(rem, "\n");
assert_eq!(
block,
Block::OrderedList {
items: vec![
Block::Paragraph {
inner: vec![Inline::Text {
content: "a".to_string()
}]
},
Block::Paragraph {
inner: vec![Inline::Text {
content: "b".to_string()
}]
},
Block::Paragraph {
inner: vec![Inline::Text {
content: "c".to_string()
}]
},
Block::Paragraph {
inner: vec![
Inline::Text {
content: "b again with some ".to_string()
},
Inline::Code {
content: "code".to_string()
}
]
},
]
}
);
}
}