protected function compileValue($value)
{
$value = $this->reduce($value);
list($type) = $value;
switch ($type) {
case "keyword":
return $value[1];
case "color":
// [1] - red component (either number for a %)
// [2] - green component
// [3] - blue component
// [4] - optional alpha component
list(, $r, $g, $b) = $value;
$r = round($r);
$g = round($g);
$b = round($b);
if (count($value) == 5 && $value[4] != 1) {
// rgba
return 'rgba(' . $r . ', ' . $g . ', ' . $b . ', ' . $value[4] . ')';
}
$h = sprintf("#%02x%02x%02x", $r, $g, $b);
// Converting hex color to short notation (e.g. #003399 to #039)
if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) {
$h = '#' . $h[1] . $h[3] . $h[5];
}
return $h;
case "number":
return round($value[1], $this->numberPrecision) . $value[2];
case "string":
return $value[1] . $this->compileStringContent($value) . $value[1];
case "function":
$args = !empty($value[2]) ? $this->compileValue($value[2]) : "";
return "{$value['1']}({$args})";
case "list":
$value = $this->extractInterpolation($value);
if ($value[0] != "list") {
return $this->compileValue($value);
}
list(, $delim, $items) = $value;
$filtered = array();
foreach ($items as $item) {
if ($item[0] == "null") {
continue;
}
$filtered[] = $this->compileValue($item);
}
return implode("{$delim} ", $filtered);
case "interpolated":
# node created by extractInterpolation
list(, $interpolate, $left, $right) = $value;
list(, , $whiteLeft, $whiteRight) = $interpolate;
$left = count($left[2]) > 0 ? $this->compileValue($left) . $whiteLeft : "";
$right = count($right[2]) > 0 ? $whiteRight . $this->compileValue($right) : "";
return $left . $this->compileValue($interpolate) . $right;
case "interpolate":
# raw parse node
list(, $exp) = $value;
// strip quotes if it's a string
$reduced = $this->reduce($exp);
switch ($reduced[0]) {
case "string":
$reduced = array("keyword", $this->compileStringContent($reduced));
break;
case "null":
$reduced = array("keyword", "");
}
return $this->compileValue($reduced);
case "null":
return "null";
default:
$this->throwError("unknown value type: {$type}");
}
}