diff options
Diffstat (limited to 'tools/cheddar/src')
-rw-r--r-- | tools/cheddar/src/main.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/tools/cheddar/src/main.rs b/tools/cheddar/src/main.rs new file mode 100644 index 000000000000..1d58bb2ad462 --- /dev/null +++ b/tools/cheddar/src/main.rs @@ -0,0 +1,84 @@ +use std::env; +use std::ffi::OsStr; +use std::io::BufRead; +use std::io; +use std::path::Path; +use syntect::easy::HighlightLines; +use syntect::highlighting::ThemeSet; +use syntect::parsing::{SyntaxSet, SyntaxReference}; + +use syntect::html::{ + append_highlighted_html_for_styled_line, + start_highlighted_html_snippet, + IncludeBackground, +}; + +fn syntax_from_args(syntaxes: &SyntaxSet) -> Option<&SyntaxReference> { + // 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>>(); + if args.len() != 2 { + return None + } + + Path::new(&args[1]) + .extension() + .and_then(OsStr::to_str) + .and_then(|ext| syntaxes.find_syntax_by_extension(ext)) +} + +fn should_continue(res: &io::Result<usize>) -> bool { + match *res { + Ok(n) => n > 0, + Err(_) => false, + } +} + +fn main() { + let syntaxes = SyntaxSet::load_defaults_newlines(); + + let stdin = io::stdin(); + let mut stdin = stdin.lock(); + let mut linebuf = String::new(); + + // Get the first line, we might need it for syntax identification. + let mut read_result = stdin.read_line(&mut linebuf); + + // Set up the highlighter + 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 mut hl = HighlightLines::new(syntax, theme); + let (mut outbuf, bg) = start_highlighted_html_snippet(theme); + + // Rather than using the `lines` iterator, read each line manually + // and maintain buffer state. + // + // This is done because the syntax highlighter requires trailing + // newlines to be efficient, and those are stripped in the lines + // iterator. + while should_continue(&read_result) { + let regions = hl.highlight(&linebuf, &syntaxes); + + append_highlighted_html_for_styled_line( + ®ions[..], + IncludeBackground::IfDifferent(bg), + &mut outbuf, + ); + + // immediately output the current state to avoid keeping + // things in memory + print!("{}", outbuf); + + // merry go round again + linebuf.clear(); + outbuf.clear(); + read_result = stdin.read_line(&mut linebuf); + } + + println!("</pre>"); +} |