From 409e913f34253bfae9d841e150f8013bc15844dc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 21 Apr 2022 15:45:29 +0200 Subject: Add WhitespaceHandling::Minimize --- askama_shared/src/generator.rs | 57 +++++++++++++++++++++++++++++------------- askama_shared/src/lib.rs | 4 +++ askama_shared/src/parser.rs | 6 ++--- 3 files changed, 47 insertions(+), 20 deletions(-) (limited to 'askama_shared/src') diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index a8636fa..92f39c0 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -246,7 +246,7 @@ struct Generator<'a, S: std::hash::BuildHasher> { next_ws: Option<&'a str>, // Whitespace suppression from the previous non-literal. Will be used to // determine whether to flush prefix whitespace from the next literal. - skip_ws: bool, + skip_ws: WhitespaceHandling, // If currently in a block, this will contain the name of a potential parent block super_block: Option<(&'a str, usize)>, // buffer for writable @@ -272,7 +272,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { heritage, locals, next_ws: None, - skip_ws: false, + skip_ws: WhitespaceHandling::Preserve, super_block: None, buf_writable: vec![], named: 0, @@ -1230,13 +1230,22 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { fn visit_lit(&mut self, lws: &'a str, val: &'a str, rws: &'a str) { assert!(self.next_ws.is_none()); if !lws.is_empty() { - if self.skip_ws { - self.skip_ws = false; - } else if val.is_empty() { - assert!(rws.is_empty()); - self.next_ws = Some(lws); - } else { - self.buf_writable.push(Writable::Lit(lws)); + match self.skip_ws { + WhitespaceHandling::Suppress => { + self.skip_ws = WhitespaceHandling::Preserve; + } + _ if val.is_empty() => { + assert!(rws.is_empty()); + self.next_ws = Some(lws); + } + WhitespaceHandling::Preserve => self.buf_writable.push(Writable::Lit(lws)), + WhitespaceHandling::Minimize => { + self.buf_writable + .push(Writable::Lit(match lws.contains('\n') { + true => "\n", + false => " ", + })) + } } } @@ -1819,11 +1828,12 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { self.prepare_ws(ws); } - fn should_trim_ws(&self, ws: Option) -> bool { + fn should_trim_ws(&self, ws: Option) -> WhitespaceHandling { match ws { - Some(Whitespace::Trim) => true, - Some(Whitespace::Preserve) => false, - None => self.whitespace == WhitespaceHandling::Suppress, + Some(Whitespace::Trim) => WhitespaceHandling::Suppress, + Some(Whitespace::Preserve) => WhitespaceHandling::Preserve, + Some(Whitespace::Minimize) => WhitespaceHandling::Minimize, + None => self.whitespace, } } @@ -1837,11 +1847,24 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { // 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(); - if !val.is_empty() { - self.buf_writable.push(Writable::Lit(val)); + match self.should_trim_ws(ws.0) { + WhitespaceHandling::Preserve => { + let val = self.next_ws.unwrap(); + if !val.is_empty() { + self.buf_writable.push(Writable::Lit(val)); + } + } + WhitespaceHandling::Minimize => { + let val = self.next_ws.unwrap(); + if !val.is_empty() { + self.buf_writable + .push(Writable::Lit(match val.contains('\n') { + true => "\n", + false => " ", + })); + } } + WhitespaceHandling::Suppress => {} } self.next_ws = None; } diff --git a/askama_shared/src/lib.rs b/askama_shared/src/lib.rs index 874be9d..3e87242 100644 --- a/askama_shared/src/lib.rs +++ b/askama_shared/src/lib.rs @@ -314,6 +314,10 @@ pub(crate) enum WhitespaceHandling { Preserve, /// It'll remove all the whitespace characters before and after the jinja block. Suppress, + /// It'll remove all the whitespace characters except one before and after the jinja blocks. + /// If there is a newline character, the preserved character in the trimmed characters, it will + /// the one preserved. + Minimize, } impl Default for WhitespaceHandling { diff --git a/askama_shared/src/parser.rs b/askama_shared/src/parser.rs index d7e33fb..2289e09 100644 --- a/askama_shared/src/parser.rs +++ b/askama_shared/src/parser.rs @@ -1447,12 +1447,12 @@ mod tests { #[test] fn change_delimiters_parse_filter() { let syntax = Syntax { - expr_start: "{~", - expr_end: "~}", + expr_start: "{=", + expr_end: "=}", ..Syntax::default() }; - super::parse("{~ strvar|e ~}", &syntax).unwrap(); + super::parse("{= strvar|e =}", &syntax).unwrap(); } #[test] -- cgit