use std::path;
use syntect::{
easy::HighlightLines,
highlighting::ThemeSet,
parsing::SyntaxSet,
util::LinesWithEndings,
};
lazy_static::lazy_static! {
pub static ref SYNTAX_SET: SyntaxSet = {
let default_set = SyntaxSet::load_defaults_newlines();
let mut builder = default_set.into_builder();
if cfg!(debug_assertions) {
builder.add_from_folder("./assets", true).ok();
} else {
let exe_path = std::env::current_exe().expect("Can't get current exe path");
let root_path = exe_path
.parent()
.expect("Could not get parent path of current executable");
let mut tmp = root_path.to_path_buf();
tmp.push("assets");
let asset_path = tmp.to_str().expect("Couldn't convert pathbuf to str");
match builder.add_from_folder(asset_path, true) {
Ok(_) => (),
Err(err) => log::warn!("Syntax builder error : {}", err),
};
}
builder.build()
};
}
pub fn highlight(path: &str, content: &str, theme_name: &str) -> Option<String> {
let syntax = path::Path::new(path)
.extension()
.and_then(std::ffi::OsStr::to_str)
.and_then(|ext| SYNTAX_SET.find_syntax_by_extension(ext));
let ts = ThemeSet::load_defaults();
let theme = ts.themes.get(theme_name);
match (syntax, theme) {
(Some(syntax), Some(theme)) => {
let mut highlighter = HighlightLines::new(syntax, theme);
let mut html = String::with_capacity(content.len());
for line in LinesWithEndings::from(content) {
let regions = highlighter.highlight(line, &SYNTAX_SET);
syntect::html::append_highlighted_html_for_styled_line(
®ions[..],
syntect::html::IncludeBackground::No,
&mut html,
);
}
Some(html)
},
_ => None,
}
}