Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@
],
"autoload": {
"classmap": ["lessc.inc.php"]
},
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
}
}
7 changes: 5 additions & 2 deletions docs/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,9 @@ function that let's you unquote any value. It is called `e`.
the alpha of the colors if it exists. See
<http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method>.

* `constrast(color, dark, light)` -- if `color` has a lightness value greater
than 50% then `dark` is returned, otherwise return `light`.

* `rgbahex(color)` -- returns a string containing 4 part hex color.

This is used to convert a CSS color into the hex format that IE's filter
Expand Down Expand Up @@ -1206,8 +1209,8 @@ like so:

```php
$less->registerFunction("double", function($arg) {
list($type, $value) = $arg;
return array($type, $value*2);
list($type, $value, $unit) = $arg;
return array($type, $value*2, $unit);
});
```

Expand Down
152 changes: 133 additions & 19 deletions lessc.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ protected function compileMediaQuery($queries) {
$parts[] = "($q[1])";
}
break;
case "variable":
$parts[] = $this->compileValue($this->reduce($q));
break;
}
}

Expand Down Expand Up @@ -436,7 +439,7 @@ protected function compileSelectors($selectors) {
foreach ($selectors as $s) {
if (is_array($s)) {
list(, $value) = $s;
$out[] = $this->compileValue($this->reduce($value));
$out[] = trim($this->compileValue($this->reduce($value)));
} else {
$out[] = $s;
}
Expand Down Expand Up @@ -858,6 +861,10 @@ protected function lib_isem($value) {
return $this->toBool($value[0] == "number" && $value[2] == "em");
}

protected function lib_isrem($value) {
return $this->toBool($value[0] == "number" && $value[2] == "rem");
}

protected function lib_rgbahex($color) {
$color = $this->coerceColor($color);
if (is_null($color))
Expand Down Expand Up @@ -934,6 +941,16 @@ protected function lib_round($arg) {
return array("number", round($value), $arg[2]);
}

protected function lib_unit($arg) {
if ($arg[0] == "list") {
list($number, $newUnit) = $arg[2];
return array("number", $this->assertNumber($number),
$this->compileValue($this->lib_e($newUnit)));
} else {
return array("number", $this->assertNumber($arg), "");
}
}

/**
* Helper function to get arguments for color manipulation functions.
* takes a list that contains a color like thing and a percentage
Expand Down Expand Up @@ -1073,6 +1090,25 @@ protected function lib_mix($args) {
return $this->fixColor($new);
}

protected function lib_contrast($args) {
if ($args[0] != 'list' || count($args[2]) < 3) {
return array(array('color', 0, 0, 0), 0);
}

list($inputColor, $darkColor, $lightColor) = $args[2];

$inputColor = $this->assertColor($inputColor);
$darkColor = $this->assertColor($darkColor);
$lightColor = $this->assertColor($lightColor);
$hsl = $this->toHSL($inputColor);

if ($hsl[3] > 50) {
return $darkColor;
}

return $lightColor;
}

protected function assertColor($value, $error = "expected color value") {
$color = $this->coerceColor($value);
if (is_null($color)) $this->throwError($error);
Expand Down Expand Up @@ -1223,6 +1259,14 @@ protected function funcToColor($func) {

protected function reduce($value, $forExpression = false) {
switch ($value[0]) {
case "interpolate":
$reduced = $this->reduce($value[1]);
$var = $this->compileValue($reduced);
$res = $this->reduce(array("variable", $this->vPrefix . $var));

if (empty($value[2])) $res = $this->lib_e($res);

return $res;
case "variable":
$key = $value[1];
if (is_array($key)) {
Expand Down Expand Up @@ -1343,8 +1387,12 @@ protected function coerceColor($value) {
case 'keyword':
$name = $value[1];
if (isset(self::$cssColors[$name])) {
list($r, $g, $b) = explode(',', self::$cssColors[$name]);
return array('color', $r, $g, $b);
$rgba = explode(',', self::$cssColors[$name]);

if(isset($rgba[3]))
return array('color', $rgba[0], $rgba[1], $rgba[2], $rgba[3]);

return array('color', $rgba[0], $rgba[1], $rgba[2]);
}
return null;
}
Expand Down Expand Up @@ -1489,6 +1537,34 @@ protected function op_color_color($op, $left, $right) {
return $this->fixColor($out);
}

function lib_red($color){
$color = $this->coerceColor($color);
if (is_null($color)) {
$this->throwError('color expected for red()');
}

return $color[1];
}

function lib_green($color){
$color = $this->coerceColor($color);
if (is_null($color)) {
$this->throwError('color expected for green()');
}

return $color[2];
}

function lib_blue($color){
$color = $this->coerceColor($color);
if (is_null($color)) {
$this->throwError('color expected for blue()');
}

return $color[3];
}


// operator on two numbers
protected function op_number_number($op, $left, $right) {
$unit = empty($left[2]) ? $right[2] : $left[2];
Expand Down Expand Up @@ -1993,6 +2069,7 @@ public static function cexecute($in, $force = false, $less = null) {
'teal' => '0,128,128',
'thistle' => '216,191,216',
'tomato' => '255,99,71',
'transparent' => '0,0,0,0',
'turquoise' => '64,224,208',
'violet' => '238,130,238',
'wheat' => '245,222,179',
Expand Down Expand Up @@ -2567,6 +2644,9 @@ protected function mediaExpression(&$out) {
$out = array("mediaExp", $feature);
if ($value) $out[] = $value;
return true;
} elseif ($this->variable($variable)) {
$out = array('variable', $variable);
return true;
}

$this->seek($s);
Expand Down Expand Up @@ -2620,12 +2700,11 @@ protected function openString($end, &$out, $nestingOpen=null, $rejectStrs = null
continue;
}

if (in_array($tok, $rejectStrs)) {
$count = null;
if (!empty($rejectStrs) && in_array($tok, $rejectStrs)) {
$ount = null;
break;
}


$content[] = $tok;
$this->count+= strlen($tok);
}
Expand Down Expand Up @@ -2700,10 +2779,10 @@ protected function interpolation(&$out) {

$s = $this->seek();
if ($this->literal("@{") &&
$this->keyword($var) &&
$this->openString("}", $interp, null, array("'", '"', ";")) &&
$this->literal("}", false))
{
$out = array("variable", $this->lessc->vPrefix . $var);
$out = array("interpolate", $interp);
$this->eatWhiteDefault = $oldWhite;
if ($this->eatWhiteDefault) $this->whitespace();
return true;
Expand Down Expand Up @@ -2877,38 +2956,73 @@ protected function tagExpression(&$value) {
return false;
}

// a single tag
// a space separated list of selectors
protected function tag(&$tag, $simple = false) {
if ($simple)
$chars = '^,:;{}\][>\(\) "\'';
$chars = '^@,:;{}\][>\(\) "\'';
else
$chars = '^,;{}["\'';
$chars = '^@,;{}["\'';

$s = $this->seek();

if (!$simple && $this->tagExpression($tag)) {
return true;
}

$tag = '';
while ($this->tagBracket($first)) $tag .= $first;
$hasExpression = false;
$parts = array();
while ($this->tagBracket($first)) $parts[] = $first;

$oldWhite = $this->eatWhiteDefault;
$this->eatWhiteDefault = false;

while (true) {
if ($this->match('(['.$chars.'0-9]['.$chars.']*)', $m)) {
$tag .= $m[1];
$parts[] = $m[1];
if ($simple) break;

while ($this->tagBracket($brack)) $tag .= $brack;
while ($this->tagBracket($brack)) {
$parts[] = $brack;
}
continue;
} elseif ($this->unit($unit)) { // for keyframes
$tag .= $unit[1] . $unit[2];
}

if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "@") {
if ($this->interpolation($interp)) {
$hasExpression = true;
$interp[2] = true; // don't unescape
$parts[] = $interp;
continue;
}

if ($this->literal("@")) {
$parts[] = "@";
continue;
}
}

if ($this->unit($unit)) { // for keyframes
$parts[] = $unit[1];
$parts[] = $unit[2];
continue;
}

break;
}

$this->eatWhiteDefault = $oldWhite;
if (!$parts) {
$this->seek($s);
return false;
}

$tag = trim($tag);
if ($tag == '') return false;
if ($hasExpression) {
$tag = array("exp", array("string", "", $parts));
} else {
$tag = trim(implode($parts));
}

$this->whitespace();
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion lessify
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/php -q
#!/usr/bin/php
<?php

if (php_sapi_name() != "cli") {
Expand Down
2 changes: 1 addition & 1 deletion plessc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env php -q
#!/usr/bin/env php
<?php
// Command line utility to compile LESS to STDOUT
// Leaf Corcoran <leafot@gmail.com>, 2012
Expand Down
8 changes: 8 additions & 0 deletions tests/inputs/builtins.less
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,11 @@ format {
}


#unit {
@unit: "em";
height: unit(10px);
height: unit(10px, "s");
height: unit(10px, @unit);
height: unit(0.07407s) * 100%;
}

16 changes: 15 additions & 1 deletion tests/inputs/colors.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@

body {
color:rgb(red(#f00), red(#0F0), red(#00f));
color:rgb(red(#f00), green(#0F0), blue(#00f));
color:rgb(red(#0ff), green(#f0f), blue(#ff0));

color: hsl(34, 50%, 40%);
color: hsla(34, 50%, 40%, 0.3);

Expand Down Expand Up @@ -85,6 +89,11 @@ fade {
color: mix(rgba(5,3,1,0.3), rgba(6,3,2, 0.8), 50%);
}

.contrast {
color: contrast(#000, red, blue);
color: contrast(#fff, red, blue);
}

.percent {
per: percentage(0.5);
}
Expand Down Expand Up @@ -135,5 +144,10 @@ dd {
c: 132- red;
}


.transparent {
r: red(transparent);
g: green(transparent);
b: blue(transparent);
a: alpha(transparent);
}

33 changes: 33 additions & 0 deletions tests/inputs/interpolation.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

@cool-hello: "yes";
@cool-yes: "okay";
@var: "hello";

div {
color: ~"@{cool-hello}";
color: ~"@{cool-@{var}}";
color: ~"@{cool-@{cool-@{var}}}";
}

// interpolation in selectors

@hello: 10;
@world: "yeah";

@{hello}@{world} {
color: blue;
}

@{hello} {
color: blue;
}

hello world @{hello} {
color: red;
}

#@{world} {
color: "hello @{hello}";
}


Loading