diff options
-rw-r--r-- | askama_shared/src/generator.rs | 21 | ||||
-rw-r--r-- | askama_shared/src/lib.rs | 53 | ||||
-rw-r--r-- | testing/test_trim.toml | 2 |
3 files changed, 56 insertions, 20 deletions
diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index 9aec1d6..a8636fa 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -1,7 +1,9 @@ use crate::heritage::{Context, Heritage}; use crate::input::{Print, Source, TemplateInput}; use crate::parser::{parse, Cond, CondTest, Expr, Loop, Node, Target, When, Whitespace, Ws}; -use crate::{filters, get_template_source, read_config_file, CompileError, Config}; +use crate::{ + filters, get_template_source, read_config_file, CompileError, Config, WhitespaceHandling, +}; use proc_macro2::TokenStream; use quote::{quote, ToTokens}; @@ -66,7 +68,7 @@ fn build_template(ast: &syn::DeriveInput) -> Result<String, CompileError> { &contexts, heritage.as_ref(), MapChain::new(), - config.suppress_whitespace, + config.whitespace, ) .build(&contexts[input.path.as_path()])?; if input.print == Print::Code || input.print == Print::All { @@ -251,8 +253,9 @@ struct Generator<'a, S: std::hash::BuildHasher> { buf_writable: Vec<Writable<'a>>, // Counter for write! hash named arguments named: usize, - // If set to `true`, the whitespace characters will be removed by default unless `+` is used. - suppress_whitespace: bool, + // If set to `suppress`, the whitespace characters will be removed by default unless `+` is + // used. + whitespace: WhitespaceHandling, } impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { @@ -261,7 +264,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { contexts: &'n HashMap<&'n Path, Context<'n>, S>, heritage: Option<&'n Heritage<'_>>, locals: MapChain<'n, &'n str, LocalMeta>, - suppress_whitespace: bool, + whitespace: WhitespaceHandling, ) -> Generator<'n, S> { Generator { input, @@ -273,7 +276,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { super_block: None, buf_writable: vec![], named: 0, - suppress_whitespace, + whitespace, } } @@ -284,7 +287,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { self.contexts, self.heritage, locals, - self.suppress_whitespace, + self.whitespace, ) } @@ -1820,7 +1823,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { match ws { Some(Whitespace::Trim) => true, Some(Whitespace::Preserve) => false, - None => self.suppress_whitespace, + None => self.whitespace == WhitespaceHandling::Suppress, } } @@ -1832,7 +1835,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { return; } - // If `suppress_whitespace` is enabled, we keep the whitespace characters only if there is + // If `whitespace` is set to `suppress`, we keep the whitespace characters only if there is // a `+` character. if !self.should_trim_ws(ws.0) { let val = self.next_ws.unwrap(); diff --git a/askama_shared/src/lib.rs b/askama_shared/src/lib.rs index 07331bc..874be9d 100644 --- a/askama_shared/src/lib.rs +++ b/askama_shared/src/lib.rs @@ -118,7 +118,7 @@ struct Config<'a> { syntaxes: BTreeMap<String, Syntax<'a>>, default_syntax: &'a str, escapers: Vec<(HashSet<String>, String)>, - suppress_whitespace: bool, + whitespace: WhitespaceHandling, } impl Config<'_> { @@ -135,19 +135,23 @@ impl Config<'_> { RawConfig::from_toml_str(s)? }; - let (dirs, default_syntax, suppress_whitespace) = match raw.general { + let (dirs, default_syntax, whitespace) = match raw.general { Some(General { dirs, default_syntax, - suppress_whitespace, + whitespace, }) => ( dirs.map_or(default_dirs, |v| { v.into_iter().map(|dir| root.join(dir)).collect() }), default_syntax.unwrap_or(DEFAULT_SYNTAX_NAME), - suppress_whitespace.unwrap_or(false), + whitespace, + ), + None => ( + default_dirs, + DEFAULT_SYNTAX_NAME, + WhitespaceHandling::default(), ), - None => (default_dirs, DEFAULT_SYNTAX_NAME, false), }; if let Some(raw_syntaxes) = raw.syntax { @@ -189,7 +193,7 @@ impl Config<'_> { syntaxes, default_syntax, escapers, - suppress_whitespace, + whitespace, }) } @@ -302,12 +306,29 @@ impl RawConfig<'_> { } } +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[cfg_attr(feature = "serde", derive(Deserialize))] +#[cfg_attr(feature = "serde", serde(field_identifier, rename_all = "lowercase"))] +pub(crate) enum WhitespaceHandling { + /// The default behaviour. It will leave the whitespace characters "as is". + Preserve, + /// It'll remove all the whitespace characters before and after the jinja block. + Suppress, +} + +impl Default for WhitespaceHandling { + fn default() -> Self { + WhitespaceHandling::Preserve + } +} + #[cfg_attr(feature = "serde", derive(Deserialize))] struct General<'a> { #[cfg_attr(feature = "serde", serde(borrow))] dirs: Option<Vec<&'a str>>, default_syntax: Option<&'a str>, - suppress_whitespace: Option<bool>, + #[cfg_attr(feature = "serde", serde(default))] + whitespace: WhitespaceHandling, } #[cfg_attr(feature = "serde", derive(Deserialize))] @@ -659,14 +680,26 @@ mod tests { } #[test] - fn test_suppress_whitespace_parsing() { + fn test_whitespace_parsing() { + let config = Config::new( + r#" + [general] + whitespace = "suppress" + "#, + ) + .unwrap(); + assert_eq!(config.whitespace, WhitespaceHandling::Suppress); + + let config = Config::new(r#""#).unwrap(); + assert_eq!(config.whitespace, WhitespaceHandling::Preserve); + let config = Config::new( r#" [general] - suppress_whitespace = true + whitespace = "preserve" "#, ) .unwrap(); - assert!(config.suppress_whitespace); + assert_eq!(config.whitespace, WhitespaceHandling::Preserve); } } diff --git a/testing/test_trim.toml b/testing/test_trim.toml index 57e88f8..019d574 100644 --- a/testing/test_trim.toml +++ b/testing/test_trim.toml @@ -1,2 +1,2 @@ [general] -suppress_whitespace = true +whitespace = "suppress" |