From f02ade3b94e0eb7f97498439142a2448ebdcdfcc Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 5 Sep 2017 20:34:18 +0200 Subject: Introduce attribute parameter to disable escaping --- askama_shared/src/generator.rs | 14 +++++++++----- askama_shared/src/input.rs | 26 +++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index 7fbc5d9..d8b3a42 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -352,16 +352,20 @@ impl<'a> Generator<'a> { } } - fn write_expr(&mut self, ws: &WS, s: &Expr) { + fn write_expr(&mut self, state: &'a State, ws: &WS, s: &Expr) { self.handle_ws(ws); self.write("let askama_expr = &"); let wrapped = self.visit_expr(s); self.writeln(";"); + use self::DisplayWrap::*; + use super::input::EscapeMode::*; self.write("writer.write_fmt(format_args!(\"{}\", "); - self.write(match wrapped { - DisplayWrap::Wrapped => "askama_expr", - DisplayWrap::Unwrapped => "&::askama::MarkupDisplay::from(askama_expr)", + self.write(match (wrapped, &state.input.meta.escaping) { + (Wrapped, &Html) | + (Wrapped, &None) | + (Unwrapped, &None) => "askama_expr", + (Unwrapped, &Html) => "&::askama::MarkupDisplay::from(askama_expr)", }); self.writeln("))?;"); } @@ -508,7 +512,7 @@ impl<'a> Generator<'a> { match *n { Node::Lit(lws, val, rws) => { self.write_lit(lws, val, rws); } Node::Comment() => {}, - Node::Expr(ref ws, ref val) => { self.write_expr(ws, val); }, + Node::Expr(ref ws, ref val) => { self.write_expr(state, ws, val); }, Node::LetDecl(ref ws, ref var) => { self.write_let_decl(ws, var); }, Node::Let(ref ws, ref var, ref val) => { self.write_let(ws, var, val); }, Node::Cond(ref conds, ref ws) => { diff --git a/askama_shared/src/input.rs b/askama_shared/src/input.rs index 73b9a60..40dc39f 100644 --- a/askama_shared/src/input.rs +++ b/askama_shared/src/input.rs @@ -32,6 +32,7 @@ impl<'a> TemplateInput<'a> { pub struct TemplateMeta<'a> { source: Source<'a>, pub print: Print, + pub escaping: EscapeMode, } impl<'a> TemplateMeta<'a> { @@ -46,6 +47,7 @@ impl<'a> TemplateMeta<'a> { let attr = attr.unwrap(); let mut source = None; let mut print = Print::None; + let mut escaping = EscapeMode::Html; if let syn::MetaItem::List(_, ref inner) = attr.value { for nm_item in inner { if let syn::NestedMetaItem::MetaItem(ref item) = *nm_item { @@ -66,6 +68,11 @@ impl<'a> TemplateMeta<'a> { } else { panic!("print value must be string literal"); }, + "escape" => if let syn::Lit::Str(ref s, _) = *val { + escaping = s.into(); + } else { + panic!("escape value must be string literal"); + }, _ => { panic!("unsupported annotation key found") } } } @@ -74,7 +81,7 @@ impl<'a> TemplateMeta<'a> { } match source { - Some(s) => TemplateMeta { source: s, print }, + Some(s) => TemplateMeta { source: s, print, escaping }, None => panic!("template path or source not found in struct attributes"), } } @@ -85,6 +92,23 @@ enum Source<'a> { Source(&'a str), } +#[derive(PartialEq)] +pub enum EscapeMode { + Html, + None, +} + +impl<'a> From<&'a String> for EscapeMode { + fn from(s: &'a String) -> EscapeMode { + use self::EscapeMode::*; + match s.as_ref() { + "html" => Html, + "none" => None, + v => panic!("invalid value for escape option: {}", v), + } + } +} + #[derive(PartialEq)] pub enum Print { All, -- cgit