Skip to content

Commit

Permalink
Merge pull request #251 from okj579/maps
Browse files Browse the repository at this point in the history
Maps
  • Loading branch information
robocoder committed May 20, 2015
2 parents 75db452 + 9fc2d71 commit 3508eec
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 8 deletions.
91 changes: 90 additions & 1 deletion src/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,14 @@ protected function compileChild($child, $out)
$list = $this->coerceList($this->reduce($each->list));
foreach ($list[2] as $item) {
$this->pushEnv();
$this->set($each->var, $item);
if (count($each->vars) == 1) {
$this->set($each->vars[0], $item);
} else {
list(,,$values) = $this->coerceList($item);
foreach ($each->vars as $i => $var) {
$this->set($var, isset($values[$i]) ? $values[$i] : self::$null);
}
}
// TODO: allow return from here
$this->compileChildren($each->children, $out);
$this->popEnv();
Expand Down Expand Up @@ -1517,6 +1524,19 @@ protected function compileValue($value)
}

return implode("$delim ", $filtered);
case 'map':
$map = $value[1];

$filtered = array();
foreach ($map as $key => $item) {
if ($item[0] == 'null') {
continue;
}

$filtered[] = $key . ': ' . $this->compileValue($item);
}

return '(' . implode(", ", $filtered) . ')';
case 'interpolated': # node created by extractInterpolation
list(, $interpolate, $left, $right) = $value;
list(,, $whiteLeft, $whiteRight) = $interpolate;
Expand Down Expand Up @@ -1685,6 +1705,17 @@ protected function coerceList($item, $delim = ',')
return $item;
}

if (isset($item) && $item[0] == 'map') {
$map = $item[1];
$list = array();

foreach ($map as $key => $value) {
$list[] = array('list', '', array(array('keyword', $key), $value));
}

return array('list', ',', $list);
}

return array('list', $delim, !isset($item) ? array(): array($item));
}

Expand Down Expand Up @@ -2859,6 +2890,64 @@ protected function libNth($args)
return isset($list[2][$n]) ? $list[2][$n] : self::$defaultValue;
}

protected static $libMapGet = array('map', 'key');
protected function libMapGet($args)
{
$map = $args[0];
$key = $this->compileStringContent($this->coerceString($args[1]));

return isset($map[1][$key]) ? $map[1][$key] : self::$defaultValue;
}

protected static $libMapKeys = array('map');
protected function libMapKeys($args)
{
$map = $args[0][1];
$keys = array();
foreach (array_keys($map) as $key) {
$keys[] = array('keyword', $key);
}

return array('list', ',', $keys);
}

protected static $libMapValues = array('map');
protected function libMapValues($args)
{
$map = $args[0][1];

return array('list', ',', array_values($map));
}

protected static $libMapRemove = array('map', 'key');
protected function libMapRemove($args)
{
$map = $args[0][1];
$key = $this->compileStringContent($this->coerceString($args[1]));

unset($map[$key]);

return array('map', $map);
}

protected static $libMapHasKey = array('map', 'key');
protected function libMapHasKey($args)
{
$map = $args[0][1];
$key = $this->compileStringContent($this->coerceString($args[1]));

return isset($map[$key]) ? self::$true : self::$false;
}


protected static $libMapMerge = array('map-1', 'map-2');
protected function libMapMerge($args)
{
$map1 = $args[0][1];
$map2 = $args[1][1];

return array('map', array_merge($map1, $map2));
}
protected function listSeparatorForJoin($list1, $sep)
{
if (!isset($sep)) {
Expand Down
36 changes: 34 additions & 2 deletions src/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,15 @@ protected function parseChunk()
$this->seek($s);

if ($this->literal('@each') &&
$this->variable($varName) &&
$this->genericList($varNames, 'variable', ',', false) &&
$this->literal('in') &&
$this->valueList($list) &&
$this->literal('{')
) {
$each = $this->pushSpecialBlock('each');
$each->var = $varName[1];
foreach ($varNames[2] as $varName) {
$each->vars[] = $varName[1];
}
$each->list = $list;

return true;
Expand Down Expand Up @@ -783,6 +785,10 @@ protected function expression(&$out)
}

$this->seek($s);

if ($this->map($out)) {
return true;
}
}

if ($this->value($lhs)) {
Expand Down Expand Up @@ -1072,6 +1078,32 @@ protected function argumentDef(&$out)
return true;
}

protected function map(&$out)
{
$s = $this->seek();
$this->literal('(');

$map = array();

while ($this->keyword($key) && $this->literal(':') && $this->genericList($value, 'expression')) {
$map[$key] = $value;

if (!$this->literal(',')) {
break;
}
}

if (!count($map) || !$this->literal(')')) {
$this->seek($s);

return false;
}

$out = array('map', $map);

return true;
}

protected function color(&$out)
{
$color = array('color');
Expand Down
15 changes: 15 additions & 0 deletions tests/inputs/looping.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ div {
@each $var in $list {
border: $var;
}

@each $var in what what, is is, this this {
background: $var;
}

@each $var in (what: what, is: is, this: this) {
background: $var;
}

@each $header, $size, $nonexistent in (h1: 2em, h2: 1.5em, h3: 1.2em) {
#{$header} {
font-size: $size;
border: $nonexistent;
}
}
}


Expand Down
26 changes: 26 additions & 0 deletions tests/inputs/map.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
$map: (
color: black,
color2: red,
color3: #00FF00
);
$map2: (
color: rgb(255, 255, 255),
length: 40em
);

// Map functions
div {
color: map_get($map, color);
color: map_get($map, 'color#{2}');
foo: map_values($map);
bar: map_keys($map2);
baz: map_merge($map, $map2);
foo: map_remove($map2, color);
bar: if(map_has_key($map, color), true, false);
}

// List functions
div {
foo: nth($map, 1);
bar: nth(nth($map, 1), 1);
}
14 changes: 13 additions & 1 deletion tests/outputs/looping.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,19 @@ div {
background: this;
border: what;
border: is;
border: this; }
border: this;
background: what what;
background: is is;
background: this this;
background: what what;
background: is is;
background: this this; }
div h1 {
font-size: 2em; }
div h2 {
font-size: 1.5em; }
div h3 {
font-size: 1.2em; }

span {
color: 0;
Expand Down
12 changes: 12 additions & 0 deletions tests/outputs/map.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
div {
color: black;
color: red;
foo: black, red, #0f0;
bar: color, length;
baz: (color: #fff, color2: red, color3: #0f0, length: 40em);
foo: (length: 40em);
bar: true; }

div {
foo: color black;
bar: color; }
6 changes: 2 additions & 4 deletions tests/outputs/scss_css.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
@import url(foo.css);
@import "foo.css" screen;
@import "foo.css" screen, print;
@import "foo.css" screen, print and (foo: 0);
@import "foo.css" screen, only print, screen and (foo: 0);
@charset "UTF-8";
[foo~=bar] {
a: b; }
Expand Down Expand Up @@ -203,10 +205,6 @@ foo {
a: foo-bar(12);
b: -foo-bar-baz(13, 14 15); }

@import "foo.css" screen, print and (foo: 0);

@import "foo.css" screen, only print, screen and (foo: 0);

foo {
a: foo !important;
b: foo bar !important;
Expand Down

0 comments on commit 3508eec

Please sign in to comment.