mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-29 22:11:17 +00:00
Extend parser and generator to handle else blocks
This commit is contained in:
parent
fa651a7350
commit
f5ecfda679
@ -1,4 +1,4 @@
|
||||
use parser::{Expr, Node};
|
||||
use parser::{Conds, Expr, Node};
|
||||
use std::str;
|
||||
|
||||
struct Generator {
|
||||
@ -79,13 +79,24 @@ impl Generator {
|
||||
self.writeln(")).unwrap();");
|
||||
}
|
||||
|
||||
fn write_cond(&mut self, cond: &Expr, nodes: &Vec<Node>) {
|
||||
self.write("if ");
|
||||
self.visit_expr(cond);
|
||||
self.writeln(" {");
|
||||
self.indent();
|
||||
self.handle(nodes);
|
||||
self.dedent();
|
||||
fn write_cond(&mut self, conds: &Conds) {
|
||||
for (i, &(ref cond, ref nodes)) in conds.iter().enumerate() {
|
||||
match cond {
|
||||
&Some(ref expr) => {
|
||||
if i == 0 {
|
||||
self.write("if ");
|
||||
} else {
|
||||
self.write("} else if ");
|
||||
}
|
||||
self.visit_expr(expr);
|
||||
},
|
||||
&None => { self.writeln("} else"); },
|
||||
}
|
||||
self.writeln(" {");
|
||||
self.indent();
|
||||
self.handle(nodes);
|
||||
self.dedent();
|
||||
}
|
||||
self.writeln("}");
|
||||
}
|
||||
|
||||
@ -94,9 +105,7 @@ impl Generator {
|
||||
match n {
|
||||
&Node::Lit(val) => { self.write_lit(val); },
|
||||
&Node::Expr(ref val) => { self.write_expr(&val); },
|
||||
&Node::Cond(ref cond, ref nodes) => {
|
||||
self.write_cond(&cond, &nodes);
|
||||
},
|
||||
&Node::Cond(ref conds) => { self.write_cond(&conds); },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,12 @@ pub enum Expr<'a> {
|
||||
pub enum Node<'a> {
|
||||
Lit(&'a [u8]),
|
||||
Expr(Expr<'a>),
|
||||
Cond(Expr<'a>, Vec<Node<'a>>),
|
||||
Cond(Vec<(Option<Expr<'a>>, Vec<Node<'a>>)>),
|
||||
}
|
||||
|
||||
pub type Nodes<'a> = Vec<Node<'a>>;
|
||||
pub type Conds<'a> = Vec<(Option<Expr<'a>>, Nodes<'a>)>;
|
||||
|
||||
fn take_content(i: &[u8]) -> IResult<&[u8], Node> {
|
||||
if i.len() < 1 || i[0] == b'{' {
|
||||
return IResult::Error(error_position!(nom::ErrorKind::TakeUntil, i));
|
||||
@ -59,16 +62,31 @@ named!(expr_node<Node>, map!(
|
||||
delimited!(tag_s!("{{"), ws!(expr_filtered), tag_s!("}}")),
|
||||
Node::Expr));
|
||||
|
||||
named!(cond_blocks<Conds>, do_parse!(
|
||||
tag_s!("{%") >>
|
||||
ws!(tag_s!("else")) >>
|
||||
tag_s!("%}") >>
|
||||
block: parse_template >>
|
||||
(vec![(None, block)])));
|
||||
|
||||
named!(block_if<Node>, do_parse!(
|
||||
tag_s!("{%") >>
|
||||
ws!(tag_s!("if")) >>
|
||||
cond: ws!(expr_filtered) >>
|
||||
tag_s!("%}") >>
|
||||
block: parse_template >>
|
||||
rest: opt!(cond_blocks) >>
|
||||
tag_s!("{%") >>
|
||||
ws!(tag_s!("endif")) >>
|
||||
tag_s!("%}") >>
|
||||
(Node::Cond(cond, block))));
|
||||
({
|
||||
let mut res = Vec::new();
|
||||
res.push((Some(cond), block));
|
||||
if let Some(blocks) = rest {
|
||||
res.extend(blocks);
|
||||
}
|
||||
Node::Cond(res)
|
||||
})));
|
||||
|
||||
named!(parse_template< Vec<Node> >, many1!(alt!(
|
||||
take_content |
|
||||
|
Loading…
x
Reference in New Issue
Block a user