aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar René Kijewski <kijewski@library.vetmed.fu-berlin.de>2021-10-12 19:24:40 +0200
committerLibravatar René Kijewski <kijewski@library.vetmed.fu-berlin.de>2021-11-29 23:53:27 +0100
commitef3e840ac4874e52aa52da6ed5f0afddafa61d1a (patch)
tree2074c13e9c0b978fe1538ec81e88e1957a9a1b96
parent4940b5dd5e792811491f1c3c3b1c70c8177c7e02 (diff)
downloadaskama-ef3e840ac4874e52aa52da6ed5f0afddafa61d1a.tar.gz
askama-ef3e840ac4874e52aa52da6ed5f0afddafa61d1a.tar.bz2
askama-ef3e840ac4874e52aa52da6ed5f0afddafa61d1a.zip
Allow whitespace trimming in {{raw}} blocks
-rw-r--r--askama_shared/src/generator.rs4
-rw-r--r--askama_shared/src/parser.rs35
-rw-r--r--testing/templates/raw-ws.html2
-rw-r--r--testing/tests/simple.rs10
4 files changed, 33 insertions, 18 deletions
diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs
index e121be5..cb395d4 100644
--- a/askama_shared/src/generator.rs
+++ b/askama_shared/src/generator.rs
@@ -457,9 +457,9 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
self.flush_ws(m.ws1);
self.prepare_ws(m.ws2);
}
- Node::Raw(ws1, contents, ws2) => {
+ Node::Raw(ws1, lws, val, rws, ws2) => {
self.handle_ws(ws1);
- self.buf_writable.push(Writable::Lit(contents));
+ self.visit_lit(lws, val, rws);
self.handle_ws(ws2);
}
Node::Import(ws, _, _) => {
diff --git a/askama_shared/src/parser.rs b/askama_shared/src/parser.rs
index 44902d0..535c7f2 100644
--- a/askama_shared/src/parser.rs
+++ b/askama_shared/src/parser.rs
@@ -4,7 +4,7 @@ use std::str;
use nom::branch::alt;
use nom::bytes::complete::{escaped, is_not, tag, take_till, take_until};
use nom::character::complete::{anychar, char, digit1};
-use nom::combinator::{complete, cut, eof, map, not, opt, recognize, value};
+use nom::combinator::{complete, consumed, cut, eof, map, not, opt, peek, recognize, value};
use nom::error::{Error, ErrorKind};
use nom::multi::{fold_many0, many0, many1, separated_list0, separated_list1};
use nom::sequence::{delimited, pair, preceded, terminated, tuple};
@@ -28,7 +28,7 @@ pub enum Node<'a> {
Include(Ws, &'a str),
Import(Ws, &'a str, &'a str),
Macro(&'a str, Macro<'a>),
- Raw(Ws, &'a str, Ws),
+ Raw(Ws, &'a str, &'a str, &'a str, Ws),
Break(Ws),
Continue(Ws),
}
@@ -1048,29 +1048,32 @@ fn block_macro<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
}
fn block_raw<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
+ let endraw = tuple((
+ |i| tag_block_start(i, s),
+ opt(char('-')),
+ ws(tag("endraw")),
+ opt(char('-')),
+ peek(|i| tag_block_end(i, s)),
+ ));
+
let mut p = tuple((
opt(char('-')),
ws(tag("raw")),
cut(tuple((
opt(char('-')),
|i| tag_block_end(i, s),
- take_until("{% endraw %}"),
- |i| tag_block_start(i, s),
- opt(char('-')),
- ws(tag("endraw")),
- opt(char('-')),
+ consumed(skip_till(endraw)),
))),
));
- let (i, (pws1, _, (nws1, _, contents, _, pws2, _, nws2))) = p(i)?;
- Ok((
- i,
- Node::Raw(
- Ws(pws1.is_some(), nws1.is_some()),
- contents,
- Ws(pws2.is_some(), nws2.is_some()),
- ),
- ))
+ let (_, (pws1, _, (nws1, _, (contents, (i, (_, pws2, _, nws2, _)))))) = p(i)?;
+ let (lws, val, rws) = match split_ws_parts(contents) {
+ Node::Lit(lws, val, rws) => (lws, val, rws),
+ _ => unreachable!(),
+ };
+ let ws1 = Ws(pws1.is_some(), nws1.is_some());
+ let ws2 = Ws(pws2.is_some(), nws2.is_some());
+ Ok((i, Node::Raw(ws1, lws, val, rws, ws2)))
}
fn break_statement<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Node<'a>> {
diff --git a/testing/templates/raw-ws.html b/testing/templates/raw-ws.html
new file mode 100644
index 0000000..d590be7
--- /dev/null
+++ b/testing/templates/raw-ws.html
@@ -0,0 +1,2 @@
+<{% raw -%} {{hello}} {%- endraw %}>
+< {%- raw %}{{bye}}{% endraw -%} >
diff --git a/testing/tests/simple.rs b/testing/tests/simple.rs
index c712900..e66485a 100644
--- a/testing/tests/simple.rs
+++ b/testing/tests/simple.rs
@@ -433,6 +433,16 @@ fn test_raw_complex() {
);
}
+#[derive(Template)]
+#[template(path = "raw-ws.html")]
+struct RawTemplateWs;
+
+#[test]
+fn test_raw_ws() {
+ let template = RawTemplateWs;
+ assert_eq!(template.render().unwrap(), "<{{hello}}>\n<{{bye}}>");
+}
+
mod without_import_on_derive {
#[derive(askama::Template)]
#[template(source = "foo", ext = "txt")]