public Ruleset Evaluate(NodeList<Expression> args, Env env) { if(args) Guard.ExpectMaxArguments(Params.Count, args.Count, string.Format("'{0}'", Name)); var frame = new Ruleset(null, new List<Node>()); for (var i = 0; i < Params.Count; i++) { if (!string.IsNullOrEmpty(Params[i].Name)) { Node val; if (args && i < args.Count) val = args[i]; else val = Params[i].Value; if (val) frame.Rules.Add(new Rule(Params[i].Name, val)); else throw new ParsingException("wrong number of arguments for " + Name); } } var frames = new[] {this, frame}.Concat(env.Frames).Reverse(); var context = new Env{ Frames = new Stack<Ruleset>(frames) }; var newRules = new List<Node>(); foreach (var rule in Rules) { if (rule is Mixin.Definition) { var mixin = rule as Mixin.Definition; var parameters = mixin.Params.Concat(frame.Rules.Cast<Rule>()); newRules.Add(new Mixin.Definition(mixin.Name, new NodeList<Rule>(parameters), mixin.Rules)); } else if (rule is Ruleset) { var ruleset = (rule as Ruleset); var rules = ruleset.Rules .Select(r => r.Evaluate(context)) .ToList(); newRules.Add(new Ruleset(ruleset.Selectors, rules)); } else if (rule is Mixin.Call) { newRules.AddRange((NodeList)rule.Evaluate(context)); } else { newRules.Add(rule.Evaluate(context)); } } return new Ruleset(null, newRules); }
public Ruleset Parse(string input) { Tokenizer.SetupInput(input); ParsingException parsingException = null; Ruleset root = null; try { var parsers = new Parsers(new DefaultNodeProvider()); root = new Ruleset(new NodeList<Selector>(), parsers.Primary(this)); root.Root = true; } catch (ParsingException e) { parsingException = e; } CheckForParsingError(parsingException); return root; }
public NodeList Find(Selector selector, Ruleset self) { self = self ?? this; var rules = new NodeList(); var key = selector.ToCSS(); if (_lookups.ContainsKey(key)) return _lookups[key]; foreach (var rule in Rulesets().Where(rule => rule != self)) { if (rule.Selectors && rule.Selectors.Any(selector.Match)) { if (selector.Elements.Count > 1) { var remainingSelectors = new Selector(new NodeList<Element>(selector.Elements.Skip(1))); rules.AddRange(rule.Find(remainingSelectors, self)); } else rules.Add(rule); } } return _lookups[key] = rules; }