From 5d4bc6fbdb6d7dba1bbaf080d5d948cce5367b00 Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Sun, 2 Feb 2025 17:16:15 +0100 Subject: [PATCH] Derive foreground and background color from theme --- src/highlight.rs | 104 +++++++++++++++++++++------- {src/themes => templates}/style.css | 8 +-- 2 files changed, 84 insertions(+), 28 deletions(-) rename {src/themes => templates}/style.css (89%) diff --git a/src/highlight.rs b/src/highlight.rs index 32229d0..53c724d 100644 --- a/src/highlight.rs +++ b/src/highlight.rs @@ -1,11 +1,12 @@ use crate::db::read::Entry; use crate::env; use crate::errors::Error; +use askama::Template; use sha2::{Digest, Sha256}; use std::cmp::Ordering; use std::io::Cursor; use std::sync::LazyLock; -use syntect::highlighting::ThemeSet; +use syntect::highlighting::{Color, ThemeSet}; use syntect::html::{css_for_theme_with_class_style, line_tokens_to_classed_spans, ClassStyle}; use syntect::parsing::{ParseState, ScopeStack, SyntaxReference, SyntaxSet}; use syntect::util::LinesWithEndings; @@ -24,49 +25,104 @@ pub enum Theme { Solarized, } +#[derive(Template)] +#[template(path = "style.css", escape = "none")] +struct StyleCss { + light_background: Color, + light_foreground: Color, + dark_background: Color, + dark_foreground: Color, +} + #[derive(Clone)] pub struct Html(String); -pub static LIGHT_CSS: LazyLock = LazyLock::new(|| { +pub static LIGHT_THEME: LazyLock = LazyLock::new(|| { let theme_set = two_face::theme::extra(); - let theme = match *env::THEME { + match *env::THEME { Theme::Ayu => { let theme = include_str!("themes/ayu-light.tmTheme"); - &ThemeSet::load_from_reader(&mut Cursor::new(theme)).expect("loading theme") + ThemeSet::load_from_reader(&mut Cursor::new(theme)).expect("loading theme") } - Theme::Base16Ocean => theme_set.get(EmbeddedThemeName::Base16OceanLight), - Theme::Coldark => theme_set.get(EmbeddedThemeName::ColdarkCold), - Theme::Gruvbox => theme_set.get(EmbeddedThemeName::GruvboxLight), - Theme::Monokai => theme_set.get(EmbeddedThemeName::MonokaiExtendedLight), - Theme::Onehalf => theme_set.get(EmbeddedThemeName::OneHalfLight), - Theme::Solarized => theme_set.get(EmbeddedThemeName::SolarizedLight), - }; + Theme::Base16Ocean => theme_set.get(EmbeddedThemeName::Base16OceanLight).clone(), + Theme::Coldark => theme_set.get(EmbeddedThemeName::ColdarkCold).clone(), + Theme::Gruvbox => theme_set.get(EmbeddedThemeName::GruvboxLight).clone(), + Theme::Monokai => theme_set + .get(EmbeddedThemeName::MonokaiExtendedLight) + .clone(), + Theme::Onehalf => theme_set.get(EmbeddedThemeName::OneHalfLight).clone(), + Theme::Solarized => theme_set.get(EmbeddedThemeName::SolarizedLight).clone(), + } +}); - css_for_theme_with_class_style(theme, ClassStyle::Spaced).expect("generating CSS") +pub static LIGHT_CSS: LazyLock = LazyLock::new(|| { + css_for_theme_with_class_style(&LIGHT_THEME, ClassStyle::Spaced).expect("generating CSS") }); -pub static DARK_CSS: LazyLock = LazyLock::new(|| { +pub static DARK_THEME: LazyLock = LazyLock::new(|| { let theme_set = two_face::theme::extra(); - let theme = match *env::THEME { + match *env::THEME { Theme::Ayu => { let theme = include_str!("themes/ayu-dark.tmTheme"); - &ThemeSet::load_from_reader(&mut Cursor::new(theme)).expect("loading theme") + ThemeSet::load_from_reader(&mut Cursor::new(theme)).expect("loading theme") } - Theme::Base16Ocean => theme_set.get(EmbeddedThemeName::Base16OceanDark), - Theme::Coldark => theme_set.get(EmbeddedThemeName::ColdarkDark), - Theme::Gruvbox => theme_set.get(EmbeddedThemeName::GruvboxDark), - Theme::Monokai => theme_set.get(EmbeddedThemeName::MonokaiExtended), - Theme::Onehalf => theme_set.get(EmbeddedThemeName::OneHalfDark), - Theme::Solarized => theme_set.get(EmbeddedThemeName::SolarizedDark), - }; + Theme::Base16Ocean => theme_set.get(EmbeddedThemeName::Base16OceanDark).clone(), + Theme::Coldark => theme_set.get(EmbeddedThemeName::ColdarkDark).clone(), + Theme::Gruvbox => theme_set.get(EmbeddedThemeName::GruvboxDark).clone(), + Theme::Monokai => theme_set.get(EmbeddedThemeName::MonokaiExtended).clone(), + Theme::Onehalf => theme_set.get(EmbeddedThemeName::OneHalfDark).clone(), + Theme::Solarized => theme_set.get(EmbeddedThemeName::SolarizedDark).clone(), + } +}); + +pub static DARK_CSS: LazyLock = LazyLock::new(|| { + css_for_theme_with_class_style(&DARK_THEME, ClassStyle::Spaced).expect("generating CSS") +}); + +trait ColorExt { + fn new(r: u8, g: u8, b: u8, a: u8) -> Self; +} - css_for_theme_with_class_style(theme, ClassStyle::Spaced).expect("generating CSS") +impl ColorExt for Color { + fn new(r: u8, g: u8, b: u8, a: u8) -> Self { + Self { r, g, b, a } + } +} + +pub static STYLE_CSS: LazyLock = LazyLock::new(|| { + let light_foreground = LIGHT_THEME + .settings + .foreground + .unwrap_or(Color::new(3, 3, 3, 100)); + + let light_background = LIGHT_THEME + .settings + .background + .unwrap_or(Color::new(250, 250, 250, 100)); + + let dark_foreground = DARK_THEME + .settings + .foreground + .unwrap_or(Color::new(230, 225, 207, 100)); + + let dark_background = DARK_THEME + .settings + .background + .unwrap_or(Color::new(15, 20, 25, 100)); + + let style = StyleCss { + light_background, + light_foreground, + dark_background, + dark_foreground, + }; + style.render().expect("rendering style css") }); pub static DATA: LazyLock = LazyLock::new(|| { - let style = Hashed::new("style", "css", include_str!("themes/style.css")); + let style = Hashed::new("style", "css", &STYLE_CSS); let index = Hashed::new("index", "js", include_str!("javascript/index.js")); let paste = Hashed::new("paste", "js", include_str!("javascript/paste.js")); let syntax_set = two_face::syntax::extra_newlines(); diff --git a/src/themes/style.css b/templates/style.css similarity index 89% rename from src/themes/style.css rename to templates/style.css index 500fecf..28bd0d2 100644 --- a/src/themes/style.css +++ b/templates/style.css @@ -9,15 +9,15 @@ @media (prefers-color-scheme: dark) { :root { - --main-bg-color: #0f1419; - --main-fg-color: #e6e1cf; + --main-bg-color: rgb({{ dark_background.r }}, {{ dark_background.g }}, {{ dark_background.b }}, {{ dark_background.a }}); + --main-fg-color: rgb({{ dark_foreground.r }}, {{ dark_foreground.g }}, {{ dark_foreground.b }}, {{ dark_foreground.a }}); } } @media (prefers-color-scheme: light) { :root { - --main-bg-color: #fafafa; - --main-fg-color: #333; + --main-bg-color: rgb({{ light_background.r }}, {{ light_background.g }}, {{ light_background.b }}, {{ light_background.a }}); + --main-fg-color: rgb({{ light_foreground.r }}, {{ light_foreground.g }}, {{ light_foreground.b }}, {{ light_foreground.a }}); } }