Skip to content

Commit

Permalink
Merge pull request #152 from epage/raw
Browse files Browse the repository at this point in the history
 fix(raw): Stop swapping the text's order
  • Loading branch information
epage authored Dec 27, 2017
2 parents 89d7d20 + 5cffe44 commit fbcccba
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 12 deletions.
32 changes: 22 additions & 10 deletions src/compiler/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,32 @@ pub fn parse(elements: &[Element], options: &LiquidOptions) -> Result<Vec<Box<Re
let mut iter = elements.iter();
let mut token = iter.next();
while token.is_some() {
match *token.unwrap() {
Element::Expression(ref tokens, _) => ret.push(try!(parse_expression(tokens, options))),
Element::Tag(ref tokens, _) => ret.push(try!(parse_tag(&mut iter, tokens, options))),
Element::Raw(ref x) => ret.push(Box::new(Text::new(x))),
}
let render = match *token.unwrap() {
Element::Expression(ref tokens, _) => parse_expression(tokens, options)?,
Element::Tag(ref tokens, _) => parse_tag(&mut iter, tokens, options)?,
Element::Raw(ref x) => Box::new(Text::new(x)),
};
ret.push(render);
token = iter.next();
}
Ok(ret)
}

// creates an expression, which wraps everything that gets rendered
fn parse_expression(tokens: &[Token], options: &LiquidOptions) -> Result<Box<Renderable>> {
match tokens[0] {
Token::Identifier(ref x) if tokens.len() > 1 &&
(tokens[1] == Token::Dot || tokens[1] == Token::OpenSquare) => {
match tokens.get(0) {
Some(&Token::Identifier(ref x)) if tokens.len() > 1 &&
(tokens[1] == Token::Dot ||
tokens[1] == Token::OpenSquare) => {
let indexes = parse_indexes(&tokens[1..])?;
let mut result = Variable::new(x.clone());
result.extend(indexes);
Ok(Box::new(result))
}
Token::Identifier(ref x) if options.tags.contains_key(x) => {
Some(&Token::Identifier(ref x)) if options.tags.contains_key(x) => {
options.tags[x].parse(x, &tokens[1..], options)
}
None => Error::parser("expression", None),
_ => {
let output = parse_output(tokens)?;
Ok(Box::new(output))
Expand Down Expand Up @@ -381,6 +384,7 @@ mod test_split_block {
use super::super::FnParseBlock;
use interpreter::Renderable;
use interpreter::Context;
use interpreter;

#[derive(Debug)]
struct NullBlock;
Expand Down Expand Up @@ -409,6 +413,15 @@ mod test_split_block {
options
}

#[test]
fn parse_empty_expression() {
let text = "{{}}";

let tokens = tokenize(&text).unwrap();
let template = parse(&tokens, &options()).map(interpreter::Template::new);
assert!(template.is_err());
}

#[test]
fn handles_nonmatching_stream() {
// A stream of tokens with lots of `else`s in it, but only one at the
Expand All @@ -425,7 +438,6 @@ mod test_split_block {
assert!(trailing.is_none());
}


#[test]
fn honours_nesting() {
// A stream of tokens with lots of `else`s in it, but only one at the
Expand Down
34 changes: 32 additions & 2 deletions src/tags/raw_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ pub fn raw_block(_tag_name: &str,
_options: &LiquidOptions)
-> Result<Box<Renderable>> {
let content = tokens.iter().fold("".to_owned(), |a, b| {
a +
match *b {
Element::Expression(_, ref text) |
Element::Tag(_, ref text) |
Element::Raw(ref text) => text,
}.to_owned() + &a
}
});
Ok(Box::new(RawT { content: content }))
}
Expand All @@ -36,6 +37,7 @@ pub fn raw_block(_tag_name: &str,
mod test {
use super::*;
use compiler;
use interpreter;

fn options() -> LiquidOptions {
let mut options = LiquidOptions::default();
Expand All @@ -45,7 +47,7 @@ mod test {
}

#[test]
fn test_raw() {
fn raw_text() {
let raw = raw_block("raw",
&[],
&vec![Element::Expression(vec![], "This is a test".to_owned())],
Expand All @@ -54,4 +56,32 @@ mod test {
let output = raw.render(&mut Default::default()).unwrap();
assert_eq!(output, Some("This is a test".to_owned()));
}

#[test]
fn raw_escaped() {
let text = "{%raw%}{%if%}{%endraw%}";

let tokens = compiler::tokenize(&text).unwrap();
let template = compiler::parse(&tokens, &options())
.map(interpreter::Template::new)
.unwrap();

let mut context = Context::new();
let output = template.render(&mut context).unwrap();
assert_eq!(output, Some("{%if%}".to_owned()));
}

#[test]
fn raw_mixed() {
let text = "{%raw%}hello{%if%}world{%endraw%}";

let tokens = compiler::tokenize(&text).unwrap();
let template = compiler::parse(&tokens, &options())
.map(interpreter::Template::new)
.unwrap();

let mut context = Context::new();
let output = template.render(&mut context).unwrap();
assert_eq!(output, Some("hello{%if%}world".to_owned()));
}
}

0 comments on commit fbcccba

Please sign in to comment.