/** * Compiles the node * * @param Context $context The context * @param array|null $arguments Array of arguments * @param boolean|null $important Important flag * @return UrlNode */ public function compile(Context $context, $arguments = null, $important = null) { $value = $this->value->compile($context); if (!$this->isCompiled) { $rootPath = isset($this->currentFileInfo) && $this->currentFileInfo->rootPath ? $this->currentFileInfo->rootPath : false; if ($rootPath && is_string($value->value) && Util::isPathRelative($value->value)) { $quoteExists = self::propertyExists($value, 'quote'); if ($quoteExists && empty($value->quote) || !$quoteExists) { $rootPath = preg_replace_callback('/[\\(\\)\'"\\s]/', function ($match) { return '\\' . $match[0]; }, $rootPath); } $value->value = $rootPath . $value->value; } $value->value = Util::normalizePath($value->value, false); if ($context->urlArgs) { if (!preg_match('/^\\s*data:/', $value->value, $matches)) { $delimiter = strpos($value->value, '?') === false ? '?' : '&'; $urlArgs = $delimiter . $context->urlArgs; if (strpos($value->value, '#') !== false) { $value->value = str_replace('#', $urlArgs . '#', $value->value); } else { $value->value .= $urlArgs; } } } } return new UrlNode($value, $this->index, $this->currentFileInfo, true); }
/** * @see Importer::getLastModified */ public function getLastModified($path, FileInfo $currentFileInfo) { $normalizedPath = Util::normalizePath($currentFileInfo->currentDirectory . $path); if (isset($this->files[$normalizedPath])) { $path = $normalizedPath; } if (isset($this->lastModified[$path])) { return $this->lastModified[$path]; } return false; }
/** * Tries to find a file. * * @param string $path The path to a file * @param FileInfo $currentFileInfo * * @return string|false */ protected function find($path, FileInfo $currentFileInfo) { if (Util::isPathAbsolute($path) && is_readable($path)) { return realpath($path); } elseif (is_readable($currentFileInfo->currentDirectory . $path)) { return realpath($currentFileInfo->currentDirectory . $path); } // try import dirs foreach ($this->importDirs as $importDir) { if (is_readable($importDir . '/' . $path)) { return realpath($importDir . '/' . $path); } } return false; }
/** * Generates unique cache key for given $filename * * @param string $filename * @return string */ protected function generateCacheKey($filename) { return Util::generateCacheKey($filename); }
/** * Returns the file path, takes care about relative urls * * @param string $path * @return mixed|string */ protected function getFilePath($path) { $path = Util::sanitizePath($path); if (Util::isPathRelative($path) && $this->currentFileInfo) { if ($this->context->relativeUrls) { $path = $this->currentFileInfo->currentDirectory . $path; } else { $path = $this->currentFileInfo->entryPath . $path; } $path = Util::normalizePath($path); } return $path; }
/** * Constructor * * @param string $path The absolute path or URL * @param string $content The content of the local or remote file * @param integer $lastModified The last modification time */ public function __construct($path, $content, $lastModified) { $this->path = $path; $this->content = Util::normalizeLineFeeds($content); $this->lastModified = $lastModified; }
/** * Compiles the node * * @param Context $context The context * @param array|null $arguments Array of arguments * @param boolean|null $important Important flag * @return boolean */ public function compile(Context $context, $arguments = null, $important = null) { $a = $this->lvalue->compile($context); $b = $this->rvalue->compile($context); switch ($this->op) { case 'and': $result = $a && $b; break; case 'or': $result = $a || $b; break; default: $compared = Util::compareNodes($a, $b); // strict comparison, we cannot use switch here if ($compared === -1) { $result = $this->op === '<' || $this->op === '=<' || $this->op === '<='; } elseif ($compared === 0) { $result = $this->op === '=' || $this->op === '>=' || $this->op === '=<' || $this->op === '<='; } elseif ($compared === 1) { $result = $this->op === '>' || $this->op === '>=' || $this->op === '=>'; } else { $result = false; } break; } return $this->negate ? !$result : $result; }
/** * Compares with another node * * @param Node $other * @return integer|null */ public function compare(Node $other) { if ($other instanceof QuotedNode && !$this->escaped && !$other->escaped) { return Util::numericCompare($this->value, $other->value); } else { $context = new Context(); return $other->toCSS($context) === $this->toCSS($context) ? 0 : null; } }
/** * Compiles the path * * @param Context $context * @return UrlNode */ public function compilePath(Context $context) { $path = $this->path->compile($context); if (!$path instanceof UrlNode) { $rootPath = $this->currentFileInfo && $this->currentFileInfo->rootPath ? $this->currentFileInfo->rootPath : false; if ($rootPath) { $pathValue = $path->value; // Add the base path if the import is relative if ($pathValue && Util::isPathRelative($pathValue)) { $path->value = $rootPath . $pathValue; } } $path->value = Util::normalizePath($path->value); } return $path; }
/** * @covers compareNodes * @dataProvider getDataForCompareNodes */ public function testCompareNodes($expected, $a, $b) { $this->assertSame($expected, Util::compareNodes($a, $b)); }
/** * Compares with another dimension * * @param Node $other * @return integer */ public function compare(Node $other) { if (!$other instanceof DimensionNode) { return null; } if ($this->unit->isEmpty() || $other->unit->isEmpty()) { $a = $this; $b = $other; } else { $a = $this->unify(); $b = $other->unify(); if ($a->unit->compare($b->unit) !== 0) { return null; } } return Util::numericCompare($a->value, $b->value); }
/** * Runs the task based on the arguments * * @return integer 0 on success, error code on failure */ public function run() { if (!$this->isValid()) { echo $this->getUsage(); // return error return 1; } elseif ($this->getOption('version')) { echo Parser\Core::VERSION . ' [compatible with less.js ' . Parser\Core::LESS_JS_VERSION . ']' . PHP_EOL; return 0; } elseif ($this->getOption('help')) { echo $this->getUsage(); return 0; } try { $toBeParsed = $this->cliArguments['arguments'][0]; $parser = new Parser($this->prepareOptionsForTheParser()); $method = null; // read from stdin if (in_array($toBeParsed, $this->stdAliases)) { $toBeParsed = file_get_contents('php://stdin'); $method = 'parseString'; } else { if (!Util::isPathAbsolute($toBeParsed)) { $toBeParsed = sprintf('%s/%s', $this->currentDir, $toBeParsed); } $method = 'parseFile'; } // setup file $setupFile = $this->getOption('setup_file'); if ($setupFile === null) { $setupFilePath = getcwd() . '/.iless'; if (file_exists($setupFilePath)) { if (!is_readable($setupFilePath)) { throw new \RuntimeException(sprintf('Setup file "%s" could not be loaded. File does not exist or is not readable.', $setupFile)); } self::loadSetupFile($setupFilePath, $parser); } } else { $setupFilePath = $setupFile; if (!Util::isPathAbsolute($setupFilePath)) { $setupFilePath = getcwd() . '/' . $setupFile; } if (!is_readable($setupFilePath)) { throw new \RuntimeException(sprintf('Setup file "%s" could not be loaded. File does not exist or is not readable.', $setupFilePath)); } self::loadSetupFile($setupFilePath, $parser); } $parser->{$method}($toBeParsed); $toBeSavedTo = null; if (isset($this->cliArguments['arguments'][1])) { $toBeSavedTo = $this->cliArguments['arguments'][1]; if (!Util::isPathAbsolute($toBeSavedTo)) { $toBeSavedTo = sprintf('%s/%s', $this->currentDir, $toBeSavedTo); } } $css = $parser->getCSS(); // where to put the css? if ($toBeSavedTo) { // write the result $this->saveCSS($toBeSavedTo, $css, $this->getOption('append')); } else { echo $css; } } catch (Exception $e) { if (!$this->getOption('silent')) { $this->renderException($e); } return $e->getCode() ?: 1; } return 0; }
/** * Sets current file. * * @param string $file The path to a file */ public function setCurrentFile($file) { $file = Util::normalizePath($file); $dirname = preg_replace('/[^\\/\\\\]*$/', '', $file); $this->currentFileInfo = new FileInfo(['currentDirectory' => $dirname, 'filename' => $file, 'rootPath' => $this->currentFileInfo && $this->currentFileInfo->rootPath ? $this->currentFileInfo->rootPath : $this->rootPath, 'entryPath' => $dirname]); }
/** * Returns the debug information. * * @param int $index The index * * @return \ILess\DebugInfo */ protected function getDebugInfo($index) { list($lineNumber) = Util::getLocation($this->input->getInput(), $index); return new DebugInfo($this->context->currentFileInfo->filename, $lineNumber); }
/** * Normalizes the filename. * * @param string $filename * * @return string */ protected function normalizeFilename($filename) { $filename = Util::normalizePath($filename); if (($basePath = $this->getOption('base_path')) && ($pos = strpos($filename, $basePath)) !== false) { $filename = substr($filename, $pos + strlen($basePath)); if (strpos($filename, '/') === 0) { $filename = substr($filename, 1); } } return $this->getOption('root_path') . $filename; }
/** * Returns file editor link. The link format can be customized. * * @param FileInfo|string $file The current file * @param int $line * * @return string|void * * @see setFileEditorUrlFormat */ protected function getFileEditorLink($file, $line = null) { if ($file instanceof FileInfo) { $path = $file->filename; if ($file->importedFile) { $path = $file->importedFile->getPath(); } if (strpos($path, '__string_to_parse__') === 0) { $path = '[input string]'; } } else { $path = $file; } // when in cli or not accessible via filesystem, don't generate links if (PHP_SAPI == 'cli' || !Util::isPathAbsolute($path)) { return $path; } return sprintf('<a href="%s" class="file-edit">%s</a>', htmlspecialchars(strtr(self::$fileEditUrlFormat, ['%f' => $path, '%file' => $path, '%line' => $line, '%l' => $line])), $path); }