From a645424186816ba0dd4f53fa70792f77234749de Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Mon, 24 Feb 2020 16:58:48 -0500 Subject: [PATCH] Refactor handling of quotes inside interpolation --- src/utils.rs | 41 ++++++++++++++++++++++++++++------------- src/value/mod.rs | 2 +- tests/interpolation.rs | 5 +++++ 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 43276a4..d59115f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -41,32 +41,47 @@ pub(crate) fn devour_whitespace_or_comment, W: IsWhitespac found_whitespace } -pub(crate) fn parse_interpolation>( - tokens: &mut I, +fn _parse_interpolation>( + tokens: &mut Peekable, scope: &Scope, ) -> SassResult> { - let mut val = Vec::new(); + let mut val = String::new(); while let Some(tok) = tokens.next() { match tok.kind { TokenKind::Symbol(Symbol::CloseCurlyBrace) => break, TokenKind::Symbol(Symbol::OpenCurlyBrace) => { todo!("invalid character in interpolation") } - TokenKind::Variable(ref v) => { - val.extend(Lexer::new(&scope.get_var(v)?.to_string()).collect::>()) + q @ TokenKind::Symbol(Symbol::DoubleQuote) + | q @ TokenKind::Symbol(Symbol::SingleQuote) => { + val.push_str(&parse_quoted_string(tokens, scope, q)?.to_string()) } - TokenKind::Interpolation => val.extend(parse_interpolation(tokens, scope)?), - _ => val.push(tok), + TokenKind::Variable(ref v) => { + val.push_str(&scope.get_var(v)?.clone().unquote().to_string()) + } + TokenKind::Interpolation => val.push_str( + &_parse_interpolation(tokens, scope)? + .iter() + .map(|x| x.kind.to_string()) + .collect::(), + ), + _ => val.push_str(&tok.kind.to_string()), } } Ok(Lexer::new( - &Value::from_tokens(&mut val.into_iter().peekable(), scope) - .unwrap() - .to_string() - .replace("\"", "") - .replace("'", ""), + &Value::from_tokens(&mut Lexer::new(&val).peekable(), scope)? + .eval()? + .unquote() + .to_string(), ) - .collect::>()) + .collect()) +} + +pub(crate) fn parse_interpolation>( + tokens: &mut Peekable, + scope: &Scope, +) -> SassResult> { + _parse_interpolation(tokens, scope) } pub(crate) struct VariableDecl { diff --git a/src/value/mod.rs b/src/value/mod.rs index 726dfd8..398d513 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -66,7 +66,7 @@ impl Value { pub fn unquote(self) -> Self { match self { Self::Ident(s1, _) => Self::Ident(s1, QuoteKind::None), - _ => todo!(), + v => v, } } diff --git a/tests/interpolation.rs b/tests/interpolation.rs index 4a7c8eb..93a5afc 100644 --- a/tests/interpolation.rs +++ b/tests/interpolation.rs @@ -23,3 +23,8 @@ test!( "a {\n --#{foo}: red;\n}\n", "a {\n --foo: red;\n}\n" ); +test!( + preserves_inner_single_quotes, + "a {\n color: #{\"''\"};\n}\n", + "a {\n color: '';\n}\n" +);