diff options
Diffstat (limited to '')
| -rw-r--r-- | askama_derive/src/generator.rs | 20 | ||||
| -rw-r--r-- | askama_derive/src/parser.rs | 37 | 
2 files changed, 44 insertions, 13 deletions
| diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index dd34bec..6eb16e8 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -317,6 +317,25 @@ impl<'a> Generator<'a> {          self.writeln("))?;");      } +    fn write_call(&mut self, ws: &WS, name: &str, args: &[Expr]) { +        self.handle_ws(ws); +        let def = self.macros.get(name).expect(&format!("macro '{}' not found", name)); +        self.locals.push(); +        self.writeln("{"); +        self.prepare_ws(&def.0); +        for (i, arg) in def.2.iter().enumerate() { +            self.write(&format!("let {} = &", arg)); +            self.locals.insert(arg); +            self.visit_expr(&args.get(i) +                .expect(&format!("macro '{}' takes more than {} arguments", name, i))); +            self.writeln(";"); +        } +        self.handle(&def.3); +        self.flush_ws(&def.4); +        self.writeln("}"); +        self.locals.pop(); +    } +      fn write_let_decl(&mut self, ws: &WS, var: &'a Target) {          self.handle_ws(ws);          self.write("let "); @@ -453,6 +472,7 @@ impl<'a> Generator<'a> {                  Node::Include(ref ws, ref path) => {                      self.handle_include(ws, path);                  }, +                Node::Call(ref ws, name, ref args) => self.write_call(ws, name, args),                  Node::Macro(_, _, _, _, _) |                  Node::Extends(_) => {                      panic!("no extends or macros allowed in content"); diff --git a/askama_derive/src/parser.rs b/askama_derive/src/parser.rs index dad7e84..491a5d7 100644 --- a/askama_derive/src/parser.rs +++ b/askama_derive/src/parser.rs @@ -26,6 +26,7 @@ pub enum Node<'a> {      Lit(&'a str, &'a str, &'a str),      Comment(),      Expr(WS, Expr<'a>), +    Call(WS, &'a str, Vec<Expr<'a>>),      LetDecl(WS, Target<'a>),      Let(WS, Target<'a>, Expr<'a>),      Cond(Vec<(WS, Option<Expr<'a>>, Vec<Node<'a>>)>, WS), @@ -129,21 +130,21 @@ named!(target_single<Target>, map!(identifier,  named!(arguments<Vec<Expr>>, do_parse!(      tag_s!("(") >> -    arg0: ws!(opt!(expr_any)) >> -    args: many0!(do_parse!( -        tag_s!(",") >> -        argn: ws!(expr_any) >> -        (argn) +    args: opt!(do_parse!( +        arg0: ws!(expr_any) >> +        args: many0!(do_parse!( +            tag_s!(",") >> +            argn: ws!(expr_any) >> +            (argn) +        )) >> +        ({ +           let mut res = vec![arg0]; +           res.extend(args); +           res +        })      )) >>      tag_s!(")") >> -    ({ -        let mut res = Vec::new(); -        if arg0.is_some() { -            res.push(arg0.unwrap()); -        } -        res.extend(args); -        res -    }) +    (args.unwrap_or(Vec::new()))  ));  named!(parameters<Vec<&'a str>>, do_parse!( @@ -261,6 +262,15 @@ named!(expr_node<Node>, do_parse!(      (Node::Expr(WS(pws.is_some(), nws.is_some()), expr))  )); +named!(block_call<Node>, do_parse!( +    pws: opt!(tag_s!("-")) >> +    ws!(tag_s!("call")) >> +    name: ws!(identifier) >> +    args: ws!(arguments) >> +    nws: opt!(tag_s!("-")) >> +    (Node::Call(WS(pws.is_some(), nws.is_some()), name, args)) +)); +  named!(cond_if<Expr>, do_parse!(      ws!(tag_s!("if")) >>      cond: ws!(expr_any) >> @@ -389,6 +399,7 @@ named!(block_macro<Node>, do_parse!(  named!(block_node<Node>, do_parse!(      tag_s!("{%") >>      contents: alt!( +        block_call |          block_let |          block_if |          block_for | | 
