Use less.php instead of lesserphp
This commit is contained in:
parent
e7335d7f77
commit
0ebc1387f4
75 changed files with 11881 additions and 6180 deletions
|
@ -87,7 +87,7 @@ This source code includes:
|
|||
|
||||
* [phpqrcode](https://github.com/t0k4rt/phpqrcode) to generate QR codes
|
||||
* [Ubuntu font for the Web](https://github.com/earaujoassis/ubuntu-fontface)
|
||||
* [lesserphp](https://github.com/MarcusSchwarz/lesserphp) to compile [Less](http://lesscss.org)
|
||||
* [less.php](https://github.com/wikimedia/less.php) to compile [Less](http://lesscss.org)
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ Ce code source inclus :
|
|||
|
||||
* [phpqrcode](https://github.com/t0k4rt/phpqrcode) pour générer les codes QR
|
||||
* [La police Ubuntu pour le Web](https://github.com/earaujoassis/ubuntu-fontface)
|
||||
* [lesserphp](https://github.com/MarcusSchwarz/lesserphp) pour compiler le [Less](http://lesscss.org)
|
||||
* [less.php](https://github.com/wikimedia/less.php) pour compiler le [Less](http://lesscss.org)
|
||||
|
||||
## Licence
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ if (badQuery()) {
|
|||
// Then delete it
|
||||
unlink("temp/style.min.css");
|
||||
|
||||
require "lesserphp/lessc.inc.php";
|
||||
require "less.php/lessc.inc.php";
|
||||
$less = new lessc;
|
||||
$less->setVariables($variablesTheme); // Make these colors available in style.less
|
||||
$less->setFormatter("compressed");
|
||||
|
|
70
less.php/CHANGES.md
Normal file
70
less.php/CHANGES.md
Normal file
|
@ -0,0 +1,70 @@
|
|||
# 3.1.0
|
||||
- [All Changes](https://github.com/wikimedia/less.php/compare/v3.0.0...v3.1.0)
|
||||
* PHP 8.0 support: Drop use of curly braces for sub-string eval (James D. Forrester)
|
||||
* Make `Directive::__construct` $rules arg optional (fix PHP 7.4 warning) (Sam Reed)
|
||||
* ProcessExtends: Improve performance by using a map for selectors and parents (Andrey Legayev)
|
||||
* build: Run CI tests on PHP 8.0 too (James D. Forrester)
|
||||
* code: Fix PSR12.Properties.ConstantVisibility.NotFound (Sam Reed)
|
||||
|
||||
# 3.0.0
|
||||
- [All Changes](https://github.com/wikimedia/less.php/compare/v2.0.0...v3.0.0)
|
||||
- Raise PHP requirement from 7.1 to 7.2.9 (James Forrester)
|
||||
- build: Upgrade phpunit to ^8.5 and make pass (James Forrester)
|
||||
- build: Install php-parallel-lint (James Forrester)
|
||||
- build: Install minus-x and make pass (James Forrester)
|
||||
|
||||
# 2.0.0
|
||||
- [All Changes](https://github.com/wikimedia/less.php/compare/1.8.2...v2.0.0)
|
||||
- Relax PHP requirement down to 7.1, from 7.2.9 (Franz Liedke)
|
||||
- Reflect recent breaking changes properly with the semantic versioning (James Forrester)
|
||||
|
||||
# 1.8.2
|
||||
- [All Changes](https://github.com/wikimedia/less.php/compare/1.8.1...1.8.2)
|
||||
- Require PHP 7.2.9+, up from 5.3+ (James Forrester)
|
||||
- Release: Update Version.php with the current release ID (COBadger)
|
||||
- Fix access array offset on value of type null (Michele Locati)
|
||||
- Fixed test suite on PHP 7.4 (Sergei Morozov)
|
||||
- docs: Fix 1.8.1 "All changes" link (Timo Tijhof)
|
||||
|
||||
# 1.8.1
|
||||
- [All Changes](https://github.com/wikimedia/less.php/compare/v1.8.0...1.8.1)
|
||||
- Another PHP 7.3 compatibility tweak
|
||||
|
||||
# 1.8.0
|
||||
- [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.13...v1.8.0)
|
||||
- Wikimedia fork
|
||||
- Supports up to PHP 7.3
|
||||
- No longer tested against PHP 5, though it's still remains allowed in `composer.json` for HHVM compatibility
|
||||
- Switched to [semantic versioning](https://semver.org/), hence version numbers now use 3 digits
|
||||
|
||||
# 1.7.0.13
|
||||
- [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.12...v1.7.0.13)
|
||||
- Fix composer.json (PSR-4 was invalid)
|
||||
|
||||
# 1.7.0.12
|
||||
- [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.11...v1.7.0.12)
|
||||
- set bin/lessc bit executable
|
||||
- Add 'gettingVariables' method in Less_Parser
|
||||
|
||||
# 1.7.0.11
|
||||
- [All Changes](https://github.com/Asenar/less.php/compare/v1.7.0.10...v1.7.0.11)
|
||||
- Fix realpath issue (windows)
|
||||
- Set Less_Tree_Call property back to public ( Fix 258 266 267 issues from oyejorge/less.php)
|
||||
|
||||
# 1.7.0.10
|
||||
|
||||
- [All Changes](https://github.com/oyejorge/less.php/compare/v1.7.0.9...v1.7.10)
|
||||
- Add indentation option
|
||||
- Add 'optional' modifier for @import
|
||||
- fix $color in Exception messages
|
||||
- don't use set_time_limit when running cli
|
||||
- take relative-url into account when building the cache filename
|
||||
- urlArgs should be string no array()
|
||||
- add bug-report fixtures [#6dc898f](https://github.com/oyejorge/less.php/commit/6dc898f5d75b447464906bdf19d79c2e19d95e33)
|
||||
- fix #269, missing on NameValue type [#a8dac63](https://github.com/oyejorge/less.php/commit/a8dac63d93fb941c54fb78b12588abf635747c1b)
|
||||
|
||||
# 1.7.0.9
|
||||
|
||||
- [All Changes](https://github.com/oyejorge/less.php/compare/v1.7.0.8...v1.7.0.9)
|
||||
- Remove space at beginning of Version.php
|
||||
- Revert require() paths in test interface
|
178
less.php/LICENSE
Normal file
178
less.php/LICENSE
Normal file
|
@ -0,0 +1,178 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
315
less.php/README.md
Normal file
315
less.php/README.md
Normal file
|
@ -0,0 +1,315 @@
|
|||
[![Continuous Integration](https://github.com/wikimedia/less.php/workflows/PHP%20Test/badge.svg)](https://github.com/wikimedia/less.php/actions)
|
||||
|
||||
[Less.php](http://lessphp.typesettercms.com)
|
||||
========
|
||||
|
||||
This is the Wikimedia fork of a PHP port of the official LESS processor <http://lesscss.org>.
|
||||
|
||||
* [About](#about)
|
||||
* [Installation](#installation)
|
||||
* [Basic Use](#basic-use)
|
||||
* [Caching](#caching)
|
||||
* [Source Maps](#source-maps)
|
||||
* [Command Line](#command-line)
|
||||
* [Integration with other projects](#integration-with-other-projects)
|
||||
* [Transitioning from Leafo/lessphp](#transitioning-from-leafolessphp)
|
||||
* [Credits](#credits)
|
||||
|
||||
|
||||
|
||||
About
|
||||
---
|
||||
The code structure of less.php mirrors that of the official processor which helps us ensure compatibility and allows for easy maintenance.
|
||||
|
||||
Please note, there are a few unsupported LESS features:
|
||||
|
||||
- Evaluation of JavaScript expressions within back-ticks (for obvious reasons).
|
||||
- Definition of custom functions.
|
||||
|
||||
|
||||
Installation
|
||||
---
|
||||
|
||||
You can install the library with Composer or manually.
|
||||
|
||||
#### Composer
|
||||
|
||||
1. [Install Composer](https://getcomposer.org/download/)
|
||||
2. Run `composer require wikimedia/less.php`
|
||||
|
||||
#### Manually From Release
|
||||
|
||||
Step 1. [Download a release](https://github.com/wikimedia/less.php/releases) and upload the PHP files to your server.
|
||||
|
||||
Step 2. Include the library:
|
||||
|
||||
```php
|
||||
require_once '[path to less.php]/lib/Less/Autoloader.php';
|
||||
Less_Autoloader::register();
|
||||
```
|
||||
|
||||
Basic Use
|
||||
---
|
||||
|
||||
#### Parsing Strings
|
||||
|
||||
```php
|
||||
$parser = new Less_Parser();
|
||||
$parser->parse( '@color: #4D926F; #header { color: @color; } h2 { color: @color; }' );
|
||||
$css = $parser->getCss();
|
||||
```
|
||||
|
||||
|
||||
#### Parsing LESS Files
|
||||
The parseFile() function takes two arguments:
|
||||
|
||||
1. The absolute path of the .less file to be parsed
|
||||
2. The url root to prepend to any relative image or @import urls in the .less file.
|
||||
|
||||
```php
|
||||
$parser = new Less_Parser();
|
||||
$parser->parseFile( '/var/www/mysite/bootstrap.less', 'http://example.com/mysite/' );
|
||||
$css = $parser->getCss();
|
||||
```
|
||||
|
||||
|
||||
#### Handling Invalid LESS
|
||||
An exception will be thrown if the compiler encounters invalid LESS.
|
||||
|
||||
```php
|
||||
try{
|
||||
$parser = new Less_Parser();
|
||||
$parser->parseFile( '/var/www/mysite/bootstrap.less', 'http://example.com/mysite/' );
|
||||
$css = $parser->getCss();
|
||||
}catch(Exception $e){
|
||||
$error_message = $e->getMessage();
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Parsing Multiple Sources
|
||||
less.php can parse multiple sources to generate a single CSS file.
|
||||
|
||||
```php
|
||||
$parser = new Less_Parser();
|
||||
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
|
||||
$parser->parse( '@color: #4D926F; #header { color: @color; } h2 { color: @color; }' );
|
||||
$css = $parser->getCss();
|
||||
```
|
||||
|
||||
#### Getting Info About The Parsed Files
|
||||
less.php can tell you which .less files were imported and parsed.
|
||||
|
||||
```php
|
||||
$parser = new Less_Parser();
|
||||
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
|
||||
$css = $parser->getCss();
|
||||
$imported_files = $parser->allParsedFiles();
|
||||
```
|
||||
|
||||
|
||||
#### Compressing Output
|
||||
You can tell less.php to remove comments and whitespace to generate minimized CSS files.
|
||||
|
||||
```php
|
||||
$options = array( 'compress'=>true );
|
||||
$parser = new Less_Parser( $options );
|
||||
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
|
||||
$css = $parser->getCss();
|
||||
```
|
||||
|
||||
#### Getting Variables
|
||||
You can use the getVariables() method to get an all variables defined and
|
||||
their value in a php associative array. Note that LESS has to be previously
|
||||
compiled.
|
||||
```php
|
||||
$parser = new Less_Parser;
|
||||
$parser->parseFile( '/var/www/mysite/bootstrap.less');
|
||||
$css = $parser->getCss();
|
||||
$variables = $parser->getVariables();
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### Setting Variables
|
||||
You can use the ModifyVars() method to customize your CSS if you have variables stored in PHP associative arrays.
|
||||
|
||||
```php
|
||||
$parser = new Less_Parser();
|
||||
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
|
||||
$parser->ModifyVars( array('font-size-base'=>'16px') );
|
||||
$css = $parser->getCss();
|
||||
```
|
||||
|
||||
|
||||
#### Import Directories
|
||||
By default, less.php will look for @imports in the directory of the file passed to parseFile().
|
||||
If you're using parse() or if @imports reside in different directories, you can tell less.php where to look.
|
||||
|
||||
```php
|
||||
$directories = array( '/var/www/mysite/bootstrap/' => '/mysite/bootstrap/' );
|
||||
$parser = new Less_Parser();
|
||||
$parser->SetImportDirs( $directories );
|
||||
$parser->parseFile( '/var/www/mysite/theme.less', '/mysite/' );
|
||||
$css = $parser->getCss();
|
||||
```
|
||||
|
||||
|
||||
Caching
|
||||
---
|
||||
Compiling LESS code into CSS is a time consuming process, caching your results is highly recommended.
|
||||
|
||||
|
||||
#### Caching CSS
|
||||
Use the Less_Cache class to save and reuse the results of compiled LESS files.
|
||||
This method will check the modified time and size of each LESS file (including imported files) and regenerate a new CSS file when changes are found.
|
||||
Note: When changes are found, this method will return a different file name for the new cached content.
|
||||
|
||||
```php
|
||||
$less_files = array( '/var/www/mysite/bootstrap.less' => '/mysite/' );
|
||||
$options = array( 'cache_dir' => '/var/www/writable_folder' );
|
||||
$css_file_name = Less_Cache::Get( $less_files, $options );
|
||||
$compiled = file_get_contents( '/var/www/writable_folder/'.$css_file_name );
|
||||
```
|
||||
|
||||
#### Caching CSS With Variables
|
||||
Passing options to Less_Cache::Get()
|
||||
|
||||
```php
|
||||
$less_files = array( '/var/www/mysite/bootstrap.less' => '/mysite/' );
|
||||
$options = array( 'cache_dir' => '/var/www/writable_folder' );
|
||||
$variables = array( 'width' => '100px' );
|
||||
$css_file_name = Less_Cache::Get( $less_files, $options, $variables );
|
||||
$compiled = file_get_contents( '/var/www/writable_folder/'.$css_file_name );
|
||||
```
|
||||
|
||||
|
||||
#### Parser Caching
|
||||
less.php will save serialized parser data for each .less file if a writable folder is passed to the SetCacheDir() method.
|
||||
Note: This feature only caches intermediate parsing results to improve the performance of repeated CSS generation.
|
||||
Your application should cache any CSS generated by less.php.
|
||||
|
||||
```php
|
||||
$options = array('cache_dir'=>'/var/www/writable_folder');
|
||||
$parser = new Less_Parser( $options );
|
||||
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
|
||||
$css = $parser->getCss();
|
||||
```
|
||||
|
||||
You can specify the caching technique used by changing the ```cache_method``` option. Supported methods are:
|
||||
* ```php```: Creates valid PHP files which can be included without any changes (default method).
|
||||
* ```var_export```: Like "php", but using PHP's ```var_export()``` function without any optimizations.
|
||||
It's recommended to use "php" instead.
|
||||
* ```serialize```: Faster, but pretty memory-intense.
|
||||
* ```callback```: Use custom callback functions to implement your own caching method. Give the "cache_callback_get" and
|
||||
"cache_callback_set" options with callables (see PHP's ```call_user_func()``` and ```is_callable()``` functions). less.php
|
||||
will pass the parser object (class ```Less_Parser```), the path to the parsed .less file ("/some/path/to/file.less") and
|
||||
an identifier that will change every time the .less file is modified. The ```get``` callback must return the ruleset
|
||||
(an array with ```Less_Tree``` objects) provided as fourth parameter of the ```set``` callback. If something goes wrong,
|
||||
return ```NULL``` (cache doesn't exist) or ```FALSE```.
|
||||
|
||||
|
||||
|
||||
Source Maps
|
||||
---
|
||||
Less.php supports v3 sourcemaps
|
||||
|
||||
#### Inline
|
||||
The sourcemap will be appended to the generated CSS file.
|
||||
|
||||
```php
|
||||
$options = array( 'sourceMap' => true );
|
||||
$parser = new Less_Parser($options);
|
||||
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
|
||||
$css = $parser->getCss();
|
||||
```
|
||||
|
||||
#### Saving to Map File
|
||||
|
||||
```php
|
||||
$options = array(
|
||||
'sourceMap' => true,
|
||||
'sourceMapWriteTo' => '/var/www/mysite/writable_folder/filename.map',
|
||||
'sourceMapURL' => '/mysite/writable_folder/filename.map',
|
||||
);
|
||||
$parser = new Less_Parser($options);
|
||||
$parser->parseFile( '/var/www/mysite/bootstrap.less', '/mysite/' );
|
||||
$css = $parser->getCss();
|
||||
```
|
||||
|
||||
|
||||
Command line
|
||||
---
|
||||
An additional script has been included to use the compiler from the command line.
|
||||
In the simplest invocation, you specify an input file and the compiled CSS is written to standard out:
|
||||
|
||||
```
|
||||
$ lessc input.less > output.css
|
||||
```
|
||||
|
||||
By using the -w flag you can watch a specified input file and have it compile as needed to the output file:
|
||||
|
||||
```
|
||||
$ lessc -w input.less output.css
|
||||
```
|
||||
|
||||
Errors from watch mode are written to standard out.
|
||||
|
||||
For more help, run `lessc --help`
|
||||
|
||||
|
||||
Integration with other projects
|
||||
---
|
||||
|
||||
#### Drupal 7
|
||||
|
||||
This library can be used as drop-in replacement of lessphp to work with [Drupal 7 less module](https://drupal.org/project/less).
|
||||
|
||||
How to install:
|
||||
|
||||
1. [Download the less.php source code](https://github.com/wikimedia/less.php/archive/master.zip) and unzip it so that 'lessc.inc.php' is located at 'sites/all/libraries/lessphp/lessc.inc.php'.
|
||||
2. Download and install [Drupal 7 less module](https://drupal.org/project/less) as usual.
|
||||
3. That's it :)
|
||||
|
||||
#### JBST WordPress theme
|
||||
|
||||
JBST has a built-in LESS compiler based on lessphp. Customize your WordPress theme with LESS.
|
||||
|
||||
How to use / install:
|
||||
|
||||
1. [Download the latest release](https://github.com/bassjobsen/jamedo-bootstrap-start-theme) copy the files to your {wordpress/}wp-content/themes folder and activate it.
|
||||
2. Find the compiler under Appearance > LESS Compiler in your WordPress dashboard
|
||||
3. Enter your LESS code in the text area and press (re)compile
|
||||
|
||||
Use the built-in compiler to:
|
||||
- set any [Bootstrap](http://getbootstrap.com/customize/) variable or use Bootstrap's mixins:
|
||||
-`@navbar-default-color: blue;`
|
||||
- create a custom button: `.btn-custom {
|
||||
.button-variant(white; red; blue);
|
||||
}`
|
||||
- set any built-in LESS variable: for example `@footer_bg_color: black;` sets the background color of the footer to black
|
||||
- use built-in mixins: - add a custom font: `.include-custom-font(@family: arial,@font-path, @path: @custom-font-dir, @weight: normal, @style: normal);`
|
||||
|
||||
The compiler can also be downloaded as [plugin](http://wordpress.org/plugins/wp-less-to-css/)
|
||||
|
||||
#### WordPress
|
||||
|
||||
This simple plugin will simply make the library available to other plugins and themes and can be used as a dependency using the [TGM Library](http://tgmpluginactivation.com/)
|
||||
|
||||
How to install:
|
||||
|
||||
1. Install the plugin from your WordPress Dashboard: http://wordpress.org/plugins/lessphp/
|
||||
2. That's it :)
|
||||
|
||||
|
||||
Transitioning from Leafo/lessphp
|
||||
---
|
||||
Projects looking for an easy transition from leafo/lessphp can use the lessc.inc.php adapter. To use, [Download the less.php source code](https://github.com/wikimedia/less.php/archive/master.zip) and unzip the files into your project so that the new 'lessc.inc.php' replaces the existing 'lessc.inc.php'.
|
||||
|
||||
Note, the 'setPreserveComments' will no longer have any effect on the compiled LESS.
|
||||
|
||||
Credits
|
||||
---
|
||||
less.php was originally ported to PHP by [Matt Agar](https://github.com/agar) and then updated by [Martin Jantošovič](https://github.com/Mordred). This Wikimedia-maintained fork was split off from [Josh Schmidt's version](https://github.com/oyejorge/less.php).
|
||||
|
191
less.php/bin/lessc
Executable file
191
less.php/bin/lessc
Executable file
|
@ -0,0 +1,191 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
require_once dirname(__FILE__) . '/../lib/Less/Autoloader.php';
|
||||
Less_Autoloader::register();
|
||||
|
||||
// Create our environment
|
||||
$env = array('compress' => false, 'relativeUrls' => false);
|
||||
$silent = false;
|
||||
$watch = false;
|
||||
$rootpath = '';
|
||||
|
||||
// Check for arguments
|
||||
array_shift($argv);
|
||||
if (!count($argv)) {
|
||||
$argv[] = '-h';
|
||||
}
|
||||
|
||||
// parse arguments
|
||||
foreach ($argv as $key => $arg) {
|
||||
if (preg_match('/^--?([a-z][0-9a-z-]*)(?:=([^\s]+))?$/i', $arg, $matches)) {
|
||||
$option = $matches[1];
|
||||
$value = isset($matches[2]) ? $matches[2] : false;
|
||||
unset($argv[$key]);
|
||||
|
||||
switch ($option) {
|
||||
case 'h':
|
||||
case 'help':
|
||||
echo <<<EOD
|
||||
Usage: lessc [options] sources [destination]
|
||||
|
||||
-h, --help Print help (this message) and exit.
|
||||
-s, --silent Suppress output of error messages.
|
||||
-v, --version Print version number and exit.
|
||||
-x, --compress Compress output by removing some whitespaces.
|
||||
--include-path=PATHS Set include paths. Separated by `:'. Use `;' on Windows.
|
||||
--strict-imports Force evaluation of imports.
|
||||
-sm=on|off Turn on or off strict math, where in strict mode, math
|
||||
--strict-math=on|off requires brackets. This option may default to on and then
|
||||
be removed in the future.
|
||||
-su=on|off Allow mixed units, e.g. 1px+1em or 1px*1px which have units
|
||||
--strict-units=on|off that cannot be represented.
|
||||
-ru, --relative-urls re-write relative urls to the base less file.
|
||||
-rp, --rootpath=URL Set rootpath for url rewriting in relative imports and urls.
|
||||
Works with or without the relative-urls option.
|
||||
-w, --watch Watch input files for changes.
|
||||
|
||||
|
||||
EOD;
|
||||
exit;
|
||||
case 's':
|
||||
case 'silent':
|
||||
$silent = true;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
case 'watch':
|
||||
$watch = true;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'version':
|
||||
echo "lessc " . Less_Version::version . " (less.php)\n\n";
|
||||
exit;
|
||||
|
||||
case 'rp':
|
||||
case 'rootpath':
|
||||
$rootpath = $value;
|
||||
break;
|
||||
|
||||
|
||||
//parser options
|
||||
case 'compress':
|
||||
$env['compress'] = true;
|
||||
break;
|
||||
|
||||
case 'ru':
|
||||
case 'relative-urls':
|
||||
$env['relativeUrls'] = true;
|
||||
break;
|
||||
|
||||
case 'su':
|
||||
case 'strict-units':
|
||||
$env['strictUnits'] = ($value === 'on');
|
||||
break;
|
||||
|
||||
case 'sm':
|
||||
case 'strict-math':
|
||||
$env['strictMath'] = ($value === 'on');
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
case 'include-path':
|
||||
$env['import_dirs'] = preg_split('#;|\:#', $value);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($argv) > 1) {
|
||||
$output = array_pop($argv);
|
||||
$inputs = $argv;
|
||||
}
|
||||
else {
|
||||
$inputs = $argv;
|
||||
$output = false;
|
||||
}
|
||||
|
||||
if (!count($inputs)) {
|
||||
echo("lessc: no input files\n");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($watch) {
|
||||
if (!$output) {
|
||||
echo("lessc: you must specify the output file if --watch is given\n");
|
||||
exit;
|
||||
}
|
||||
|
||||
$lastAction = 0;
|
||||
|
||||
echo("lessc: watching input files\n");
|
||||
|
||||
while (1) {
|
||||
clearstatcache();
|
||||
|
||||
$updated = false;
|
||||
foreach ($inputs as $input) {
|
||||
if ($input == '-') {
|
||||
if (count($inputs) == 1) {
|
||||
echo("lessc: during watching files is not possible to watch stdin\n");
|
||||
exit;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (filemtime($input) > $lastAction) {
|
||||
$updated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($updated) {
|
||||
$lastAction = time();
|
||||
$parser = new Less_Parser($env);
|
||||
foreach ($inputs as $input) {
|
||||
try {
|
||||
$parser->parseFile($input, $rootpath);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo("lessc: " . $e->getMessage() . " \n");
|
||||
continue; // Invalid processing
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents($output, $parser->getCss());
|
||||
echo("lessc: output file recompiled\n");
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$parser = new Less_Parser($env);
|
||||
foreach ($inputs as $input) {
|
||||
if ($input == '-') {
|
||||
$content = file_get_contents('php://stdin');
|
||||
$parser->parse($content);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$parser->parseFile($input);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
if (!$silent) {
|
||||
echo("lessc: " . ((string)$e) . " \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($output) {
|
||||
file_put_contents($output, $parser->getCss());
|
||||
}
|
||||
else {
|
||||
echo $parser->getCss();
|
||||
}
|
||||
}
|
49
less.php/composer.json
Normal file
49
less.php/composer.json
Normal file
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"name": "wikimedia/less.php",
|
||||
"description": "PHP port of the Javascript version of LESS http://lesscss.org (Originally maintained by Josh Schmidt)",
|
||||
"keywords": [ "less", "css", "php", "stylesheet", "less.js", "lesscss" ],
|
||||
"license": "Apache-2.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Josh Schmidt",
|
||||
"homepage": "https://github.com/oyejorge"
|
||||
},
|
||||
{
|
||||
"name": "Matt Agar",
|
||||
"homepage": "https://github.com/agar"
|
||||
},
|
||||
{
|
||||
"name": "Martin Jantošovič",
|
||||
"homepage": "https://github.com/Mordred"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.2.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"mediawiki/mediawiki-codesniffer": "34.0.0",
|
||||
"mediawiki/minus-x": "1.0.0",
|
||||
"php-parallel-lint/php-console-highlighter": "0.5.0",
|
||||
"php-parallel-lint/php-parallel-lint": "1.2.0",
|
||||
"phpunit/phpunit": "^8.5"
|
||||
},
|
||||
"scripts": {
|
||||
"test": [
|
||||
"parallel-lint . --exclude vendor",
|
||||
"phpcs -sp",
|
||||
"phpunit",
|
||||
"minus-x check ."
|
||||
],
|
||||
"fix": [
|
||||
"minus-x fix .",
|
||||
"phpcbf"
|
||||
]
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Less": "lib/" },
|
||||
"classmap": ["lessc.inc.php"]
|
||||
},
|
||||
"bin": [
|
||||
"bin/lessc"
|
||||
]
|
||||
}
|
274
less.php/lessc.inc.php
Normal file
274
less.php/lessc.inc.php
Normal file
|
@ -0,0 +1,274 @@
|
|||
<?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 );
|
||||
}
|
||||
}
|
2
less.php/lib/Less/.easymin/ignore_prefixes
Normal file
2
less.php/lib/Less/.easymin/ignore_prefixes
Normal file
|
@ -0,0 +1,2 @@
|
|||
.easymin
|
||||
Autoloader.php
|
77
less.php/lib/Less/Autoloader.php
Normal file
77
less.php/lib/Less/Autoloader.php
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Autoloader
|
||||
*
|
||||
* @package Less
|
||||
* @subpackage autoload
|
||||
*/
|
||||
class Less_Autoloader {
|
||||
|
||||
/**
|
||||
* Registered flag
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected static $registered = false;
|
||||
|
||||
/**
|
||||
* Library directory
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $libDir;
|
||||
|
||||
/**
|
||||
* Register the autoloader in the spl autoloader
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception If there was an error in registration
|
||||
*/
|
||||
public static function register() {
|
||||
if ( self::$registered ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$libDir = dirname( __FILE__ );
|
||||
|
||||
if ( false === spl_autoload_register( array( 'Less_Autoloader', 'loadClass' ) ) ) {
|
||||
throw new Exception( 'Unable to register Less_Autoloader::loadClass as an autoloading method.' );
|
||||
}
|
||||
|
||||
self::$registered = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the autoloader
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function unregister() {
|
||||
spl_autoload_unregister( array( 'Less_Autoloader', 'loadClass' ) );
|
||||
self::$registered = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the class
|
||||
*
|
||||
* @param string $className The class to load
|
||||
*/
|
||||
public static function loadClass( $className ) {
|
||||
// handle only package classes
|
||||
if ( strpos( $className, 'Less_' ) !== 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$className = substr( $className, 5 );
|
||||
$fileName = self::$libDir . DIRECTORY_SEPARATOR . str_replace( '_', DIRECTORY_SEPARATOR, $className ) . '.php';
|
||||
|
||||
if ( file_exists( $fileName ) ) {
|
||||
require $fileName;
|
||||
return true;
|
||||
} else {
|
||||
throw new Exception( 'file not loadable '.$fileName );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
293
less.php/lib/Less/Cache.php
Normal file
293
less.php/lib/Less/Cache.php
Normal file
|
@ -0,0 +1,293 @@
|
|||
<?php
|
||||
|
||||
require_once dirname( __FILE__ ).'/Version.php';
|
||||
|
||||
/**
|
||||
* Utility for handling the generation and caching of css files
|
||||
*
|
||||
* @package Less
|
||||
* @subpackage cache
|
||||
*
|
||||
*/
|
||||
class Less_Cache {
|
||||
|
||||
// directory less.php can use for storing data
|
||||
public static $cache_dir = false;
|
||||
|
||||
// prefix for the storing data
|
||||
public static $prefix = 'lessphp_';
|
||||
|
||||
// prefix for the storing vars
|
||||
public static $prefix_vars = 'lessphpvars_';
|
||||
|
||||
// specifies the number of seconds after which data created by less.php will be seen as 'garbage' and potentially cleaned up
|
||||
public static $gc_lifetime = 604800;
|
||||
|
||||
/**
|
||||
* Save and reuse the results of compiled less files.
|
||||
* The first call to Get() will generate css and save it.
|
||||
* Subsequent calls to Get() with the same arguments will return the same css filename
|
||||
*
|
||||
* @param array $less_files Array of .less files to compile
|
||||
* @param array $parser_options Array of compiler options
|
||||
* @param array $modify_vars Array of variables
|
||||
* @return string Name of the css file
|
||||
*/
|
||||
public static function Get( $less_files, $parser_options = array(), $modify_vars = array() ) {
|
||||
// check $cache_dir
|
||||
if ( isset( $parser_options['cache_dir'] ) ) {
|
||||
Less_Cache::$cache_dir = $parser_options['cache_dir'];
|
||||
}
|
||||
|
||||
if ( empty( Less_Cache::$cache_dir ) ) {
|
||||
throw new Exception( 'cache_dir not set' );
|
||||
}
|
||||
|
||||
if ( isset( $parser_options['prefix'] ) ) {
|
||||
Less_Cache::$prefix = $parser_options['prefix'];
|
||||
}
|
||||
|
||||
if ( empty( Less_Cache::$prefix ) ) {
|
||||
throw new Exception( 'prefix not set' );
|
||||
}
|
||||
|
||||
if ( isset( $parser_options['prefix_vars'] ) ) {
|
||||
Less_Cache::$prefix_vars = $parser_options['prefix_vars'];
|
||||
}
|
||||
|
||||
if ( empty( Less_Cache::$prefix_vars ) ) {
|
||||
throw new Exception( 'prefix_vars not set' );
|
||||
}
|
||||
|
||||
self::CheckCacheDir();
|
||||
$less_files = (array)$less_files;
|
||||
|
||||
// create a file for variables
|
||||
if ( !empty( $modify_vars ) ) {
|
||||
$lessvars = Less_Parser::serializeVars( $modify_vars );
|
||||
$vars_file = Less_Cache::$cache_dir . Less_Cache::$prefix_vars . sha1( $lessvars ) . '.less';
|
||||
|
||||
if ( !file_exists( $vars_file ) ) {
|
||||
file_put_contents( $vars_file, $lessvars );
|
||||
}
|
||||
|
||||
$less_files += array( $vars_file => '/' );
|
||||
}
|
||||
|
||||
// generate name for compiled css file
|
||||
$hash = md5( json_encode( $less_files ) );
|
||||
$list_file = Less_Cache::$cache_dir . Less_Cache::$prefix . $hash . '.list';
|
||||
|
||||
// check cached content
|
||||
if ( !isset( $parser_options['use_cache'] ) || $parser_options['use_cache'] === true ) {
|
||||
if ( file_exists( $list_file ) ) {
|
||||
|
||||
self::ListFiles( $list_file, $list, $cached_name );
|
||||
$compiled_name = self::CompiledName( $list, $hash );
|
||||
|
||||
// if $cached_name is the same as the $compiled name, don't regenerate
|
||||
if ( !$cached_name || $cached_name === $compiled_name ) {
|
||||
|
||||
$output_file = self::OutputFile( $compiled_name, $parser_options );
|
||||
|
||||
if ( $output_file && file_exists( $output_file ) ) {
|
||||
@touch( $list_file );
|
||||
return basename( $output_file ); // for backwards compatibility, we just return the name of the file
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$compiled = self::Cache( $less_files, $parser_options );
|
||||
if ( !$compiled ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$compiled_name = self::CompiledName( $less_files, $hash );
|
||||
$output_file = self::OutputFile( $compiled_name, $parser_options );
|
||||
|
||||
// save the file list
|
||||
$list = $less_files;
|
||||
$list[] = $compiled_name;
|
||||
$cache = implode( "\n", $list );
|
||||
file_put_contents( $list_file, $cache );
|
||||
|
||||
// save the css
|
||||
file_put_contents( $output_file, $compiled );
|
||||
|
||||
// clean up
|
||||
self::CleanCache();
|
||||
|
||||
return basename( $output_file );
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the compiler to regenerate the cached css file
|
||||
*
|
||||
* @param array $less_files Array of .less files to compile
|
||||
* @param array $parser_options Array of compiler options
|
||||
* @param array $modify_vars Array of variables
|
||||
* @return string Name of the css file
|
||||
*/
|
||||
public static function Regen( $less_files, $parser_options = array(), $modify_vars = array() ) {
|
||||
$parser_options['use_cache'] = false;
|
||||
return self::Get( $less_files, $parser_options, $modify_vars );
|
||||
}
|
||||
|
||||
public static function Cache( &$less_files, $parser_options = array() ) {
|
||||
// get less.php if it exists
|
||||
$file = dirname( __FILE__ ) . '/Less.php';
|
||||
if ( file_exists( $file ) && !class_exists( 'Less_Parser' ) ) {
|
||||
require_once $file;
|
||||
}
|
||||
|
||||
$parser_options['cache_dir'] = Less_Cache::$cache_dir;
|
||||
$parser = new Less_Parser( $parser_options );
|
||||
|
||||
// combine files
|
||||
foreach ( $less_files as $file_path => $uri_or_less ) {
|
||||
|
||||
// treat as less markup if there are newline characters
|
||||
if ( strpos( $uri_or_less, "\n" ) !== false ) {
|
||||
$parser->Parse( $uri_or_less );
|
||||
continue;
|
||||
}
|
||||
|
||||
$parser->ParseFile( $file_path, $uri_or_less );
|
||||
}
|
||||
|
||||
$compiled = $parser->getCss();
|
||||
|
||||
$less_files = $parser->allParsedFiles();
|
||||
|
||||
return $compiled;
|
||||
}
|
||||
|
||||
private static function OutputFile( $compiled_name, $parser_options ) {
|
||||
// custom output file
|
||||
if ( !empty( $parser_options['output'] ) ) {
|
||||
|
||||
// relative to cache directory?
|
||||
if ( preg_match( '#[\\\\/]#', $parser_options['output'] ) ) {
|
||||
return $parser_options['output'];
|
||||
}
|
||||
|
||||
return Less_Cache::$cache_dir.$parser_options['output'];
|
||||
}
|
||||
|
||||
return Less_Cache::$cache_dir.$compiled_name;
|
||||
}
|
||||
|
||||
private static function CompiledName( $files, $extrahash ) {
|
||||
// save the file list
|
||||
$temp = array( Less_Version::cache_version );
|
||||
foreach ( $files as $file ) {
|
||||
$temp[] = filemtime( $file )."\t".filesize( $file )."\t".$file;
|
||||
}
|
||||
|
||||
return Less_Cache::$prefix.sha1( json_encode( $temp ).$extrahash ).'.css';
|
||||
}
|
||||
|
||||
public static function SetCacheDir( $dir ) {
|
||||
Less_Cache::$cache_dir = $dir;
|
||||
self::CheckCacheDir();
|
||||
}
|
||||
|
||||
public static function CheckCacheDir() {
|
||||
Less_Cache::$cache_dir = str_replace( '\\', '/', Less_Cache::$cache_dir );
|
||||
Less_Cache::$cache_dir = rtrim( Less_Cache::$cache_dir, '/' ).'/';
|
||||
|
||||
if ( !file_exists( Less_Cache::$cache_dir ) ) {
|
||||
if ( !mkdir( Less_Cache::$cache_dir ) ) {
|
||||
throw new Less_Exception_Parser( 'Less.php cache directory couldn\'t be created: '.Less_Cache::$cache_dir );
|
||||
}
|
||||
|
||||
} elseif ( !is_dir( Less_Cache::$cache_dir ) ) {
|
||||
throw new Less_Exception_Parser( 'Less.php cache directory doesn\'t exist: '.Less_Cache::$cache_dir );
|
||||
|
||||
} elseif ( !is_writable( Less_Cache::$cache_dir ) ) {
|
||||
throw new Less_Exception_Parser( 'Less.php cache directory isn\'t writable: '.Less_Cache::$cache_dir );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete unused less.php files
|
||||
*
|
||||
*/
|
||||
public static function CleanCache() {
|
||||
static $clean = false;
|
||||
|
||||
if ( $clean || empty( Less_Cache::$cache_dir ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$clean = true;
|
||||
|
||||
// only remove files with extensions created by less.php
|
||||
// css files removed based on the list files
|
||||
$remove_types = array( 'lesscache' => 1,'list' => 1,'less' => 1,'map' => 1 );
|
||||
|
||||
$files = scandir( Less_Cache::$cache_dir );
|
||||
if ( !$files ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$check_time = time() - self::$gc_lifetime;
|
||||
foreach ( $files as $file ) {
|
||||
|
||||
// don't delete if the file wasn't created with less.php
|
||||
if ( strpos( $file, Less_Cache::$prefix ) !== 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parts = explode( '.', $file );
|
||||
$type = array_pop( $parts );
|
||||
|
||||
if ( !isset( $remove_types[$type] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$full_path = Less_Cache::$cache_dir . $file;
|
||||
$mtime = filemtime( $full_path );
|
||||
|
||||
// don't delete if it's a relatively new file
|
||||
if ( $mtime > $check_time ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// delete the list file and associated css file
|
||||
if ( $type === 'list' ) {
|
||||
self::ListFiles( $full_path, $list, $css_file_name );
|
||||
if ( $css_file_name ) {
|
||||
$css_file = Less_Cache::$cache_dir . $css_file_name;
|
||||
if ( file_exists( $css_file ) ) {
|
||||
unlink( $css_file );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unlink( $full_path );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of less files and generated css file from a list file
|
||||
*
|
||||
*/
|
||||
static function ListFiles( $list_file, &$list, &$css_file_name ) {
|
||||
$list = explode( "\n", file_get_contents( $list_file ) );
|
||||
|
||||
// pop the cached name that should match $compiled_name
|
||||
$css_file_name = array_pop( $list );
|
||||
|
||||
if ( !preg_match( '/^' . Less_Cache::$prefix . '[a-f0-9]+\.css$/', $css_file_name ) ) {
|
||||
$list[] = $css_file_name;
|
||||
$css_file_name = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
169
less.php/lib/Less/Colors.php
Normal file
169
less.php/lib/Less/Colors.php
Normal file
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Utility for css colors
|
||||
*
|
||||
* @package Less
|
||||
* @subpackage color
|
||||
*/
|
||||
class Less_Colors {
|
||||
|
||||
public static $colors = array(
|
||||
'aliceblue' => '#f0f8ff',
|
||||
'antiquewhite' => '#faebd7',
|
||||
'aqua' => '#00ffff',
|
||||
'aquamarine' => '#7fffd4',
|
||||
'azure' => '#f0ffff',
|
||||
'beige' => '#f5f5dc',
|
||||
'bisque' => '#ffe4c4',
|
||||
'black' => '#000000',
|
||||
'blanchedalmond' => '#ffebcd',
|
||||
'blue' => '#0000ff',
|
||||
'blueviolet' => '#8a2be2',
|
||||
'brown' => '#a52a2a',
|
||||
'burlywood' => '#deb887',
|
||||
'cadetblue' => '#5f9ea0',
|
||||
'chartreuse' => '#7fff00',
|
||||
'chocolate' => '#d2691e',
|
||||
'coral' => '#ff7f50',
|
||||
'cornflowerblue' => '#6495ed',
|
||||
'cornsilk' => '#fff8dc',
|
||||
'crimson' => '#dc143c',
|
||||
'cyan' => '#00ffff',
|
||||
'darkblue' => '#00008b',
|
||||
'darkcyan' => '#008b8b',
|
||||
'darkgoldenrod' => '#b8860b',
|
||||
'darkgray' => '#a9a9a9',
|
||||
'darkgrey' => '#a9a9a9',
|
||||
'darkgreen' => '#006400',
|
||||
'darkkhaki' => '#bdb76b',
|
||||
'darkmagenta' => '#8b008b',
|
||||
'darkolivegreen' => '#556b2f',
|
||||
'darkorange' => '#ff8c00',
|
||||
'darkorchid' => '#9932cc',
|
||||
'darkred' => '#8b0000',
|
||||
'darksalmon' => '#e9967a',
|
||||
'darkseagreen' => '#8fbc8f',
|
||||
'darkslateblue' => '#483d8b',
|
||||
'darkslategray' => '#2f4f4f',
|
||||
'darkslategrey' => '#2f4f4f',
|
||||
'darkturquoise' => '#00ced1',
|
||||
'darkviolet' => '#9400d3',
|
||||
'deeppink' => '#ff1493',
|
||||
'deepskyblue' => '#00bfff',
|
||||
'dimgray' => '#696969',
|
||||
'dimgrey' => '#696969',
|
||||
'dodgerblue' => '#1e90ff',
|
||||
'firebrick' => '#b22222',
|
||||
'floralwhite' => '#fffaf0',
|
||||
'forestgreen' => '#228b22',
|
||||
'fuchsia' => '#ff00ff',
|
||||
'gainsboro' => '#dcdcdc',
|
||||
'ghostwhite' => '#f8f8ff',
|
||||
'gold' => '#ffd700',
|
||||
'goldenrod' => '#daa520',
|
||||
'gray' => '#808080',
|
||||
'grey' => '#808080',
|
||||
'green' => '#008000',
|
||||
'greenyellow' => '#adff2f',
|
||||
'honeydew' => '#f0fff0',
|
||||
'hotpink' => '#ff69b4',
|
||||
'indianred' => '#cd5c5c',
|
||||
'indigo' => '#4b0082',
|
||||
'ivory' => '#fffff0',
|
||||
'khaki' => '#f0e68c',
|
||||
'lavender' => '#e6e6fa',
|
||||
'lavenderblush' => '#fff0f5',
|
||||
'lawngreen' => '#7cfc00',
|
||||
'lemonchiffon' => '#fffacd',
|
||||
'lightblue' => '#add8e6',
|
||||
'lightcoral' => '#f08080',
|
||||
'lightcyan' => '#e0ffff',
|
||||
'lightgoldenrodyellow' => '#fafad2',
|
||||
'lightgray' => '#d3d3d3',
|
||||
'lightgrey' => '#d3d3d3',
|
||||
'lightgreen' => '#90ee90',
|
||||
'lightpink' => '#ffb6c1',
|
||||
'lightsalmon' => '#ffa07a',
|
||||
'lightseagreen' => '#20b2aa',
|
||||
'lightskyblue' => '#87cefa',
|
||||
'lightslategray' => '#778899',
|
||||
'lightslategrey' => '#778899',
|
||||
'lightsteelblue' => '#b0c4de',
|
||||
'lightyellow' => '#ffffe0',
|
||||
'lime' => '#00ff00',
|
||||
'limegreen' => '#32cd32',
|
||||
'linen' => '#faf0e6',
|
||||
'magenta' => '#ff00ff',
|
||||
'maroon' => '#800000',
|
||||
'mediumaquamarine' => '#66cdaa',
|
||||
'mediumblue' => '#0000cd',
|
||||
'mediumorchid' => '#ba55d3',
|
||||
'mediumpurple' => '#9370d8',
|
||||
'mediumseagreen' => '#3cb371',
|
||||
'mediumslateblue' => '#7b68ee',
|
||||
'mediumspringgreen' => '#00fa9a',
|
||||
'mediumturquoise' => '#48d1cc',
|
||||
'mediumvioletred' => '#c71585',
|
||||
'midnightblue' => '#191970',
|
||||
'mintcream' => '#f5fffa',
|
||||
'mistyrose' => '#ffe4e1',
|
||||
'moccasin' => '#ffe4b5',
|
||||
'navajowhite' => '#ffdead',
|
||||
'navy' => '#000080',
|
||||
'oldlace' => '#fdf5e6',
|
||||
'olive' => '#808000',
|
||||
'olivedrab' => '#6b8e23',
|
||||
'orange' => '#ffa500',
|
||||
'orangered' => '#ff4500',
|
||||
'orchid' => '#da70d6',
|
||||
'palegoldenrod' => '#eee8aa',
|
||||
'palegreen' => '#98fb98',
|
||||
'paleturquoise' => '#afeeee',
|
||||
'palevioletred' => '#d87093',
|
||||
'papayawhip' => '#ffefd5',
|
||||
'peachpuff' => '#ffdab9',
|
||||
'peru' => '#cd853f',
|
||||