Skip to content

Commit

Permalink
Whitespace control
Browse files Browse the repository at this point in the history
  • Loading branch information
morenol committed May 30, 2020
1 parent 52e0243 commit 4607005
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 14 deletions.
10 changes: 5 additions & 5 deletions src/template_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ impl Default for Jinja2CompatMode {
#[derive(Clone, Debug, PartialEq)]
pub struct Settings {
/// Enables use of line statements (yet not supported)
use_line_statements: bool,
pub use_line_statements: bool,
/// Enables blocks trimming the same way as it does python Jinja2 engine
trim_blocks: bool,
pub trim_blocks: bool,
/// Enables blocks stripping (from the left) the same way as it does python Jinja2 engine
lstrip_blocks: bool,
pub lstrip_blocks: bool,
/// Templates cache size
cache_size: usize,
pub cache_size: usize,
/// If auto_reload is set to true (default) every time a template is requested the loader checks if the source changed and if yes, it will reload the template
auto_reload: bool,
pub auto_reload: bool,
/// Extensions set enabled for templates
extensions: Extensions,
/// Controls Jinja2 compatibility mode
Expand Down
162 changes: 153 additions & 9 deletions src/template_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,34 @@ impl<'a, 'b> TemplateParser<'a, 'b> {
mut start_offset: usize,
) {
let end_offset = match self.current_block_info.read().unwrap().mode {
TextBlockType::RawText => self.strip_block_left(start_offset, match_start),
TextBlockType::RawText => self.strip_block_left(
start_offset,
match_start,
self.env.read().unwrap().settings().lstrip_blocks,
),
_ => return,
};
self.finish_current_block(end_offset, mode, None);

if start_offset < self.template_body.read().unwrap().len() {
let ctrl_char = self
.template_body
.read()
.unwrap()
.chars()
.nth(start_offset)
.unwrap();

if ctrl_char == '+' || ctrl_char == '-' {
start_offset += 1;
}
}
//m_currentBlockInfo.type = blockType; TODO: remove line in jinja2cpp
if let TextBlockType::RawBlock = self.current_block_info.read().unwrap().mode {
start_offset = self.strip_block_right(start_offset - 2);
start_offset = self.strip_block_right(
start_offset - 2,
self.env.read().unwrap().settings().trim_blocks,
);
}
self.current_block_info.write().unwrap().range.start = start_offset;
}
Expand All @@ -278,13 +298,43 @@ impl<'a, 'b> TemplateParser<'a, 'b> {
TextBlockType::RawBlock => {
let current_position = match_start.unwrap_or(position);
let original_position = position;
position = self.strip_block_left(current_position + 2, current_position);
new_position = self.strip_block_right(original_position);
position = self.strip_block_left(
current_position + 2,
current_position,
self.env.read().unwrap().settings().lstrip_blocks,
);
new_position = self.strip_block_right(
original_position,
self.env.read().unwrap().settings().trim_blocks,
);
}
TextBlockType::RawText => {
position = self.strip_block_left(
position + 2,
position,
self.env.read().unwrap().settings().lstrip_blocks,
)
}
TextBlockType::RawText => position = self.strip_block_left(position + 2, position),
_ => {
if let TextBlockType::RawText = next_block {
new_position = self.strip_block_right(position);
new_position = self.strip_block_right(
position,
self.env.read().unwrap().settings().trim_blocks,
);
}

if position != 0 {
let ctrl_char = self
.template_body
.read()
.unwrap()
.chars()
.nth(position - 1)
.unwrap();

if ctrl_char == '+' || ctrl_char == '-' {
position -= 1;
}
}
}
};
Expand All @@ -300,11 +350,105 @@ impl<'a, 'b> TemplateParser<'a, 'b> {

new_position
}
fn strip_block_left(&self, ctrl_char_pos: usize, end_offset: usize) -> usize {
fn strip_block_left(
&self,
ctrl_char_pos: usize,
mut end_offset: usize,
mut do_trim: bool,
) -> usize {
let mut do_total_strip = false;
if ctrl_char_pos < self.template_body.read().unwrap().len() {
let ctrl_char = self
.template_body
.read()
.unwrap()
.chars()
.nth(ctrl_char_pos)
.unwrap();
if ctrl_char == '+' {
do_trim = false;
} else {
do_total_strip = ctrl_char == '-';
}
do_trim |= do_total_strip;
}
if !do_trim {
return end_offset;
}
match self.current_block_info.read().unwrap().mode {
TextBlockType::RawText | TextBlockType::RawBlock => {}
_ => return end_offset,
}

let original_offset = end_offset;
let mut same_line = true;
let start_offset = self.current_block_info.read().unwrap().range.start;
let templ = self.template_body.read().unwrap();
for ch in templ[start_offset..original_offset].chars().rev() {
if !ch.is_whitespace() {
if !same_line {
break;
}
if do_total_strip {
return end_offset;
} else {
return original_offset;
}
}
if ch == '\n' {
if !do_total_strip {
break;
}
same_line = false;
}
end_offset -= 1;
}

end_offset
}
fn strip_block_right(&self, position: usize) -> usize {
position + 2
fn strip_block_right(&self, position: usize, mut do_trim: bool) -> usize {
let mut new_pos = position + 2;

if position != 0 {
match self.current_block_info.read().unwrap().mode {
TextBlockType::RawText => {}
_ => {
let ctrl_char = self
.template_body
.read()
.unwrap()
.chars()
.nth(position - 1)
.unwrap();
do_trim = if ctrl_char == '-' {
true
} else {
if ctrl_char == '+' {
false
} else {
do_trim
}
}
}
}
}

if do_trim {
let templ = self.template_body.read().unwrap();

for ch in templ[position + 2..].chars() {
if ch == '\n' {
new_pos += 1;
break;
}
if !ch.is_whitespace() {
break;
}
new_pos += 1;
}
}

new_pos
}
fn finish_current_line(&self, position: usize) {
self.current_line_info.write().unwrap().range.end = position;
Expand Down
1 change: 1 addition & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ mod error;
mod expressions;
mod statement_if;
mod utils;
mod whitespace_control;
31 changes: 31 additions & 0 deletions tests/whitespace_control.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use super::utils::assert_render_template_eq;
use temple::error::Result;

#[test]
fn render_raw_with_whitespace_control() -> Result<()> {
assert_render_template_eq(
"{% raw -%} Some text
{%- endraw %}",
"Some text",
)?;
assert_render_template_eq(
" {%- raw %} Some text
{% endraw -%} ",
" Some text\n ",
)?;
assert_render_template_eq(
" {%- raw -%}
Some text
{%- endraw -%}",
"Some text",
)
}

#[test]
fn render_statement_with_whitespace_control() -> Result<()> {
assert_render_template_eq(
" {%- if true -%} Text striped
{%- endif %}",
"Text striped",
)
}

0 comments on commit 4607005

Please sign in to comment.