diff options
author | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2017-08-22 20:22:33 +0200 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2017-08-22 20:22:33 +0200 |
commit | 26a000cd9e6ab48325fbd4990bf2a3d9e2100a67 (patch) | |
tree | ffe24633dc1b60642e12ead28b2ad5dcb4fb3432 | |
parent | 544f9b11926b6ccad1bc4e7a6842c5421f9f1576 (diff) | |
download | askama-26a000cd9e6ab48325fbd4990bf2a3d9e2100a67.tar.gz askama-26a000cd9e6ab48325fbd4990bf2a3d9e2100a67.tar.bz2 askama-26a000cd9e6ab48325fbd4990bf2a3d9e2100a67.zip |
Add support for calling macros
-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 | |