aboutsummaryrefslogtreecommitdiffstats
path: root/askama_shared/src
diff options
context:
space:
mode:
Diffstat (limited to 'askama_shared/src')
-rw-r--r--askama_shared/src/generator.rs57
-rw-r--r--askama_shared/src/lib.rs4
-rw-r--r--askama_shared/src/parser.rs6
3 files changed, 47 insertions, 20 deletions
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<Whitespace>) -> bool {
+ fn should_trim_ws(&self, ws: Option<Whitespace>) -> 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]