public function compile($env)
 {
     $doubleParen = false;
     if ($this->parens && !$this->parensInOp) {
         Less_Environment::$parensStack++;
     }
     $returnValue = null;
     if ($this->value) {
         $count = count($this->value);
         if ($count > 1) {
             $ret = array();
             foreach ($this->value as $e) {
                 $ret[] = $e->compile($env);
             }
             $returnValue = new Less_Tree_Expression($ret);
         } else {
             if ($this->value[0] instanceof Less_Tree_Expression && $this->value[0]->parens && !$this->value[0]->parensInOp) {
                 $doubleParen = true;
             }
             $returnValue = $this->value[0]->compile($env);
         }
     } else {
         $returnValue = $this;
     }
     if ($this->parens) {
         if (!$this->parensInOp) {
             Less_Environment::$parensStack--;
         } elseif (!Less_Environment::isMathOn() && !$doubleParen) {
             $returnValue = new Less_Tree_Paren($returnValue);
         }
     }
     return $returnValue;
 }
Example #2
0
 /**
  * @param Less_Functions $ctx
  */
 public function compile($ctx)
 {
     $val = $this->value->compile($ctx);
     if (!$this->isEvald) {
         // Add the base path if the URL is relative
         if (Less_Parser::$options['relativeUrls'] && $this->currentFileInfo && is_string($val->value) && Less_Environment::isPathRelative($val->value)) {
             $rootpath = $this->currentFileInfo['uri_root'];
             if (!$val->quote) {
                 $rootpath = preg_replace('/[\\(\\)\'"\\s]/', '\\$1', $rootpath);
             }
             $val->value = $rootpath . $val->value;
         }
         $val->value = Less_Environment::normalizePath($val->value);
     }
     // Add cache buster if enabled
     if (Less_Parser::$options['urlArgs']) {
         if (!preg_match('/^\\s*data:/', $val->value)) {
             $delimiter = strpos($val->value, '?') === false ? '?' : '&';
             $urlArgs = $delimiter . Less_Parser::$options['urlArgs'];
             $hash_pos = strpos($val->value, '#');
             if ($hash_pos !== false) {
                 $val->value = substr_replace($val->value, $urlArgs, $hash_pos, 0);
             } else {
                 $val->value .= $urlArgs;
             }
         }
     }
     return new Less_Tree_URL($val, $this->currentFileInfo, true);
 }
Example #3
0
 public function operate($env, $op, $other)
 {
     $value = Less_Environment::operate($env, $op, $this->value, $other->value);
     $unit = clone $this->unit;
     if ($op === '+' || $op === '-') {
         if (!count($unit->numerator) && !count($unit->denominator)) {
             $unit->numerator = $other->unit->numerator;
             $unit->denominator = $other->unit->denominator;
         } elseif (!count($other->unit->numerator) && !count($other->unit->denominator)) {
             // do nothing
         } else {
             $other = $other->convertTo($this->unit->usedUnits());
             if ($env->strictUnits && $other->unit->toString() !== $unit->toCSS()) {
                 throw new Less_CompilerException("Incompatible units. Change the units or use the unit function. Bad units: '" . $unit->toString() . "' and " . $other->unit->toString() + "'.");
             }
             $value = Less_Environment::operate($env, $op, $this->value, $other->value);
         }
     } elseif ($op === '*') {
         $unit->numerator = array_merge($unit->numerator, $other->unit->numerator);
         $unit->denominator = array_merge($unit->denominator, $other->unit->denominator);
         sort($unit->numerator);
         sort($unit->denominator);
         $unit->cancel();
     } elseif ($op === '/') {
         $unit->numerator = array_merge($unit->numerator, $other->unit->denominator);
         $unit->denominator = array_merge($unit->denominator, $other->unit->numerator);
         sort($unit->numerator);
         sort($unit->denominator);
         $unit->cancel();
     }
     return new Less_Tree_Dimension($value, $unit);
 }
