You are here

function lessc::chunk in Less CSS Preprocessor 6.3

1 call to lessc::chunk()
lessc::parse in lessphp/lessc.inc.php

File

lessphp/lessc.inc.php, line 48

Class

lessc

Code

function chunk() {
  if (empty($this->buffer)) {
    return false;
  }
  $s = $this
    ->seek();

  // a property
  if ($this
    ->keyword($key) && $this
    ->assign() && $this
    ->propertyValue($value) && $this
    ->end()) {

    // look for important prefix
    if ($key[0] == $this->imPrefix && strlen($key) > 1) {
      $key = substr($key, 1);
      if ($value[0] == 'list' && $value[1] == ' ') {
        $value[2][] = array(
          'keyword',
          '!important',
        );
      }
      else {
        $value = array(
          'list',
          ' ',
          array(
            $value,
            array(
              'keyword',
              '!important',
            ),
          ),
        );
      }
    }
    $this
      ->append($key, $value);
    if (count($this->env) == 1) {
      return $this
        ->compileProperty($key, array(
        $value,
      )) . "\n";
    }
    else {
      return true;
    }
  }
  else {
    $this
      ->seek($s);
  }

  // look for special css @ directives
  if (count($this->env) == 1 && $this->count < strlen($this->buffer) && $this->buffer[$this->count] == '@') {

    // a font-face block
    if ($this
      ->literal('@font-face') && $this
      ->literal('{')) {
      $this
        ->push();
      $this
        ->set('__tags', array(
        '@font-face',
      ));
      $this
        ->set('__dontsave', true);
      return true;
    }
    else {
      $this
        ->seek($s);
    }

    // charset
    if ($this
      ->literal('@charset') && $this
      ->propertyValue($value) && $this
      ->end()) {
      return "@charset " . $this
        ->compileValue($value) . ";\n";
    }
    else {
      $this
        ->seek($s);
    }
  }

  // setting variable
  if ($this
    ->variable($name) && $this
    ->assign() && $this
    ->propertyValue($value) && $this
    ->end()) {
    $this
      ->append($this->vPrefix . $name, $value);
    return true;
  }
  else {
    $this
      ->seek($s);
  }

  // opening abstract block
  if ($this
    ->tag($tag, true) && $this
    ->argumentDef($args) && $this
    ->literal('{')) {
    $this
      ->push();

    // move out of variable scope
    if ($tag[0] == $this->vPrefix) {
      $tag[0] = $this->mPrefix;
    }
    $this
      ->set('__tags', array(
      $tag,
    ));
    if (isset($args)) {
      $this
        ->set('__args', $args);
    }
    return true;
  }
  else {
    $this
      ->seek($s);
  }

  // opening css block
  if ($this
    ->tags($tags) && $this
    ->literal('{')) {

    //  move @ tags out of variable namespace!
    foreach ($tags as &$tag) {
      if ($tag[0] == $this->vPrefix) {
        $tag[0] = $this->mPrefix;
      }
    }
    $this
      ->push();
    $this
      ->set('__tags', $tags);
    return true;
  }
  else {
    $this
      ->seek($s);
  }

  // closing block
  if ($this
    ->literal('}')) {
    $tags = $this
      ->multiplyTags();
    $env = end($this->env);
    $ctags = $env['__tags'];
    unset($env['__tags']);

    // insert the default arguments
    if (isset($env['__args'])) {
      foreach ($env['__args'] as $arg) {
        if (isset($arg[1])) {
          $this
            ->prepend($this->vPrefix . $arg[0], $arg[1]);
        }
      }
    }
    if (!empty($tags)) {
      $out = $this
        ->compileBlock($tags, $env);
    }
    $this
      ->pop();

    // make the block(s) available in the new current scope
    if (!isset($env['__dontsave'])) {
      foreach ($ctags as $t) {

        // if the block already exists then merge
        if ($this
          ->get($t, array(
          end($this->env),
        ))) {
          $this
            ->merge($t, $env);
        }
        else {
          $this
            ->set($t, $env);
        }
      }
    }
    return isset($out) ? $out : true;
  }

  // import statement
  if ($this
    ->import($url, $media)) {
    if ($this->importDisabled) {
      return "/* import is disabled */\n";
    }
    $full = $this->importDir . $url;
    if (file_exists($file = $full) || file_exists($file = $full . '.less')) {
      $loaded = $this
        ->removeComments(ltrim(file_get_contents($file) . ";"));
      $this->buffer = substr($this->buffer, 0, $this->count) . $loaded . substr($this->buffer, $this->count);
      return true;
    }
    return '@import url("' . $url . '")' . ($media ? ' ' . $media : '') . ";\n";
  }

  // mixin/function expand
  if ($this
    ->tags($tags, true, '>') && ($this
    ->argumentValues($argv) || true) && $this
    ->end()) {
    $env = $this
      ->getEnv($tags);
    if ($env == null) {
      return true;
    }

    // if we have arguments then insert them
    if (!empty($env['__args'])) {
      foreach ($env['__args'] as $arg) {
        $vname = $this->vPrefix . $arg[0];
        $value = is_array($argv) ? array_shift($argv) : null;

        // copy default value if there isn't one supplied
        if ($value == null && isset($arg[1])) {
          $value = $arg[1];
        }

        // if ($value == null) continue; // don't define so it can search up
        // create new entry if var doesn't exist in scope
        if (isset($env[$vname])) {
          array_unshift($env[$vname], $value);
        }
        else {

          // new element
          $env[$vname] = array(
            $value,
          );
        }
      }
    }

    // set all properties
    ob_start();
    $blocks = array();
    foreach ($env as $name => $value) {

      // skip the metatdata
      if (preg_match('/^__/', $name)) {
        continue;
      }

      // if it is a block, remember it to compile after everything
      // is mixed in
      if (!isset($value[0])) {
        $blocks[] = array(
          $name,
          $value,
        );
      }

      // copy the data
      // don't overwrite previous value, look in current env for name
      if ($this
        ->get($name, array(
        end($this->env),
      ))) {
        while ($tval = array_shift($value)) {
          $this
            ->append($name, $tval);
        }
      }
      else {
        $this
          ->set($name, $value);
      }
    }

    // render sub blocks
    foreach ($blocks as $b) {
      $rtags = $this
        ->multiplyTags(array(
        $b[0],
      ));
      echo $this
        ->compileBlock($rtags, $b[1]);
    }
    return ob_get_clean();
  }
  else {
    $this
      ->seek($s);
  }

  // spare ;
  if ($this
    ->literal(';')) {
    return true;
  }
  return false;

  // couldn't match anything, throw error
}