aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2017-02-08 10:59:48 +0100
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2017-02-08 10:59:48 +0100
commit4805acc8eb03541cb00ec39b4f20da49c51c9317 (patch)
tree71ee14bf904a1580234506c6585f877213526814
parente6d70fc17132e8fa27cb148e330d2f17f66a2ac3 (diff)
downloadaskama-4805acc8eb03541cb00ec39b4f20da49c51c9317.tar.gz
askama-4805acc8eb03541cb00ec39b4f20da49c51c9317.tar.bz2
askama-4805acc8eb03541cb00ec39b4f20da49c51c9317.zip
Split leading and trailing whitespace out of literals
-rw-r--r--askama/src/generator.rs6
-rw-r--r--askama/src/parser.rs28
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!(