Strings containing interpolation are double quoted
This commit is contained in:
parent
011577c9f6
commit
54e71130e7
@ -375,7 +375,7 @@ impl Attribute {
|
|||||||
}
|
}
|
||||||
q @ TokenKind::Symbol(Symbol::DoubleQuote)
|
q @ TokenKind::Symbol(Symbol::DoubleQuote)
|
||||||
| q @ TokenKind::Symbol(Symbol::SingleQuote) => {
|
| q @ TokenKind::Symbol(Symbol::SingleQuote) => {
|
||||||
parse_quoted_string(toks, scope, q)?
|
parse_quoted_string(toks, scope, q)?.to_string()
|
||||||
}
|
}
|
||||||
_ => return Err("Expected identifier.".into()),
|
_ => return Err("Expected identifier.".into()),
|
||||||
}
|
}
|
||||||
@ -437,7 +437,7 @@ impl Attribute {
|
|||||||
}
|
}
|
||||||
q @ TokenKind::Symbol(Symbol::DoubleQuote)
|
q @ TokenKind::Symbol(Symbol::DoubleQuote)
|
||||||
| q @ TokenKind::Symbol(Symbol::SingleQuote) => {
|
| q @ TokenKind::Symbol(Symbol::SingleQuote) => {
|
||||||
parse_quoted_string(toks, scope, q)?
|
parse_quoted_string(toks, scope, q)?.to_string()
|
||||||
}
|
}
|
||||||
_ => return Err("Expected identifier.".into()),
|
_ => return Err("Expected identifier.".into()),
|
||||||
}
|
}
|
||||||
|
18
src/utils.rs
18
src/utils.rs
@ -152,9 +152,10 @@ pub(crate) fn parse_quoted_string<I: Iterator<Item = Token>>(
|
|||||||
toks: &mut Peekable<I>,
|
toks: &mut Peekable<I>,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
q: TokenKind,
|
q: TokenKind,
|
||||||
) -> SassResult<String> {
|
) -> SassResult<Value> {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
let mut is_escaped = false;
|
let mut is_escaped = false;
|
||||||
|
let mut found_interpolation = false;
|
||||||
while let Some(tok) = toks.next() {
|
while let Some(tok) = toks.next() {
|
||||||
match tok.kind {
|
match tok.kind {
|
||||||
TokenKind::Symbol(Symbol::DoubleQuote)
|
TokenKind::Symbol(Symbol::DoubleQuote)
|
||||||
@ -170,6 +171,7 @@ pub(crate) fn parse_quoted_string<I: Iterator<Item = Token>>(
|
|||||||
TokenKind::Symbol(Symbol::BackSlash) if !is_escaped => is_escaped = true,
|
TokenKind::Symbol(Symbol::BackSlash) if !is_escaped => is_escaped = true,
|
||||||
TokenKind::Symbol(Symbol::BackSlash) => s.push('\\'),
|
TokenKind::Symbol(Symbol::BackSlash) => s.push('\\'),
|
||||||
TokenKind::Interpolation => {
|
TokenKind::Interpolation => {
|
||||||
|
found_interpolation = true;
|
||||||
s.push_str(
|
s.push_str(
|
||||||
&parse_interpolation(toks, scope)?
|
&parse_interpolation(toks, scope)?
|
||||||
.iter()
|
.iter()
|
||||||
@ -185,10 +187,14 @@ pub(crate) fn parse_quoted_string<I: Iterator<Item = Token>>(
|
|||||||
}
|
}
|
||||||
s.push_str(&tok.kind.to_string());
|
s.push_str(&tok.kind.to_string());
|
||||||
}
|
}
|
||||||
let quotes = match q {
|
let quotes = if found_interpolation {
|
||||||
TokenKind::Symbol(Symbol::DoubleQuote) => QuoteKind::Double,
|
QuoteKind::Double
|
||||||
TokenKind::Symbol(Symbol::SingleQuote) => QuoteKind::Single,
|
} else {
|
||||||
_ => unreachable!(),
|
match q {
|
||||||
|
TokenKind::Symbol(Symbol::DoubleQuote) => QuoteKind::Double,
|
||||||
|
TokenKind::Symbol(Symbol::SingleQuote) => QuoteKind::Single,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ok(format!("{}{}{}", quotes, s, quotes))
|
Ok(Value::Ident(s, quotes))
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use crate::color::Color;
|
|||||||
use crate::common::{Keyword, ListSeparator, Op, QuoteKind, Scope, Symbol};
|
use crate::common::{Keyword, ListSeparator, Op, QuoteKind, Scope, Symbol};
|
||||||
use crate::error::SassResult;
|
use crate::error::SassResult;
|
||||||
use crate::units::Unit;
|
use crate::units::Unit;
|
||||||
use crate::utils::{devour_whitespace_or_comment, parse_interpolation};
|
use crate::utils::{devour_whitespace_or_comment, parse_interpolation, parse_quoted_string};
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::{Token, TokenKind};
|
use crate::{Token, TokenKind};
|
||||||
|
|
||||||
@ -287,46 +287,7 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
q @ TokenKind::Symbol(Symbol::DoubleQuote)
|
q @ TokenKind::Symbol(Symbol::DoubleQuote)
|
||||||
| q @ TokenKind::Symbol(Symbol::SingleQuote) => {
|
| q @ TokenKind::Symbol(Symbol::SingleQuote) => parse_quoted_string(toks, scope, q),
|
||||||
let mut s = String::new();
|
|
||||||
let mut is_escaped = false;
|
|
||||||
while let Some(tok) = toks.next() {
|
|
||||||
match tok.kind {
|
|
||||||
TokenKind::Symbol(Symbol::DoubleQuote)
|
|
||||||
if !is_escaped && q == TokenKind::Symbol(Symbol::DoubleQuote) =>
|
|
||||||
{
|
|
||||||
break
|
|
||||||
}
|
|
||||||
TokenKind::Symbol(Symbol::SingleQuote)
|
|
||||||
if !is_escaped && q == TokenKind::Symbol(Symbol::SingleQuote) =>
|
|
||||||
{
|
|
||||||
break
|
|
||||||
}
|
|
||||||
TokenKind::Symbol(Symbol::BackSlash) if !is_escaped => is_escaped = true,
|
|
||||||
TokenKind::Symbol(Symbol::BackSlash) => s.push('\\'),
|
|
||||||
TokenKind::Interpolation => {
|
|
||||||
s.push_str(
|
|
||||||
&parse_interpolation(toks, scope)?
|
|
||||||
.iter()
|
|
||||||
.map(|x| x.kind.to_string())
|
|
||||||
.collect::<String>(),
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
if is_escaped && tok.kind != TokenKind::Symbol(Symbol::BackSlash) {
|
|
||||||
is_escaped = false;
|
|
||||||
}
|
|
||||||
s.push_str(&tok.kind.to_string());
|
|
||||||
}
|
|
||||||
let quotes = match q {
|
|
||||||
TokenKind::Symbol(Symbol::DoubleQuote) => QuoteKind::Double,
|
|
||||||
TokenKind::Symbol(Symbol::SingleQuote) => QuoteKind::Single,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
Ok(Value::Ident(s, quotes))
|
|
||||||
}
|
|
||||||
TokenKind::Variable(ref v) => Ok(scope.get_var(v)?.clone()),
|
TokenKind::Variable(ref v) => Ok(scope.get_var(v)?.clone()),
|
||||||
TokenKind::Interpolation => {
|
TokenKind::Interpolation => {
|
||||||
let mut s = parse_interpolation(toks, scope)?
|
let mut s = parse_interpolation(toks, scope)?
|
||||||
|
Loading…
x
Reference in New Issue
Block a user