From ef3e840ac4874e52aa52da6ed5f0afddafa61d1a Mon Sep 17 00:00:00 2001 From: René Kijewski Date: Tue, 12 Oct 2021 19:24:40 +0200 Subject: Allow whitespace trimming in {{raw}} blocks --- askama_shared/src/generator.rs | 4 ++-- askama_shared/src/parser.rs | 35 +++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 18 deletions(-) (limited to 'askama_shared/src') 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>> { -- cgit