Example #4
0
 public function compile($env)
 {
     if (Less_Environment::isMathOn()) {
         $ret = new Less_Tree_Operation('*', array(new Less_Tree_Dimension(-1), $this->value));
         return $ret->compile($env);
     }
     return new Less_Tree_Negative($this->value->compile($env));
 }
Example #5
0
 public function operate($env, $op, $other)
 {
     $result = array();
     if (!$other instanceof Less_Tree_Color) {
         $other = $other->toColor();
     }
     for ($c = 0; $c < 3; $c++) {
         $result[$c] = Less_Environment::operate($env, $op, $this->rgb[$c], $other->rgb[$c]);
     }
     return new Less_Tree_Color($result, $this->alpha + $other->alpha);
 }
Example #6
0
 public function Init()
 {
     self::$parensStack = 0;
     self::$tabLevel = 0;
     self::$lastRule = false;
     self::$mixin_stack = 0;
     if (Less_Parser::$options['compress']) {
         Less_Environment::$_outputMap = array(',' => ',', ': ' => ':', '' => '', ' ' => ' ', ':' => ' :', '+' => '+', '~' => '~', '>' => '>', '|' => '|', '^' => '^', '^^' => '^^');
     } else {
         Less_Environment::$_outputMap = array(',' => ', ', ': ' => ': ', '' => '', ' ' => ' ', ':' => ' :', '+' => ' + ', '~' => ' ~ ', '>' => ' > ', '|' => '|', '^' => ' ^ ', '^^' => ' ^^ ');
     }
 }
Example #7
0
 public function compile($env)
 {
     $a = $this->operands[0]->compile($env);
     $b = $this->operands[1]->compile($env);
     if (Less_Environment::isMathOn()) {
         if ($a instanceof Less_Tree_Dimension && $b instanceof Less_Tree_Color) {
             $a = $a->toColor();
         } elseif ($b instanceof Less_Tree_Dimension && $a instanceof Less_Tree_Color) {
             $b = $b->toColor();
         }
         if (!method_exists($a, 'operate')) {
             throw new Less_Exception_Compiler("Operation on an invalid type");
         }
         return $a->operate($this->op, $b);
     }
     return new Less_Tree_Operation($this->op, array($a, $b), $this->isSpaced);
 }
