diff options
author | metamuffin <metamuffin@disroot.org> | 2022-09-26 14:14:58 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2022-09-26 14:14:58 +0200 |
commit | 15d78464ba9a717a71e1dc47a4101c8b13ec6581 (patch) | |
tree | 43def89ffd6e9c2ff80e7f7eeecec6fcf18c4e92 /code/src/syntax_highlight | |
parent | 0a18eae178a23e7f7bfd88c37502e5e8c1fdf64a (diff) | |
download | metamuffin-blog-15d78464ba9a717a71e1dc47a4101c8b13ec6581.tar metamuffin-blog-15d78464ba9a717a71e1dc47a4101c8b13ec6581.tar.bz2 metamuffin-blog-15d78464ba9a717a71e1dc47a4101c8b13ec6581.tar.zst |
syntax highlighting with syntect
Diffstat (limited to 'code/src/syntax_highlight')
-rw-r--r-- | code/src/syntax_highlight/grammar.rs | 67 | ||||
-rw-r--r-- | code/src/syntax_highlight/mod.rs | 44 | ||||
-rw-r--r-- | code/src/syntax_highlight/theme.rs | 13 |
3 files changed, 23 insertions, 101 deletions
diff --git a/code/src/syntax_highlight/grammar.rs b/code/src/syntax_highlight/grammar.rs deleted file mode 100644 index 0cecac9..0000000 --- a/code/src/syntax_highlight/grammar.rs +++ /dev/null @@ -1,67 +0,0 @@ -const CONST: &str = "[\\. \\(,=^]([A-Z][A-Z0-9_]*)[\\. ,\\)=$]"; -const TYPE: &str = "[\\. \\(,=^]([A-Z][a-zA-Z0-9_]*)[\\. ,\\)\\(=$]"; -const IDENT: &str = "[\\. \\(,=^]([a-z][a-zA-Z0-9_]*)[\\. ,\\)=$]"; -const FUNC: &str = "[\\. \\(,=^]([a-z][A-Z0-9_]*)\\("; - -pub fn grammar_for(syntax: &str) -> &'static [(&'static str, &'static [&'static str])] { - match syntax { - "rs" | "rust" => &[ - ( - "keyword", - &[ - "fn", "pub", "async", "return", "if", "else", "let", "for", "in", "while", - "loop", "impl", "for", "trait", "struct", "enum", "dyn", - ], - ), - ( - "type", - &[ - TYPE, "bool", "usize", "u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", - "i64", "i128", "isize", "f32", "f64", - ], - ), - ("constant", &[CONST]), - ("comment", &["(?m)(//.*)$", "(?ms)/\\*.*?\\*/"]), - ("macro", &["[\\. ,=^]([a-z_][A-Za-z0-9_]*!)[\\. ,=$]"]), - ("identifier", &[IDENT]), - ("function", &[FUNC]), - ( - "literal", - &["\".*?\"", "(0x|0o|0b)[0-9a-f]+", "\\d+", "true", "false"], - ), - ], - "py" | "python" => &[ - ("type", &["bytes", "bool", "int", "str", "float"]), - ( - "keyword", - &[ - "from", "for", "def", "if", "else", "elif", "while", "with", "in", "assert", - "global", "nonlocal", "as", "import", - ], - ), - ("comment", &["(?m)(#.*)$"]), - ("constant", &[CONST]), - ("identifier", &[IDENT]), - ( - "literal", - &[ - "b?f?\".*?\"", - "b?f?'.*?'", - "(0x|0o|0b)[0-9a-f]+", - "\\d+", - "true", - "false", - ], - ), - ], - "tree" => &[("keyword", &["[├─└│]+"])], - // makefile doesnt really match the token-kinds, i'll just use something that looks goo - "makefile" | "mk" => &[ - ("comment", &["(?m)(#.*)$"]), - ("literal", &[".+: "]), - ("macro", &["\\$\\(\\w+\\)"]), - ("type", &["\\$@", "\\$<"]), - ], - _ => &[], - } -} diff --git a/code/src/syntax_highlight/mod.rs b/code/src/syntax_highlight/mod.rs index 62a2536..86b689a 100644 --- a/code/src/syntax_highlight/mod.rs +++ b/code/src/syntax_highlight/mod.rs @@ -1,27 +1,29 @@ -pub mod grammar; -pub mod theme; -use crate::{markdown::render::escape, syntax_highlight::theme::theme}; -use grammar::grammar_for; -use synoptic::{Highlighter, Token}; +use crate::markdown::render::escape; +use lazy_static::lazy_static; +use syntect::easy::HighlightLines; +use syntect::highlighting::{Style, ThemeSet}; +use syntect::parsing::SyntaxSet; +use syntect::util::{as_24_bit_terminal_escaped, LinesWithEndings}; -pub fn syntax_highlight(lang: &str, source: &str) -> String { - let mut h = Highlighter::new(); - for (kind, regex) in grammar_for(lang) { - h.join(regex, kind).unwrap(); - } - let highlighting = h.run(source); - let mut out = String::new(); +lazy_static! { + static ref PS: SyntaxSet = SyntaxSet::load_defaults_newlines(); + static ref TS: ThemeSet = ThemeSet::load_defaults(); +} + +pub fn syntax_highlight(lang: &str, source: &str) -> Option<String> { + let syntax = PS.find_syntax_by_extension(lang)?; + let mut h = HighlightLines::new(syntax, &TS.themes["Solarized (dark)"]); - for (_c, row) in highlighting.iter().enumerate() { - for tok in row { - match tok { - Token::Start(kind) => out += &format!("<span style=\"color:{}\">", theme(kind)), - Token::Text(text) => out += &escape(text), - Token::End(_kind) => out += "</span>", - } + let mut o = String::new(); + for line in LinesWithEndings::from(source) { + let ranges: Vec<(Style, &str)> = h.highlight_line(line, &PS).unwrap(); + for (style, span) in ranges { + o += &format!( + "<span style=\"color: #{:02x}{:02x}{:02x}\">{}</span>", + style.foreground.r, style.foreground.g, style.foreground.b, span + ); } - out += "\n" } - out + return Some(o); } diff --git a/code/src/syntax_highlight/theme.rs b/code/src/syntax_highlight/theme.rs deleted file mode 100644 index 2dfd10d..0000000 --- a/code/src/syntax_highlight/theme.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub fn theme(kind: &str) -> &'static str { - match kind { - "keyword" => "#9999ff", - "macro" => "#ff2863", - "literal" => "#26a6ff", - "function" => "#26ffbc", - "types" => "#26ff34", - "identifier" => "#ccff26", - "constant" => "#ff7c26", - "comment" => "#6e6e6e", - _ => "#ff00ff", - } -} |