Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove line separator for invisible elements #404

Merged
merged 5 commits into from Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/decorator/template.hbs
Expand Up @@ -7,12 +7,12 @@
<body>
<h1>CSL {{year}}</h1>
<ul>
{{#each teams as |t| ~}}
{{#each teams as |t|}}
<li class="{{ranking_label @index ../teams}}">
{{~log @index~}}
<b>{{t.name}}</b>: {{format t.pts ~}}
</li>
{{/each~}}
{{/each}}
</ul>

{{*set version="v3.0"}}
Expand Down
4 changes: 2 additions & 2 deletions examples/error/template.hbs
Expand Up @@ -5,13 +5,13 @@
<body>
<h1>CSL {{year}}</h1>
<ul>
{{#each teams as |t| ~}}
{{#each teams as |t|}}
{{! ranking_label will produce a render error when first parameter is not a number }}
<li class="{{ranking_label true ../teams}}">
{{~log @index~}}
<b>{{t.name}}</b>: {{format t.pts ~}}
</li>
{{/each~}}
{{/each}}
</ul>

<p>Rendered by Handlebars from {{engine}} data.</p>
Expand Down
2 changes: 1 addition & 1 deletion examples/partials/base0.hbs
Expand Up @@ -2,6 +2,6 @@
<head>{{title}}</head>
<body>
<div><h1>Derived from base0.hbs</h1></div>
{{~> page}}
{{> page}}
</body>
</html>
2 changes: 1 addition & 1 deletion examples/partials/base1.hbs
Expand Up @@ -2,6 +2,6 @@
<head>{{title}}</head>
<body>
<div><h1>Derived from base1.hbs</h1></div>
{{~> page}}
{{> page}}
</body>
</html>
3 changes: 1 addition & 2 deletions examples/partials/template2.hbs
@@ -1,5 +1,4 @@
{{#*inline "page"}}
<p>Rendered in partial, parent is {{parent}}</p>
{{/inline}}
{{! remove whitespaces with ~ }}
{{~> (parent)~}}
{{> (parent)}}
4 changes: 2 additions & 2 deletions examples/render/template.hbs
Expand Up @@ -5,12 +5,12 @@
<body>
<h1>CSL {{year}}</h1>
<ul>
{{#each teams as |t| ~}}
{{#each teams as |t|}}
<li class="{{ranking_label @index ../teams}}">
{{~log @index~}}
<b>{{t.name}}</b>: {{format t.pts ~}}
</li>
{{/each~}}
{{/each}}
</ul>

<p>Rendered by Handlebars from {{engine}} data.</p>
Expand Down
4 changes: 2 additions & 2 deletions examples/script/template.hbs
@@ -1,10 +1,10 @@
Bundesliga Match Day
{{#each this as |match| ~}}
{{#each this as |match|}}
{{#each match as |team|}}
{{team.name}} - {{score team.goals}}
{{#each team.goals as |scorer|}}
> {{scorer}}
{{/each}}
{{~ /each}}
{{/each}}
---
{{/each}}
48 changes: 28 additions & 20 deletions src/grammar.pest
Expand Up @@ -55,37 +55,45 @@ decorator_expression = { "{{" ~ pre_whitespace_omitter? ~ "*" ~ exp_line ~
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 ~ "{{" ~ 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? ~ "}}" }
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 }
helper_block = _{ helper_block_start ~ template ~
(invert_tag ~ template)? ~ helper_block_end }

decorator_block_start = { "{{" ~ pre_whitespace_omitter? ~ "#" ~ "*"
~ exp_line ~ pro_whitespace_omitter? ~ "}}" }
decorator_block_end = { "{{" ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ "}}" }
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 = _{ decorator_block_start ~ template ~
decorator_block_end }

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_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 = _{ partial_block_start ~ template ~ partial_block_end }

raw_block_start = { "{{{{" ~ pre_whitespace_omitter? ~ exp_line ~
pro_whitespace_omitter? ~ "}}}}" }
raw_block_end = { "{{{{" ~ pre_whitespace_omitter? ~ "/" ~ identifier ~
pro_whitespace_omitter? ~ "}}}}" }
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 = _{ raw_block_start ~ raw_block_text ~ raw_block_end }

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

template = { (
raw_text |
Expand Down
10 changes: 9 additions & 1 deletion src/grammar.rs
Expand Up @@ -145,7 +145,9 @@ mod test {
let s = vec!["{{!-- <hello {{ a-b c-d}} {{d-c}} ok --}}",
"{{!--
<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 @@ -225,6 +227,10 @@ 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 @@ -252,6 +258,7 @@ 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 @@ -263,6 +270,7 @@ 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
10 changes: 10 additions & 0 deletions src/helpers/helper_if.rs
Expand Up @@ -126,4 +126,14 @@ mod test {
.unwrap()
);
}

#[test]
fn test_invisible_line_stripping() {
let hbs = Registry::new();
assert_eq!(
"yes\n",
hbs.render_template("{{#if a}}\nyes\n{{/if}}\n", &json!({"a": true}))
.unwrap()
);
}
}
17 changes: 15 additions & 2 deletions src/template.rs
Expand Up @@ -441,7 +441,18 @@ impl Template {
// remove escape from our pair queue
let mut it = parser_queue
.flatten()
.filter(|p| p.as_rule() != Rule::escape)
.filter(|p| {
// remove rules that should be silent but not for now due to pest limitation
!matches!(
p.as_rule(),
Rule::escape
| Rule::brackets_open
| Rule::brackets_close
| Rule::double_brackets_open
| Rule::double_brackets_close
| Rule::comment_brackets_open
)
})
.peekable();
let mut end_pos: Option<Position<'_>> = None;
loop {
Expand Down Expand Up @@ -1025,7 +1036,9 @@ fn test_whitespace_elements() {
" {{elem}}\n\t{{#if true}} \
{{/if}}\n{{{{raw}}}} {{{{/raw}}}}\n{{{{raw}}}}{{{{/raw}}}}\n",
);
assert_eq!(c.ok().unwrap().elements.len(), 9);
let r = c.unwrap();
// the \n after last raw block is dropped by pest
assert_eq!(r.elements.len(), 6);
}

#[test]
Expand Down