From b074f14b85145a8b02d3781dd85cb2ff89de0608 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Sun, 21 Dec 2025 16:44:30 +0000 Subject: [PATCH] Readme: Implement syntax highlighting via giallo Signed-off-by: Nico Burns --- Cargo.lock | 55 ++++++++++++++ apps/readme/Cargo.toml | 4 +- .../assets/blitz-markdown-overrides.css | 4 + apps/readme/src/main.rs | 6 ++ apps/readme/src/markdown/comrak.rs | 75 +++++++++++++++++-- 5 files changed, 137 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d799cd202..b627a96e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3083,6 +3083,19 @@ dependencies = [ "wasip3", ] +[[package]] +name = "giallo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e38674eaf44eef520832d4076861c544ded6e69611453f8d54283e4fba1576ad" +dependencies = [ + "flate2", + "onig-regset", + "rmp-serde", + "serde", + "serde_json", +] + [[package]] name = "gif" version = "0.13.3" @@ -5081,6 +5094,28 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "onig-regset" +version = "6.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080c4eeac92e475efa2893e52522ee3de48086cdad5fb5f36631a7fcb5293c81" +dependencies = [ + "bitflags 2.11.1", + "libc", + "once_cell", + "onig_sys", +] + +[[package]] +name = "onig_sys" +version = "69.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e68317604e77e53b85896388e1a803c1d21b74c899ec9e5e1112db90735edd7" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "openssl-probe" version = "0.2.1" @@ -5889,6 +5924,7 @@ dependencies = [ "blitz-shell", "blitz-traits", "comrak", + "giallo", "image", "notify", "pulldown-cmark", @@ -6080,6 +6116,25 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rmp" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "rmp-serde" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155" +dependencies = [ + "rmp", + "serde", +] + [[package]] name = "roxmltree" version = "0.20.0" diff --git a/apps/readme/Cargo.toml b/apps/readme/Cargo.toml index 7207fae08..6c42a1642 100644 --- a/apps/readme/Cargo.toml +++ b/apps/readme/Cargo.toml @@ -7,7 +7,7 @@ rust-version.workspace = true publish = false [features] -default = ["gpu", "comrak", "floats", "tracing"] +default = ["gpu", "comrak", "syntax-highlighting-giallo", "floats", "tracing"] # Renderers gpu = ["dep:anyrender_vello"] @@ -23,6 +23,7 @@ cpu-base = ["dep:anyrender_vello_cpu"] avif = ["dep:image", "image?/avif-native"] comrak = ["dep:comrak"] pulldown_cmark = ["dep:pulldown-cmark"] +syntax-highlighting-giallo = ["dep:giallo"] floats = ["blitz-dom/floats"] cache = ["blitz-net/cache"] logtime = ["log_frame_times", "log_phase_times"] @@ -53,6 +54,7 @@ reqwest = { workspace = true } url = { workspace = true } winit = { workspace = true } comrak = { version = "0.52", default-features = false, optional = true } +giallo = { version = "0.1", features = ["dump"], optional = true } pulldown-cmark = { version = "0.13", default-features = false, features = ["html"], optional = true } image = { workspace = true, default-features = false, optional = true } notify = "8.0.0" diff --git a/apps/readme/assets/blitz-markdown-overrides.css b/apps/readme/assets/blitz-markdown-overrides.css index 6b20ed000..9a3f94ecb 100644 --- a/apps/readme/assets/blitz-markdown-overrides.css +++ b/apps/readme/assets/blitz-markdown-overrides.css @@ -28,4 +28,8 @@ [src$="#gh-dark-mode-only"] { display: none !important; } +} + +.giallo { + background: #f6f8fa !important; } \ No newline at end of file diff --git a/apps/readme/src/main.rs b/apps/readme/src/main.rs index 43103f20b..cb18ab10b 100644 --- a/apps/readme/src/main.rs +++ b/apps/readme/src/main.rs @@ -92,6 +92,12 @@ fn main() { html = markdown_to_html(html); stylesheets.push(String::from(GITHUB_MD_STYLES)); stylesheets.push(String::from(BLITZ_MD_STYLES)); + + #[cfg(feature = "syntax-highlighting-giallo")] + { + stylesheets.push(String::from(giallo::GIALLO_CSS)) + } + title = format!( "README for {}", base_url.rsplit("/").find(|s| !s.is_empty()).unwrap() diff --git a/apps/readme/src/markdown/comrak.rs b/apps/readme/src/markdown/comrak.rs index 3668ae8f6..83fe07e7b 100644 --- a/apps/readme/src/markdown/comrak.rs +++ b/apps/readme/src/markdown/comrak.rs @@ -1,11 +1,17 @@ -//! Render the readme.md using the gpu renderer - use comrak::{Options, markdown_to_html_with_plugins, options}; pub(crate) fn markdown_to_html(contents: String) -> String { - let plugins = options::Plugins::default(); - // let syntax_highligher = CustomSyntectAdapter(SyntectAdapter::new(Some("InspiredGitHub"))); - // plugins.render.codefence_syntax_highlighter = Some(&syntax_highligher as _); + #[allow(unused_mut)] + let mut plugins = options::Plugins::default(); + + #[cfg(feature = "syntax-highlighting-giallo")] + use giallo_highlighter::{GialloAdapter, ThemeVariant}; + #[cfg(feature = "syntax-highlighting-giallo")] + let syntax_highligher = GialloAdapter(ThemeVariant::Single("github-light")); + #[cfg(feature = "syntax-highlighting-giallo")] + { + plugins.render.codefence_syntax_highlighter = Some(&syntax_highligher as _); + } let body_html = markdown_to_html_with_plugins( &contents, @@ -50,7 +56,64 @@ pub(crate) fn markdown_to_html(contents: String) -> String { ) } -// #[allow(unused)] +#[cfg(feature = "syntax-highlighting-giallo")] +mod giallo_highlighter { + use comrak::adapters::SyntaxHighlighterAdapter; + pub(crate) use giallo::ThemeVariant; + use giallo::{HighlightOptions, HtmlRenderer, PLAIN_GRAMMAR_NAME, RenderOptions}; + use std::borrow::Cow; + use std::collections::HashMap; + + static GIALLO_REGISTRY: std::sync::LazyLock = + std::sync::LazyLock::new(|| { + let mut registry = giallo::Registry::builtin().unwrap(); + registry.link_grammars(); + registry + }); + + pub(crate) struct GialloAdapter(pub(crate) ThemeVariant<&'static str>); + + impl SyntaxHighlighterAdapter for GialloAdapter { + fn write_highlighted( + &self, + output: &mut dyn std::fmt::Write, + lang: Option<&str>, + code: &str, + ) -> std::fmt::Result { + let norm_lang = lang.map(|l| l.split_once(',').map(|(lang, _)| lang).unwrap_or(l)); + let norm_lang = norm_lang.unwrap_or(PLAIN_GRAMMAR_NAME); + let options = HighlightOptions::new(&norm_lang, self.0); + let highlighted = GIALLO_REGISTRY.highlight(code, options).unwrap(); + let render_options = RenderOptions { + show_line_numbers: false, + ..Default::default() + }; + let html = HtmlRenderer::default().render(&highlighted, &render_options); + println!("{}", &html); + output.write_str(&html) + } + + fn write_pre_tag( + &self, + output: &mut dyn std::fmt::Write, + attributes: HashMap<&'static str, Cow<'_, str>>, + ) -> std::fmt::Result { + let _ = attributes; + output.write_str("") + } + + fn write_code_tag( + &self, + output: &mut dyn std::fmt::Write, + attributes: HashMap<&'static str, Cow<'_, str>>, + ) -> std::fmt::Result { + let _ = attributes; + output.write_str("") + } + } +} + +// #[cfg(feature = "syntax-highlighting-syntect")] // mod syntax_highlighter { // use comrak::adapters::SyntaxHighlighterAdapter; // use comrak::plugins::syntect::SyntectAdapter;