From ad17c765e6dc308fcf6aa7291639277fd3cade26 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 8 Jan 2020 20:29:04 +1000 Subject: [PATCH] ignore template closing characters outside of a tag --- rslib/src/template.rs | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/rslib/src/template.rs b/rslib/src/template.rs index 9376234dc..463c6e83b 100644 --- a/rslib/src/template.rs +++ b/rslib/src/template.rs @@ -21,13 +21,24 @@ pub enum Token<'a> { CloseConditional(&'a str), } -/// a span of text, terminated by {{, }} or end of string -pub(crate) fn text_until_handlebars(s: &str) -> nom::IResult<&str, &str> { +/// a span of text, terminated by {{ or end of string +pub(crate) fn text_until_open_handlebars(s: &str) -> nom::IResult<&str, &str> { let end = s.len(); - let limited_end = end - .min(s.find("{{").unwrap_or(end)) - .min(s.find("}}").unwrap_or(end)); + let limited_end = end.min(s.find("{{").unwrap_or(end)); + let (output, input) = s.split_at(limited_end); + if output.is_empty() { + Err(nom::Err::Error((input, ErrorKind::TakeUntil))) + } else { + Ok((input, output)) + } +} + +/// a span of text, terminated by }} or end of string +pub(crate) fn text_until_close_handlebars(s: &str) -> nom::IResult<&str, &str> { + let end = s.len(); + + let limited_end = end.min(s.find("}}").unwrap_or(end)); let (output, input) = s.split_at(limited_end); if output.is_empty() { Err(nom::Err::Error((input, ErrorKind::TakeUntil))) @@ -38,12 +49,12 @@ pub(crate) fn text_until_handlebars(s: &str) -> nom::IResult<&str, &str> { /// text outside handlebars fn text_token(s: &str) -> nom::IResult<&str, Token> { - text_until_handlebars(s).map(|(input, output)| (input, Token::Text(output))) + text_until_open_handlebars(s).map(|(input, output)| (input, Token::Text(output))) } /// text wrapped in handlebars fn handle_token(s: &str) -> nom::IResult<&str, Token> { - delimited(tag("{{"), text_until_handlebars, tag("}}"))(s) + delimited(tag("{{"), text_until_close_handlebars, tag("}}"))(s) .map(|(input, output)| (input, classify_handle(output))) } @@ -393,6 +404,12 @@ mod test { filters: vec![] }] ); + + // stray closing characters (like in javascript) are ignored + assert_eq!( + PT::from_text("text }} more").unwrap().0, + vec![Text("text }} more")] + ); } #[test]