Skip to content

Commit

Permalink
Merge pull request #448 from sunng87/fix/stripping-newlines-issue
Browse files Browse the repository at this point in the history
Empty line stripping fix
  • Loading branch information
sunng87 authored Jun 30, 2021
2 parents 47df588 + 509e3d0 commit 708c773
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 59 deletions.
5 changes: 3 additions & 2 deletions examples/render_file/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
<body>
<h1>CSL {{year}}</h1>
<ul>
{{#each teams as |t| ~}}
{{#each teams as |t| }}
<li class="{{ranking_label @index ../teams}}">
{{~log @index~}}
{{!-- I'm comment --}}
<b>{{t.name}}</b>: {{format t.pts ~}}
</li>
{{/each~}}
{{/each}}
</ul>

<p>Rendered by Handlebars from {{engine}} data.</p>
Expand Down
47 changes: 20 additions & 27 deletions src/grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -62,44 +62,37 @@ pro_whitespace_omitter? ~ "}}" }
partial_expression = { "{{" ~ pre_whitespace_omitter? ~ ">" ~ partial_exp_line
~ pro_whitespace_omitter? ~ "}}" }

brackets_open = @{ (NEWLINE ~ (" "|"\t")*)? ~ "{{" }
brackets_close = @{ "}}" ~ ((" "|"\t")* ~ NEWLINE)? }

invert_tag_item = { "else"|"^" }
invert_tag = { !escape ~ brackets_open ~ pre_whitespace_omitter? ~ invert_tag_item
~ pro_whitespace_omitter? ~ brackets_close }
helper_block_start = { brackets_open ~ pre_whitespace_omitter? ~ "#" ~ exp_line ~
pro_whitespace_omitter? ~ brackets_close }
helper_block_end = { brackets_open ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ brackets_close }
invert_tag = { !escape ~ "{{" ~ pre_whitespace_omitter? ~ invert_tag_item
~ pro_whitespace_omitter? ~ "}}" }
helper_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ exp_line ~
pro_whitespace_omitter? ~ "}}" }
helper_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ "}}" }
helper_block = _{ helper_block_start ~ template ~
(invert_tag ~ template)? ~ helper_block_end }

decorator_block_start = { brackets_open ~ pre_whitespace_omitter? ~ "#" ~ "*"
~ exp_line ~ pro_whitespace_omitter? ~ brackets_close }
decorator_block_end = { brackets_open ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ brackets_close }
decorator_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ "*"
~ exp_line ~ pro_whitespace_omitter? ~ "}}" }
decorator_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ "}}" }
decorator_block = _{ decorator_block_start ~ template ~
decorator_block_end }

partial_block_start = { brackets_open ~ pre_whitespace_omitter? ~ "#" ~ ">"
~ partial_exp_line ~ pro_whitespace_omitter? ~ brackets_close }
partial_block_end = { brackets_open ~ pre_whitespace_omitter? ~ "/" ~ partial_identifier ~
pro_whitespace_omitter? ~ brackets_close }
partial_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ ">"
~ partial_exp_line ~ pro_whitespace_omitter? ~ "}}" }
partial_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ partial_identifier ~
pro_whitespace_omitter? ~ "}}" }
partial_block = _{ partial_block_start ~ template ~ partial_block_end }

double_brackets_open = @{ (NEWLINE ~ (" "|"\t")*)? ~ "{{{{" }
double_brackets_close = @{ "}}}}" ~ ((" "|"\t")* ~ NEWLINE)? }

raw_block_start = { double_brackets_open ~ pre_whitespace_omitter? ~ exp_line ~
pro_whitespace_omitter? ~ double_brackets_close }
raw_block_end = { double_brackets_open ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ double_brackets_close }
raw_block_start = { "{{{{" ~ pre_whitespace_omitter? ~ exp_line ~
pro_whitespace_omitter? ~ "}}}}" }
raw_block_end = { "{{{{" ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ "}}}}" }
raw_block = _{ raw_block_start ~ raw_block_text ~ raw_block_end }

