From 702271dacb205d43f91736386e5575590f2c3af2 Mon Sep 17 00:00:00 2001 From: Yip Coekjan <69834864+Coekjan@users.noreply.github.com> Date: Thu, 30 May 2024 15:57:12 +0800 Subject: [PATCH] Allow setting `raw.theme` to `none` to disable syntax highlighting (#4256) --- crates/typst/src/text/raw.rs | 53 ++++++++++++++++++---------- tests/ref/raw-theme-set-to-none.png | Bin 0 -> 449 bytes tests/suite/text/raw.typ | 6 ++++ 3 files changed, 40 insertions(+), 19 deletions(-) create mode 100644 tests/ref/raw-theme-set-to-none.png diff --git a/crates/typst/src/text/raw.rs b/crates/typst/src/text/raw.rs index 0493c080d..f20dfce48 100644 --- a/crates/typst/src/text/raw.rs +++ b/crates/typst/src/text/raw.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use ecow::{eco_format, EcoString, EcoVec}; use once_cell::sync::Lazy; use once_cell::unsync::Lazy as UnsyncLazy; -use syntect::highlighting as synt; +use syntect::highlighting::{self as synt, Theme}; use syntect::parsing::{SyntaxDefinition, SyntaxSet, SyntaxSetBuilder}; use unicode_segmentation::UnicodeSegmentation; @@ -30,6 +30,7 @@ use crate::{syntax, World}; type StyleFn<'a> = &'a mut dyn FnMut(usize, &LinkedNode, Range, synt::Style) -> Content; type LineFn<'a> = &'a mut dyn FnMut(usize, Range, &mut Vec); +type ThemeArgType = Smart>; /// Raw text with optional syntax highlighting. /// @@ -217,6 +218,8 @@ pub struct RawElem { /// the background with a [filled block]($block.fill). You could also use /// the [`xml`] function to extract these properties from the theme. /// + /// Additionally, you can set the theme to `none` to disable highlighting. + /// /// ````example /// #set raw(theme: "halcyon.tmTheme") /// #show raw: it => block( @@ -236,7 +239,7 @@ pub struct RawElem { theme_path )] #[borrowed] - pub theme: Smart, + pub theme: ThemeArgType, /// The raw file buffer of syntax theme file. #[internal] @@ -315,13 +318,29 @@ impl Packed { let extra_syntaxes = UnsyncLazy::new(|| { load_syntaxes(&elem.syntaxes(styles), &elem.syntaxes_data(styles)).unwrap() }); + let non_highlighted_result = |lines: EcoVec<(EcoString, Span)>| { + lines.into_iter().enumerate().map(|(i, (line, line_span))| { + Packed::new(RawLine::new( + i as i64 + 1, + count, + line.clone(), + TextElem::packed(line).spanned(line_span), + )) + .spanned(line_span) + }) + }; let theme = elem.theme(styles).as_ref().as_ref().map(|theme_path| { - load_theme(theme_path, elem.theme_data(styles).as_ref().as_ref().unwrap()) - .unwrap() + theme_path.as_ref().map(|path| { + load_theme(path, elem.theme_data(styles).as_ref().as_ref().unwrap()) + .unwrap() + }) }); - - let theme = theme.as_ref().map(std::ops::Deref::deref).unwrap_or(&RAW_THEME); + let theme: &Theme = match theme { + Smart::Auto => &RAW_THEME, + Smart::Custom(Some(ref theme)) => theme, + Smart::Custom(None) => return non_highlighted_result(lines).collect(), + }; let foreground = theme.settings.foreground.unwrap_or(synt::Color::BLACK); let mut seq = vec![]; @@ -400,15 +419,7 @@ impl Packed { ); } } else { - seq.extend(lines.into_iter().enumerate().map(|(i, (line, line_span))| { - Packed::new(RawLine::new( - i as i64 + 1, - count, - line.clone(), - TextElem::packed(line).spanned(line_span), - )) - .spanned(line_span) - })); + seq.extend(non_highlighted_result(lines)); }; seq @@ -784,9 +795,8 @@ fn load_theme(path: &str, bytes: &Bytes) -> StrResult> { fn parse_theme( engine: &mut Engine, args: &mut Args, -) -> SourceResult<(Option>, Option)> { - let Some(Spanned { v: path, span }) = - args.named::>>("theme")? +) -> SourceResult<(Option, Option)> { + let Some(Spanned { v: path, span }) = args.named::>("theme")? else { // Argument `theme` not found. return Ok((None, None)); @@ -797,6 +807,11 @@ fn parse_theme( return Ok((Some(Smart::Auto), None)); }; + let Some(path) = path else { + // Argument `theme` is `none`. + return Ok((Some(Smart::Custom(None)), None)); + }; + // Load theme file. let id = span.resolve_path(&path).at(span)?; let data = engine.world.file(id).at(span)?; @@ -804,7 +819,7 @@ fn parse_theme( // Check that parsing works. let _ = load_theme(&path, &data).at(span)?; - Ok((Some(Smart::Custom(path)), Some(data))) + Ok((Some(Smart::Custom(Some(path))), Some(data))) } /// The syntect syntax definitions. diff --git a/tests/ref/raw-theme-set-to-none.png b/tests/ref/raw-theme-set-to-none.png new file mode 100644 index 0000000000000000000000000000000000000000..1451e0c927c0de6d7c52c6b0b0d381a2cbb6ee4c GIT binary patch literal 449 zcmV;y0Y3hTP)FBdo$lthW#SZ$;gS`mpuZboXUy|viI;$Ws>?b1t2=rkLd zZ6TYjZT4d4hqGZc7h9opzE@Abn@>+qJz4mpvN)K7Ir!hfkznli;jnbgzRuGkkrZzY zc3bgX!?XhA_NPf>9!?96>Lne1EWE;d%VCBpq|VtrKowIS9I4!ZK@-83nhwT6%GLL9 zsVD}4)7=fs8Jp6AR||S`Nfw?Ql(#X4BEu!S2VYKJQ?0U$neUObveSt`AeaK1?(Ps| zwW1tb`dK09oEaI8UAnYjTl0<}e&hTRaW+ts*xA$2CWwm$CkojiH+`PksPkJb;gm0th}Lo)1943c!7Z rRE0t|2Dpy+5DRcW7YB1N2mg4_D`m|9iVHtc00000NkvXXu0mjfZ~4BC literal 0 HcmV?d00001 diff --git a/tests/suite/text/raw.typ b/tests/suite/text/raw.typ index 8ced276c6..1807e71ad 100644 --- a/tests/suite/text/raw.typ +++ b/tests/suite/text/raw.typ @@ -648,6 +648,12 @@ fn main() { #let hi = "Hello World" ``` +--- raw-theme-set-to-none --- +#set raw(theme: none) +```typ +#let foo = "bar" +``` + --- raw-unclosed --- // Test unterminated raw text. //