aboutsummaryrefslogtreecommitdiff
path: root/code/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2022-09-26 14:14:58 +0200
committermetamuffin <metamuffin@disroot.org>2022-09-26 14:14:58 +0200
commit15d78464ba9a717a71e1dc47a4101c8b13ec6581 (patch)
tree43def89ffd6e9c2ff80e7f7eeecec6fcf18c4e92 /code/src
parent0a18eae178a23e7f7bfd88c37502e5e8c1fdf64a (diff)
downloadmetamuffin-blog-15d78464ba9a717a71e1dc47a4101c8b13ec6581.tar
metamuffin-blog-15d78464ba9a717a71e1dc47a4101c8b13ec6581.tar.bz2
metamuffin-blog-15d78464ba9a717a71e1dc47a4101c8b13ec6581.tar.zst
syntax highlighting with syntect
Diffstat (limited to 'code/src')
-rw-r--r--code/src/html.rs13
-rw-r--r--code/src/markdown/render.rs10
-rw-r--r--code/src/syntax_highlight/grammar.rs67
-rw-r--r--code/src/syntax_highlight/mod.rs44
-rw-r--r--code/src/syntax_highlight/theme.rs13
5 files changed, 40 insertions, 107 deletions
diff --git a/code/src/html.rs b/code/src/html.rs
index d310ad3..23ac6c8 100644
--- a/code/src/html.rs
+++ b/code/src/html.rs
@@ -1,7 +1,10 @@
use crate::{
- article_metadata, file_history, get_articles, markdown::{render::blocks_to_html, self}, ArticleMeta,
+ article_metadata, file_history, get_articles,
+ markdown::{self, render::blocks_to_html},
+ ArticleMeta,
};
use laby::{frag, html, iter, li, ul, Render};
+use pest::Parser;
use std::fs::read_to_string;
pub fn scaffold(title: String, body: impl Render) -> impl Render {
@@ -25,6 +28,14 @@ pub fn scaffold(title: String, body: impl Render) -> impl Render {
}
pub fn article(path: String) -> impl Render {
+ // match parsers::markdown::Grammar::parse(
+ // parsers::markdown::Rule::file,
+ // &read_to_string(&path).unwrap(),
+ // ) {
+ // Ok(ast) => eprintln!("{ast:#?}"),
+ // Err(e) => panic!("{e}"),
+ // }
+
scaffold(
article_metadata(path.clone().into()).title,
frag!(
diff --git a/code/src/markdown/render.rs b/code/src/markdown/render.rs
index f6b7686..7962561 100644
--- a/code/src/markdown/render.rs
+++ b/code/src/markdown/render.rs
@@ -34,11 +34,11 @@ pub fn blocks_to_html(blocks: Vec<Block>) -> String {
Block::Paragraph(p) => format!("<p>{}</p>", span_to_html(p)),
Block::Blockquote(q) => format!("<quote>{}</quote>", blocks_to_html(q)),
Block::CodeBlock(syntax, content) => {
- if let Some(s) = &syntax {
- format!("<pre>{}</pre>", syntax_highlight(s, &content))
- } else {
- format!("<pre>{}</pre>", escape(&content))
- }
+ format!(
+ "<pre>{}</pre>",
+ syntax_highlight(&syntax.unwrap_or(String::from("")), &content)
+ .unwrap_or_else(|| escape(&content))
+ )
}
Block::OrderedList(els) => format!(
"<ol>{}</ol>",
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",
- }
-}