/** * Parse this node. * This raises an error. * @return array An empty array */ public function parse($context) { // If we are in a loop, function or mixin then the parent isn't what should // go inside the media node. Walk up the parent tree to find the rule node // to put inside the media node or the root node if the media node should be // at the root. $parent = $this->parent; while (!$parent instanceof SassRuleNode && !$parent instanceof SassRootNode) { $parent = $parent->parent; } // Make a copy of the token before parsing in case we are in a loop and it contains variables $token = clone $this->token; $token->source = SassDirectiveNode::interpolate_nonstrict($token->source, $context); $node = new SassRuleNode($token, $context); $node->root = $parent->root; $rule = clone $parent; $rule->root = $node->root; $rule->children = $this->children; $try = $rule->parse($context); if (is_array($try)) { $rule->children = $try; } // Tests were failing with this, but I'm not sure if we cover every case. //else if (is_object($try) && method_exists($try, 'render')) { // $rule = $try; //} $node->children = array(new SassString($rule->render($context))); return array($node); }
/** * Parse this node. * This raises an error. * @return array An empty array */ public function parse($context) { $this->token->source = SassDirectiveNode::interpolate_nonstrict($this->token->source, $context); $node = new SassRuleNode($this->token, $context); $node->root = $this->parent->root; $rule = clone $this->parent; $rule->root = $node->root; $rule->children = $this->children; $try = $rule->parse($context); if (is_array($try)) { $rule->children = $try; } // Tests were failing with this, but I'm not sure if we cover every case. //else if (is_object($try) && method_exists($try, 'render')) { // $rule = $try; //} $node->children = array(new SassString($rule->render($context))); return array($node); }
/** * Parses a directive * @param SassToken token to parse * @param SassNode parent node * @return SassNode a Sass directive node */ public function parseDirective($token, $parent) { switch (SassDirectiveNode::extractDirective($token)) { case '@content': return new SassContentNode($token); break; case '@extend': return new SassExtendNode($token); break; case '@function': return new SassFunctionDefinitionNode($token); break; case '@return': return new SassReturnNode($token); break; case '@media': return new SassMediaNode($token); break; case '@mixin': return new SassMixinDefinitionNode($token); break; case '@include': return new SassMixinNode($token); break; case '@import': if ($this->syntax == SassFile::SASS) { $i = 0; $source = ''; while (sizeof($this->source) > $i && empty($source) && isset($this->source[$i + 1])) { $source = $this->source[$i++]; } if (!empty($source) && $this->getLevel($source) > $token->level) { if ($this->debug) { throw new SassException('Nesting not allowed beneath @import directive', $token); } } } return new SassImportNode($token, $parent); break; case '@each': return new SassEachNode($token); break; case '@for': return new SassForNode($token); break; case '@if': return new SassIfNode($token); break; case '@else': // handles else and else if directives return new SassElseNode($token); break; case '@do': case '@while': return new SassWhileNode($token); break; case '@warn': return new SassWarnNode($token); break; case '@debug': return new SassDebugNode($token); break; default: return new SassDirectiveNode($token); break; } }
/** * Parses a directive * @param SassToken token to parse * @param SassNode parent node * @return SassNode a Sass directive node */ private function parseDirective($token, $parent) { switch (SassDirectiveNode::extractDirective($token)) { case '@extend': return new SassExtendNode($token); break; case '@mixin': return new SassMixinDefinitionNode($token); break; case '@include': return new SassMixinNode($token); break; case '@import': if ($this->syntax == SassFile::SASS) { $i = 0; $source = ''; while (!empty($this->source) && empty($source)) { $source = $this->source[$i++]; } if (!empty($source) && $this->getLevel($source) > $token->level) { throw new SassException('Nesting not allowed beneath {what}', array('{what}' => '@import directive'), $token); } } return new SassImportNode($token); break; case '@for': return new SassForNode($token); break; case '@if': return new SassIfNode($token); break; case '@else': // handles else and else if directives return new SassElseNode($token); break; case '@do': case '@while': return new SassWhileNode($token); break; case '@debug': return new SassDebugNode($token); break; case '@warn': return new SassDebugNode($token, true); break; default: return new SassDirectiveNode($token); break; } }
/** * Parse a line and its children. * @param array line to parse * @param array remaining lines * @param SassNode parent node * @return SassNode a SassNode of the appropriate type */ private function parseLine($line, &$lines, $parent) { if (empty($line)) { return null; } switch (true) { case SassCommentNode::isa($line): return $this->parseComment($line, $lines); break; case SassDirectiveNode::isa($line): return $this->parseDirective($line, $lines, $parent); break; case SassMixinDefinitionNode::isa($line): return $this->parseMixinDefinition($line); break; case SassMixinNode::isa($line): return $this->parseMixin($line); break; case SassVariableNode::isa($line): if ($this->hasChild($line, $Lines)) { throw new SassException("Illegal nesting. Nesting not allowed beneath variables.\nLine {$line['number']}: " . (is_array($line['file']) ? join(DIRECTORY_SEPARATOR, $line['file']) : '')); } return $this->parseVariable($line); break; case SassPropertyNode::isa($line, $this->options['property_syntax']): return $this->parseProperty($line); break; default: return $this->parseRule($line, $lines); break; } // switch }