Skip to content

Commit fbcccba

Browse files
authored
Merge pull request #152 from epage/raw
fix(raw): Stop swapping the text's order
2 parents 89d7d20 + 5cffe44 commit fbcccba

File tree

2 files changed

+54
-12
lines changed

2 files changed

+54
-12
lines changed

src/compiler/parser.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,29 +42,32 @@ pub fn parse(elements: &[Element], options: &LiquidOptions) -> Result<Vec<Box<Re
4242
let mut iter = elements.iter();
4343
let mut token = iter.next();
4444
while token.is_some() {
45-
match *token.unwrap() {
46-
Element::Expression(ref tokens, _) => ret.push(try!(parse_expression(tokens, options))),
47-
Element::Tag(ref tokens, _) => ret.push(try!(parse_tag(&mut iter, tokens, options))),
48-
Element::Raw(ref x) => ret.push(Box::new(Text::new(x))),
49-
}
45+
let render = match *token.unwrap() {
46+
Element::Expression(ref tokens, _) => parse_expression(tokens, options)?,
47+
Element::Tag(ref tokens, _) => parse_tag(&mut iter, tokens, options)?,
48+
Element::Raw(ref x) => Box::new(Text::new(x)),
49+
};
50+
ret.push(render);
5051
token = iter.next();
5152
}
5253
Ok(ret)
5354
}
5455

5556
// creates an expression, which wraps everything that gets rendered
5657
fn parse_expression(tokens: &[Token], options: &LiquidOptions) -> Result<Box<Renderable>> {
57-
match tokens[0] {
58-
Token::Identifier(ref x) if tokens.len() > 1 &&
59-
(tokens[1] == Token::Dot || tokens[1] == Token::OpenSquare) => {
58+
match tokens.get(0) {
59+
Some(&Token::Identifier(ref x)) if tokens.len() > 1 &&
60+
(tokens[1] == Token::Dot ||
61+
tokens[1] == Token::OpenSquare) => {
6062
let indexes = parse_indexes(&tokens[1..])?;
6163
let mut result = Variable::new(x.clone());
6264
result.extend(indexes);
6365
Ok(Box::new(result))
6466
}
65-
Token::Identifier(ref x) if options.tags.contains_key(x) => {
67+
Some(&Token::Identifier(ref x)) if options.tags.contains_key(x) => {
6668
options.tags[x].parse(x, &tokens[1..], options)
6769
}
70+
None => Error::parser("expression", None),
6871
_ => {
6972
let output = parse_output(tokens)?;
7073
Ok(Box::new(output))
@@ -381,6 +384,7 @@ mod test_split_block {
381384
use super::super::FnParseBlock;
382385
use interpreter::Renderable;
383386
use interpreter::Context;
387+
use interpreter;
384388

385389
#[derive(Debug)]
386390
struct NullBlock;
@@ -409,6 +413,15 @@ mod test_split_block {
409413
options
410414
}
411415

416+
#[test]
417+
fn parse_empty_expression() {
418+
let text = "{{}}";
419+
420+
let tokens = tokenize(&text).unwrap();
421+
let template = parse(&tokens, &options()).map(interpreter::Template::new);
422+
assert!(template.is_err());
423+
}
424+
412425
#[test]
413426
fn handles_nonmatching_stream() {
414427
// A stream of tokens with lots of `else`s in it, but only one at the
@@ -425,7 +438,6 @@ mod test_split_block {
425438
assert!(trailing.is_none());
426439
}
427440

428-
429441
#[test]
430442
fn honours_nesting() {
431443
// A stream of tokens with lots of `else`s in it, but only one at the

src/tags/raw_block.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ pub fn raw_block(_tag_name: &str,
2323
_options: &LiquidOptions)
2424
-> Result<Box<Renderable>> {
2525
let content = tokens.iter().fold("".to_owned(), |a, b| {
26+
a +
2627
match *b {
2728
Element::Expression(_, ref text) |
2829
Element::Tag(_, ref text) |
2930
Element::Raw(ref text) => text,
30-
}.to_owned() + &a
31+
}
3132
});
3233
Ok(Box::new(RawT { content: content }))
3334
}
@@ -36,6 +37,7 @@ pub fn raw_block(_tag_name: &str,
3637
mod test {
3738
use super::*;
3839
use compiler;
40+
use interpreter;
3941

4042
fn options() -> LiquidOptions {
4143
let mut options = LiquidOptions::default();
@@ -45,7 +47,7 @@ mod test {
4547
}
4648

4749
#[test]
48-
fn test_raw() {
50+
fn raw_text() {
4951
let raw = raw_block("raw",
5052
&[],
5153
&vec![Element::Expression(vec![], "This is a test".to_owned())],
@@ -54,4 +56,32 @@ mod test {
5456
let output = raw.render(&mut Default::default()).unwrap();
5557
assert_eq!(output, Some("This is a test".to_owned()));
5658
}
59+
60+
#[test]
61+
fn raw_escaped() {
62+
let text = "{%raw%}{%if%}{%endraw%}";
63+
64+
let tokens = compiler::tokenize(&text).unwrap();
65+
let template = compiler::parse(&tokens, &options())
66+
.map(interpreter::Template::new)
67+
.unwrap();
68+
69+
let mut context = Context::new();
70+
let output = template.render(&mut context).unwrap();
71+
assert_eq!(output, Some("{%if%}".to_owned()));
72+
}
73+
74+
#[test]
75+
fn raw_mixed() {
76+
let text = "{%raw%}hello{%if%}world{%endraw%}";
77+
78+
let tokens = compiler::tokenize(&text).unwrap();
79+
let template = compiler::parse(&tokens, &options())
80+
.map(interpreter::Template::new)
81+
.unwrap();
82+
83+
let mut context = Context::new();
84+
let output = template.render(&mut context).unwrap();
85+
assert_eq!(output, Some("hello{%if%}world".to_owned()));
86+
}
5787
}

0 commit comments

Comments
 (0)