blog: refactor: apply highlight via idomatic Iterator operations
parent
8fcb7fef17
commit
994da996bc
70
src/blog.rs
70
src/blog.rs
|
@ -231,6 +231,43 @@ impl PostContentCache {
|
|||
}
|
||||
}
|
||||
|
||||
fn transform_code_block_highlight<'iter, 'ev>(
|
||||
parser: impl Iterator<Item = Event<'ev>>
|
||||
) -> impl Iterator<Item = Event<'ev>> {
|
||||
let mut in_code_block = false;
|
||||
let mut code_block_lang = None;
|
||||
parser.map(move |ev| {
|
||||
match &ev {
|
||||
Event::Start(Tag::CodeBlock(block)) => {
|
||||
in_code_block = true;
|
||||
match block {
|
||||
CodeBlockKind::Fenced(lang) => code_block_lang = Some(lang.to_string()),
|
||||
CodeBlockKind::Indented => code_block_lang = None
|
||||
}
|
||||
},
|
||||
Event::End(Tag::CodeBlock(_)) => {
|
||||
in_code_block = false;
|
||||
code_block_lang = None;
|
||||
},
|
||||
Event::Text(text) => {
|
||||
if in_code_block {
|
||||
let highlighted = if let Some(ref code_block_lang) = code_block_lang {
|
||||
crate::hljs::highlight(&code_block_lang, text)
|
||||
} else {
|
||||
crate::hljs::highlight_auto(text)
|
||||
};
|
||||
|
||||
return Event::Html(
|
||||
highlighted.into());
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
ev
|
||||
})
|
||||
}
|
||||
|
||||
// Do some HTML-level transformations to the compiled result
|
||||
// Because the Markdown parser doesn't always allow us to do
|
||||
// everything, like adding `id` attributes to tags
|
||||
|
@ -276,41 +313,22 @@ impl PostContentCache {
|
|||
// because we need to asynchronously transform the events
|
||||
// which could not be done through mapping on iterators
|
||||
let mut parser: Vec<Event> = Parser::new_ext(&post.content, Options::all()).collect();
|
||||
let mut in_code_block = false;
|
||||
let mut code_block_lang = "";
|
||||
for ev in parser.iter_mut() {
|
||||
match ev {
|
||||
Event::Start(Tag::CodeBlock(block)) => {
|
||||
in_code_block = true;
|
||||
match block {
|
||||
CodeBlockKind::Fenced(lang) => code_block_lang = lang,
|
||||
CodeBlockKind::Indented => code_block_lang = ""
|
||||
}
|
||||
},
|
||||
Event::End(Tag::CodeBlock(_)) => {
|
||||
in_code_block = false;
|
||||
code_block_lang = "";
|
||||
},
|
||||
Event::Start(tag) | Event::End(tag) => {
|
||||
Self::transform_tag(tag).await;
|
||||
},
|
||||
Event::Text(text) => {
|
||||
if in_code_block {
|
||||
let highlighted = if code_block_lang != "" {
|
||||
crate::hljs::highlight(code_block_lang, text)
|
||||
} else {
|
||||
crate::hljs::highlight_auto(text)
|
||||
};
|
||||
|
||||
*ev = Event::Html(
|
||||
highlighted.into());
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
};
|
||||
}
|
||||
|
||||
// Now some pure iterator operations
|
||||
let parser = parser.into_iter();
|
||||
// Apply code highlighting via Highlight.js
|
||||
let parser = Self::transform_code_block_highlight(parser);
|
||||
|
||||
let mut html_output = String::new();
|
||||
html::push_html(&mut html_output, parser.into_iter());
|
||||
html::push_html(&mut html_output, parser);
|
||||
html_output = Self::transform_html(html_output);
|
||||
PostContentCache {
|
||||
uuid: post.uuid.clone(),
|
||||
|
|
Loading…
Reference in New Issue