Example #8
0
 public function datauri($mimetypeNode, $filePathNode = null)
 {
     $filePath = $filePathNode ? $filePathNode->value : null;
     $mimetype = $mimetypeNode->value;
     $args = 2;
     if (!$filePath) {
         $filePath = $mimetype;
         $args = 1;
     }
     $filePath = str_replace('\\', '/', $filePath);
     if (Less_Environment::isPathRelative($filePath)) {
         if (Less_Parser::$options['relativeUrls']) {
             $temp = $this->currentFileInfo['currentDirectory'];
         } else {
             $temp = $this->currentFileInfo['entryPath'];
         }
         if (!empty($temp)) {
             $filePath = Less_Environment::normalizePath(rtrim($temp, '/') . '/' . $filePath);
         }
     }
     // detect the mimetype if not given
     if ($args < 2) {
         /* incomplete
         			$mime = require('mime');
         			mimetype = mime.lookup(path);
         
         			// use base 64 unless it's an ASCII or UTF-8 format
         			var charset = mime.charsets.lookup(mimetype);
         			useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;
         			if (useBase64) mimetype += ';base64';
         			*/
         $mimetype = Less_Mime::lookup($filePath);
         $charset = Less_Mime::charsets_lookup($mimetype);
         $useBase64 = !in_array($charset, array('US-ASCII', 'UTF-8'));
         if ($useBase64) {
             $mimetype .= ';base64';
         }
     } else {
         $useBase64 = preg_match('/;base64$/', $mimetype);
     }
     if (file_exists($filePath)) {
         $buf = @file_get_contents($filePath);
     } else {
         $buf = false;
     }
     // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded
     // and the --ieCompat flag is enabled, return a normal url() instead.
     $DATA_URI_MAX_KB = 32;
     $fileSizeInKB = round(strlen($buf) / 1024);
     if ($fileSizeInKB >= $DATA_URI_MAX_KB) {
         $url = new Less_Tree_Url($filePathNode ? $filePathNode : $mimetypeNode, $this->currentFileInfo);
         return $url->compile($this);
     }
     if ($buf) {
         $buf = $useBase64 ? base64_encode($buf) : rawurlencode($buf);
         $filePath = '"data:' . $mimetype . ',' . $buf . '"';
     }
     return new Less_Tree_Url(new Less_Tree_Anonymous($filePath));
 }
 /**
  * @see Less_Tree::genCSS
  */
 public function genCSS($output)
 {
     if (!$this->root) {
         Less_Environment::$tabLevel++;
     }
     $tabRuleStr = $tabSetStr = '';
     if (!Less_Parser::$options['compress']) {
         if (Less_Environment::$tabLevel) {
             $tabRuleStr = "\n" . str_repeat(Less_Parser::$options['indentation'], Less_Environment::$tabLevel);
             $tabSetStr = "\n" . str_repeat(Less_Parser::$options['indentation'], Less_Environment::$tabLevel - 1);
         } else {
             $tabSetStr = $tabRuleStr = "\n";
         }
     }
     $ruleNodes = array();
     $rulesetNodes = array();
     foreach ($this->rules as $rule) {
         $class = get_class($rule);
         if ($class === 'Less_Tree_Media' || $class === 'Less_Tree_Directive' || $this->root && $class === 'Less_Tree_Comment' || $class === 'Less_Tree_Ruleset' && $rule->rules) {
             $rulesetNodes[] = $rule;
         } else {
             $ruleNodes[] = $rule;
         }
     }
     // If this is the root node, we don't render
     // a selector, or {}.
     if (!$this->root) {
         /*
         debugInfo = tree.debugInfo(env, this, tabSetStr);
         
         if (debugInfo) {
         	output.add(debugInfo);
         	output.add(tabSetStr);
         }
         */
         $paths_len = count($this->paths);
         for ($i = 0; $i < $paths_len; $i++) {
             $path = $this->paths[$i];
             $firstSelector = true;
             foreach ($path as $p) {
                 $p->genCSS($output, $firstSelector);
                 $firstSelector = false;
             }
             if ($i + 1 < $paths_len) {
                 $output->add(',' . $tabSetStr);
             }
         }
         $output->add((Less_Parser::$options['compress'] ? '{' : " {") . $tabRuleStr);
     }
     // Compile rules and rulesets
     $ruleNodes_len = count($ruleNodes);
     $rulesetNodes_len = count($rulesetNodes);
     for ($i = 0; $i < $ruleNodes_len; $i++) {
         $rule = $ruleNodes[$i];
         // @page{ directive ends up with root elements inside it, a mix of rules and rulesets
         // In this instance we do not know whether it is the last property
         if ($i + 1 === $ruleNodes_len && (!$this->root || $rulesetNodes_len === 0 || $this->firstRoot)) {
             Less_Environment::$lastRule = true;
         }
         $rule->genCSS($output);
         if (!Less_Environment::$lastRule) {
             $output->add($tabRuleStr);
         } else {
             Less_Environment::$lastRule = false;
         }
     }
     if (!$this->root) {
         $output->add($tabSetStr . '}');
         Less_Environment::$tabLevel--;
     }
     $firstRuleset = true;
     $space = $this->root ? $tabRuleStr : $tabSetStr;
     for ($i = 0; $i < $rulesetNodes_len; $i++) {
         if ($ruleNodes_len && $firstRuleset) {
             $output->add($space);
         } elseif (!$firstRuleset) {
             $output->add($space);
         }
         $firstRuleset = false;
         $rulesetNodes[$i]->genCSS($output);
     }
     if (!Less_Parser::$options['compress'] && $this->firstRoot) {
         $output->add("\n");
     }
 }
