src/highlight.rs 1.3 K raw
1
use std::io::Cursor;
2
use syntect::highlighting::{Theme, ThemeSet};
3
use syntect::html::highlighted_html_for_string;
4
use syntect::parsing::SyntaxSet;
5
6
pub struct Highlighter {
7
    syntax_set: SyntaxSet,
8
    theme: Theme,
9
}
10
11
impl Highlighter {
12
    pub fn new() -> Self {
13
        let theme_data = include_bytes!("darkmatter.tmTheme");
14
        let theme = ThemeSet::load_from_reader(&mut Cursor::new(&theme_data[..]))
15
            .expect("failed to load darkmatter theme");
16
        Self {
17
            syntax_set: SyntaxSet::load_defaults_newlines(),
18
            theme,
19
        }
20
    }
21
22
    pub fn highlight(&self, name: &str, content: &str) -> String {
23
        let raw_ext = name.rsplit('.').next().unwrap_or("");
24
        let ext = match raw_ext {
25
            "ts" | "tsx" | "jsx" => "js",
26
            other => other,
27
        };
28
        let syntax = self
29
            .syntax_set
30
            .find_syntax_by_extension(ext)
31
            .unwrap_or_else(|| self.syntax_set.find_syntax_plain_text());
32
        highlighted_html_for_string(content, &self.syntax_set, syntax, &self.theme)
33
            .unwrap_or_else(|_| {
34
                let escaped = content
35
                    .replace('&', "&")
36
                    .replace('<', "&lt;")
37
                    .replace('>', "&gt;");
38
                format!("<pre>{}</pre>", escaped)
39
            })
40
    }
41
}