refactor md parser, TODO: parse_str
Some checks failed
Test the running changes / Test (push) Failing after 44s

This commit is contained in:
2025-11-14 02:22:51 +02:00
parent ddd6d072f9
commit 05a0b32d9b
7 changed files with 382 additions and 42 deletions

View File

@@ -1,61 +1,65 @@
use crate::ast::Inline;
use crate::{MdParseError, ast::Inline};
pub fn parse_inlines(input: &str) -> Vec<Inline> {
pub fn parse_inlines(input: &str) -> Result<Vec<Inline>, MdParseError> {
let mut inlines = Vec::new();
let mut chars = input.chars().peekable();
while let Some(c) = chars.next() {
match c {
'*' => {
let inner = collect_until(&mut chars, '*');
inlines.push(Inline::Bold(parse_inlines(&inner)));
let inner = collect_until(&mut chars, '*')?;
inlines.push(Inline::Bold(parse_inlines(&inner)?));
}
'_' => {
let inner = collect_until(&mut chars, '_');
inlines.push(Inline::Italic(parse_inlines(&inner)));
let inner = collect_until(&mut chars, '_')?;
inlines.push(Inline::Italic(parse_inlines(&inner)?));
}
'`' => {
let code = collect_until(&mut chars, '`');
let code = collect_until(&mut chars, '`')?;
inlines.push(Inline::Code(code));
}
'[' => {
let text = collect_until(&mut chars, ']');
if chars.next() == Some('(') {
let href = collect_until(&mut chars, ')');
let text = collect_until(&mut chars, ']')?;
if let Some('(') = chars.next() {
let href = collect_until(&mut chars, ')')?;
inlines.push(Inline::Link {
text: parse_inlines(&text),
text: parse_inlines(&text)?,
href,
});
} else {
Err(MdParseError::new(
"(<href>)",
chars.next().unwrap_or_default(),
))?;
}
}
_ => {
let mut text = String::new();
text.push(c);
while let Some(&nc) = chars.peek() {
while let Some(nc) = chars.next() {
if matches!(nc, '*' | '_' | '`' | '[') {
break;
}
text.push(chars.next().unwrap());
text.push(nc);
}
inlines.push(Inline::Text(text));
}
}
}
inlines
Ok(inlines)
}
fn collect_until<I: Iterator<Item = char>>(
chars: &mut std::iter::Peekable<I>,
end: char,
) -> String {
) -> Result<String, MdParseError> {
let mut s = String::new();
while let Some(&c) = chars.peek() {
while let Some(c) = chars.next() {
if c == end {
chars.next();
break;
return Ok(s);
}
s.push(chars.next().unwrap());
s.push(c);
}
s
Err(MdParseError::new(end, ""))
}