123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- <?php
- /**
- * This file provides the part of lessphp API (https://github.com/leafo/lessphp)
- * to be a drop-in replacement for following products:
- * - Drupal 7, by the less module v3.0+ (https://drupal.org/project/less)
- * - Symfony 2
- */
- // Register autoloader for non-composer installations
- if ( !class_exists( 'Less_Parser' ) ) {
- require_once __DIR__ . '/lib/Less/Autoloader.php';
- Less_Autoloader::register();
- }
- class lessc {
- static public $VERSION = Less_Version::less_version;
- public $importDir = '';
- protected $allParsedFiles = array();
- protected $libFunctions = array();
- protected $registeredVars = array();
- private $formatterName;
- private $options = array();
- public function __construct( $lessc = null, $sourceName = null ) {
- }
- public function setImportDir( $dirs ) {
- $this->importDir = (array)$dirs;
- }
- public function addImportDir( $dir ) {
- $this->importDir = (array)$this->importDir;
- $this->importDir[] = $dir;
- }
- public function setFormatter( $name ) {
- $this->formatterName = $name;
- }
- public function setPreserveComments( $preserve ) {
- }
- public function registerFunction( $name, $func ) {
- $this->libFunctions[$name] = $func;
- }
- public function unregisterFunction( $name ) {
- unset( $this->libFunctions[$name] );
- }
- public function setVariables( $variables ) {
- foreach ( $variables as $name => $value ) {
- $this->setVariable( $name, $value );
- }
- }
- public function setVariable( $name, $value ) {
- $this->registeredVars[$name] = $value;
- }
- public function unsetVariable( $name ) {
- unset( $this->registeredVars[$name] );
- }
- public function setOptions( $options ) {
- foreach ( $options as $name => $value ) {
- $this->setOption( $name, $value );
- }
- }
- public function setOption( $name, $value ) {
- $this->options[$name] = $value;
- }
- public function parse( $buffer, $presets = array() ) {
- $this->setVariables( $presets );
- $parser = new Less_Parser( $this->getOptions() );
- $parser->setImportDirs( $this->getImportDirs() );
- foreach ( $this->libFunctions as $name => $func ) {
- $parser->registerFunction( $name, $func );
- }
- $parser->parse( $buffer );
- if ( count( $this->registeredVars ) ) {
- $parser->ModifyVars( $this->registeredVars );
- }
- return $parser->getCss();
- }
- protected function getOptions() {
- $options = array( 'relativeUrls' => false );
- switch ( $this->formatterName ) {
- case 'compressed':
- $options['compress'] = true;
- break;
- }
- if ( is_array( $this->options ) ) {
- $options = array_merge( $options, $this->options );
- }
- return $options;
- }
- protected function getImportDirs() {
- $dirs_ = (array)$this->importDir;
- $dirs = array();
- foreach ( $dirs_ as $dir ) {
- $dirs[$dir] = '';
- }
- return $dirs;
- }
- public function compile( $string, $name = null ) {
- $oldImport = $this->importDir;
- $this->importDir = (array)$this->importDir;
- $this->allParsedFiles = array();
- $parser = new Less_Parser( $this->getOptions() );
- $parser->SetImportDirs( $this->getImportDirs() );
- if ( count( $this->registeredVars ) ) {
- $parser->ModifyVars( $this->registeredVars );
- }
- foreach ( $this->libFunctions as $name => $func ) {
- $parser->registerFunction( $name, $func );
- }
- $parser->parse( $string );
- $out = $parser->getCss();
- $parsed = Less_Parser::AllParsedFiles();
- foreach ( $parsed as $file ) {
- $this->addParsedFile( $file );
- }
- $this->importDir = $oldImport;
- return $out;
- }
- public function compileFile( $fname, $outFname = null ) {
- if ( !is_readable( $fname ) ) {
- throw new Exception( 'load error: failed to find '.$fname );
- }
- $pi = pathinfo( $fname );
- $oldImport = $this->importDir;
- $this->importDir = (array)$this->importDir;
- $this->importDir[] = Less_Parser::AbsPath( $pi['dirname'] ).'/';
- $this->allParsedFiles = array();
- $this->addParsedFile( $fname );
- $parser = new Less_Parser( $this->getOptions() );
- $parser->SetImportDirs( $this->getImportDirs() );
- if ( count( $this->registeredVars ) ) {
- $parser->ModifyVars( $this->registeredVars );
- }
- foreach ( $this->libFunctions as $name => $func ) {
- $parser->registerFunction( $name, $func );
- }
- $parser->parseFile( $fname );
- $out = $parser->getCss();
- $parsed = Less_Parser::AllParsedFiles();
- foreach ( $parsed as $file ) {
- $this->addParsedFile( $file );
- }
- $this->importDir = $oldImport;
- if ( $outFname !== null ) {
- return file_put_contents( $outFname, $out );
- }
- return $out;
- }
- public function checkedCompile( $in, $out ) {
- if ( !is_file( $out ) || filemtime( $in ) > filemtime( $out ) ) {
- $this->compileFile( $in, $out );
- return true;
- }
- return false;
- }
- /**
- * Execute lessphp on a .less file or a lessphp cache structure
- *
- * The lessphp cache structure contains information about a specific
- * less file having been parsed. It can be used as a hint for future
- * calls to determine whether or not a rebuild is required.
- *
- * The cache structure contains two important keys that may be used
- * externally:
- *
- * compiled: The final compiled CSS
- * updated: The time (in seconds) the CSS was last compiled
- *
- * The cache structure is a plain-ol' PHP associative array and can
- * be serialized and unserialized without a hitch.
- *
- * @param mixed $in Input
- * @param bool $force Force rebuild?
- * @return array lessphp cache structure
- */
- public function cachedCompile( $in, $force = false ) {
- // assume no root
- $root = null;
- if ( is_string( $in ) ) {
- $root = $in;
- } elseif ( is_array( $in ) and isset( $in['root'] ) ) {
- if ( $force or !isset( $in['files'] ) ) {
- // If we are forcing a recompile or if for some reason the
- // structure does not contain any file information we should
- // specify the root to trigger a rebuild.
- $root = $in['root'];
- } elseif ( isset( $in['files'] ) and is_array( $in['files'] ) ) {
- foreach ( $in['files'] as $fname => $ftime ) {
- if ( !file_exists( $fname ) or filemtime( $fname ) > $ftime ) {
- // One of the files we knew about previously has changed
- // so we should look at our incoming root again.
- $root = $in['root'];
- break;
- }
- }
- }
- } else {
- // TODO: Throw an exception? We got neither a string nor something
- // that looks like a compatible lessphp cache structure.
- return null;
- }
- if ( $root !== null ) {
- // If we have a root value which means we should rebuild.
- $out = array();
- $out['root'] = $root;
- $out['compiled'] = $this->compileFile( $root );
- $out['files'] = $this->allParsedFiles();
- $out['updated'] = time();
- return $out;
- } else {
- // No changes, pass back the structure
- // we were given initially.
- return $in;
- }
- }
- public function ccompile( $in, $out, $less = null ) {
- if ( $less === null ) {
- $less = new self;
- }
- return $less->checkedCompile( $in, $out );
- }
- public static function cexecute( $in, $force = false, $less = null ) {
- if ( $less === null ) {
- $less = new self;
- }
- return $less->cachedCompile( $in, $force );
- }
- public function allParsedFiles() {
- return $this->allParsedFiles;
- }
- protected function addParsedFile( $file ) {
- $this->allParsedFiles[Less_Parser::AbsPath( $file )] = filemtime( $file );
- }
- }
|