Refactor conversion of SCSS to CSS

This commit is contained in:
ConnorSkees 2020-01-19 19:27:52 -05:00
parent 500b682739
commit c64daceb20
2 changed files with 31 additions and 56 deletions

View File

@ -47,84 +47,49 @@ impl Toplevel {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Css { pub struct Css {
blocks: Vec<Toplevel>, blocks: Vec<Toplevel>,
idx: usize,
inner_rulesets: usize,
at_root: bool,
} }
impl Css { impl Css {
pub const fn new() -> Self { pub const fn new() -> Self {
Css { Css { blocks: Vec::new() }
blocks: Vec::new(),
idx: 0,
inner_rulesets: 0,
at_root: true,
}
} }
pub fn from_stylesheet(s: StyleSheet) -> Self { pub fn from_stylesheet(s: StyleSheet) -> Self {
Css::new().parse_stylesheet(s) Css::new().parse_stylesheet(s)
} }
fn parse_stmt(&mut self, stmt: Stmt) { fn parse_stmt(&mut self, stmt: Stmt) -> Vec<Toplevel> {
match stmt { match stmt {
Stmt::Style(s) => {
if self.at_root {
self.blocks
.get_mut(self.idx - 1)
.expect("expected block to exist at root")
.push_style(s)
} else {
self.blocks
.get_mut(self.idx + self.inner_rulesets - 1)
.expect("expected block to exist")
.push_style(s)
}
}
Stmt::MultilineComment(s) => {
if self.idx == 0 {
self.blocks.push(Toplevel::MultilineComment(s));
} else {
self.blocks
.get_mut(self.idx + self.inner_rulesets - 1)
.expect("expected block to exist")
.push_comment(s)
}
}
Stmt::RuleSet(RuleSet { Stmt::RuleSet(RuleSet {
selector, selector,
super_selector, super_selector,
rules, rules,
}) => { }) => {
if self.idx == 0 { let mut vals = vec![Toplevel::new_rule(super_selector.zip(&selector))];
self.idx = self.blocks.len() + 1;
self.inner_rulesets = 0;
self.blocks
.push(Toplevel::new_rule(super_selector.zip(&selector)));
for rule in rules { for rule in rules {
self.at_root = true; match rule {
self.parse_stmt(rule); Stmt::RuleSet(_) => vals.extend(self.parse_stmt(rule)),
self.at_root = true; Stmt::Style(s) => vals
} .get_mut(0)
self.idx = 0; .expect("expected block to exist")
} else { .push_style(s),
self.idx += 1; Stmt::MultilineComment(s) => vals
self.at_root = false; .get_mut(0)
self.blocks .expect("expected block to exist")
.push(Toplevel::new_rule(super_selector.zip(&selector))); .push_comment(s),
for rule in rules { };
self.parse_stmt(rule);
}
self.idx -= 1;
self.inner_rulesets += 1;
} }
vals
} }
Stmt::MultilineComment(s) => vec![Toplevel::MultilineComment(s)],
Stmt::Style(_) => panic!("expected toplevel element, found style"),
} }
} }
fn parse_stylesheet(mut self, s: StyleSheet) -> Css { fn parse_stylesheet(mut self, s: StyleSheet) -> Css {
for stmt in s.0 { for stmt in s.0 {
self.parse_stmt(stmt); let v = self.parse_stmt(stmt);
self.blocks.extend(v);
} }
self self
} }

View File

@ -624,9 +624,9 @@ fn main() -> SassResult<()> {
for arg in args { for arg in args {
let s = StyleSheet::from_path(arg)?; let s = StyleSheet::from_path(arg)?;
s.print_as_css(&mut stdout)?; s.print_as_css(&mut stdout)?;
// s.pretty_print(&mut stdout)?;
} }
// dbg!(s); // dbg!(s);
// s.pretty_print(&mut stdout)?;
// s.pretty_print_selectors(&mut stdout)?; // s.pretty_print_selectors(&mut stdout)?;
Ok(()) Ok(())
} }
@ -1033,6 +1033,16 @@ mod test_styles {
"a {\n color : red ; \n}\n", "a {\n color : red ; \n}\n",
"a {\n color: red;\n}\n" "a {\n color: red;\n}\n"
); );
test!(
triple_nested_preceding_ruleset,
"a {\n b {\n foo: bar;\n c {}\n }\n}\n",
"a b {\n foo: bar;\n}\n"
);
test!(
triple_nested_following_ruleset,
"a {\n b {\n c {}\n foo: bar;\n }\n}\n",
"a b {\n foo: bar;\n}\n"
);
} }
#[cfg(test)] #[cfg(test)]