From f55535bc4db6de5e68d8130bee0b5b8c04d466da Mon Sep 17 00:00:00 2001 From: Maurits van Riezen <12109031+mousetail@users.noreply.github.com> Date: Tue, 31 Dec 2024 08:45:56 +0100 Subject: [PATCH 1/3] Add support for class-based highlighting --- src/plugins/extra/syntect.rs | 44 +++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/src/plugins/extra/syntect.rs b/src/plugins/extra/syntect.rs index 5014491..6250e44 100644 --- a/src/plugins/extra/syntect.rs +++ b/src/plugins/extra/syntect.rs @@ -1,7 +1,9 @@ //! Syntax highlighting for code blocks use syntect::highlighting::ThemeSet; -use syntect::html::highlighted_html_for_string; +use syntect::html::{highlighted_html_for_string, ClassedHtmlGenerator}; +pub use syntect::html::ClassStyle; use syntect::parsing::SyntaxSet; +use syntect::util::LinesWithEndings; use crate::parser::core::CoreRule; use crate::parser::extset::MarkdownItExt; @@ -21,12 +23,18 @@ impl NodeValue for SyntectSnippet { } #[derive(Debug, Clone, Copy)] -struct SyntectSettings(&'static str); +enum SyntectMode { + InlineStyles { theme: &'static str }, + CssClasses { class_style: ClassStyle } +} + +#[derive(Debug, Clone, Copy)] +struct SyntectSettings(SyntectMode); impl MarkdownItExt for SyntectSettings {} impl Default for SyntectSettings { fn default() -> Self { - Self("InspiredGitHub") + Self(SyntectMode::InlineStyles { theme: "InspiredGitHub" }) } } @@ -34,8 +42,20 @@ pub fn add(md: &mut MarkdownIt) { md.add_rule::(); } +/// Use inline styles with the given theme pub fn set_theme(md: &mut MarkdownIt, theme: &'static str) { - md.ext.insert(SyntectSettings(theme)); + md.ext.insert(SyntectSettings( + SyntectMode::InlineStyles { theme } + )); +} + +/// Generate spans with css classes applied +/// +/// This is an alternative to using a theme. You are responsible for including a style sheet. +pub fn use_css_classes(md: &mut MarkdownIt, class_style: ClassStyle) { + md.ext_insert(SyntectSettings( + SyntectMode::CssClasses { class_style } + )); } pub struct SyntectRule; @@ -43,7 +63,10 @@ impl CoreRule for SyntectRule { fn run(root: &mut Node, md: &MarkdownIt) { let ss = SyntaxSet::load_defaults_newlines(); let ts = ThemeSet::load_defaults(); - let theme = &ts.themes[md.ext.get::().copied().unwrap_or_default().0]; + let mode = match md.ext.get::().copied().unwrap_or_default().0 { + SyntectMode::InlineStyles {theme} => Some(&ts.themes[theme]), + SyntectMode::CssClasses => None + }; root.walk_mut(|node, _| { let mut content = None; @@ -63,7 +86,16 @@ impl CoreRule for SyntectRule { } let syntax = syntax.unwrap_or_else(|| ss.find_syntax_plain_text()); - let html = highlighted_html_for_string(content, &ss, syntax, theme); + let html = match mode { + SyntectMode::InlineStyles { theme } => highlighted_html_for_string(content, &ss, syntax, &ts.themes[theme]), + SyntectMode::CssClasses { class_style } => { + let mut html_generator = ClassedHTMLGenerator::new_with_class_style(syntax, &ss, class_style); + for line in LinesWithEndings::from(content) { + html_generator.parse_html_for_line_which_includes_newline(line); + } + Ok(html_generator.finalize()) + } + }; if let Ok(html) = html { node.replace(SyntectSnippet { html }); From 273796f24456cc8de350866bed1ee75d1a1bf1d6 Mon Sep 17 00:00:00 2001 From: Maurits van Riezen <12109031+mousetail@users.noreply.github.com> Date: Tue, 31 Dec 2024 08:48:08 +0100 Subject: [PATCH 2/3] Remove unnececairy code --- src/plugins/extra/syntect.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/extra/syntect.rs b/src/plugins/extra/syntect.rs index 6250e44..6b1913b 100644 --- a/src/plugins/extra/syntect.rs +++ b/src/plugins/extra/syntect.rs @@ -63,10 +63,7 @@ impl CoreRule for SyntectRule { fn run(root: &mut Node, md: &MarkdownIt) { let ss = SyntaxSet::load_defaults_newlines(); let ts = ThemeSet::load_defaults(); - let mode = match md.ext.get::().copied().unwrap_or_default().0 { - SyntectMode::InlineStyles {theme} => Some(&ts.themes[theme]), - SyntectMode::CssClasses => None - }; + let mode = match md.ext.get::().copied().unwrap_or_default().0; root.walk_mut(|node, _| { let mut content = None; From 9f87a17d615ae011507794432eddac974368f50c Mon Sep 17 00:00:00 2001 From: "Maurits \"Mousetail\" van Riezen" Date: Tue, 31 Dec 2024 08:55:43 +0100 Subject: [PATCH 3/3] fix build --- src/plugins/extra/syntect.rs | 40 +++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/plugins/extra/syntect.rs b/src/plugins/extra/syntect.rs index 6b1913b..b7cab67 100644 --- a/src/plugins/extra/syntect.rs +++ b/src/plugins/extra/syntect.rs @@ -1,7 +1,7 @@ //! Syntax highlighting for code blocks use syntect::highlighting::ThemeSet; -use syntect::html::{highlighted_html_for_string, ClassedHtmlGenerator}; pub use syntect::html::ClassStyle; +use syntect::html::{highlighted_html_for_string, ClassedHTMLGenerator}; use syntect::parsing::SyntaxSet; use syntect::util::LinesWithEndings; @@ -25,7 +25,7 @@ impl NodeValue for SyntectSnippet { #[derive(Debug, Clone, Copy)] enum SyntectMode { InlineStyles { theme: &'static str }, - CssClasses { class_style: ClassStyle } + CssClasses { class_style: ClassStyle }, } #[derive(Debug, Clone, Copy)] @@ -34,7 +34,9 @@ impl MarkdownItExt for SyntectSettings {} impl Default for SyntectSettings { fn default() -> Self { - Self(SyntectMode::InlineStyles { theme: "InspiredGitHub" }) + Self(SyntectMode::InlineStyles { + theme: "InspiredGitHub", + }) } } @@ -44,18 +46,16 @@ pub fn add(md: &mut MarkdownIt) { /// Use inline styles with the given theme pub fn set_theme(md: &mut MarkdownIt, theme: &'static str) { - md.ext.insert(SyntectSettings( - SyntectMode::InlineStyles { theme } - )); + md.ext + .insert(SyntectSettings(SyntectMode::InlineStyles { theme })); } /// Generate spans with css classes applied -/// +/// /// This is an alternative to using a theme. You are responsible for including a style sheet. pub fn use_css_classes(md: &mut MarkdownIt, class_style: ClassStyle) { - md.ext_insert(SyntectSettings( - SyntectMode::CssClasses { class_style } - )); + md.ext + .insert(SyntectSettings(SyntectMode::CssClasses { class_style })); } pub struct SyntectRule; @@ -63,7 +63,12 @@ impl CoreRule for SyntectRule { fn run(root: &mut Node, md: &MarkdownIt) { let ss = SyntaxSet::load_defaults_newlines(); let ts = ThemeSet::load_defaults(); - let mode = match md.ext.get::().copied().unwrap_or_default().0; + let mode = md + .ext + .get::() + .copied() + .unwrap_or_default() + .0; root.walk_mut(|node, _| { let mut content = None; @@ -84,11 +89,18 @@ impl CoreRule for SyntectRule { let syntax = syntax.unwrap_or_else(|| ss.find_syntax_plain_text()); let html = match mode { - SyntectMode::InlineStyles { theme } => highlighted_html_for_string(content, &ss, syntax, &ts.themes[theme]), + SyntectMode::InlineStyles { theme } => { + highlighted_html_for_string(content, &ss, syntax, &ts.themes[theme]) + } SyntectMode::CssClasses { class_style } => { - let mut html_generator = ClassedHTMLGenerator::new_with_class_style(syntax, &ss, class_style); + let mut html_generator = + ClassedHTMLGenerator::new_with_class_style(syntax, &ss, class_style); for line in LinesWithEndings::from(content) { - html_generator.parse_html_for_line_which_includes_newline(line); + if let Err(_) = + html_generator.parse_html_for_line_which_includes_newline(line) + { + return; + }; } Ok(html_generator.finalize()) }