/_plugins_/sasspip/sassphp/tree/SassFunctionDefinitionNode.php

https://bitbucket.org/pombredanne/spip-zone-treemap · PHP · 116 lines · 53 code · 11 blank · 52 comment · 4 complexity · e8edd5470d698acc2c4061df077372f8 MD5 · raw file

  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * SassFunctionDefinitionNode class file.
  5. * @author Chris Yates <chris.l.yates@gmail.com>
  6. * @copyright Copyright (c) 2010 PBM Web Development
  7. * @license http://phamlp.googlecode.com/files/license.txt
  8. * @package PHamlP
  9. * @subpackage Sass.tree
  10. */
  11. /**
  12. * SassFunctionDefinitionNode class.
  13. * Represents a Function definition.
  14. * @package PHamlP
  15. * @subpackage Sass.tree
  16. */
  17. class SassFunctionDefinitionNode extends SassNode {
  18. const NODE_IDENTIFIER = FALSE;
  19. const MATCH = '/^@function\s+([_-\w]+)\s*(?:\((.*?)\))?\s*$/im';
  20. const IDENTIFIER = 1;
  21. const NAME = 1;
  22. const ARGUMENTS = 2;
  23. /**
  24. * @var string name of the function
  25. */
  26. private $name;
  27. /**
  28. * @var array arguments for the function as name=>value pairs were value is the
  29. * default value or null for required arguments
  30. */
  31. private $args = array();
  32. public $parent;
  33. /**
  34. * SassFunctionDefinitionNode constructor.
  35. * @param object source token
  36. * @return SassFunctionDefinitionNode
  37. */
  38. public function __construct($token) {
  39. // if ($token->level !== 0) {
  40. // throw new SassFunctionDefinitionNodeException('Functions can only be defined at root level', $token);
  41. // }
  42. parent::__construct($token);
  43. preg_match(self::MATCH, $token->source, $matches);
  44. if (empty($matches)) {
  45. throw new SassFunctionDefinitionNodeException('Invalid Function', $token);
  46. }
  47. $this->name = $matches[self::NAME];
  48. $this->name = preg_replace('/[^a-z0-9_]/', '_', strtolower($this->name));
  49. if (isset($matches[self::ARGUMENTS])) {
  50. if (strlen(trim($matches[self::ARGUMENTS]))) {
  51. foreach (explode(',', $matches[self::ARGUMENTS]) as $arg) {
  52. $arg = explode(($matches[self::IDENTIFIER] === self::NODE_IDENTIFIER ? '=' : ':'), trim($arg));
  53. $this->args[substr(trim($arg[0]), 1)] = (count($arg) == 2 ? trim($arg[1]) : null);
  54. } // foreach
  55. }
  56. }
  57. }
  58. /**
  59. * Parse this node.
  60. * Add this function to the current context.
  61. * @param SassContext the context in which this node is parsed
  62. * @return array the parsed node - an empty array
  63. */
  64. public function parse($context) {
  65. $context->addFunction($this->name, $this);
  66. return array();
  67. }
  68. /**
  69. * Returns the arguments with default values for this function
  70. * @return array the arguments with default values for this function
  71. */
  72. public function getArgs() {
  73. return $this->args;
  74. }
  75. /**
  76. * Returns a value indicating if the token represents this type of node.
  77. * @param object token
  78. * @return boolean true if the token represents this type of node, false if not
  79. */
  80. public static function isa($token) {
  81. return $token->source[0] === self::NODE_IDENTIFIER;
  82. }
  83. /**
  84. * Evalutes the function in the given context, with the provided arguments
  85. * @param SassContext - the parent context
  86. * @param array - the list of provided variables
  87. * @throws SassReturn - if the @return is fired then this is thrown to break early
  88. * @return SassBoolean(false) - if no @return was fired, return false
  89. */
  90. public function execute($pcontext, $provided) {
  91. list($arguments, $context) = SassScriptFunction::fill_parameters($this->args, $provided, $pcontext, $this);
  92. $context->setVariables($arguments);
  93. $parser = $this->parent->parser;
  94. $children = array();
  95. try {
  96. foreach ($this->children as $child) {
  97. $child->parent = $this;
  98. $children = array_merge($children, $child->parse($context));
  99. }
  100. } catch (SassReturn $e) {
  101. return $e->value;
  102. }
  103. return new SassBoolean('false');
  104. }
  105. }