comment_brackets_open = @{ ("\r"? ~ "\n" ~ (" "|"\t")*)? ~ "{{!" }
hbs_comment = { comment_brackets_open ~ "--" ~ (!"--}}" ~ ANY)* ~ "--" ~ brackets_close }
hbs_comment_compact = { comment_brackets_open ~ (!"}}" ~ ANY)* ~ brackets_close }
hbs_comment = { "{{!" ~ "--" ~ (!"--}}" ~ ANY)* ~ "--" ~ "}}" }
hbs_comment_compact = { "{{!" ~ (!"}}" ~ ANY)* ~ "}}" }

template = { (
raw_text |
Expand Down
27 changes: 20 additions & 7 deletions src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@
#[grammar = "grammar.pest"]
pub struct HandlebarsParser;

#[inline]
pub(crate) fn whitespace_matcher(c: char) -> bool {
c == ' ' || c == '\t'
}

#[inline]
pub(crate) fn newline_matcher(c: char) -> bool {
c == '\n' || c == '\r'
}

pub(crate) fn ends_with_empty_line(text: &str) -> bool {
text.trim_end_matches(whitespace_matcher)
.ends_with(newline_matcher)
}

pub(crate) fn starts_with_empty_line(text: &str) -> bool {
text.trim_start_matches(whitespace_matcher)
.starts_with(newline_matcher)
}

#[cfg(test)]
mod test {
use super::{HandlebarsParser, Rule};
Expand Down Expand Up @@ -144,7 +164,6 @@ mod test {
"{{!--
<li><a href=\"{{up-dir nest-count}}{{base-url}}index.html\">{{this.title}}</a></li>
--}}",
"\r\n {{!-- yes --}} \r\n",
"{{! -- good --}}"];
for i in s.iter() {
assert_rule!(Rule::hbs_comment, i);
Expand Down Expand Up @@ -226,10 +245,6 @@ mod test {
"{{#each people as |person|}}",
"{{#each-obj obj as |val key|}}",
"{{#each assets}}",
"\n{{#each assets}}\n",
"\r\n{{#each assets}}\r\n",
"\r\n {{#each assets}}\r\n",
"\r\n\t\t{{#each assets}}\r\n",
];
for i in s.iter() {
assert_rule!(Rule::helper_block_start, i);
Expand Down Expand Up @@ -257,7 +272,6 @@ mod test {
"{{#if}}hello{{else~}}world{{/if}}",
"{{#if}}hello{{~^~}}world{{/if}}",
"{{#if}}{{/if}}",
"\r\n{{#if}}\r\n\r\n{{/if}}\r\n",
];
for i in s.iter() {
assert_rule!(Rule::helper_block, i);
Expand All @@ -269,7 +283,6 @@ mod test {
let s = vec![
"{{{{if hello}}}}good {{hello}}{{{{/if}}}}",
"{{{{if hello}}}}{{#if nice}}{{/if}}{{{{/if}}}}",
"\n{{{{if hello}}}}\n{{#if nice}}{{/if}}{{{{/if}}}}",
];
for i in s.iter() {
assert_rule!(Rule::raw_block, i);
Expand Down
19 changes: 19 additions & 0 deletions src/helpers/helper_each.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,4 +571,23 @@ mod test {
.render_template("{{#each data}}{{else}}food{{/each}}", &json!({"data": 24}))
.is_ok());
}

#[test]
fn newline_stripping_for_each() {
let reg = Registry::new();

let tpl = r#"<ul>
{{#each a}}
{{!-- comment --}}
<li>{{this}}</li>
{{/each}}
</ul>"#;
assert_eq!(
r#"<ul>
<li>0</li>
<li>1</li>
</ul>"#,
reg.render_template(tpl, &json!({"a": [0, 1]})).unwrap()
);
}
}
12 changes: 12 additions & 0 deletions src/helpers/helper_if.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,17 @@ mod test {
hbs.render_template("{{#if a}}\nyes\n{{/if}}\n", &json!({"a": true}))
.unwrap()
);

assert_eq!(
"x\ny",
hbs.render_template("{{#if a}}x{{/if}}\ny", &json!({"a": true}))
.unwrap()
);

assert_eq!(
"y\nz",
hbs.render_template("{{#if a}}\nx\n{{^}}\ny\n{{/if}}\nz", &json!({"a": false}))
.unwrap()
);
}
}
Loading

0 comments on commit 708c773

Please sign in to comment.