diff options
author | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2017-02-08 10:59:48 +0100 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2017-02-08 10:59:48 +0100 |
commit | 4805acc8eb03541cb00ec39b4f20da49c51c9317 (patch) | |
tree | 71ee14bf904a1580234506c6585f877213526814 | |
parent | e6d70fc17132e8fa27cb148e330d2f17f66a2ac3 (diff) | |
download | askama-4805acc8eb03541cb00ec39b4f20da49c51c9317.tar.gz askama-4805acc8eb03541cb00ec39b4f20da49c51c9317.tar.bz2 askama-4805acc8eb03541cb00ec39b4f20da49c51c9317.zip |
Split leading and trailing whitespace out of literals
-rw-r--r-- | askama/src/generator.rs | 6 | ||||
-rw-r--r-- | askama/src/parser.rs | 28 |
2 files changed, 29 insertions, 5 deletions
diff --git a/askama/src/generator.rs b/askama/src/generator.rs index e5fc6aa..ae794ae 100644 --- a/askama/src/generator.rs +++ b/askama/src/generator.rs @@ -179,7 +179,11 @@ impl Generator { fn handle(&mut self, nodes: &[Node]) { for n in nodes { match *n { - Node::Lit(val) => { self.write_lit(val); }, + Node::Lit(lws, val, rws) => { + self.write_lit(lws); + self.write_lit(val); + self.write_lit(rws); + }, Node::Expr(ref val) => { self.write_expr(val); }, Node::Cond(ref conds) => { self.write_cond(conds); }, Node::Loop(ref var, ref iter, ref body) => { diff --git a/askama/src/parser.rs b/askama/src/parser.rs index 8d35f31..f338456 100644 --- a/askama/src/parser.rs +++ b/askama/src/parser.rs @@ -13,7 +13,7 @@ pub enum Target<'a> { } pub enum Node<'a> { - Lit(&'a [u8]), + Lit(&'a [u8], &'a [u8], &'a [u8]), Expr(Expr<'a>), Cond(Vec<(Option<Expr<'a>>, Vec<Node<'a>>)>), Loop(Target<'a>, Expr<'a>, Vec<Node<'a>>), @@ -24,6 +24,26 @@ pub enum Node<'a> { pub type Cond<'a> = (Option<Expr<'a>>, Vec<Node<'a>>); +fn split_ws_parts(s: &[u8]) -> Node { + if s.is_empty() { + return Node::Lit(s, s, s); + } + let is_ws = |c: &u8| { + *c != b' ' && *c != b'\t' && *c != b'\r' && *c != b'\n' + }; + let start = s.iter().position(&is_ws); + if let None = start { + return Node::Lit(s, &s[0..0], &s[0..0]); + } + let start = start.unwrap(); + let end = s.iter().rposition(&is_ws); + if let None = end { + return Node::Lit(&s[..start], &s[start..], &s[0..0]); + } + let end = end.unwrap(); + Node::Lit(&s[..start], &s[start..end + 1], &s[end + 1..]) +} + fn take_content(i: &[u8]) -> IResult<&[u8], Node> { if i.len() < 1 || i[0] == b'{' { return IResult::Error(error_position!(nom::ErrorKind::TakeUntil, i)); @@ -31,13 +51,13 @@ fn take_content(i: &[u8]) -> IResult<&[u8], Node> { for (j, c) in i.iter().enumerate() { if *c == b'{' { if i.len() < j + 2 { - return IResult::Done(&i[..0], Node::Lit(&i[..])); + return IResult::Done(&i[..0], split_ws_parts(&i[..])); } else if i[j + 1] == b'{' || i[j + 1] == b'%' { - return IResult::Done(&i[j..], Node::Lit(&i[..j])); + return IResult::Done(&i[j..], split_ws_parts(&i[..j])); } } } - IResult::Done(&i[..0], Node::Lit(&i[..])) + IResult::Done(&i[..0], split_ws_parts(&i[..])) } named!(expr_str_lit<Expr>, map!( |