diff options
Diffstat (limited to 'code/src/markdown/parser.rs')
-rw-r--r-- | code/src/markdown/parser.rs | 167 |
1 files changed, 3 insertions, 164 deletions
diff --git a/code/src/markdown/parser.rs b/code/src/markdown/parser.rs index 94eab49..8876335 100644 --- a/code/src/markdown/parser.rs +++ b/code/src/markdown/parser.rs @@ -1,3 +1,6 @@ +use pest::Parser; +use pest_derive::Parser; + #[derive(Debug, Clone)] pub enum Block { Header(usize, Vec<Span>), @@ -21,167 +24,3 @@ pub enum Span { Strong(Vec<Span>), Latex(String), } - -pub fn parse(mut s: &str) -> Vec<Block> { - let mut blocks = Vec::new(); - while s.len() != 0 { - if s.starts_with("\n") { - s = &s[1..]; - continue; - } - // TODO bad code here - if let Some((block, rest)) = try_header(s) { - s = rest; - blocks.push(block); - continue; - } - if let Some((block, rest)) = try_latex_block(s) { - s = rest; - blocks.push(block); - continue; - } - if let Some((block, rest)) = try_code_block(s) { - s = rest; - blocks.push(block); - continue; - } - if let Some((block, rest)) = try_list(s) { - s = rest; - blocks.push(block); - continue; - } - let lf = [s.find("\n\n"), s.find("\n-")] - .iter() - .filter_map(|e| *e) - .min() - .unwrap_or(s.len()); - let span = Span::parse(&s[..lf]); - blocks.push(Block::Paragraph(span)); - if lf >= s.len() { - break; - } - s = &s[lf + 1..]; - } - blocks -} - -fn try_code_block(mut s: &str) -> Option<(Block, &str)> { - if !s.starts_with("```") { - return None; - } - s = &s[3..]; - let lf = s.find('\n')?; - let syntax = if lf != 0 { - Some(String::from(&s[0..lf])) - } else { - None - }; - s = &s[lf..]; - let end = s.find("\n```\n")?; - Some(( - Block::CodeBlock(syntax, String::from(&s[..end])), - &s[end + 4..], - )) -} -fn try_latex_block(mut s: &str) -> Option<(Block, &str)> { - if !s.starts_with("$$") { - return None; - } - s = &s[2..]; - let end = s.find("$$")?; - Some((Block::LatexBlock(String::from(&s[..end])), &s[end + 2..])) -} -fn try_list(mut s: &str) -> Option<(Block, &str)> { - if !s.starts_with("-") { - return None; - }; - let mut blocks = vec![]; - loop { - if !s.starts_with("-") || s.len() == 0 { - break Some((Block::UnorderedList(blocks), s)); - } - s = &s[1..]; - let mut lf = s.find("\n").unwrap(); - while s[lf + 1..].starts_with(" ") { - lf += 2 + s[lf + 2..].find("\n").unwrap(); - } - let mut k = s[..lf] - .split("\n") - .map(|l| if l.starts_with(" ") { &l[2..] } else { &l }) - .collect::<Vec<_>>() - .join("\n"); - k.push('\n'); - blocks.push(parse(&k)); - s = &s[lf + 1..]; - } -} -fn try_header(s: &str) -> Option<(Block, &str)> { - if s.starts_with("#") { - let mut u = 0; - while s.chars().nth(u)? == '#' { - u += 1; - } - let lf = s.find('\n')?; - Some((Block::Header(u, Span::parse(&s[u..lf])), &s[lf + 1..])) - } else { - None - } -} - -impl Span { - pub fn parse(mut s: &str) -> Vec<Span> { - let mut spans = Vec::new(); - while s.len() != 0 { - let nt = s.find(&['*', '_', '`', '[', '$']); - - if let Some(nt) = nt { - spans.push(Span::Text(String::from(&s[..nt]))); - s = &s[nt..]; - if s.starts_with("**") { - s = &s[2..]; - let end = s.find("**").expect("** not ended"); - spans.push(Span::Strong(Span::parse(&s[..end]))); - s = &s[end + 2..]; - continue; - } - if s.starts_with("_") { - s = &s[1..]; - let end = s.find("_").expect("_ not ended"); - spans.push(Span::Emphasis(Span::parse(&s[..end]))); - s = &s[end + 1..]; - continue; - } - if s.starts_with("`") { - s = &s[1..]; - let end = s.find("`").expect("` not ended"); - spans.push(Span::Code(String::from(&s[..end]))); - s = &s[end + 1..]; - continue; - } - if s.starts_with("$") { - s = &s[1..]; - let end = s.find("$").expect("$ not ended"); - spans.push(Span::Latex(String::from(&s[..end]))); - s = &s[end + 1..]; - continue; - } - if s.starts_with("[") { - s = &s[1..]; - let del = s.find("](").expect("]( expected"); - let end = del + s[del..].find(")").expect(") expected"); - spans.push(Span::Link( - String::from(&s[..del]), - String::from(&s[del + 2..end]), - )); - s = &s[end + 1..]; - continue; - } - panic!("{s:?}") - } else { - spans.push(Span::Text(String::from(s))); - break; - } - } - spans - } -} |