refactor(cheddar): Set up scaffolding for Markdown rendering

Generalises the two bits of the program that will be required either
way (extension parsing and syntax loading).

A dependency on Comrak is introduced as I think GitHub-flavoured
Markdown (with all its fancy extensions) is desirable!
This commit is contained in:
Vincent Ambo 2019-12-21 14:09:12 +00:00
parent eb650eb8d8
commit d35aa4ae46
3 changed files with 224 additions and 13 deletions

View file

@ -6,7 +6,8 @@ use std::path::Path;
use syntect::easy::HighlightLines;
use syntect::dumps::from_binary;
use syntect::highlighting::ThemeSet;
use syntect::parsing::{SyntaxSet, SyntaxReference};
use syntect::parsing::SyntaxSet;
use lazy_static::lazy_static;
use syntect::html::{
append_highlighted_html_for_styled_line,
@ -14,7 +15,14 @@ use syntect::html::{
IncludeBackground,
};
fn syntax_from_args(syntaxes: &SyntaxSet) -> Option<&SyntaxReference> {
// Set up syntaxes as a lazy_static. Initialisation might not be
// required in the case of Markdown rendering (if there's no code
// blocks within the document).
lazy_static! {
static ref SYNTAXES: SyntaxSet = from_binary(include_bytes!(env!("BAT_SYNTAXES")));
}
fn args_extension() -> Option<String> {
// The name of the file to be formatted is usually passed in as
// the first argument and can be used to determine a syntax set.
let args = env::args().collect::<Vec<String>>();
@ -22,10 +30,9 @@ fn syntax_from_args(syntaxes: &SyntaxSet) -> Option<&SyntaxReference> {
return None
}
Path::new(&args[1])
.extension()
Path::new(&args[1]).extension()
.and_then(OsStr::to_str)
.and_then(|ext| syntaxes.find_syntax_by_extension(ext))
.map(|s| s.to_string())
}
fn should_continue(res: &io::Result<usize>) -> bool {
@ -35,9 +42,11 @@ fn should_continue(res: &io::Result<usize>) -> bool {
}
}
fn main() {
let syntaxes = from_binary(include_bytes!(env!("BAT_SYNTAXES")));
fn format_markdown() {
unimplemented!("Not able to format Markdown just yet");
}
fn format_code(extension: String) {
let stdin = io::stdin();
let mut stdin = stdin.lock();
let mut linebuf = String::new();
@ -49,9 +58,15 @@ fn main() {
let ts = ThemeSet::load_defaults();
let theme = &ts.themes["InspiredGitHub"];
let syntax = syntax_from_args(&syntaxes)
.or_else(|| syntaxes.find_syntax_by_first_line(&linebuf))
.unwrap_or_else(|| syntaxes.find_syntax_plain_text());
let syntax = SYNTAXES.find_syntax_by_extension(&extension)
.or_else(|| SYNTAXES.find_syntax_by_first_line(&linebuf))
.unwrap_or_else(|| SYNTAXES.find_syntax_plain_text());
// We're doing a completely different thing if the file is
// Markdown, so lets do that thing.
if syntax.name == "markdown" {
}
let mut hl = HighlightLines::new(syntax, theme);
let (mut outbuf, bg) = start_highlighted_html_snippet(theme);
@ -63,7 +78,7 @@ fn main() {
// newlines to be efficient, and those are stripped in the lines
// iterator.
while should_continue(&read_result) {
let regions = hl.highlight(&linebuf, &syntaxes);
let regions = hl.highlight(&linebuf, &SYNTAXES);
append_highlighted_html_for_styled_line(
&regions[..],
@ -83,3 +98,14 @@ fn main() {
println!("</pre>");
}
fn main() {
let extension = args_extension()
.expect("cheddar should be invoked with a filename!");
if extension == "md" {
format_markdown();
} else {
format_code(extension);
}
}