From 802efbca25cb92d8567761361b6513fd57e05578 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 30 Aug 2022 16:54:57 +0200 Subject: basic syntax highlighting --- code/src/main.rs | 1 + code/src/markdown.rs | 10 +++++++--- code/src/syntax_highlight/grammar.rs | 6 ++++++ code/src/syntax_highlight/mod.rs | 29 +++++++++++++++++++++++++++++ code/src/syntax_highlight/theme.rs | 6 ++++++ 5 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 code/src/syntax_highlight/grammar.rs create mode 100644 code/src/syntax_highlight/mod.rs create mode 100644 code/src/syntax_highlight/theme.rs (limited to 'code/src') diff --git a/code/src/main.rs b/code/src/main.rs index 0bd0169..c20d137 100644 --- a/code/src/main.rs +++ b/code/src/main.rs @@ -1,6 +1,7 @@ pub mod atom; pub mod html; pub mod markdown; +pub mod syntax_highlight; use atom::generate_atom; use clap::{Parser, Subcommand}; diff --git a/code/src/markdown.rs b/code/src/markdown.rs index 5d98f83..22934c5 100644 --- a/code/src/markdown.rs +++ b/code/src/markdown.rs @@ -1,5 +1,6 @@ use markdown::{Block, ListItem, Span}; +use crate::syntax_highlight::syntax_highlight; pub fn span_to_html(ss: Vec) -> String { let mut out = String::new(); @@ -28,8 +29,12 @@ pub fn blocks_to_html(blocks: Vec) -> String { } Block::Paragraph(p) => format!("

{}

", span_to_html(p)), Block::Blockquote(q) => format!("{}", blocks_to_html(q)), - Block::CodeBlock(_syntax, content) => { - format!("
{}
", escape(&content)) // TODO syntax highlighting + Block::CodeBlock(syntax, content) => { + if let Some(s) = &syntax { + format!("
{}
", syntax_highlight(s, &content)) + } else { + format!("
{}
", escape(&content)) + } } Block::OrderedList(els, _) => format!( "
    {}
", @@ -74,4 +79,3 @@ pub fn escape(text: &str) -> String { .replace("'", "’") .replace("\"", """) } - diff --git a/code/src/syntax_highlight/grammar.rs b/code/src/syntax_highlight/grammar.rs new file mode 100644 index 0000000..95417ab --- /dev/null +++ b/code/src/syntax_highlight/grammar.rs @@ -0,0 +1,6 @@ +pub fn grammar_for(syntax: &str) -> &'static [(&'static [&'static str], &'static str)] { + match syntax { + "rs" => &[(&["fn", "pub", "async"], "keyword")], + _ => unreachable!(), + } +} diff --git a/code/src/syntax_highlight/mod.rs b/code/src/syntax_highlight/mod.rs new file mode 100644 index 0000000..688b010 --- /dev/null +++ b/code/src/syntax_highlight/mod.rs @@ -0,0 +1,29 @@ +pub mod grammar; +pub mod theme; + +use crate::{markdown::escape, syntax_highlight::theme::theme}; +use grammar::grammar_for; +use synoptic::{Highlighter, Token}; + +pub fn syntax_highlight(lang: &str, source: &str) -> String { + let mut h = Highlighter::new(); + for (regex, kind) in grammar_for(lang) { + h.join(regex, kind).unwrap(); + } + let highlighting = h.run(source); + let mut out = String::new(); + + for (_c, row) in highlighting.iter().enumerate() { + eprintln!("{row:?}"); + for tok in row { + match tok { + Token::Start(kind) => out += &format!("", theme(kind)), + Token::Text(text) => out += &escape(text), + Token::End(_kind) => out += "", + } + } + out += "\n" + } + eprintln!("{out:?}"); + out +} diff --git a/code/src/syntax_highlight/theme.rs b/code/src/syntax_highlight/theme.rs new file mode 100644 index 0000000..40434ad --- /dev/null +++ b/code/src/syntax_highlight/theme.rs @@ -0,0 +1,6 @@ +pub fn theme(kind: &str) -> &'static str { + match kind { + "keyword" => "#9999ff", + _ => "#ff00ff", + } +} -- cgit v1.2.3-70-g09d2