You are here

SassScriptFunction.php in Sassy 7

File

phamlp/sass/script/SassScriptFunction.php
View source
<?php

/* SVN FILE: $Id$ */

/**
 * SassScriptFunction class file.
 * @author			Chris Yates <chris.l.yates@gmail.com>
 * @copyright 	Copyright (c) 2010 PBM Web Development
 * @license			http://phamlp.googlecode.com/files/license.txt
 * @package			PHamlP
 * @subpackage	Sass.script
 */

/**
 * SassScriptFunction class.
 * Preforms a SassScript function.
 * @package			PHamlP
 * @subpackage	Sass.script
 */
class SassScriptFunction {

  /**@#+
   * Regexes for matching and extracting functions and arguments
   */
  const MATCH = '/^(((-\\w)|(\\w))[-\\w]*)\\(/';
  const MATCH_FUNC = '/^((?:(?:-\\w)|(?:\\w))[-\\w]*)\\((.*)\\)/';
  const SPLIT_ARGS = '/\\s*((?:[\'"].*?["\'])|(?:.+?(?:\\(.*\\).*?)?))\\s*(?:,|$)/';
  const NAME = 1;
  const ARGS = 2;
  private $name;
  private $args;

  /**
   * SassScriptFunction constructor
   * @param string name of the function
   * @param array arguments for the function
   * @return SassScriptFunction
   */
  public function __construct($name, $args) {
    $this->name = $name;
    $this->args = $args;
  }

  /**
   * Evaluates the function.
   * Look for a user defined function first - this allows users to override
   * pre-defined functions, then try the pre-defined functions.
   * @return Function the value of this Function
   * @throws SassScriptFunctionException if function is undefined
   */
  public function perform() {
    $name = str_replace('-', '_', $this->name);
    foreach (SassScriptParser::$context->node->parser->function_paths as $path) {
      $_path = explode(DIRECTORY_SEPARATOR, $path);
      $_class = ucfirst($_path[sizeof($_path) - 2]);
      foreach (array_slice(scandir($path), 2) as $file) {
        $filename = $path . DIRECTORY_SEPARATOR . $file;
        if (is_file($filename)) {
          require_once $filename;
          $class = 'SassExtentions' . $_class . 'Functions' . ucfirst(substr($file, 0, -4));
          if (method_exists($class, $name)) {
            return call_user_func_array(array(
              $class,
              $name,
            ), $this->args);
          }
        }
      }

      // foreach
    }

    // foreach
    require_once 'SassScriptFunctions.php';
    if (method_exists('SassScriptFunctions', $name)) {
      return call_user_func_array(array(
        'SassScriptFunctions',
        $name,
      ), $this->args);
    }

    // CSS function: create a SassString that will emit the function into the CSS
    $args = array();
    foreach ($this->args as $arg) {
      $args[] = $arg
        ->toString();
    }
    return new SassString($this->name . '(' . join(', ', $args) . ')');
  }

  /**
   * Imports files in the specified directory.
   * @param string path to directory to import
   * @return array filenames imported
   */
  private function import($dir) {
    $files = array();
    foreach (array_slice(scandir($dir), 2) as $file) {
      if (is_file($dir . DIRECTORY_SEPARATOR . $file)) {
        $files[] = $file;
        require_once $dir . DIRECTORY_SEPARATOR . $file;
      }
    }

    // foreach
    return $files;
  }

  /**
   * Returns a value indicating if a token of this type can be matched at
   * the start of the subject string.
   * @param string the subject string
   * @return mixed match at the start of the string or false if no match
   */
  public static function isa($subject) {
    if (!preg_match(self::MATCH, $subject, $matches)) {
      return false;
    }
    $match = $matches[0];
    $paren = 1;
    $strpos = strlen($match);
    $strlen = strlen($subject);
    while ($paren && $strpos < $strlen) {
      $c = $subject[$strpos++];
      $match .= $c;
      if ($c === '(') {
        $paren += 1;
      }
      elseif ($c === ')') {
        $paren -= 1;
      }
    }
    return $match;
  }
  public static function extractArgs($string) {
    $args = array();
    $arg = '';
    $paren = 0;
    $strpos = 0;
    $strlen = strlen($string);
    while ($strpos < $strlen) {
      $c = $string[$strpos++];
      switch ($c) {
        case '(':
          $paren += 1;
          $arg .= $c;
          break;
        case ')':
          $paren -= 1;
          $arg .= $c;
          break;
        case '"':
        case "'":
          $arg .= $c;
          do {
            $_c = $string[$strpos++];
            $arg .= $_c;
          } while ($_c !== $c);
          break;
        case ',':
          if ($paren) {
            $arg .= $c;
            break;
          }
          $args[] = trim($arg);
          $arg = '';
          break;
        default:
          $arg .= $c;
          break;
      }
    }
    if ($arg != '') {
      $args[] = trim($arg);
    }
    return $args;
  }

}

Classes

Namesort descending Description
SassScriptFunction SassScriptFunction class. Preforms a SassScript function. @package PHamlP @subpackage Sass.script