Example #10
0
 /**
  * @param string $filename
  */
 public function SetFileInfo($filename, $uri_root = '')
 {
     $filename = Less_Environment::normalizePath($filename);
     $dirname = preg_replace('/[^\\/\\\\]*$/', '', $filename);
     if (!empty($uri_root)) {
         $uri_root = rtrim($uri_root, '/') . '/';
     }
     $currentFileInfo = array();
     //entry info
     if (isset($this->env->currentFileInfo)) {
         $currentFileInfo['entryPath'] = $this->env->currentFileInfo['entryPath'];
         $currentFileInfo['entryUri'] = $this->env->currentFileInfo['entryUri'];
         $currentFileInfo['rootpath'] = $this->env->currentFileInfo['rootpath'];
     } else {
         $currentFileInfo['entryPath'] = $dirname;
         $currentFileInfo['entryUri'] = $uri_root;
         $currentFileInfo['rootpath'] = $dirname;
     }
     $currentFileInfo['currentDirectory'] = $dirname;
     $currentFileInfo['currentUri'] = $uri_root . basename($filename);
     $currentFileInfo['filename'] = $filename;
     $currentFileInfo['uri_root'] = $uri_root;
     //inherit reference
     if (isset($this->env->currentFileInfo['reference']) && $this->env->currentFileInfo['reference']) {
         $currentFileInfo['reference'] = true;
     }
     $this->env->currentFileInfo = $currentFileInfo;
 }
 /**
  * Using the import directories, get the full absolute path and uri of the import
  *
  * @param Less_Tree_Import $evald
  */
 public function PathAndUri()
 {
     $evald_path = $this->getPath();
     if ($evald_path) {
         $import_dirs = array();
         if (Less_Environment::isPathRelative($evald_path)) {
             //if the path is relative, the file should be in the current directory
             $import_dirs[$this->currentFileInfo['currentDirectory']] = $this->currentFileInfo['uri_root'];
         } else {
             //otherwise, the file should be relative to the server root
             $import_dirs[$this->currentFileInfo['entryPath']] = $this->currentFileInfo['entryUri'];
             //if the user supplied entryPath isn't the actual root
             $import_dirs[$_SERVER['DOCUMENT_ROOT']] = '';
         }
         // always look in user supplied import directories
         $import_dirs = array_merge($import_dirs, Less_Parser::$options['import_dirs']);
         foreach ($import_dirs as $rootpath => $rooturi) {
             if (is_callable($rooturi)) {
                 list($path, $uri) = call_user_func($rooturi, $evald_path);
                 if (is_string($path)) {
                     $full_path = $path;
                     return array($full_path, $uri);
                 }
             } elseif (!empty($rootpath)) {
                 $path = rtrim($rootpath, '/\\') . '/' . ltrim($evald_path, '/\\');
                 if (file_exists($path)) {
                     $full_path = Less_Environment::normalizePath($path);
                     $uri = Less_Environment::normalizePath(dirname($rooturi . $evald_path));
                     return array($full_path, $uri);
                 } elseif (file_exists($path . '.less')) {
                     $full_path = Less_Environment::normalizePath($path . '.less');
                     $uri = Less_Environment::normalizePath(dirname($rooturi . $evald_path . '.less'));
                     return array($full_path, $uri);
                 }
             }
         }
     }
 }
 public function compilePath($env)
 {
     $path = $this->path->compile($env);
     $rootpath = '';
     if ($this->currentFileInfo && $this->currentFileInfo['rootpath']) {
         $rootpath = $this->currentFileInfo['rootpath'];
     }
     if (!$path instanceof Less_Tree_URL) {
         if ($rootpath) {
             $pathValue = $path->value;
             // Add the base path if the import is relative
             if ($pathValue && Less_Environment::isPathRelative($pathValue)) {
                 $path->value = $this->currentFileInfo['uri_root'] . $pathValue;
             }
         }
         $path->value = Less_Environment::normalizePath($path->value);
     }
     return $path;
 }
