refactor(cheddar): Extract code block highlighting into function
Since I am going down the path of adding additional Markdown extensions it makes sense to avoid letting `format_markdown` turn into a giant beast of a function. Therefore this commit extracts the logic for rendering code blocks via syntect and changes the innards of `format_markdown` to instead provide arbitrary AST value replacements.
This commit is contained in:
parent
97f069db9e
commit
d4e469508f
1 changed files with 47 additions and 37 deletions
|
@ -1,4 +1,4 @@
|
||||||
use comrak::nodes::{AstNode, NodeValue, NodeHtmlBlock};
|
use comrak::nodes::{Ast, AstNode, NodeValue, NodeCodeBlock, NodeHtmlBlock};
|
||||||
use comrak::{Arena, parse_document, format_html, ComrakOptions};
|
use comrak::{Arena, parse_document, format_html, ComrakOptions};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -80,27 +80,14 @@ fn iter_nodes<'a, F>(node: &'a AstNode<'a>, f: &F) where F : Fn(&'a AstNode<'a>)
|
||||||
// Instead, try finding a syntax match by comparing case insensitively (for
|
// Instead, try finding a syntax match by comparing case insensitively (for
|
||||||
// ASCII characters, anyways).
|
// ASCII characters, anyways).
|
||||||
fn find_syntax_case_insensitive(info: &str) -> Option<&'static SyntaxReference> {
|
fn find_syntax_case_insensitive(info: &str) -> Option<&'static SyntaxReference> {
|
||||||
|
// TODO(tazjin): memoize this lookup
|
||||||
SYNTAXES.syntaxes().iter().rev().find(|&s| info.eq_ignore_ascii_case(&s.name))
|
SYNTAXES.syntaxes().iter().rev().find(|&s| info.eq_ignore_ascii_case(&s.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_markdown() {
|
// Replaces code-block inside of a Markdown AST with HTML blocks rendered by
|
||||||
let document = {
|
// syntect. This enables static (i.e. no JavaScript) syntax highlighting, even
|
||||||
let mut buffer = String::new();
|
// of complex languages.
|
||||||
let stdin = io::stdin();
|
fn highlight_code_block(code_block: &NodeCodeBlock) -> NodeValue {
|
||||||
let mut stdin = stdin.lock();
|
|
||||||
stdin.read_to_string(&mut buffer).expect("failed to read stdin");
|
|
||||||
buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
let arena = Arena::new();
|
|
||||||
let root = parse_document(&arena, &document, &MD_OPTS);
|
|
||||||
|
|
||||||
// Syntax highlighting is implemented by traversing the arena and
|
|
||||||
// replacing all code blocks with HTML blocks rendered by syntect.
|
|
||||||
iter_nodes(root, &|node| {
|
|
||||||
let mut ast = node.data.borrow_mut();
|
|
||||||
match &ast.value {
|
|
||||||
NodeValue::CodeBlock(code_block) => {
|
|
||||||
let theme = &THEMES.themes["InspiredGitHub"];
|
let theme = &THEMES.themes["InspiredGitHub"];
|
||||||
let info = String::from_utf8_lossy(&code_block.info);
|
let info = String::from_utf8_lossy(&code_block.info);
|
||||||
|
|
||||||
|
@ -132,10 +119,33 @@ fn format_markdown() {
|
||||||
literal: rendered.into_bytes(),
|
literal: rendered.into_bytes(),
|
||||||
};
|
};
|
||||||
|
|
||||||
ast.value = NodeValue::HtmlBlock(block);
|
NodeValue::HtmlBlock(block)
|
||||||
},
|
}
|
||||||
_ => (),
|
|
||||||
|
fn format_markdown() {
|
||||||
|
let document = {
|
||||||
|
let mut buffer = String::new();
|
||||||
|
let stdin = io::stdin();
|
||||||
|
let mut stdin = stdin.lock();
|
||||||
|
stdin.read_to_string(&mut buffer).expect("failed to read stdin");
|
||||||
|
buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let arena = Arena::new();
|
||||||
|
let root = parse_document(&arena, &document, &MD_OPTS);
|
||||||
|
|
||||||
|
// Syntax highlighting is implemented by traversing the arena and
|
||||||
|
// replacing all code blocks with HTML blocks rendered by syntect.
|
||||||
|
iter_nodes(root, &|node| {
|
||||||
|
let mut ast = node.data.borrow_mut();
|
||||||
|
let new = match &ast.value {
|
||||||
|
NodeValue::CodeBlock(code) => Some(highlight_code_block(code)),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(new_value) = new {
|
||||||
|
ast.value = new_value
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
format_html(root, &MD_OPTS, &mut io::stdout())
|
format_html(root, &MD_OPTS, &mut io::stdout())
|
||||||
|
|
Loading…
Add table
Reference in a new issue