Repository: Keats/tera (rust)

Issue:
Add {% raw %} ... {% endraw %} tag
that makes it so the content inside is just text

Pull request:
Add raw tag
Closes #32 

Patch:
diff --git a/src/parser.rs b/src/parser.rs
index 8e489a5..8a22496 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -24,6 +24,7 @@ pub enum Node {
     For {variable: String, array: String, body: Box<Node>},
     Block {name: String, body: Box<Node>},
 
+    Raw(String),
     Identifier(String),
     Extends(String),
     VariableBlock(Box<Node>),
@@ -107,19 +108,23 @@ impl_rdp! {
         elif_tag        = !@{ tag_start ~ ["elif"] ~ expression ~ tag_end }
         else_tag        = !@{ tag_start ~ ["else"] ~ tag_end }
         for_tag         = !@{ tag_start ~ ["for"] ~ identifier ~ ["in"] ~ identifier ~ tag_end }
+        raw_tag         = !@{ tag_start ~ ["raw"] ~ tag_end }
+        endraw_tag      = !@{ tag_start ~ ["endraw"] ~ tag_end }
         endblock_tag    = !@{ tag_start ~ ["endblock"] ~ identifier ~ tag_end }
         endif_tag       = !@{ tag_start ~ ["endif"] ~ tag_end }
         endfor_tag      = !@{ tag_start ~ ["endfor"] ~ tag_end }
 
         elif_block = { elif_tag ~ content* }
+        raw_text   = { (!endraw_tag ~ any )* }
+        text       = { (!(block_start) ~ any )+ }
 
-        text = { (!(block_start) ~ any )+ }
         content = @{
             variable_tag |
             comment_tag |
             block_tag ~ content* ~ endblock_tag |
             if_tag ~ content* ~ elif_block* ~ (else_tag ~ content*)? ~ endif_tag |
             for_tag ~ content* ~ endfor_tag |
+            raw_tag ~ raw_text ~ endraw_tag |
             text
         }
 
@@ -167,6 +172,9 @@ impl_rdp! {
             (_: variable_tag, exp: _expression()) => {
                 Ok(Some(Node::VariableBlock(Box::new(try!(exp)))))
             },
+            (_: raw_tag, &body: raw_text, _: endraw_tag) => {
+                Ok(Some(Node::Raw(body.to_string())))
+            },
             (_: block_tag, &name: identifier, body: _template(), _: endblock_tag, &end_name: identifier) => {
                 if name != end_name {
                     let (line_no, col_no) = self.input().line_col(self.input.pos());
@@ -730,6 +738,18 @@ mod tests {
         assert_eq!(parsed_ast.unwrap(), root);
     }
 
+    #[test]
+    fn test_ast_raw() {
+        let parsed_ast = parse("Hey {% raw %}Hey {{ name }}{% endraw %} Ho");
+        let mut ast = LinkedList::new();
+        // A bit ugly to have a separate node for the leading ws but oh well
+        ast.push_front(Node::Text(" Ho".to_string()));
+        ast.push_front(Node::Raw("Hey {{ name }}".to_string()));
+        ast.push_front(Node::Text("Hey ".to_string()));
+        let root = Node::List(ast);
+        assert_eq!(parsed_ast.unwrap(), root);
+    }
+
     #[test]
     fn test_ast_error_old_and() {
         let parsed_ast = parse("{{ true && 1 }}");
diff --git a/src/render.rs b/src/render.rs
index 681525d..4001635 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -339,6 +339,7 @@ impl<'a> Renderer<'a> {
     pub fn render_node(&mut self, node: Node) -> TeraResult<String> {
         match node {
             Text(s) => Ok(s),
+            Raw(s) => Ok(s.trim().to_string()),
             VariableBlock(exp) => self.render_variable_block(*exp),
             If {condition_nodes, else_node} => {
                 self.render_if(condition_nodes, else_node)


Test patch:
diff --git a/tests/expected/raw.html b/tests/expected/raw.html
new file mode 100644
index 0000000..20e0daa
--- /dev/null
+++ b/tests/expected/raw.html
@@ -0,0 +1,2 @@
+<h1>Hello</h1>
+Hey there {{ name }}
diff --git a/tests/render_ok.rs b/tests/render_ok.rs
index 5f8c80e..7876c62 100644
--- a/tests/render_ok.rs
+++ b/tests/render_ok.rs
@@ -87,3 +87,8 @@ fn test_ok_basic_inheritance_template() {
         Some("tests/templates/base.html")
     );
 }
+
+#[test]
+fn test_ok_raw_template() {
+    assert_template_ok("tests/templates/raw.html", None);
+}
diff --git a/tests/templates/raw.html b/tests/templates/raw.html
new file mode 100644
index 0000000..5124a1b
--- /dev/null
+++ b/tests/templates/raw.html
@@ -0,0 +1,4 @@
+<h1>Hello</h1>
+{% raw %}
+ Hey there {{ name }}
+{% endraw %}