From 265e30f438c503c036d1097317d5d1889f5776af Mon Sep 17 00:00:00 2001 From: rm-dr <96270320+rm-dr@users.noreply.github.com> Date: Mon, 3 Nov 2025 23:06:30 -0800 Subject: [PATCH] Markdown upgrades --- Cargo.lock | 22 +++ crates/service/service-webpage/Cargo.toml | 1 + .../service/service-webpage/css/blocks.scss | 6 +- .../service-webpage/src/components/fa.rs | 3 + .../service-webpage/src/components/md.rs | 130 ++++++++++--- .../service-webpage/src/routes/assets.rs | 2 +- .../service-webpage/src/routes/handouts.rs | 15 +- .../service-webpage/src/routes/index.md | 45 +++++ .../service-webpage/src/routes/index.rs | 174 +----------------- 9 files changed, 184 insertions(+), 214 deletions(-) create mode 100644 crates/service/service-webpage/src/routes/index.md diff --git a/Cargo.lock b/Cargo.lock index 3f97cd7..cb6cada 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1924,6 +1924,7 @@ dependencies = [ "macro-sass", "markdown-it", "maud", + "strum", "tracing", "utoipa", ] @@ -2034,6 +2035,27 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.108", +] + [[package]] name = "subtle" version = "2.6.1" diff --git a/crates/service/service-webpage/Cargo.toml b/crates/service/service-webpage/Cargo.toml index 9fee011..35cc89c 100644 --- a/crates/service/service-webpage/Cargo.toml +++ b/crates/service/service-webpage/Cargo.toml @@ -19,3 +19,4 @@ utoipa = { workspace = true } maud = { workspace = true } markdown-it = { workspace = true } emojis = { workspace = true } +strum = { workspace = true } diff --git a/crates/service/service-webpage/css/blocks.scss b/crates/service/service-webpage/css/blocks.scss index 6f1234f..d417938 100644 --- a/crates/service/service-webpage/css/blocks.scss +++ b/crates/service/service-webpage/css/blocks.scss @@ -13,9 +13,9 @@ li p { } /* Bonus space after last li */ -li:last-child { - margin-bottom: 3rem; -} +//li:last-child { +// margin-bottom: 3rem; +//} ul li::marker { content: "> "; diff --git a/crates/service/service-webpage/src/components/fa.rs b/crates/service/service-webpage/src/components/fa.rs index 36d3749..09b4cdf 100644 --- a/crates/service/service-webpage/src/components/fa.rs +++ b/crates/service/service-webpage/src/components/fa.rs @@ -1,7 +1,10 @@ use maud::{Markup, Render, html}; +use strum::{Display, EnumString}; +#[derive(Debug, Clone, Copy, EnumString, Display)] #[expect(clippy::allow_attributes)] #[allow(dead_code)] +#[strum(serialize_all = "snake_case")] pub enum FAIcon { Github, Git, diff --git a/crates/service/service-webpage/src/components/md.rs b/crates/service/service-webpage/src/components/md.rs index a4dec77..0ab495c 100644 --- a/crates/service/service-webpage/src/components/md.rs +++ b/crates/service/service-webpage/src/components/md.rs @@ -1,7 +1,10 @@ -use emojis::Emoji; use markdown_it::parser::inline::{InlineRule, InlineState}; use markdown_it::{Node, NodeValue, Renderer}; use maud::{Markup, PreEscaped, Render}; +use std::str::FromStr; + +use crate::components::fa::FAIcon; +use crate::components::mangle::{MangledBetaEmail, MangledGoogleEmail}; pub struct Markdown<'a>(pub &'a str); @@ -26,11 +29,11 @@ impl Render for Markdown<'_> { // #[derive(Debug)] -pub struct InlineEmote(&'static Emoji); +pub struct InlineEmote(String); impl NodeValue for InlineEmote { fn render(&self, _node: &Node, fmt: &mut dyn Renderer) { - fmt.text(self.0.as_str()); + fmt.text_raw(self.0.as_str()); } } @@ -45,9 +48,21 @@ impl InlineRule for InlineEmote { } let end_idx = input[1..].find(':')? + 1; - let emote = emojis::get_by_shortcode(&input[1..end_idx])?; + let code = &input[1..end_idx]; - Some((Node::new(InlineEmote(emote)), end_idx + 1)) + let mut emote = None; + + if emote.is_none() + && let Some(code) = code.strip_prefix("fa-") + { + emote = FAIcon::from_str(code).ok().map(|x| x.render().0) + } + + if emote.is_none() { + emote = emojis::get_by_shortcode(code).map(|x| x.to_string()); + } + + Some((Node::new(InlineEmote(emote?)), end_idx + 1)) } } @@ -60,6 +75,10 @@ impl NodeValue for InlineMdx { return; } + if mdx_include(&self.0, node, fmt) { + return; + } + fmt.open("code", &[]); fmt.text(&self.0); fmt.close("code"); @@ -101,35 +120,39 @@ impl InlineRule for InlineMdx { } fn mdx_style(mdx: &str, _node: &Node, fmt: &mut dyn Renderer) -> bool { - let mdx = mdx.trim(); - - if !mdx.starts_with("style(") { - return false; - } - - let skip = 6; - let mut balance = 1; - let mut end = skip; - for i in mdx[skip..].bytes() { - match i { - b')' => balance -= 1, - b'(' => balance += 1, - _ => {} + // Parse inside of mdx: `style(