diff --git a/Cargo.lock b/Cargo.lock index 9c10eba55..6ae258bb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1418,14 +1418,13 @@ checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" [[package]] name = "comrak" -version = "0.44.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07fcaf1ac457de7574ce514fd9a68e86e8196165529f48a544ec90cbea840e04" +checksum = "dc151d9c800c4fadd542c949b84c1dae6d1b424315ebcfd154e611d4f7910a97" dependencies = [ "caseless", "entities", - "memchr", - "slug", + "jetscii", "typed-arena", "unicode_categories", ] @@ -4551,6 +4550,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jetscii" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47f142fe24a9c9944451e8349de0a56af5f3e7226dc46f3ed4d4ecc0b85af75e" + [[package]] name = "jiff" version = "0.2.15" diff --git a/Cargo.toml b/Cargo.toml index 662db9272..727b3cad0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ docsrs-metadata = { path = "crates/metadata" } anyhow = { version = "1.0.42", features = ["backtrace"]} backtrace = "0.3.61" thiserror = "2.0.3" -comrak = { version = "0.44.0", default-features = false } +comrak = { version = "0.46.0", default-features = false } syntect = { version = "5.0.0", default-features = false, features = ["parsing", "html", "dump-load", "regex-onig"] } toml = "0.9.2" prometheus = { version = "0.14.0", default-features = false } diff --git a/src/web/markdown.rs b/src/web/markdown.rs index a44ade19c..79998b6c4 100644 --- a/src/web/markdown.rs +++ b/src/web/markdown.rs @@ -1,8 +1,8 @@ use crate::web::highlight; -use comrak::{ - ExtensionOptions, Options, Plugins, RenderPlugins, adapters::SyntaxHighlighterAdapter, -}; -use std::{collections::HashMap, fmt}; +use comrak::{Options, adapters::SyntaxHighlighterAdapter, options}; +use std::{borrow::Cow, collections::HashMap, fmt}; + +type Attributes<'s> = HashMap<&'static str, std::borrow::Cow<'s, str>>; #[derive(Debug)] struct CodeAdapter(F, Option<&'static str>); @@ -22,41 +22,42 @@ impl, &str, Option<&str>) -> String + Send + Sync> SyntaxHigh write!(output, "{}", (self.0)(lang, code, self.1)) } - fn write_pre_tag( + fn write_pre_tag<'s>( &self, output: &mut dyn fmt::Write, - attributes: HashMap, - ) -> Result<(), fmt::Error> { + attributes: Attributes<'s>, + ) -> fmt::Result { write_opening_tag(output, "pre", &attributes) } - fn write_code_tag( + fn write_code_tag<'s>( &self, output: &mut dyn fmt::Write, - attributes: HashMap, - ) -> Result<(), fmt::Error> { + attributes: Attributes<'s>, + ) -> fmt::Result { // similarly to above, since comrak does not treat `,` as an info-string delimiter it will // try to apply `class="language-rust,ignore"` for the info-string `rust,ignore`, so we // have to detect that case and fixup the class here // TODO: https://github.com/kivikakk/comrak/issues/246 let mut attributes = attributes; if let Some(classes) = attributes.get_mut("class") { - *classes = classes + let mut updated: String = classes .split(' ') .flat_map(|class| [class.split(',').next().unwrap_or(class), " "]) .collect(); // remove trailing ' ' // TODO: https://github.com/rust-lang/rust/issues/79524 or itertools - classes.pop(); + updated.pop(); + *classes = Cow::Owned(updated); } write_opening_tag(output, "code", &attributes) } } -fn write_opening_tag( +fn write_opening_tag<'s>( output: &mut dyn fmt::Write, tag: &str, - attributes: &HashMap, + attributes: &Attributes<'s>, ) -> Result<(), fmt::Error> { write!(output, "<{tag}")?; for (attr, val) in attributes { @@ -75,7 +76,7 @@ fn render_with_highlighter( comrak::markdown_to_html_with_plugins( text, &Options { - extension: ExtensionOptions { + extension: options::Extension { superscript: true, table: true, autolink: true, @@ -85,8 +86,8 @@ fn render_with_highlighter( }, ..Default::default() }, - &Plugins { - render: RenderPlugins { + &options::Plugins { + render: options::RenderPlugins { codefence_syntax_highlighter: Some(&code_adapter), ..Default::default() },