Example #13
0
 function compile($env)
 {
     $evald = $this->compileForImport($env);
     $uri = $full_path = false;
     //get path & uri
     $evald_path = $evald->getPath();
     if ($evald_path && $env->isPathRelative($evald_path)) {
         foreach (Less_Parser::$import_dirs as $rootpath => $rooturi) {
             $temp = $rootpath . $evald_path;
             if (file_exists($temp)) {
                 $full_path = Less_Environment::NormPath($temp);
                 $uri = Less_Environment::NormPath(dirname($rooturi . $evald_path));
                 break;
             }
         }
     }
     if (!$full_path) {
         $uri = $evald_path;
         $full_path = $evald_path;
     }
     //import once
     $realpath = realpath($full_path);
     if (!isset($evald->options['multiple']) && $realpath && Less_Parser::FileParsed($realpath)) {
         $evald->skip = true;
     }
     $features = $evald->features ? $evald->features->compile($env) : null;
     if ($evald->skip) {
         return array();
     }
     if ($evald->css) {
         $temp = $this->compilePath($env);
         return new Less_Tree_Import($this->compilePath($env), $features, $this->options, $this->index);
     }
     $parser = new Less_Parser($env);
     $evald->root = $parser->parseFile($full_path, $uri, true);
     $ruleset = new Less_Tree_Ruleset(array(), $evald->root->rules);
     $ruleset->evalImports($env);
     return $this->features ? new Less_Tree_Media($ruleset->rules, $this->features->value) : $ruleset->rules;
 }
Example #14
0
 /**
  * @param Less_Functions $ctx
  */
 public function compile($ctx)
 {
     $val = $this->value->compile($ctx);
     if (!$this->isEvald) {
         // Add the base path if the URL is relative
         if (Less_Parser::$options['relativeUrls'] && $this->currentFileInfo && is_string($val->value) && Less_Environment::isPathRelative($val->value)) {
             $rootpath = $this->currentFileInfo['uri_root'];
             if (!$val->quote) {
                 $rootpath = preg_replace('/[\\(\\)\'"\\s]/', '\\$1', $rootpath);
             }
             $val->value = $rootpath . $val->value;
         }
         $val->value = Less_Environment::normalizePath($val->value);
     }
     return new Less_Tree_URL($val, $this->currentFileInfo, true);
 }
Example #15
0
 public function compile($env, $args = NULL, $important = NULL)
 {
     $_arguments = array();
     $mixinFrames = array_merge($this->frames, $env->frames);
     $mixinEnv = new Less_Environment();
     $mixinEnv->addFrames($mixinFrames);
     $frame = $this->compileParams($env, $mixinEnv, $args, $_arguments);
     $ex = new Less_Tree_Expression($_arguments);
     array_unshift($frame->rules, new Less_Tree_Rule('@arguments', $ex->compile($env)));
     $rules = $important ? Less_Tree_Ruleset::makeImportant($this->selectors, $this->rules)->rules : array_slice($this->rules, 0);
     $ruleset = new Less_Tree_Ruleset(null, $rules);
     // duplicate the environment, adding new frames.
     $ruleSetEnv = new Less_Environment();
     $ruleSetEnv->addFrame($this);
     $ruleSetEnv->addFrame($frame);
     $ruleSetEnv->addFrames($mixinFrames);
     $ruleSetEnv->compress = $env->compress;
     $ruleset = $ruleset->compile($ruleSetEnv);
     $ruleset->originalRuleset = $this;
     return $ruleset;
 }
Example #16
0
	public function SetFileInfo( $filename, $uri_root = ''){

		$this->path = pathinfo($filename, PATHINFO_DIRNAME);
		$this->filename = Less_Environment::NormPath($filename);

		$dirname = preg_replace('/[^\/\\\\]*$/','',$this->filename);

		$currentFileInfo = array();
		$currentFileInfo['currentDirectory'] = $dirname;
		$currentFileInfo['filename'] = $filename;
		$currentFileInfo['rootpath'] = $dirname;
		$currentFileInfo['entryPath'] = $dirname;

		if( empty($uri_root) ){
			$currentFileInfo['uri_root'] = $uri_root;
		}else{
			$currentFileInfo['uri_root'] = rtrim($uri_root,'/').'/';
		}

		$this->env->currentFileInfo = $currentFileInfo;

		self::$import_dirs = array_merge( array( $dirname => $currentFileInfo['uri_root'] ), self::$import_dirs );
	}