예제 #1
0
      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);
      }
예제 #2
0
    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;
    }
예제 #3
0
        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;
        }