ftd/
code.rs

1static SYNTAX_DIR: include_dir::Dir<'_> = include_dir::include_dir!("syntax");
2pub const DEFAULT_THEME: &str = "base16-ocean.dark";
3
4lazy_static::lazy_static! {
5    pub static ref SS: syntect::parsing::SyntaxSet = {
6        let mut builder = syntect::parsing::SyntaxSet::load_defaults_newlines().into_builder();
7        for f in SYNTAX_DIR.files() {
8            builder.add(syntect::parsing::syntax_definition::SyntaxDefinition::load_from_str(
9                f.contents_utf8().unwrap(),
10                true,
11                f.path().file_stem().and_then(|x| x.to_str())
12            ).unwrap());
13        }
14        builder.build()
15    };
16    pub static ref KNOWN_EXTENSIONS: std::collections::HashSet<String> =
17        SS.syntaxes().iter().flat_map(|v| v.file_extensions.to_vec()).collect();
18    pub static ref TS: syntect::highlighting::ThemeSet =
19        syntect::highlighting::ThemeSet::load_defaults();
20}
21
22pub fn code(code: &str, ext: &str, theme: &str, doc_id: &str) -> ftd::p1::Result<String> {
23    let syntax = SS
24        .find_syntax_by_extension(ext)
25        .unwrap_or_else(|| SS.find_syntax_plain_text());
26    if !TS.themes.contains_key(theme) {
27        return Err(ftd::p1::Error::ParseError {
28            message: format!("'{}' is not a valid theme", theme),
29            doc_id: doc_id.to_string(),
30            line_number: 0,
31        });
32    }
33
34    let theme = &TS.themes[theme];
35
36    let code = code
37        .lines()
38        .skip_while(|l| l.trim().is_empty())
39        .collect::<Vec<_>>()
40        .join("\n")
41        .trim_end()
42        .to_string()
43        + "\n";
44
45    // TODO: handle various params
46    Ok(
47        syntect::html::highlighted_html_for_string(code.as_str(), &SS, syntax, theme)?
48            .replacen('\n', "", 1),
49    )
50}