added comma separated imports
This commit is contained in:
parent
741f560e90
commit
be4d02490c
@ -1,9 +1,15 @@
|
||||
use std::{ffi::OsStr, fs, path::Path, path::PathBuf};
|
||||
|
||||
use codemap::Spanned;
|
||||
use codemap::{Span, Spanned};
|
||||
use peekmore::PeekMore;
|
||||
|
||||
use crate::{common::QuoteKind, error::SassResult, lexer::Lexer, value::Value, Token};
|
||||
use crate::{
|
||||
common::{ListSeparator::Comma, QuoteKind},
|
||||
error::SassResult,
|
||||
lexer::Lexer,
|
||||
value::Value,
|
||||
Token,
|
||||
};
|
||||
|
||||
use super::{Parser, Stmt};
|
||||
|
||||
@ -58,41 +64,7 @@ fn find_import(file_path: &PathBuf, name: &OsStr, load_paths: &[&Path]) -> Optio
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
pub(super) fn import(&mut self) -> SassResult<Vec<Stmt>> {
|
||||
self.whitespace();
|
||||
|
||||
match self.toks.peek() {
|
||||
Some(Token { kind: '\'', .. })
|
||||
| Some(Token { kind: '"', .. })
|
||||
| Some(Token { kind: 'u', .. }) => {}
|
||||
Some(Token { pos, .. }) => return Err(("Expected string.", *pos).into()),
|
||||
None => return Err(("expected more input.", self.span_before).into()),
|
||||
};
|
||||
|
||||
let Spanned {
|
||||
node: file_name_as_value,
|
||||
span,
|
||||
} = self.parse_value(true)?;
|
||||
let file_name = match file_name_as_value {
|
||||
Value::String(s, QuoteKind::Quoted) => {
|
||||
if s.ends_with(".css") || s.starts_with("http://") || s.starts_with("https://") {
|
||||
return Ok(vec![Stmt::Import(format!("\"{}\"", s))]);
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
Value::String(s, QuoteKind::None) => {
|
||||
if s.starts_with("url(") {
|
||||
return Ok(vec![Stmt::Import(s)]);
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
_ => return Err(("Expected string.", span).into()),
|
||||
};
|
||||
|
||||
self.whitespace();
|
||||
|
||||
pub fn _parse_single_import(&mut self, file_name: &str, span: Span) -> SassResult<Vec<Stmt>> {
|
||||
let path: &Path = file_name.as_ref();
|
||||
|
||||
let path_buf = if path.is_absolute() {
|
||||
@ -104,7 +76,6 @@ impl<'a> Parser<'a> {
|
||||
.unwrap_or_else(|| Path::new(""))
|
||||
.join(path)
|
||||
};
|
||||
|
||||
let name = path_buf.file_name().unwrap_or_else(|| OsStr::new(".."));
|
||||
|
||||
if let Some(name) = find_import(&path_buf, name, &self.options.load_paths) {
|
||||
@ -112,7 +83,6 @@ impl<'a> Parser<'a> {
|
||||
name.to_string_lossy().into(),
|
||||
String::from_utf8(fs::read(&name)?)?,
|
||||
);
|
||||
|
||||
return Parser {
|
||||
toks: &mut Lexer::new(&file)
|
||||
.collect::<Vec<Token>>()
|
||||
@ -134,7 +104,67 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
.parse();
|
||||
}
|
||||
self.whitespace();
|
||||
|
||||
Err(("Can't find stylesheet to import.", span).into())
|
||||
}
|
||||
pub(super) fn import(&mut self) -> SassResult<Vec<Stmt>> {
|
||||
self.whitespace();
|
||||
match self.toks.peek() {
|
||||
Some(Token { kind: '\'', .. })
|
||||
| Some(Token { kind: '"', .. })
|
||||
| Some(Token { kind: 'u', .. }) => {}
|
||||
Some(Token { pos, .. }) => return Err(("Expected string.", *pos).into()),
|
||||
None => return Err(("expected more input.", self.span_before).into()),
|
||||
};
|
||||
let Spanned {
|
||||
node: file_name_as_value,
|
||||
span,
|
||||
} = self.parse_value(true)?;
|
||||
|
||||
match file_name_as_value {
|
||||
Value::String(s, QuoteKind::Quoted) => {
|
||||
if s.ends_with(".css") || s.starts_with("http://") || s.starts_with("https://") {
|
||||
Ok(vec![Stmt::Import(format!("\"{}\"", s))])
|
||||
} else {
|
||||
self._parse_single_import(&s, span)
|
||||
}
|
||||
}
|
||||
Value::String(s, QuoteKind::None) => {
|
||||
if s.starts_with("url(") {
|
||||
Ok(vec![Stmt::Import(s)])
|
||||
} else {
|
||||
self._parse_single_import(&s, span)
|
||||
}
|
||||
}
|
||||
Value::List(v, Comma, _) => {
|
||||
let mut list_of_imports: Vec<Stmt> = Vec::new();
|
||||
for file_name_element in v {
|
||||
match file_name_element {
|
||||
Value::String(s, QuoteKind::Quoted) => {
|
||||
if s.ends_with(".css")
|
||||
|| s.starts_with("http://")
|
||||
|| s.starts_with("https://")
|
||||
{
|
||||
list_of_imports.push(Stmt::Import(format!("\"{}\"", s)));
|
||||
} else {
|
||||
list_of_imports.append(&mut self._parse_single_import(&s, span)?);
|
||||
}
|
||||
}
|
||||
Value::String(s, QuoteKind::None) => {
|
||||
if s.starts_with("url(") {
|
||||
list_of_imports.push(Stmt::Import(s));
|
||||
} else {
|
||||
list_of_imports.append(&mut self._parse_single_import(&s, span)?);
|
||||
}
|
||||
}
|
||||
_ => return Err(("Expected string.", span).into()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(list_of_imports)
|
||||
}
|
||||
_ => Err(("Expected string.", span).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +82,28 @@ fn single_quotes_import() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn comma_seperated_import() {
|
||||
let input = "@import 'firsta', 'seconda';\na {\n color: $a;\n}";
|
||||
tempfile!("firsta", "$a: red;");
|
||||
tempfile!("seconda", "p { color: blue; }");
|
||||
assert_eq!(
|
||||
"p {\n color: blue;\n}\n\na {\n color: red;\n}\n",
|
||||
&grass::from_string(input.to_string(), &grass::Options::default()).expect(input)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn comma_seperated_import_order() {
|
||||
let input = "@import 'firstb', 'secondb', url(third);";
|
||||
tempfile!("firstb", "p { color: red; }");
|
||||
tempfile!("secondb", "p { color: blue; }");
|
||||
assert_eq!(
|
||||
"p {\n color: red;\n}\n\np {\n color: blue;\n}\n@import url(third);\n",
|
||||
&grass::from_string(input.to_string(), &grass::Options::default()).expect(input)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_name_scss() {
|
||||
let input = "@import \"finds_name_scss\";\na {\n color: $a;\n}";
|
||||
|
Loading…
x
Reference in New Issue
Block a user