Capture whitespace around interpolations

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-05 20:34:10 +01:00
parent 4177649202
commit c5a2179b9e

View file

@ -8,10 +8,12 @@ use annotate_snippets::Snippet;
use winnow::LocatingSlice; use winnow::LocatingSlice;
use winnow::Parser; use winnow::Parser;
use winnow::RecoverableParser; use winnow::RecoverableParser;
use winnow::ascii::multispace0;
use winnow::ascii::multispace1; use winnow::ascii::multispace1;
use winnow::combinator::alt; use winnow::combinator::alt;
use winnow::combinator::cut_err; use winnow::combinator::cut_err;
use winnow::combinator::eof; use winnow::combinator::eof;
use winnow::combinator::opt;
use winnow::combinator::peek; use winnow::combinator::peek;
use winnow::combinator::repeat_till; use winnow::combinator::repeat_till;
use winnow::combinator::terminated; use winnow::combinator::terminated;
@ -218,7 +220,11 @@ fn parse_tokens<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<Templa
} }
fn parse_content<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<TemplateToken<'input>>> { fn parse_content<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<TemplateToken<'input>>> {
alt((take_until(1.., "{{"), rest)) alt((
repeat_till(1.., any, peek((multispace0, "{{"))).map(|((), _)| ()),
rest.void(),
))
.take()
.map(TemplateToken::Content) .map(TemplateToken::Content)
.map(|v| vec![v]) .map(|v| vec![v])
.parse_next(input) .parse_next(input)
@ -227,6 +233,7 @@ fn parse_content<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<Templ
fn parse_interpolate<'input>( fn parse_interpolate<'input>(
input: &mut Input<'input>, input: &mut Input<'input>,
) -> PResult<'input, Vec<TemplateToken<'input>>> { ) -> PResult<'input, Vec<TemplateToken<'input>>> {
let prev_whitespace = opt(parse_whitespace).parse_next(input)?;
let left_delim = "{{".map(TemplateToken::LeftDelim).parse_next(input)?; let left_delim = "{{".map(TemplateToken::LeftDelim).parse_next(input)?;
let get_tokens = repeat_till(1.., parse_interpolate_token, peek("}}")); let get_tokens = repeat_till(1.., parse_interpolate_token, peek("}}"));
@ -239,10 +246,14 @@ fn parse_interpolate<'input>(
.parse_next(input)?; .parse_next(input)?;
let right_delim = "}}".map(TemplateToken::RightDelim).parse_next(input)?; let right_delim = "}}".map(TemplateToken::RightDelim).parse_next(input)?;
let post_whitespace = opt(parse_whitespace).parse_next(input)?;
let mut tokens = vec![left_delim]; let mut tokens = vec![];
tokens.extend(prev_whitespace);
tokens.push(left_delim);
tokens.extend(inside_tokens); tokens.extend(inside_tokens);
tokens.push(right_delim); tokens.push(right_delim);
tokens.extend(post_whitespace);
Ok(tokens) Ok(tokens)
} }
@ -392,6 +403,9 @@ mod tests {
Content( Content(
"Hello", "Hello",
), ),
Whitespace(
" ",
),
LeftDelim( LeftDelim(
"{{", "{{",
), ),