aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2017-02-08 13:30:57 +0100
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2017-02-08 13:30:57 +0100
commite54b8c898ec634234eef4e12125577596e9d42d7 (patch)
tree8b7c2754ceca31d67fd61bad9265689158352348
parentb1dc4d5057198330551879c48cb1b4dceb9f381e (diff)
downloadaskama-e54b8c898ec634234eef4e12125577596e9d42d7.tar.gz
askama-e54b8c898ec634234eef4e12125577596e9d42d7.tar.bz2
askama-e54b8c898ec634234eef4e12125577596e9d42d7.zip
Add support for whitespace handling markers to parser
-rw-r--r--askama/src/generator.rs16
-rw-r--r--askama/src/parser.rs53
2 files changed, 47 insertions, 22 deletions
diff --git a/askama/src/generator.rs b/askama/src/generator.rs
index 32d7c71..8ff5836 100644
--- a/askama/src/generator.rs
+++ b/askama/src/generator.rs
@@ -131,7 +131,7 @@ impl Generator {
}
fn write_cond(&mut self, conds: &[Cond]) {
- for (i, &(ref cond, ref nodes)) in conds.iter().enumerate() {
+ for (i, &(_, ref cond, ref nodes)) in conds.iter().enumerate() {
match *cond {
Some(ref expr) => {
if i == 0 {
@@ -195,13 +195,13 @@ impl Generator {
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) => {
+ Node::Expr(_, ref val) => { self.write_expr(val); },
+ Node::Cond(ref conds, _) => { self.write_cond(conds); },
+ Node::Loop(_, ref var, ref iter, ref body, _) => {
self.write_loop(var, iter, body);
},
- Node::Block(name) => { self.write_block(name) },
- Node::BlockDef(name, ref block_nodes) => {
+ Node::Block(_, name, _) => { self.write_block(name) },
+ Node::BlockDef(_, name, ref block_nodes, _) => {
self.write_block_def(name, block_nodes);
}
Node::Extends(_) => {
@@ -301,9 +301,9 @@ pub fn generate(ast: &syn::DeriveInput, path: &str, mut nodes: Vec<Node>) -> Str
None => { base = Some(path); },
}
},
- Node::BlockDef(name, _) => {
+ Node::BlockDef(ws1, name, _, ws2) => {
blocks.push(n);
- content.push(Node::Block(name));
+ content.push(Node::Block(ws1, name, ws2));
},
_ => { content.push(n); },
}
diff --git a/askama/src/parser.rs b/askama/src/parser.rs
index f6a8726..0242356 100644
--- a/askama/src/parser.rs
+++ b/askama/src/parser.rs
@@ -12,17 +12,20 @@ pub enum Target<'a> {
Name(&'a [u8]),
}
+#[derive(Clone, Copy)]
+pub struct WS(bool, bool);
+
pub enum Node<'a> {
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>>),
+ Expr(WS, Expr<'a>),
+ Cond(Vec<(WS, Option<Expr<'a>>, Vec<Node<'a>>)>, WS),
+ Loop(WS, Target<'a>, Expr<'a>, Vec<Node<'a>>, WS),
Extends(Expr<'a>),
- BlockDef(&'a str, Vec<Node<'a>>),
- Block(&'a str),
+ BlockDef(WS, &'a str, Vec<Node<'a>>, WS),
+ Block(WS, &'a str, WS),
}
-pub type Cond<'a> = (Option<Expr<'a>>, Vec<Node<'a>>);
+pub type Cond<'a> = (WS, Option<Expr<'a>>, Vec<Node<'a>>);
fn split_ws_parts(s: &[u8]) -> Node {
if s.is_empty() {
@@ -110,9 +113,13 @@ named!(expr_any<Expr>, alt!(
expr_str_lit
));
-named!(expr_node<Node>, map!(
- delimited!(tag_s!("{{"), ws!(expr_any), tag_s!("}}")),
- Node::Expr
+named!(expr_node<Node>, do_parse!(
+ tag_s!("{{") >>
+ pws: opt!(tag_s!("-")) >>
+ expr: ws!(expr_any) >>
+ nws: opt!(tag_s!("-")) >>
+ tag_s!("}}") >>
+ (Node::Expr(WS(pws.is_some(), nws.is_some()), expr))
));
named!(cond_if<Expr>, do_parse!(
@@ -123,42 +130,54 @@ named!(cond_if<Expr>, do_parse!(
named!(cond_block<Cond>, do_parse!(
tag_s!("{%") >>
+ pws: opt!(tag_s!("-")) >>
ws!(tag_s!("else")) >>
cond: opt!(cond_if) >>
+ nws: opt!(tag_s!("-")) >>
tag_s!("%}") >>
block: parse_template >>
- (cond, block)
+ (WS(pws.is_some(), nws.is_some()), cond, block)
));
named!(block_if<Node>, do_parse!(
tag_s!("{%") >>
+ pws1: opt!(tag_s!("-")) >>
cond: ws!(cond_if) >>
+ nws1: opt!(tag_s!("-")) >>
tag_s!("%}") >>
block: parse_template >>
elifs: many0!(cond_block) >>
tag_s!("{%") >>
+ pws2: opt!(tag_s!("-")) >>
ws!(tag_s!("endif")) >>
+ nws2: opt!(tag_s!("-")) >>
tag_s!("%}") >>
({
let mut res = Vec::new();
- res.push((Some(cond), block));
+ res.push((WS(pws1.is_some(), nws1.is_some()), Some(cond), block));
res.extend(elifs);
- Node::Cond(res)
+ Node::Cond(res, WS(pws2.is_some(), nws2.is_some()))
})
));
named!(block_for<Node>, do_parse!(
tag_s!("{%") >>
+ pws1: opt!(tag_s!("-")) >>
ws!(tag_s!("for")) >>
var: ws!(target_single) >>
ws!(tag_s!("in")) >>
iter: ws!(expr_any) >>
+ nws1: opt!(tag_s!("-")) >>
tag_s!("%}") >>
block: parse_template >>
tag_s!("{%") >>
+ pws2: opt!(tag_s!("-")) >>
ws!(tag_s!("endfor")) >>
+ nws2: opt!(tag_s!("-")) >>
tag_s!("%}") >>
- (Node::Loop(var, iter, block))
+ (Node::Loop(WS(pws1.is_some(), nws1.is_some()),
+ var, iter, block,
+ WS(pws2.is_some(), pws2.is_some())))
));
named!(block_extends<Node>, do_parse!(
@@ -171,14 +190,20 @@ named!(block_extends<Node>, do_parse!(
named!(block_block<Node>, do_parse!(
tag_s!("{%") >>
+ pws1: opt!(tag_s!("-")) >>
ws!(tag_s!("block")) >>
name: ws!(nom::alphanumeric) >>
+ nws1: opt!(tag_s!("-")) >>
tag_s!("%}") >>
contents: parse_template >>
tag_s!("{%") >>
+ pws2: opt!(tag_s!("-")) >>
ws!(tag_s!("endblock")) >>
+ nws2: opt!(tag_s!("-")) >>
tag_s!("%}") >>
- (Node::BlockDef(str::from_utf8(name).unwrap(), contents))
+ (Node::BlockDef(WS(pws1.is_some(), nws1.is_some()),
+ str::from_utf8(name).unwrap(), contents,
+ WS(pws2.is_some(), pws2.is_some())))
));
named!(parse_template<Vec<Node<'a>>>, many0!(alt!(