Refactor handling of quotes inside interpolation

This commit is contained in:
ConnorSkees 2020-02-24 16:58:48 -05:00
parent 54e71130e7
commit a645424186
3 changed files with 34 additions and 14 deletions

View File

@ -41,32 +41,47 @@ pub(crate) fn devour_whitespace_or_comment<I: Iterator<Item = W>, W: IsWhitespac
found_whitespace found_whitespace
} }
pub(crate) fn parse_interpolation<I: Iterator<Item = Token>>( fn _parse_interpolation<I: Iterator<Item = Token>>(
tokens: &mut I, tokens: &mut Peekable<I>,
scope: &Scope, scope: &Scope,
) -> SassResult<Vec<Token>> { ) -> SassResult<Vec<Token>> {
let mut val = Vec::new(); let mut val = String::new();
while let Some(tok) = tokens.next() { while let Some(tok) = tokens.next() {
match tok.kind { match tok.kind {
TokenKind::Symbol(Symbol::CloseCurlyBrace) => break, TokenKind::Symbol(Symbol::CloseCurlyBrace) => break,
TokenKind::Symbol(Symbol::OpenCurlyBrace) => { TokenKind::Symbol(Symbol::OpenCurlyBrace) => {
todo!("invalid character in interpolation") todo!("invalid character in interpolation")
} }
TokenKind::Variable(ref v) => { q @ TokenKind::Symbol(Symbol::DoubleQuote)
val.extend(Lexer::new(&scope.get_var(v)?.to_string()).collect::<Vec<Token>>()) | q @ TokenKind::Symbol(Symbol::SingleQuote) => {
val.push_str(&parse_quoted_string(tokens, scope, q)?.to_string())
} }
TokenKind::Interpolation => val.extend(parse_interpolation(tokens, scope)?), TokenKind::Variable(ref v) => {
_ => val.push(tok), 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::<String>(),
),
_ => val.push_str(&tok.kind.to_string()),
} }
} }
Ok(Lexer::new( Ok(Lexer::new(
&Value::from_tokens(&mut val.into_iter().peekable(), scope) &Value::from_tokens(&mut Lexer::new(&val).peekable(), scope)?
.unwrap() .eval()?
.to_string() .unquote()
.replace("\"", "") .to_string(),
.replace("'", ""),
) )
.collect::<Vec<Token>>()) .collect())
}
pub(crate) fn parse_interpolation<I: Iterator<Item = Token>>(
tokens: &mut Peekable<I>,
scope: &Scope,
) -> SassResult<Vec<Token>> {
_parse_interpolation(tokens, scope)
} }
pub(crate) struct VariableDecl { pub(crate) struct VariableDecl {

View File

@ -66,7 +66,7 @@ impl Value {
pub fn unquote(self) -> Self { pub fn unquote(self) -> Self {
match self { match self {
Self::Ident(s1, _) => Self::Ident(s1, QuoteKind::None), Self::Ident(s1, _) => Self::Ident(s1, QuoteKind::None),
_ => todo!(), v => v,
} }
} }

View File

@ -23,3 +23,8 @@ test!(
"a {\n --#{foo}: red;\n}\n", "a {\n --#{foo}: red;\n}\n",
"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"
);