Skip to content

Commit

Permalink
Added support for {% raw %} tag (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Jun 17, 2022
1 parent 069d726 commit a201af3
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 14 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Tests
on: [push]

jobs:
build-latest:
test-latest:
name: Test on Latest
runs-on: ubuntu-latest

Expand All @@ -18,28 +18,28 @@ jobs:
run: make test

build-old-stable:
name: Build on 1.43.0
name: Build on 1.45.0
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.43.0
toolchain: 1.45.0
profile: minimal
override: true
- name: Build
run: cargo build --features=unstable_machinery,builtins,source,json,urlencode,debug,internal_debug
working-directory: ./minijinja

build-stable:
name: Test on 1.46.0
test-stable:
name: Test on 1.56.1
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.46.0
toolchain: 1.56.1
profile: minimal
override: true
- name: Test
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

All notable changes to MiniJinja are documented here.

# 0.17.0

- Added support for `{% raw %}`. (#67)
- Minimum Rust version moved up to 1.45.

# 0.16.0

- Added support for unpacking in `with` blocks. (#65)
Expand Down
6 changes: 0 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ test:
@echo "CARGO TEST ALL FEATURES"
@cd minijinja; cargo test --all-features

test-142:
@$(MAKE) run-tests FEATURES=$(TEST_FEATURES)
@$(MAKE) run-tests FEATURES=$(TEST_FEATURES),key_interning
@echo "CARGO TEST ALL FEATURES"
@cd minijinja; cargo test --all-features

run-tests:
@rustup component add rustfmt 2> /dev/null
@echo "CARGO TESTS"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Build Status](https://github.com/mitsuhiko/minijinja/workflows/Tests/badge.svg?branch=main)](https://github.com/mitsuhiko/minijinja/actions?query=workflow%3ATests)
[![License](https://img.shields.io/github/license/mitsuhiko/minijinja)](https://github.com/mitsuhiko/minijinja/blob/main/LICENSE)
[![Crates.io](https://img.shields.io/crates/d/minijinja.svg)](https://crates.io/crates/minijinja)
[![rustc 1.43.0](https://img.shields.io/badge/rust-1.43%2B-orange.svg)](https://img.shields.io/badge/rust-1.43%2B-orange.svg)
[![rustc 1.43.0](https://img.shields.io/badge/rust-1.45%2B-orange.svg)](https://img.shields.io/badge/rust-1.45%2B-orange.svg)
[![Documentation](https://docs.rs/minijinja/badge.svg)](https://docs.rs/minijinja)

</div>
Expand Down
2 changes: 1 addition & 1 deletion minijinja/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ homepage = "https://github.com/mitsuhiko/minijinja"
repository = "https://github.com/mitsuhiko/minijinja"
keywords = ["jinja", "jinja2", "templates"]
readme = "README.md"
rust-version = "1.43"
rust-version = "1.45"

[package.metadata.docs.rs]
features = ["source", "json", "urlencode"]
Expand Down
48 changes: 48 additions & 0 deletions minijinja/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,29 @@ fn find_marker(a: &str) -> Option<usize> {
}
}

fn skip_basic_tag(block_str: &str, name: &str) -> Option<usize> {
let mut ptr = block_str;

if let Some(rest) = ptr.strip_prefix('-') {
ptr = rest;
}
while let Some(rest) = ptr.strip_prefix(|x: char| x.is_ascii_whitespace()) {
ptr = rest;
}

ptr = ptr.strip_prefix(name)?;

while let Some(rest) = ptr.strip_prefix(|x: char| x.is_ascii_whitespace()) {
ptr = rest;
}
if let Some(rest) = ptr.strip_prefix('-') {
ptr = rest;
}
ptr = ptr.strip_prefix("%}")?;

Some(block_str.len() - ptr.len())
}

/// Tokenizes without whitespace handling.
fn tokenize_raw(
input: &str,
Expand Down Expand Up @@ -182,13 +205,30 @@ fn tokenize_raw(
return Some(Ok((Token::VariableStart(ws), span!(old_loc))));
}
Some("{%") => {
// raw blocks require some special handling. If we are at the beginning of a raw
// block we want to skip everything until {% endraw %} completely ignoring iterior
// syntax and emit the entire raw block as TemplateData.
if let Some(mut ptr) = skip_basic_tag(&rest[2..], "raw") {
ptr += 2;
while let Some(block) = memstr(&rest.as_bytes()[ptr..], b"{%") {
ptr += block + 2;
if let Some(endraw) = skip_basic_tag(&rest[ptr..], "endraw") {
let result = &rest[..ptr + endraw];
advance!(ptr + endraw);
return Some(Ok((Token::TemplateData(result), span!(old_loc))));
}
}
syntax_error!("unexpected end of raw block");
}

let ws = if rest.as_bytes().get(2) == Some(&b'-') {
advance!(3);
true
} else {
advance!(2);
false
};

stack.push(LexerState::InBlock);
return Some(Ok((Token::BlockStart(ws), span!(old_loc))));
}
Expand Down Expand Up @@ -400,3 +440,11 @@ fn test_find_marker() {
assert!(find_marker("foo {").is_none());
assert_eq!(find_marker("foo {{"), Some(4));
}

#[test]
fn test_is_basic_tag() {
assert_eq!(skip_basic_tag(" raw %}", "raw"), Some(7));
assert_eq!(skip_basic_tag(" raw %}", "endraw"), None);
assert_eq!(skip_basic_tag(" raw %}", "raw"), Some(9));
assert_eq!(skip_basic_tag("- raw -%}", "raw"), Some(11));
}
19 changes: 19 additions & 0 deletions minijinja/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
//! - [`{% with %}`](#-with-)
//! - [`{% filter %}`](#-filter-)
//! - [`{% autoescape %}`](#-autoescape-)
//! - [`{% raw %}`](#-raw-)
//!
//! </details>
//!
Expand Down Expand Up @@ -433,5 +434,23 @@
//! ```
//!
//! After an `endautoescape` the behavior is reverted to what it was before.
//!
//! ## `{% raw %}`
//!
//! A raw block is a special construct that lets you ignore the embedded template
//! syntax. This is particularly useful if a segment of template code would
//! otherwise require constant escaping with things like `{{ "{{" }}`:
//!
//! Example:
//!
//! ```jinja
//! {% raw %}
//! <ul>
//! {% for item in seq %}
//! <li>{{ item }}</li>
//! {% endfor %}
//! </ul>
//! {% endraw %}
//! ```

// this is just for docs
5 changes: 5 additions & 0 deletions minijinja/tests/lexer-inputs/raw.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
before {% raw %} this is a {{ raw }} {% block %} {% endraw %} after

before {%- raw %} this is a {{ raw }} {% block %} {% endraw -%} after

before {%- raw -%} this is a {{ raw }} {% block %} {%- endraw -%} after
14 changes: 14 additions & 0 deletions minijinja/tests/snapshots/test_lexer__lexer@raw.txt.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
source: minijinja/tests/test_lexer.rs
expression: "&tokens"
input_file: minijinja/tests/lexer-inputs/raw.txt
---
[
TEMPLATE_DATA("before "),
TEMPLATE_DATA("{% raw %} this is a {{ raw }} {% block %} {% endraw %}"),
TEMPLATE_DATA(" after\n\nbefore "),
TEMPLATE_DATA("{%- raw %} this is a {{ raw }} {% block %} {% endraw -%}"),
TEMPLATE_DATA(" after\n\nbefore "),
TEMPLATE_DATA("{%- raw -%} this is a {{ raw }} {% block %} {%- endraw -%}"),
TEMPLATE_DATA(" after"),
]

0 comments on commit a201af3

Please sign in to comment.