Sass - Version 1.1.4

Version Notes

Support of Magento CE 1.8
phpsass library updated.

Download this release

Release Info

Developer Laurent Clouet
Extension Sass
Version 1.1.4
Comparing to
See all releases


Code changes from version 1.1.3 to 1.1.4

Files changed (57) hide show
  1. app/code/community/Laurent/Sass/etc/config.xml +1 -1
  2. lib/phpsass/Extensions/Compass/Compass.php +25 -9
  3. lib/phpsass/Extensions/Own/Own.php +2 -1
  4. lib/phpsass/Extensions/Susy/Susy.php +2 -2
  5. lib/phpsass/Extensions/example.php +1 -5
  6. lib/phpsass/SassException.php +5 -3
  7. lib/phpsass/SassFile.php +20 -8
  8. lib/phpsass/SassParser.php +95 -60
  9. lib/phpsass/VERSION +2 -0
  10. lib/phpsass/renderers/SassCompactRenderer.php +25 -13
  11. lib/phpsass/renderers/SassCompressedRenderer.php +22 -11
  12. lib/phpsass/renderers/SassExpandedRenderer.php +14 -7
  13. lib/phpsass/renderers/SassNestedRenderer.php +17 -10
  14. lib/phpsass/renderers/SassRenderer.php +9 -7
  15. lib/phpsass/script/SassScriptFunction.php +35 -24
  16. lib/phpsass/script/SassScriptFunctions.php +155 -65
  17. lib/phpsass/script/SassScriptLexer.php +27 -31
  18. lib/phpsass/script/SassScriptOperation.php +17 -11
  19. lib/phpsass/script/SassScriptParser.php +27 -30
  20. lib/phpsass/script/SassScriptParserExceptions.php +1 -1
  21. lib/phpsass/script/SassScriptVariable.php +11 -7
  22. lib/phpsass/script/literals/SassBoolean.php +18 -12
  23. lib/phpsass/script/literals/SassColour.php +132 -103
  24. lib/phpsass/script/literals/SassList.php +38 -29
  25. lib/phpsass/script/literals/SassLiteral.php +78 -42
  26. lib/phpsass/script/literals/SassLiteralExceptions.php +1 -1
  27. lib/phpsass/script/literals/SassNumber.php +106 -69
  28. lib/phpsass/script/literals/SassString.php +30 -16
  29. lib/phpsass/tests/alt.css +15 -14
  30. lib/phpsass/tests/extend_included.css +0 -3
  31. lib/phpsass/tests/functions.css +9 -69
  32. lib/phpsass/tests/phpSassTest.php +134 -73
  33. lib/phpsass/tree/SassCommentNode.php +12 -6
  34. lib/phpsass/tree/SassContentNode.php +9 -4
  35. lib/phpsass/tree/SassContext.php +35 -20
  36. lib/phpsass/tree/SassDebugNode.php +9 -6
  37. lib/phpsass/tree/SassDirectiveNode.php +24 -16
  38. lib/phpsass/tree/SassEachNode.php +8 -5
  39. lib/phpsass/tree/SassElseNode.php +5 -3
  40. lib/phpsass/tree/SassExtendNode.php +8 -4
  41. lib/phpsass/tree/SassForNode.php +11 -7
  42. lib/phpsass/tree/SassFunctionDefinitionNode.php +13 -6
  43. lib/phpsass/tree/SassIfNode.php +19 -16
  44. lib/phpsass/tree/SassImportNode.php +10 -6
  45. lib/phpsass/tree/SassMediaNode.php +6 -4
  46. lib/phpsass/tree/SassMixinDefinitionNode.php +11 -5
  47. lib/phpsass/tree/SassMixinNode.php +8 -4
  48. lib/phpsass/tree/SassNode.php +89 -56
  49. lib/phpsass/tree/SassNodeExceptions.php +0 -1
  50. lib/phpsass/tree/SassPropertyNode.php +33 -21
  51. lib/phpsass/tree/SassReturnNode.php +15 -9
  52. lib/phpsass/tree/SassRootNode.php +17 -7
  53. lib/phpsass/tree/SassRuleNode.php +51 -37
  54. lib/phpsass/tree/SassVariableNode.php +10 -5
  55. lib/phpsass/tree/SassWarnNode.php +10 -8
  56. lib/phpsass/tree/SassWhileNode.php +9 -6
  57. package.xml +7 -6
app/code/community/Laurent/Sass/etc/config.xml CHANGED
@@ -14,7 +14,7 @@
14
  <config>
15
  <modules>
16
  <Laurent_Sass>
17
- <version>1.1.3</version>
18
  </Laurent_Sass>
19
  </modules>
20
  <global>
14
  <config>
15
  <modules>
16
  <Laurent_Sass>
17
+ <version>1.1.4</version>
18
  </Laurent_Sass>
19
  </modules>
20
  <global>
lib/phpsass/Extensions/Compass/Compass.php CHANGED
@@ -152,6 +152,7 @@ class Compass implements ExtensionInterface
152
  if ($path) {
153
  return $path;
154
  }
 
155
  return false;
156
  }
157
 
@@ -160,6 +161,7 @@ class Compass implements ExtensionInterface
160
  if ($info = self::compassImageInfo($file)) {
161
  return new SassNumber($info[0] . 'px');
162
  }
 
163
  return new SassNumber('0px');
164
  }
165
 
@@ -168,6 +170,7 @@ class Compass implements ExtensionInterface
168
  if ($info = self::compassImageInfo($file)) {
169
  return new SassNumber($info[1] . 'px');
170
  }
 
171
  return new SassNumber('0px');
172
  }
173
 
@@ -178,10 +181,10 @@ class Compass implements ExtensionInterface
178
  return $info;
179
  }
180
  }
 
181
  return false;
182
  }
183
 
184
-
185
  public static function compassInlineImage($file, $mime = null)
186
  {
187
  if ($path = self::compassUrl($file, true, false)) {
@@ -189,8 +192,10 @@ class Compass implements ExtensionInterface
189
  $mime = $info['mime'];
190
  $data = base64_encode(file_get_contents($path));
191
  # todo - do not return encoded if file size > 32kb
 
192
  return new SassString("url('data:$mime;base64,$data')");
193
  }
 
194
  return new SassString('');
195
  }
196
 
@@ -252,7 +257,7 @@ class Compass implements ExtensionInterface
252
  if (is_object($v)) {
253
  $string = (isset($v->value) ? $v->value : false);
254
  } else {
255
- $string = (string)$v;
256
  }
257
  if (empty($string) || $string == 'false') {
258
  unset($args[$k]);
@@ -260,6 +265,7 @@ class Compass implements ExtensionInterface
260
  }
261
  $list[] = $string;
262
  }
 
263
  return new SassString(implode($sep, $list));
264
  }
265
 
@@ -282,6 +288,7 @@ class Compass implements ExtensionInterface
282
  if (isset($list[$place])) {
283
  return current(SassScriptLexer::$instance->lex($list[$place], new SassContext()));
284
  }
 
285
  return new SassBoolean(false);
286
  }
287
 
@@ -292,6 +299,7 @@ class Compass implements ExtensionInterface
292
  foreach ($args as $arg) {
293
  $list = array_merge($list, self::compassList($arg));
294
  }
 
295
  return new SassString(implode(', ', $list));
296
  }
297
 
@@ -299,6 +307,7 @@ class Compass implements ExtensionInterface
299
  {
300
  $args = func_get_args();
301
  $list = self::compassList($args, ',');
 
302
  return new SassString(implode(' ', $list));
303
  }
304
 
@@ -306,6 +315,7 @@ class Compass implements ExtensionInterface
306
  {
307
  $args = func_get_args();
308
  $list = self::compassList($args, ',');
 
309
  return new SassNumber(count($list));
310
  }
311
 
@@ -315,6 +325,7 @@ class Compass implements ExtensionInterface
315
  $end = array_pop($args);
316
  $start = array_pop($args);
317
  $list = self::compassList($args, ',');
 
318
  return implode(',', array_slice($list, $start, $end));
319
  }
320
 
@@ -322,6 +333,7 @@ class Compass implements ExtensionInterface
322
  {
323
  $args = array();
324
  $args[] = 'first';
 
325
  return call_user_func_array('self::compassCompassNth', $args);
326
  }
327
 
@@ -366,6 +378,7 @@ class Compass implements ExtensionInterface
366
  }
367
  }
368
  $out[] = $stack;
 
369
  return $out;
370
  }
371
 
@@ -395,6 +408,7 @@ class Compass implements ExtensionInterface
395
  foreach ($list as $k => $selector) {
396
  $list[$k] = trim($selector) . $new;
397
  }
 
398
  return new SassString(implode(', ', $list));
399
  }
400
 
@@ -414,13 +428,14 @@ class Compass implements ExtensionInterface
414
  $to = 6;
415
  }
416
 
417
- $from = (int)$from;
418
- $to = (int)$to;
419
 
420
  $output = array();
421
  for ($i = $from; $i <= $to; $i++) {
422
  $output[] = 'h' . $i;
423
  }
 
424
  return new SassString(implode(', ', $output));
425
  }
426
 
@@ -459,7 +474,6 @@ class Compass implements ExtensionInterface
459
 
460
  public static function compassStylesheetUrl($path, $only_path = false)
461
  {
462
-
463
  return self::compassUrl($path, $only_path);
464
  }
465
 
@@ -489,6 +503,7 @@ class Compass implements ExtensionInterface
489
  if ($only_path) {
490
  return new SassString($path);
491
  }
 
492
  return new SassString("url('$path')");
493
  }
494
 
@@ -497,15 +512,16 @@ class Compass implements ExtensionInterface
497
  $ret = '';
498
  if ($from == 'top') {
499
  $ret = 'bottom';
500
- } else if ($from == 'bottom') {
501
  $ret = 'top';
502
- } else if ($from == 'left') {
503
  $ret = 'right';
504
- } else if ($from == 'right') {
505
  $ret = 'left';
506
- } else if ($from == 'center') {
507
  $ret = 'center';
508
  }
 
509
  return $ret;
510
  }
511
  }
152
  if ($path) {
153
  return $path;
154
  }
155
+
156
  return false;
157
  }
158
 
161
  if ($info = self::compassImageInfo($file)) {
162
  return new SassNumber($info[0] . 'px');
163
  }
164
+
165
  return new SassNumber('0px');
166
  }
167
 
170
  if ($info = self::compassImageInfo($file)) {
171
  return new SassNumber($info[1] . 'px');
172
  }
173
+
174
  return new SassNumber('0px');
175
  }
176
 
181
  return $info;
182
  }
183
  }
184
+
185
  return false;
186
  }
187
 
 
188
  public static function compassInlineImage($file, $mime = null)
189
  {
190
  if ($path = self::compassUrl($file, true, false)) {
192
  $mime = $info['mime'];
193
  $data = base64_encode(file_get_contents($path));
194
  # todo - do not return encoded if file size > 32kb
195
+
196
  return new SassString("url('data:$mime;base64,$data')");
197
  }
198
+
199
  return new SassString('');
200
  }
201
 
257
  if (is_object($v)) {
258
  $string = (isset($v->value) ? $v->value : false);
259
  } else {
260
+ $string = (string) $v;
261
  }
262
  if (empty($string) || $string == 'false') {
263
  unset($args[$k]);
265
  }
266
  $list[] = $string;
267
  }
268
+
269
  return new SassString(implode($sep, $list));
270
  }
271
 
288
  if (isset($list[$place])) {
289
  return current(SassScriptLexer::$instance->lex($list[$place], new SassContext()));
290
  }
291
+
292
  return new SassBoolean(false);
293
  }
294
 
299
  foreach ($args as $arg) {
300
  $list = array_merge($list, self::compassList($arg));
301
  }
302
+
303
  return new SassString(implode(', ', $list));
304
  }
305
 
307
  {
308
  $args = func_get_args();
309
  $list = self::compassList($args, ',');
310
+
311
  return new SassString(implode(' ', $list));
312
  }
313
 
315
  {
316
  $args = func_get_args();
317
  $list = self::compassList($args, ',');
318
+
319
  return new SassNumber(count($list));
320
  }
321
 
325
  $end = array_pop($args);
326
  $start = array_pop($args);
327
  $list = self::compassList($args, ',');
328
+
329
  return implode(',', array_slice($list, $start, $end));
330
  }
331
 
333
  {
334
  $args = array();
335
  $args[] = 'first';
336
+
337
  return call_user_func_array('self::compassCompassNth', $args);
338
  }
339
 
378
  }
379
  }
380
  $out[] = $stack;
381
+
382
  return $out;
383
  }
384
 
408
  foreach ($list as $k => $selector) {
409
  $list[$k] = trim($selector) . $new;
410
  }
411
+
412
  return new SassString(implode(', ', $list));
413
  }
414
 
428
  $to = 6;
429
  }
430
 
431
+ $from = (int) $from;
432
+ $to = (int) $to;
433
 
434
  $output = array();
435
  for ($i = $from; $i <= $to; $i++) {
436
  $output[] = 'h' . $i;
437
  }
438
+
439
  return new SassString(implode(', ', $output));
440
  }
441
 
474
 
475
  public static function compassStylesheetUrl($path, $only_path = false)
476
  {
 
477
  return self::compassUrl($path, $only_path);
478
  }
479
 
503
  if ($only_path) {
504
  return new SassString($path);
505
  }
506
+
507
  return new SassString("url('$path')");
508
  }
509
 
512
  $ret = '';
513
  if ($from == 'top') {
514
  $ret = 'bottom';
515
+ } elseif ($from == 'bottom') {
516
  $ret = 'top';
517
+ } elseif ($from == 'left') {
518
  $ret = 'right';
519
+ } elseif ($from == 'right') {
520
  $ret = 'left';
521
+ } elseif ($from == 'center') {
522
  $ret = 'center';
523
  }
524
+
525
  return $ret;
526
  }
527
  }
lib/phpsass/Extensions/Own/Own.php CHANGED
@@ -84,7 +84,8 @@ class Own implements ExtensionInterface
84
  }
85
  }
86
 
87
- public static function ownDemoFunction(){
 
88
  return new SassString("'This is my own Demo Function'");
89
  }
90
  }
84
  }
85
  }
86
 
87
+ public static function ownDemoFunction()
88
+ {
89
  return new SassString("'This is my own Demo Function'");
90
  }
91
  }
lib/phpsass/Extensions/Susy/Susy.php CHANGED
@@ -13,7 +13,6 @@ class Susy implements ExtensionInterface
13
 
14
  public static function getFunctions($namespace)
15
  {
16
-
17
  return array();
18
  }
19
 
@@ -51,6 +50,7 @@ class Susy implements ExtensionInterface
51
  closedir($handle);
52
  }
53
  }
 
54
  return $alias;
55
  }
56
 
@@ -72,4 +72,4 @@ class Susy implements ExtensionInterface
72
  return self::$filePaths[$alias];
73
  }
74
  }
75
- }
13
 
14
  public static function getFunctions($namespace)
15
  {
 
16
  return array();
17
  }
18
 
50
  closedir($handle);
51
  }
52
  }
53
+
54
  return $alias;
55
  }
56
 
72
  return self::$filePaths[$alias];
73
  }
74
  }
75
+ }
lib/phpsass/Extensions/example.php CHANGED
@@ -15,10 +15,10 @@ function loadCallback($file, $parser)
15
 
16
  }
17
  }
 
18
  return $paths;
19
  }
20
 
21
-
22
  function getFunctions($extensions)
23
  {
24
  $output = array();
@@ -42,14 +42,12 @@ function getFunctions($extensions)
42
  return $output;
43
  }
44
 
45
-
46
  $file = 'example.scss';
47
  $path = '../';
48
  $library = $path . '/SassParser.php';
49
 
50
  if ($path && file_exists($library)) {
51
 
52
-
53
  try {
54
  require_once ($library);
55
 
@@ -82,5 +80,3 @@ if ($path && file_exists($library)) {
82
  } else {
83
  echo 'Path or library are wrong';
84
  }
85
-
86
-
15
 
16
  }
17
  }
18
+
19
  return $paths;
20
  }
21
 
 
22
  function getFunctions($extensions)
23
  {
24
  $output = array();
42
  return $output;
43
  }
44
 
 
45
  $file = 'example.scss';
46
  $path = '../';
47
  $library = $path . '/SassParser.php';
48
 
49
  if ($path && file_exists($library)) {
50
 
 
51
  try {
52
  require_once ($library);
53
 
80
  } else {
81
  echo 'Path or library are wrong';
82
  }
 
 
lib/phpsass/SassException.php CHANGED
@@ -14,14 +14,16 @@
14
  * @package PHamlP
15
  * @subpackage Sass
16
  */
17
- class SassException extends Exception {
 
18
  /**
19
  * Sass Exception.
20
  * @param string Exception message
21
  * @param array parameters to be applied to the message using <code>strtr</code>.
22
  * @param object object with source code and meta data
23
  */
24
- public function __construct($message, $object) {
 
25
  parent::__construct($message . (is_object($object) ? ": {$object->filename}::{$object->line}\nSource: {$object->source}" : ''));
26
  }
27
- }
14
  * @package PHamlP
15
  * @subpackage Sass
16
  */
17
+ class SassException extends Exception
18
+ {
19
  /**
20
  * Sass Exception.
21
  * @param string Exception message
22
  * @param array parameters to be applied to the message using <code>strtr</code>.
23
  * @param object object with source code and meta data
24
  */
25
+ public function __construct($message, $object)
26
+ {
27
  parent::__construct($message . (is_object($object) ? ": {$object->filename}::{$object->line}\nSource: {$object->source}" : ''));
28
  }
29
+ }
lib/phpsass/SassFile.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass
17
  */
18
- class SassFile {
 
19
  const CSS = 'css';
20
  const SASS = 'sass';
21
  const SCSS = 'scss';
@@ -32,7 +33,8 @@ class SassFile {
32
  * @param SassParser Sass parser
33
  * @return SassRootNode
34
  */
35
- public static function get_tree($filename, &$parser) {
 
36
  $contents = self::get_file_contents($filename, $parser);
37
 
38
  $options = array_merge($parser->options, array('line'=>1));
@@ -51,10 +53,12 @@ class SassFile {
51
 
52
  $sassParser = new SassParser($options);
53
  $tree = $sassParser->parse($contents, FALSE);
 
54
  return $tree;
55
  }
56
 
57
- public static function get_file_contents($filename, $parser) {
 
58
  $contents = file_get_contents($filename) . "\n\n "; #add some whitespace to fix bug
59
  # strip // comments at this stage, with allowances for http:// style locations.
60
  $contents = preg_replace("/(^|\s)\/\/[^\n]+/", '', $contents);
@@ -64,12 +68,14 @@ class SassFile {
64
  return $contents;
65
  }
66
 
67
- public static function resolve_paths($matches) {
 
68
  // Resolve the path into something nicer...
69
  return 'url("' . self::resolve_path($matches[1]) . '")';
70
  }
71
 
72
- public static function resolve_path($name) {
 
73
  $path = self::$parser->basepath . self::$path;
74
  $path = substr($path, 0, strrpos($path, '/')) . '/';
75
  $path = $path . $name;
@@ -78,6 +84,7 @@ class SassFile {
78
  $last = $path;
79
  $path = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $path);
80
  }
 
81
  return $path;
82
  }
83
 
@@ -90,18 +97,20 @@ class SassFile {
90
  * @param SassParser Sass parser
91
  * @return array of string path(s) to file(s) or FALSE if no such file
92
  */
93
- public static function get_file($filename, &$parser, $sass_only = TRUE) {
 
94
  $ext = substr($filename, strrpos($filename, '.') + 1);
95
  // if the last char isn't *, and it's not (.sass|.scss|.css)
96
  if ($sass_only && substr($filename, -1) != '*' && $ext !== self::SASS && $ext !== self::SCSS && $ext !== self::CSS) {
97
  $sass = self::get_file($filename . '.' . self::SASS, $parser);
 
98
  return $sass ? $sass : self::get_file($filename . '.' . self::SCSS, $parser);
99
  }
100
  if (file_exists($filename)) {
101
  return array($filename);
102
  }
103
  $paths = $parser->load_paths;
104
- if(is_string($parser->filename) && $path = dirname($parser->filename)) {
105
  $paths[] = $path;
106
  if (!in_array($path, $parser->load_paths)) {
107
  $parser->load_paths[] = $path;
@@ -118,6 +127,7 @@ class SassFile {
118
  return $paths;
119
  }
120
  }
 
121
  return FALSE;
122
  }
123
 
@@ -128,7 +138,8 @@ class SassFile {
128
  * @param string path to directory to look in and under
129
  * @return mixed string: full path to file if found, false if not
130
  */
131
- public static function find_file($filename, $dir) {
 
132
  $partialname = dirname($filename).DIRECTORY_SEPARATOR.'_'.basename($filename);
133
 
134
  foreach (array($filename, $partialname) as $file) {
@@ -149,6 +160,7 @@ class SassFile {
149
  }
150
  }
151
  }
 
152
  return false;
153
  }
154
  }
15
  * @package PHamlP
16
  * @subpackage Sass
17
  */
18
+ class SassFile
19
+ {
20
  const CSS = 'css';
21
  const SASS = 'sass';
22
  const SCSS = 'scss';
33
  * @param SassParser Sass parser
34
  * @return SassRootNode
35
  */
36
+ public static function get_tree($filename, &$parser)
37
+ {
38
  $contents = self::get_file_contents($filename, $parser);
39
 
40
  $options = array_merge($parser->options, array('line'=>1));
53
 
54
  $sassParser = new SassParser($options);
55
  $tree = $sassParser->parse($contents, FALSE);
56
+
57
  return $tree;
58
  }
59
 
60
+ public static function get_file_contents($filename, $parser)
61
+ {
62
  $contents = file_get_contents($filename) . "\n\n "; #add some whitespace to fix bug
63
  # strip // comments at this stage, with allowances for http:// style locations.
64
  $contents = preg_replace("/(^|\s)\/\/[^\n]+/", '', $contents);
68
  return $contents;
69
  }
70
 
71
+ public static function resolve_paths($matches)
72
+ {
73
  // Resolve the path into something nicer...
74
  return 'url("' . self::resolve_path($matches[1]) . '")';
75
  }
76
 
77
+ public static function resolve_path($name)
78
+ {
79
  $path = self::$parser->basepath . self::$path;
80
  $path = substr($path, 0, strrpos($path, '/')) . '/';
81
  $path = $path . $name;
84
  $last = $path;
85
  $path = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $path);
86
  }
87
+
88
  return $path;
89
  }
90
 
97
  * @param SassParser Sass parser
98
  * @return array of string path(s) to file(s) or FALSE if no such file
99
  */
100
+ public static function get_file($filename, &$parser, $sass_only = TRUE)
101
+ {
102
  $ext = substr($filename, strrpos($filename, '.') + 1);
103
  // if the last char isn't *, and it's not (.sass|.scss|.css)
104
  if ($sass_only && substr($filename, -1) != '*' && $ext !== self::SASS && $ext !== self::SCSS && $ext !== self::CSS) {
105
  $sass = self::get_file($filename . '.' . self::SASS, $parser);
106
+
107
  return $sass ? $sass : self::get_file($filename . '.' . self::SCSS, $parser);
108
  }
109
  if (file_exists($filename)) {
110
  return array($filename);
111
  }
112
  $paths = $parser->load_paths;
113
+ if (is_string($parser->filename) && $path = dirname($parser->filename)) {
114
  $paths[] = $path;
115
  if (!in_array($path, $parser->load_paths)) {
116
  $parser->load_paths[] = $path;
127
  return $paths;
128
  }
129
  }
130
+
131
  return FALSE;
132
  }
133
 
138
  * @param string path to directory to look in and under
139
  * @return mixed string: full path to file if found, false if not
140
  */
141
+ public static function find_file($filename, $dir)
142
+ {
143
  $partialname = dirname($filename).DIRECTORY_SEPARATOR.'_'.basename($filename);
144
 
145
  foreach (array($filename, $partialname) as $file) {
160
  }
161
  }
162
  }
163
+
164
  return false;
165
  }
166
  }
lib/phpsass/SassParser.php CHANGED
@@ -22,9 +22,9 @@
22
  * @subpackage Sass
23
  */
24
 
25
- require_once('SassFile.php');
26
- require_once('SassException.php');
27
- require_once('tree/SassNode.php');
28
 
29
  /**
30
  * SassParser class.
@@ -32,7 +32,8 @@ require_once('tree/SassNode.php');
32
  * @package PHamlP
33
  * @subpackage Sass
34
  */
35
- class SassParser {
 
36
  /**#@+
37
  * Default option values
38
  */
@@ -51,7 +52,7 @@ class SassParser {
51
  /**
52
  * Static holder for last instance of a SassParser
53
  */
54
- static public $instance;
55
 
56
  /**
57
  * @var string the character used for indenting
@@ -80,7 +81,6 @@ class SassParser {
80
 
81
  public $basepath;
82
 
83
-
84
  /**
85
  * debug_info:
86
  * @var boolean When true the line number and file where a selector is defined
@@ -220,7 +220,8 @@ class SassParser {
220
  * @param array $options
221
  * @return SassParser
222
  */
223
- public function __construct($options = array()) {
 
224
  if (!is_array($options)) {
225
  if (isset($options['debug']) && $options['debug']) {
226
  throw new SassException('Options must be an array');
@@ -282,7 +283,8 @@ class SassParser {
282
  * @param string name of property to get
283
  * @return mixed return value of getter function
284
  */
285
- public function __get($name) {
 
286
  $getter = 'get' . ucfirst($name);
287
  if (method_exists($this, $getter)) {
288
  return $this->$getter();
@@ -295,70 +297,86 @@ class SassParser {
295
  }
296
  }
297
 
298
- public function getBasepath() {
 
299
  return $this->basepath;
300
  }
301
 
302
- public function getDebug_info() {
 
303
  return $this->debug_info;
304
  }
305
 
306
- public function getFilename() {
 
307
  return $this->filename;
308
  }
309
 
310
- public function getLine() {
 
311
  return $this->line;
312
  }
313
 
314
- public function getSource() {
 
315
  return $this->source;
316
  }
317
 
318
- public function getLine_numbers() {
 
319
  return $this->line_numbers;
320
  }
321
 
322
- public function getFunctions() {
 
323
  return self::$functions;
324
  }
325
 
326
- public function getLoad_paths() {
 
327
  return $this->load_paths;
328
  }
329
 
330
- public function getLoad_path_functions() {
 
331
  return $this->load_path_functions;
332
  }
333
 
334
- public function getProperty_syntax() {
 
335
  return $this->property_syntax;
336
  }
337
 
338
- public function getQuiet() {
 
339
  return $this->quiet;
340
  }
341
 
342
- public function getStyle() {
 
343
  return $this->style;
344
  }
345
 
346
- public function getSyntax() {
 
347
  return $this->syntax;
348
  }
349
 
350
- public function getDebug() {
 
351
  return $this->debug;
352
  }
353
 
354
- public function getCallbacks() {
 
355
  return $this->callbacks + array(
356
  'warn' => NULL,
357
  'debug' => NULL,
358
  );
359
  }
360
 
361
- public function getOptions() {
 
362
  return array(
363
  'callbacks' => $this->callbacks,
364
  // 'debug' => $this->debug,
@@ -380,7 +398,8 @@ class SassParser {
380
  * @param string name of source file or Sass source
381
  * @return string CSS
382
  */
383
- public function toCss($source, $isFile = true) {
 
384
  return $this->parse($source, $isFile)->render();
385
  }
386
 
@@ -392,7 +411,8 @@ class SassParser {
392
  * @param string name of source file or Sass source
393
  * @return SassRootNode Root node of document tree
394
  */
395
- public function parse($source, $isFile = true) {
 
396
  # Richard Lyon - 2011-10-25 - ignore unfound files
397
  # Richard Lyon - 2011-10-25 - add multiple files to load functions
398
  if (!$source) {
@@ -402,22 +422,23 @@ class SassParser {
402
  if (is_array($source)) {
403
  $return = null;
404
  foreach ($source as $key => $value) {
405
- if(is_numeric($key)){
406
  $code = $value;
407
  $type = true;
408
  } else {
409
  $code = $key;
410
  $type = $value;
411
  }
412
- if($return===null){
413
  $return = $this->parse($code, $type);
414
  } else {
415
  $newNode = $this->parse($code, $type);
416
- foreach($newNode->children as $children){
417
  array_push($return->children, $children);
418
  }
419
  }
420
  }
 
421
  return $return;
422
  }
423
 
@@ -426,9 +447,9 @@ class SassParser {
426
  foreach ($files as $file) {
427
  $this->filename = $file;
428
  $this->syntax = substr(strrchr($file, '.'), 1);
429
- if($this->syntax == SassFile::CSS){
430
  $this->property_syntax = "css";
431
- }elseif (!$this->property_syntax && $this->syntax == SassFile::SCSS) {
432
  $this->property_syntax = "scss";
433
  }
434
 
@@ -436,13 +457,14 @@ class SassParser {
436
  if ($this->debug) {
437
  throw new SassException('Invalid {what}', array('{what}' => 'syntax option'));
438
  }
 
439
  return FALSE;
440
  }
441
  $files_source .= SassFile::get_file_contents($this->filename, $this);
442
  }
 
443
  return $this->toTree($files_source);
444
- }
445
- else {
446
  return $this->toTree($source);
447
  }
448
  }
@@ -453,18 +475,19 @@ class SassParser {
453
  * @param string Sass source
454
  * @return SassRootNode the root of this document tree
455
  */
456
- public function toTree($source) {
 
457
  if ($this->syntax === SassFile::SASS) {
458
  $source = str_replace(array("\r\n", "\n\r", "\r"), "\n", $source);
459
  $this->source = explode("\n", $source);
460
  $this->setIndentChar();
461
- }
462
- else {
463
  $this->source = $source;
464
  }
465
  unset($source);
466
  $root = new SassRootNode($this);
467
  $this->buildTree($root);
 
468
  return $root;
469
  }
470
 
@@ -473,12 +496,14 @@ class SassParser {
473
  * Called recursivly until the source is parsed.
474
  * @param SassNode the node
475
  */
476
- public function buildTree($parent) {
 
477
  $node = $this->getNode($parent);
478
  while (is_object($node) && $node->isChildOf($parent)) {
479
  $parent->addChild($node);
480
  $node = $this->buildTree($node);
481
  }
 
482
  return $node;
483
  }
484
 
@@ -488,7 +513,8 @@ class SassParser {
488
  * @return SassNode a SassNode of the appropriate type. Null when no more
489
  * source to parse.
490
  */
491
- public function getNode($node) {
 
492
  $token = $this->getToken();
493
  if (empty($token)) return null;
494
  switch (true) {
@@ -507,9 +533,9 @@ class SassParser {
507
  if ($this->debug) {
508
  throw new SassException('Mixin definition shortcut not allowed in SCSS', $this);
509
  }
 
510
  return;
511
- }
512
- else {
513
  return new SassMixinDefinitionNode($token);
514
  }
515
  case SassMixinNode::isa($token):
@@ -517,9 +543,9 @@ class SassParser {
517
  if ($this->debug) {
518
  throw new SassException('Mixin include shortcut not allowed in SCSS', $this);
519
  }
 
520
  return;
521
- }
522
- else {
523
  return new SassMixinNode($token);
524
  }
525
  default:
@@ -533,7 +559,8 @@ class SassParser {
533
  * meta data about it.
534
  * @return object
535
  */
536
- public function getToken() {
 
537
  return ($this->syntax === SassFile::SASS ? $this->sass2Token() : $this->scss2Token());
538
  }
539
 
@@ -544,7 +571,8 @@ class SassParser {
544
  * CSS comments and selectors, are assembled into a single statement.
545
  * @return object Statement token. Null if end of source.
546
  */
547
- public function sass2Token() {
 
548
  $statement = ''; // source line being tokenised
549
  $token = null;
550
 
@@ -566,7 +594,7 @@ class SassParser {
566
  // Consume Sass comments
567
  if (substr($statement, 0, strlen(self::BEGIN_SASS_COMMENT)) === self::BEGIN_SASS_COMMENT) {
568
  unset($statement);
569
- while($this->getLevel($this->source[0]) > $level) {
570
  array_shift($this->source);
571
  $this->line++;
572
  }
@@ -575,12 +603,11 @@ class SassParser {
575
  // Build CSS comments
576
  elseif (substr($statement, 0, strlen(self::BEGIN_CSS_COMMENT))
577
  === self::BEGIN_CSS_COMMENT) {
578
- while($this->getLevel($this->source[0]) > $level) {
579
  $statement .= "\n" . ltrim(array_shift($this->source));
580
  $this->line++;
581
  }
582
- }
583
- else {
584
  $this->source = $statement;
585
 
586
  if ($this->debug) {
@@ -591,7 +618,7 @@ class SassParser {
591
  // Selector statements can span multiple lines
592
  elseif (substr($statement, -1) === SassRuleNode::CONTINUED) {
593
  // Build the selector statement
594
- while($this->getLevel($this->source[0]) === $level) {
595
  $statement .= ltrim(array_shift($this->source));
596
  $this->line++;
597
  }
@@ -604,6 +631,7 @@ class SassParser {
604
  'line' => $this->line - 1,
605
  );
606
  }
 
607
  return $token;
608
  }
609
 
@@ -614,7 +642,8 @@ class SassParser {
614
  * @return integer the level of the source
615
  * @throws Exception if the source indentation is invalid
616
  */
617
- public function getLevel($source) {
 
618
  $indent = strlen($source) - strlen(ltrim($source));
619
  $level = $indent/$this->indentSpaces;
620
  if (is_float($level)) {
@@ -625,11 +654,11 @@ class SassParser {
625
 
626
  if ($this->debug) {
627
  throw new SassException('Invalid indentation', $this);
628
- }
629
- else {
630
  return 0;
631
  }
632
  }
 
633
  return $level;
634
  }
635
 
@@ -638,7 +667,8 @@ class SassParser {
638
  * about it from SCSS source.
639
  * @return object Statement token. Null if end of source.
640
  */
641
- public function scss2Token() {
 
642
  static $srcpos = 0; // current position in the source stream
643
  static $srclen; // the length of the source stream
644
 
@@ -661,8 +691,7 @@ class SassParser {
661
  ));
662
  }
663
  $statement .= "\n";
664
- }
665
- elseif (substr($this->source, $srcpos-1, strlen(self::BEGIN_CSS_COMMENT)) === self::BEGIN_CSS_COMMENT) {
666
  if (ltrim($statement)) {
667
  if ($this->debug) {
668
  throw new SassException('Invalid comment', (object) array(
@@ -678,8 +707,7 @@ class SassParser {
678
  }
679
  $srcpos += strlen(self::END_CSS_COMMENT);
680
  $token = $this->createToken($statement.self::END_CSS_COMMENT);
681
- }
682
- else {
683
  $statement .= $c;
684
  }
685
  break;
@@ -730,7 +758,8 @@ class SassParser {
730
  * @param string source statement
731
  * @return SassToken
732
  */
733
- public function createToken($statement) {
 
734
  static $level = 0;
735
 
736
  $this->line += substr_count($statement, "\n");
@@ -749,6 +778,7 @@ class SassParser {
749
  'line' => $this->line,
750
  ) : null);
751
  $level += ($last === self::BEGIN_BLOCK ? 1 : ($last === self::END_BLOCK ? -1 : 0));
 
752
  return $token;
753
  }
754
 
@@ -758,7 +788,8 @@ class SassParser {
758
  * @param SassNode parent node
759
  * @return SassNode a Sass directive node
760
  */
761
- public function parseDirective($token, $parent) {
 
762
  switch (SassDirectiveNode::extractDirective($token)) {
763
  case '@content':
764
  return new SassContentNode($token);
@@ -794,6 +825,7 @@ class SassParser {
794
  }
795
  }
796
  }
 
797
  return new SassImportNode($token, $parent);
798
  break;
799
  case '@each':
@@ -806,6 +838,7 @@ class SassParser {
806
  return new SassIfNode($token);
807
  break;
808
  case '@else': // handles else and else if directives
 
809
  return new SassElseNode($token);
810
  break;
811
  case '@do':
@@ -833,7 +866,8 @@ class SassParser {
833
  * @throws SassException if the indent is mixed or
834
  * the indent character can not be determined
835
  */
836
- public function setIndentChar() {
 
837
  foreach ($this->source as $l=>$source) {
838
  if (!empty($source) && in_array($source[0], $this->indentChars)) {
839
  $this->indentChar = $source[0];
@@ -846,6 +880,7 @@ class SassParser {
846
  }
847
  }
848
  $this->indentSpaces = ($this->indentChar == ' ' ? $i : 1);
 
849
  return;
850
  }
851
  } // foreach
22
  * @subpackage Sass
23
  */
24
 
25
+ require_once 'SassFile.php';
26
+ require_once 'SassException.php';
27
+ require_once 'tree/SassNode.php';
28
 
29
  /**
30
  * SassParser class.
32
  * @package PHamlP
33
  * @subpackage Sass
34
  */
35
+ class SassParser
36
+ {
37
  /**#@+
38
  * Default option values
39
  */
52
  /**
53
  * Static holder for last instance of a SassParser
54
  */
55
+ public static $instance;
56
 
57
  /**
58
  * @var string the character used for indenting
81
 
82
  public $basepath;
83
 
 
84
  /**
85
  * debug_info:
86
  * @var boolean When true the line number and file where a selector is defined
220
  * @param array $options
221
  * @return SassParser
222
  */
223
+ public function __construct($options = array())
224
+ {
225
  if (!is_array($options)) {
226
  if (isset($options['debug']) && $options['debug']) {
227
  throw new SassException('Options must be an array');
283
  * @param string name of property to get
284
  * @return mixed return value of getter function
285
  */
286
+ public function __get($name)
287
+ {
288
  $getter = 'get' . ucfirst($name);
289
  if (method_exists($this, $getter)) {
290
  return $this->$getter();
297
  }
298
  }
299
 
300
+ public function getBasepath()
301
+ {
302
  return $this->basepath;
303
  }
304
 
305
+ public function getDebug_info()
306
+ {
307
  return $this->debug_info;
308
  }
309
 
310
+ public function getFilename()
311
+ {
312
  return $this->filename;
313
  }
314
 
315
+ public function getLine()
316
+ {
317
  return $this->line;
318
  }
319
 
320
+ public function getSource()
321
+ {
322
  return $this->source;
323
  }
324
 
325
+ public function getLine_numbers()
326
+ {
327
  return $this->line_numbers;
328
  }
329
 
330
+ public function getFunctions()
331
+ {
332
  return self::$functions;
333
  }
334
 
335
+ public function getLoad_paths()
336
+ {
337
  return $this->load_paths;
338
  }
339
 
340
+ public function getLoad_path_functions()
341
+ {
342
  return $this->load_path_functions;
343
  }
344
 
345
+ public function getProperty_syntax()
346
+ {
347
  return $this->property_syntax;
348
  }
349
 
350
+ public function getQuiet()
351
+ {
352
  return $this->quiet;
353
  }
354
 
355
+ public function getStyle()
356
+ {
357
  return $this->style;
358
  }
359
 
360
+ public function getSyntax()
361
+ {
362
  return $this->syntax;
363
  }
364
 
365
+ public function getDebug()
366
+ {
367
  return $this->debug;
368
  }
369
 
370
+ public function getCallbacks()
371
+ {
372
  return $this->callbacks + array(
373
  'warn' => NULL,
374
  'debug' => NULL,
375
  );
376
  }
377
 
378
+ public function getOptions()
379
+ {
380
  return array(
381
  'callbacks' => $this->callbacks,
382
  // 'debug' => $this->debug,
398
  * @param string name of source file or Sass source
399
  * @return string CSS
400
  */
401
+ public function toCss($source, $isFile = true)
402
+ {
403
  return $this->parse($source, $isFile)->render();
404
  }
405
 
411
  * @param string name of source file or Sass source
412
  * @return SassRootNode Root node of document tree
413
  */
414
+ public function parse($source, $isFile = true)
415
+ {
416
  # Richard Lyon - 2011-10-25 - ignore unfound files
417
  # Richard Lyon - 2011-10-25 - add multiple files to load functions
418
  if (!$source) {
422
  if (is_array($source)) {
423
  $return = null;
424
  foreach ($source as $key => $value) {
425
+ if (is_numeric($key)) {
426
  $code = $value;
427
  $type = true;
428
  } else {
429
  $code = $key;
430
  $type = $value;
431
  }
432
+ if ($return===null) {
433
  $return = $this->parse($code, $type);
434
  } else {
435
  $newNode = $this->parse($code, $type);
436
+ foreach ($newNode->children as $children) {
437
  array_push($return->children, $children);
438
  }
439
  }
440
  }
441
+
442
  return $return;
443
  }
444
 
447
  foreach ($files as $file) {
448
  $this->filename = $file;
449
  $this->syntax = substr(strrchr($file, '.'), 1);
450
+ if ($this->syntax == SassFile::CSS) {
451
  $this->property_syntax = "css";
452
+ } elseif (!$this->property_syntax && $this->syntax == SassFile::SCSS) {
453
  $this->property_syntax = "scss";
454
  }
455
 
457
  if ($this->debug) {
458
  throw new SassException('Invalid {what}', array('{what}' => 'syntax option'));
459
  }
460
+
461
  return FALSE;
462
  }
463
  $files_source .= SassFile::get_file_contents($this->filename, $this);
464
  }
465
+
466
  return $this->toTree($files_source);
467
+ } else {
 
468
  return $this->toTree($source);
469
  }
470
  }
475
  * @param string Sass source
476
  * @return SassRootNode the root of this document tree
477
  */
478
+ public function toTree($source)
479
+ {
480
  if ($this->syntax === SassFile::SASS) {
481
  $source = str_replace(array("\r\n", "\n\r", "\r"), "\n", $source);
482
  $this->source = explode("\n", $source);
483
  $this->setIndentChar();
484
+ } else {
 
485
  $this->source = $source;
486
  }
487
  unset($source);
488
  $root = new SassRootNode($this);
489
  $this->buildTree($root);
490
+
491
  return $root;
492
  }
493
 
496
  * Called recursivly until the source is parsed.
497
  * @param SassNode the node
498
  */
499
+ public function buildTree($parent)
500
+ {
501
  $node = $this->getNode($parent);
502
  while (is_object($node) && $node->isChildOf($parent)) {
503
  $parent->addChild($node);
504
  $node = $this->buildTree($node);
505
  }
506
+
507
  return $node;
508
  }
509
 
513
  * @return SassNode a SassNode of the appropriate type. Null when no more
514
  * source to parse.
515
  */
516
+ public function getNode($node)
517
+ {
518
  $token = $this->getToken();
519
  if (empty($token)) return null;
520
  switch (true) {
533
  if ($this->debug) {
534
  throw new SassException('Mixin definition shortcut not allowed in SCSS', $this);
535
  }
536
+
537
  return;
538
+ } else {
 
539
  return new SassMixinDefinitionNode($token);
540
  }
541
  case SassMixinNode::isa($token):
543
  if ($this->debug) {
544
  throw new SassException('Mixin include shortcut not allowed in SCSS', $this);
545
  }
546
+
547
  return;
548
+ } else {
 
549
  return new SassMixinNode($token);
550
  }
551
  default:
559
  * meta data about it.
560
  * @return object
561
  */
562
+ public function getToken()
563
+ {
564
  return ($this->syntax === SassFile::SASS ? $this->sass2Token() : $this->scss2Token());
565
  }
566
 
571
  * CSS comments and selectors, are assembled into a single statement.
572
  * @return object Statement token. Null if end of source.
573
  */
574
+ public function sass2Token()
575
+ {
576
  $statement = ''; // source line being tokenised
577
  $token = null;
578
 
594
  // Consume Sass comments
595
  if (substr($statement, 0, strlen(self::BEGIN_SASS_COMMENT)) === self::BEGIN_SASS_COMMENT) {
596
  unset($statement);
597
+ while ($this->getLevel($this->source[0]) > $level) {
598
  array_shift($this->source);
599
  $this->line++;
600
  }
603
  // Build CSS comments
604
  elseif (substr($statement, 0, strlen(self::BEGIN_CSS_COMMENT))
605
  === self::BEGIN_CSS_COMMENT) {
606
+ while ($this->getLevel($this->source[0]) > $level) {
607
  $statement .= "\n" . ltrim(array_shift($this->source));
608
  $this->line++;
609
  }
610
+ } else {
 
611
  $this->source = $statement;
612
 
613
  if ($this->debug) {
618
  // Selector statements can span multiple lines
619
  elseif (substr($statement, -1) === SassRuleNode::CONTINUED) {
620
  // Build the selector statement
621
+ while ($this->getLevel($this->source[0]) === $level) {
622
  $statement .= ltrim(array_shift($this->source));
623
  $this->line++;
624
  }
631
  'line' => $this->line - 1,
632
  );
633
  }
634
+
635
  return $token;
636
  }
637
 
642
  * @return integer the level of the source
643
  * @throws Exception if the source indentation is invalid
644
  */
645
+ public function getLevel($source)
646
+ {
647
  $indent = strlen($source) - strlen(ltrim($source));
648
  $level = $indent/$this->indentSpaces;
649
  if (is_float($level)) {
654
 
655
  if ($this->debug) {
656
  throw new SassException('Invalid indentation', $this);
657
+ } else {
 
658
  return 0;
659
  }
660
  }
661
+
662
  return $level;
663
  }
664
 
667
  * about it from SCSS source.
668
  * @return object Statement token. Null if end of source.
669
  */
670
+ public function scss2Token()
671
+ {
672
  static $srcpos = 0; // current position in the source stream
673
  static $srclen; // the length of the source stream
674
 
691
  ));
692
  }
693
  $statement .= "\n";
694
+ } elseif (substr($this->source, $srcpos-1, strlen(self::BEGIN_CSS_COMMENT)) === self::BEGIN_CSS_COMMENT) {
 
695
  if (ltrim($statement)) {
696
  if ($this->debug) {
697
  throw new SassException('Invalid comment', (object) array(
707
  }
708
  $srcpos += strlen(self::END_CSS_COMMENT);
709
  $token = $this->createToken($statement.self::END_CSS_COMMENT);
710
+ } else {
 
711
  $statement .= $c;
712
  }
713
  break;
758
  * @param string source statement
759
  * @return SassToken
760
  */
761
+ public function createToken($statement)
762
+ {
763
  static $level = 0;
764
 
765
  $this->line += substr_count($statement, "\n");
778
  'line' => $this->line,
779
  ) : null);
780
  $level += ($last === self::BEGIN_BLOCK ? 1 : ($last === self::END_BLOCK ? -1 : 0));
781
+
782
  return $token;
783
  }
784
 
788
  * @param SassNode parent node
789
  * @return SassNode a Sass directive node
790
  */
791
+ public function parseDirective($token, $parent)
792
+ {
793
  switch (SassDirectiveNode::extractDirective($token)) {
794
  case '@content':
795
  return new SassContentNode($token);
825
  }
826
  }
827
  }
828
+
829
  return new SassImportNode($token, $parent);
830
  break;
831
  case '@each':
838
  return new SassIfNode($token);
839
  break;
840
  case '@else': // handles else and else if directives
841
+
842
  return new SassElseNode($token);
843
  break;
844
  case '@do':
866
  * @throws SassException if the indent is mixed or
867
  * the indent character can not be determined
868
  */
869
+ public function setIndentChar()
870
+ {
871
  foreach ($this->source as $l=>$source) {
872
  if (!empty($source) && in_array($source[0], $this->indentChars)) {
873
  $this->indentChar = $source[0];
880
  }
881
  }
882
  $this->indentSpaces = ($this->indentChar == ' ' ? $i : 1);
883
+
884
  return;
885
  }
886
  } // foreach
lib/phpsass/VERSION CHANGED
@@ -1,3 +1,5 @@
 
 
1
  Version 201306071300 - Version bump to reflect multiple merged pull requests
2
  Version 201304222300 - Version bump to reflect multiple merged pull requests
3
  Version 201211282000 - Version bump to reflect multiple pull requests being merged over time.
1
+ Version 201206271500 - Verbump, merge pr #119
2
+ Version 201206181400 - Run PHP-CS-Fixer on all files to fix coding style
3
  Version 201306071300 - Version bump to reflect multiple merged pull requests
4
  Version 201304222300 - Version bump to reflect multiple merged pull requests
5
  Version 201211282000 - Version bump to reflect multiple pull requests being merged over time.
lib/phpsass/renderers/SassCompactRenderer.php CHANGED
@@ -9,7 +9,7 @@
9
  * @subpackage Sass.renderers
10
  */
11
 
12
- require_once('SassCompressedRenderer.php');
13
 
14
  /**
15
  * SassCompactRenderer class.
@@ -19,7 +19,8 @@ require_once('SassCompressedRenderer.php');
19
  * @package PHamlP
20
  * @subpackage Sass.renderers
21
  */
22
- class SassCompactRenderer extends SassCompressedRenderer {
 
23
  const DEBUG_INFO_RULE = '@media -sass-debug-info';
24
  const DEBUG_INFO_PROPERTY = 'font-family';
25
 
@@ -27,7 +28,8 @@ class SassCompactRenderer extends SassCompressedRenderer {
27
  * Renders the brace between the selectors and the properties
28
  * @return string the brace between the selectors and the properties
29
  */
30
- protected function between() {
 
31
  return ' { ';
32
  }
33
 
@@ -35,7 +37,8 @@ class SassCompactRenderer extends SassCompressedRenderer {
35
  * Renders the brace at the end of the rule
36
  * @return string the brace between the rule and its properties
37
  */
38
- protected function end() {
 
39
  return " }\n";
40
  }
41
 
@@ -46,8 +49,10 @@ class SassCompactRenderer extends SassCompressedRenderer {
46
  * @param SassNode the node being rendered
47
  * @return string the rendered commnt
48
  */
49
- public function renderComment($node) {
 
50
  $nl = ($node->parent instanceof SassRuleNode?'':"\n");
 
51
  return "$nl/* " . join("\n * ", $node->children) . " */$nl" ;
52
  }
53
 
@@ -57,7 +62,8 @@ class SassCompactRenderer extends SassCompressedRenderer {
57
  * @param array properties of the directive
58
  * @return string the rendered directive
59
  */
60
- public function renderDirective($node, $properties) {
 
61
  return str_replace("\n", '', parent::renderDirective($node, $properties)) .
62
  "\n\n";
63
  }
@@ -68,7 +74,8 @@ class SassCompactRenderer extends SassCompressedRenderer {
68
  * @param array properties to render
69
  * @return string the rendered properties
70
  */
71
- public function renderProperties($node, $properties) {
 
72
  return join(' ', $properties);
73
  }
74
 
@@ -77,8 +84,10 @@ class SassCompactRenderer extends SassCompressedRenderer {
77
  * @param SassNode the node being rendered
78
  * @return string the rendered property
79
  */
80
- public function renderProperty($node) {
 
81
  $node->important = $node->important ? ' !important' : '';
 
82
  return "{$node->name}: {$node->value}{$node->important};";
83
  }
84
 
@@ -89,7 +98,8 @@ class SassCompactRenderer extends SassCompressedRenderer {
89
  * @param string rendered rules
90
  * @return string the rendered rule
91
  */
92
- public function renderRule($node, $properties, $rules) {
 
93
  return $this->renderDebug($node) . parent::renderRule($node, $properties,
94
  str_replace("\n\n", "\n", $rules)) . "\n";
95
  }
@@ -104,7 +114,8 @@ class SassCompactRenderer extends SassCompressedRenderer {
104
  * @param SassNode the node being rendered
105
  * @return string the debug information
106
  */
107
- protected function renderDebug($node) {
 
108
  $indent = $this->getIndent($node);
109
  $debug = '';
110
 
@@ -114,10 +125,10 @@ class SassCompactRenderer extends SassCompressedRenderer {
114
  $debug .= 'filename{' . self::DEBUG_INFO_PROPERTY . ':' . preg_replace('/([^-\w])/', '\\\\\1', "file://{$node->filename}") . ';}';
115
  $debug .= 'line{' . self::DEBUG_INFO_PROPERTY . ":'{$node->line}';}";
116
  $debug .= "}\n";
117
- }
118
- elseif ($node->line_numbers) {
119
  $debug .= "$indent/* line {$node->line} {$node->filename} */\n";
120
  }
 
121
  return $debug;
122
  }
123
 
@@ -126,7 +137,8 @@ class SassCompactRenderer extends SassCompressedRenderer {
126
  * @param SassNode the node being rendered
127
  * @return string the rendered selectors
128
  */
129
- protected function renderSelectors($node) {
 
130
  return join(', ', $node->selectors);
131
  }
132
  }
9
  * @subpackage Sass.renderers
10
  */
11
 
12
+ require_once 'SassCompressedRenderer.php';
13
 
14
  /**
15
  * SassCompactRenderer class.
19
  * @package PHamlP
20
  * @subpackage Sass.renderers
21
  */
22
+ class SassCompactRenderer extends SassCompressedRenderer
23
+ {
24
  const DEBUG_INFO_RULE = '@media -sass-debug-info';
25
  const DEBUG_INFO_PROPERTY = 'font-family';
26
 
28
  * Renders the brace between the selectors and the properties
29
  * @return string the brace between the selectors and the properties
30
  */
31
+ protected function between()
32
+ {
33
  return ' { ';
34
  }
35
 
37
  * Renders the brace at the end of the rule
38
  * @return string the brace between the rule and its properties
39
  */
40
+ protected function end()
41
+ {
42
  return " }\n";
43
  }
44
 
49
  * @param SassNode the node being rendered
50
  * @return string the rendered commnt
51
  */
52
+ public function renderComment($node)
53
+ {
54
  $nl = ($node->parent instanceof SassRuleNode?'':"\n");
55
+
56
  return "$nl/* " . join("\n * ", $node->children) . " */$nl" ;
57
  }
58
 
62
  * @param array properties of the directive
63
  * @return string the rendered directive
64
  */
65
+ public function renderDirective($node, $properties)
66
+ {
67
  return str_replace("\n", '', parent::renderDirective($node, $properties)) .
68
  "\n\n";
69
  }
74
  * @param array properties to render
75
  * @return string the rendered properties
76
  */
77
+ public function renderProperties($node, $properties)
78
+ {
79
  return join(' ', $properties);
80
  }
81
 
84
  * @param SassNode the node being rendered
85
  * @return string the rendered property
86
  */
87
+ public function renderProperty($node)
88
+ {
89
  $node->important = $node->important ? ' !important' : '';
90
+
91
  return "{$node->name}: {$node->value}{$node->important};";
92
  }
93
 
98
  * @param string rendered rules
99
  * @return string the rendered rule
100
  */
101
+ public function renderRule($node, $properties, $rules)
102
+ {
103
  return $this->renderDebug($node) . parent::renderRule($node, $properties,
104
  str_replace("\n\n", "\n", $rules)) . "\n";
105
  }
114
  * @param SassNode the node being rendered
115
  * @return string the debug information
116
  */
117
+ protected function renderDebug($node)
118
+ {
119
  $indent = $this->getIndent($node);
120
  $debug = '';
121
 
125
  $debug .= 'filename{' . self::DEBUG_INFO_PROPERTY . ':' . preg_replace('/([^-\w])/', '\\\\\1', "file://{$node->filename}") . ';}';
126
  $debug .= 'line{' . self::DEBUG_INFO_PROPERTY . ":'{$node->line}';}";
127
  $debug .= "}\n";
128
+ } elseif ($node->line_numbers) {
 
129
  $debug .= "$indent/* line {$node->line} {$node->filename} */\n";
130
  }
131
+
132
  return $debug;
133
  }
134
 
137
  * @param SassNode the node being rendered
138
  * @return string the rendered selectors
139
  */
140
+ protected function renderSelectors($node)
141
+ {
142
  return join(', ', $node->selectors);
143
  }
144
  }
lib/phpsass/renderers/SassCompressedRenderer.php CHANGED
@@ -16,12 +16,14 @@
16
  * @package PHamlP
17
  * @subpackage Sass.renderers
18
  */
19
- class SassCompressedRenderer extends SassRenderer {
 
20
  /**
21
  * Renders the brace between the selectors and the properties
22
  * @return string the brace between the selectors and the properties
23
  */
24
- protected function between() {
 
25
  return '{';
26
  }
27
 
@@ -29,7 +31,8 @@ class SassCompressedRenderer extends SassRenderer {
29
  * Renders the brace at the end of the rule
30
  * @return string the brace between the rule and its properties
31
  */
32
- protected function end() {
 
33
  return '}';
34
  }
35
 
@@ -38,7 +41,8 @@ class SassCompressedRenderer extends SassRenderer {
38
  * @param SassNode the node to return the indent string for
39
  * @return string the indent string for this SassNode
40
  */
41
- protected function getIndent($node) {
 
42
  return '';
43
  }
44
 
@@ -47,7 +51,8 @@ class SassCompressedRenderer extends SassRenderer {
47
  * @param SassNode the node being rendered
48
  * @return string the rendered comment
49
  */
50
- public function renderComment($node) {
 
51
  return '';
52
  }
53
 
@@ -57,7 +62,8 @@ class SassCompressedRenderer extends SassRenderer {
57
  * @param array properties of the directive
58
  * @return string the rendered directive
59
  */
60
- public function renderDirective($node, $properties) {
 
61
  return $node->directive . $this->between() . $this->renderProperties($node, $properties) . $this->end();
62
  }
63
 
@@ -67,7 +73,8 @@ class SassCompressedRenderer extends SassRenderer {
67
  * @param array properties to render
68
  * @return string the rendered properties
69
  */
70
- public function renderProperties($node, $properties) {
 
71
  return join('', $properties);
72
  }
73
 
@@ -76,8 +83,10 @@ class SassCompressedRenderer extends SassRenderer {
76
  * @param SassNode the node being rendered
77
  * @return string the rendered property
78
  */
79
- public function renderProperty($node) {
 
80
  $node->important = $node->important ? '!important' : '';
 
81
  return "{$node->name}:{$node->value}{$node->important};";
82
  }
83
 
@@ -88,7 +97,8 @@ class SassCompressedRenderer extends SassRenderer {
88
  * @param string rendered rules
89
  * @return string the rendered directive
90
  */
91
- public function renderRule($node, $properties, $rules) {
 
92
  $selectors = $this->renderSelectors($node);
93
  if ($selectors) {
94
  return (!empty($properties) ? $selectors . $this->between() . $this->renderProperties($node, $properties) . $this->end() : '') . $rules;
@@ -100,7 +110,8 @@ class SassCompressedRenderer extends SassRenderer {
100
  * @param SassNode the node being rendered
101
  * @return string the rendered selectors
102
  */
103
- protected function renderSelectors($node) {
 
104
  $selectors = array();
105
  foreach ($node->selectors as $selector) {
106
  if (!$node->isPlaceholder($selector)) {
@@ -110,4 +121,4 @@ class SassCompressedRenderer extends SassRenderer {
110
 
111
  return join(',', $selectors);
112
  }
113
- }
16
  * @package PHamlP
17
  * @subpackage Sass.renderers
18
  */
19
+ class SassCompressedRenderer extends SassRenderer
20
+ {
21
  /**
22
  * Renders the brace between the selectors and the properties
23
  * @return string the brace between the selectors and the properties
24
  */
25
+ protected function between()
26
+ {
27
  return '{';
28
  }
29
 
31
  * Renders the brace at the end of the rule
32
  * @return string the brace between the rule and its properties
33
  */
34
+ protected function end()
35
+ {
36
  return '}';
37
  }
38
 
41
  * @param SassNode the node to return the indent string for
42
  * @return string the indent string for this SassNode
43
  */
44
+ protected function getIndent($node)
45
+ {
46
  return '';
47
  }
48
 
51
  * @param SassNode the node being rendered
52
  * @return string the rendered comment
53
  */
54
+ public function renderComment($node)
55
+ {
56
  return '';
57
  }
58
 
62
  * @param array properties of the directive
63
  * @return string the rendered directive
64
  */
65
+ public function renderDirective($node, $properties)
66
+ {
67
  return $node->directive . $this->between() . $this->renderProperties($node, $properties) . $this->end();
68
  }
69
 
73
  * @param array properties to render
74
  * @return string the rendered properties
75
  */
76
+ public function renderProperties($node, $properties)
77
+ {
78
  return join('', $properties);
79
  }
80
 
83
  * @param SassNode the node being rendered
84
  * @return string the rendered property
85
  */
86
+ public function renderProperty($node)
87
+ {
88
  $node->important = $node->important ? '!important' : '';
89
+
90
  return "{$node->name}:{$node->value}{$node->important};";
91
  }
92
 
97
  * @param string rendered rules
98
  * @return string the rendered directive
99
  */
100
+ public function renderRule($node, $properties, $rules)
101
+ {
102
  $selectors = $this->renderSelectors($node);
103
  if ($selectors) {
104
  return (!empty($properties) ? $selectors . $this->between() . $this->renderProperties($node, $properties) . $this->end() : '') . $rules;
110
  * @param SassNode the node being rendered
111
  * @return string the rendered selectors
112
  */
113
+ protected function renderSelectors($node)
114
+ {
115
  $selectors = array();
116
  foreach ($node->selectors as $selector) {
117
  if (!$node->isPlaceholder($selector)) {
121
 
122
  return join(',', $selectors);
123
  }
124
+ }
lib/phpsass/renderers/SassExpandedRenderer.php CHANGED
@@ -9,7 +9,7 @@
9
  * @subpackage Sass.renderers
10
  */
11
 
12
- require_once('SassCompactRenderer.php');
13
 
14
  /**
15
  * SassExpandedRenderer class.
@@ -19,20 +19,23 @@ require_once('SassCompactRenderer.php');
19
  * @package PHamlP
20
  * @subpackage Sass.renderers
21
  */
22
- class SassExpandedRenderer extends SassCompactRenderer {
 
23
  /**
24
  * Renders the brace between the selectors and the properties
25
  * @return string the brace between the selectors and the properties
26
  */
27
- protected function between() {
 
28
  return " {\n" ;
29
  }
30
-
31
  /**
32
  * Renders the brace at the end of the rule
33
  * @return string the brace between the rule and its properties
34
  */
35
- protected function end() {
 
36
  return "\n}\n\n";
37
  }
38
 
@@ -41,12 +44,14 @@ class SassExpandedRenderer extends SassCompactRenderer {
41
  * @param SassNode the node being rendered
42
  * @return string the rendered commnt
43
  */
44
- public function renderComment($node) {
 
45
  $indent = $this->getIndent($node);
46
  $lines = explode("\n", $node->value);
47
  foreach ($lines as &$line) {
48
  $line = trim($line);
49
  }
 
50
  return "$indent/*\n$indent * ".join("\n$indent * ", $lines)."\n$indent */".(empty($indent)?"\n":'');
51
  }
52
 
@@ -55,8 +60,10 @@ class SassExpandedRenderer extends SassCompactRenderer {
55
  * @param array properties to render
56
  * @return string the rendered properties
57
  */
58
- public function renderProperties($node, $properties) {
 
59
  $indent = $this->getIndent($node).self::INDENT;
 
60
  return $indent.join("\n$indent", $properties);
61
  }
62
  }
9
  * @subpackage Sass.renderers
10
  */
11
 
12
+ require_once 'SassCompactRenderer.php';
13
 
14
  /**
15
  * SassExpandedRenderer class.
19
  * @package PHamlP
20
  * @subpackage Sass.renderers
21
  */
22
+ class SassExpandedRenderer extends SassCompactRenderer
23
+ {
24
  /**
25
  * Renders the brace between the selectors and the properties
26
  * @return string the brace between the selectors and the properties
27
  */
28
+ protected function between()
29
+ {
30
  return " {\n" ;
31
  }
32
+
33
  /**
34
  * Renders the brace at the end of the rule
35
  * @return string the brace between the rule and its properties
36
  */
37
+ protected function end()
38
+ {
39
  return "\n}\n\n";
40
  }
41
 
44
  * @param SassNode the node being rendered
45
  * @return string the rendered commnt
46
  */
47
+ public function renderComment($node)
48
+ {
49
  $indent = $this->getIndent($node);
50
  $lines = explode("\n", $node->value);
51
  foreach ($lines as &$line) {
52
  $line = trim($line);
53
  }
54
+
55
  return "$indent/*\n$indent * ".join("\n$indent * ", $lines)."\n$indent */".(empty($indent)?"\n":'');
56
  }
57
 
60
  * @param array properties to render
61
  * @return string the rendered properties
62
  */
63
+ public function renderProperties($node, $properties)
64
+ {
65
  $indent = $this->getIndent($node).self::INDENT;
66
+
67
  return $indent.join("\n$indent", $properties);
68
  }
69
  }
lib/phpsass/renderers/SassNestedRenderer.php CHANGED
@@ -9,32 +9,35 @@
9
  * @subpackage Sass.renderers
10
  */
11
 
12
- require_once('SassExpandedRenderer.php');
13
 
14
  /**
15
  * SassNestedRenderer class.
16
  * Nested style is the default Sass style, because it reflects the structure of
17
  * the document in much the same way Sass does. Each rule is indented based on
18
  * how deeply it's nested. Each property has its own line and is indented
19
- * within the rule.
20
  * @package PHamlP
21
  * @subpackage Sass.renderers
22
  */
23
- class SassNestedRenderer extends SassExpandedRenderer {
 
24
  /**
25
  * Renders the brace at the end of the rule
26
  * @return string the brace between the rule and its properties
27
  */
28
- protected function end() {
 
29
  return " }\n";
30
  }
31
-
32
  /**
33
  * Returns the indent string for the node
34
  * @param SassNode the node being rendered
35
  * @return string the indent string for this SassNode
36
  */
37
- protected function getIndent($node) {
 
38
  return str_repeat(self::INDENT, $node->level);
39
  }
40
 
@@ -44,8 +47,10 @@ class SassNestedRenderer extends SassExpandedRenderer {
44
  * @param array properties of the directive
45
  * @return string the rendered directive
46
  */
47
- public function renderDirective($node, $properties) {
 
48
  $directive = $this->getIndent($node) . $node->directive . $this->between() . $this->renderProperties($node, $properties);
 
49
  return preg_replace('/(.*})\n$/', '\1', $directive) . $this->end();
50
  }
51
 
@@ -54,15 +59,17 @@ class SassNestedRenderer extends SassExpandedRenderer {
54
  * @param SassNode the node being rendered
55
  * @return string the rendered selectors
56
  */
57
- protected function renderSelectors($node) {
 
58
  $selectors = array();
59
  foreach ($node->selectors as $selector) {
60
  if (!$node->isPlaceholder($selector)) {
61
  $selectors[] = $selector;
62
  }
63
  }
64
-
65
  $indent = $this->getIndent($node);
 
66
  return $indent.join(",\n$indent", $selectors);
67
  }
68
- }
9
  * @subpackage Sass.renderers
10
  */
11
 
12
+ require_once 'SassExpandedRenderer.php';
13
 
14
  /**
15
  * SassNestedRenderer class.
16
  * Nested style is the default Sass style, because it reflects the structure of
17
  * the document in much the same way Sass does. Each rule is indented based on
18
  * how deeply it's nested. Each property has its own line and is indented
19
+ * within the rule.
20
  * @package PHamlP
21
  * @subpackage Sass.renderers
22
  */
23
+ class SassNestedRenderer extends SassExpandedRenderer
24
+ {
25
  /**
26
  * Renders the brace at the end of the rule
27
  * @return string the brace between the rule and its properties
28
  */
29
+ protected function end()
30
+ {
31
  return " }\n";
32
  }
33
+
34
  /**
35
  * Returns the indent string for the node
36
  * @param SassNode the node being rendered
37
  * @return string the indent string for this SassNode
38
  */
39
+ protected function getIndent($node)
40
+ {
41
  return str_repeat(self::INDENT, $node->level);
42
  }
43
 
47
  * @param array properties of the directive
48
  * @return string the rendered directive
49
  */
50
+ public function renderDirective($node, $properties)
51
+ {
52
  $directive = $this->getIndent($node) . $node->directive . $this->between() . $this->renderProperties($node, $properties);
53
+
54
  return preg_replace('/(.*})\n$/', '\1', $directive) . $this->end();
55
  }
56
 
59
  * @param SassNode the node being rendered
60
  * @return string the rendered selectors
61
  */
62
+ protected function renderSelectors($node)
63
+ {
64
  $selectors = array();
65
  foreach ($node->selectors as $selector) {
66
  if (!$node->isPlaceholder($selector)) {
67
  $selectors[] = $selector;
68
  }
69
  }
70
+
71
  $indent = $this->getIndent($node);
72
+
73
  return $indent.join(",\n$indent", $selectors);
74
  }
75
+ }
lib/phpsass/renderers/SassRenderer.php CHANGED
@@ -9,17 +9,18 @@
9
  * @subpackage Sass.renderers
10
  */
11
 
12
- require_once('SassCompactRenderer.php');
13
- require_once('SassCompressedRenderer.php');
14
- require_once('SassExpandedRenderer.php');
15
- require_once('SassNestedRenderer.php');
16
 
17
  /**
18
  * SassRenderer class.
19
  * @package PHamlP
20
  * @subpackage Sass.renderers
21
  */
22
- class SassRenderer {
 
23
  /**#@+
24
  * Output Styles
25
  */
@@ -36,7 +37,8 @@ class SassRenderer {
36
  * @param string render style
37
  * @return SassRenderer
38
  */
39
- public static function getRenderer($style) {
 
40
  switch ($style) {
41
  case self::STYLE_COMPACT:
42
  return new SassCompactRenderer();
@@ -48,4 +50,4 @@ class SassRenderer {
48
  return new SassNestedRenderer();
49
  } // switch
50
  }
51
- }
9
  * @subpackage Sass.renderers
10
  */
11
 
12
+ require_once 'SassCompactRenderer.php';
13
+ require_once 'SassCompressedRenderer.php';
14
+ require_once 'SassExpandedRenderer.php';
15
+ require_once 'SassNestedRenderer.php';
16
 
17
  /**
18
  * SassRenderer class.
19
  * @package PHamlP
20
  * @subpackage Sass.renderers
21
  */
22
+ class SassRenderer
23
+ {
24
  /**#@+
25
  * Output Styles
26
  */
37
  * @param string render style
38
  * @return SassRenderer
39
  */
40
+ public static function getRenderer($style)
41
+ {
42
  switch ($style) {
43
  case self::STYLE_COMPACT:
44
  return new SassCompactRenderer();
50
  return new SassNestedRenderer();
51
  } // switch
52
  }
53
+ }
lib/phpsass/script/SassScriptFunction.php CHANGED
@@ -8,7 +8,7 @@
8
  * @subpackage Sass.script
9
  */
10
 
11
- require_once('SassScriptFunctions.php');
12
 
13
  /**
14
  * SassScriptFunction class.
@@ -16,7 +16,8 @@ require_once('SassScriptFunctions.php');
16
  * @package PHamlP
17
  * @subpackage Sass.script
18
  */
19
- class SassScriptFunction {
 
20
  /**@#+
21
  * Regexes for matching and extracting functions and arguments
22
  */
@@ -37,17 +38,20 @@ class SassScriptFunction {
37
  * @param array arguments for the function
38
  * @return SassScriptFunction
39
  */
40
- public function __construct($name, $args) {
 
41
  $this->name = $name;
42
  $this->args = $args;
43
  }
44
 
45
- private function process_arguments($input) {
 
46
  if (is_array($input)) {
47
  $output = array();
48
  foreach ($input as $k => $token) {
49
  $output[$k] = trim($this->process_arguments($token), '\'"');
50
  }
 
51
  return $output;
52
  }
53
 
@@ -76,7 +80,8 @@ class SassScriptFunction {
76
  * pre-defined functions, then try the pre-defined functions.
77
  * @return Function the value of this Function
78
  */
79
- public function perform() {
 
80
  self::$context = new SassContext(SassScriptParser::$context);
81
 
82
  $name = preg_replace('/[^a-z0-9_]/', '_', strtolower($this->name));
@@ -91,10 +96,11 @@ class SassScriptFunction {
91
  try {
92
  if (SassScriptParser::$context->hasFunction($this->name)) {
93
  $return = SassScriptParser::$context->getFunction($this->name)->execute(SassScriptParser::$context, $this->args);
 
94
  return $return;
95
- }
96
- else if (SassScriptParser::$context->hasFunction($name)) {
97
  $return = SassScriptParser::$context->getFunction($name)->execute(SassScriptParser::$context, $this->args);
 
98
  return $return;
99
  }
100
  } catch (Exception $e) {
@@ -110,8 +116,10 @@ class SassScriptFunction {
110
  if (count($lexed) === 1) {
111
  return $lexed[0];
112
  }
 
113
  return new SassString(implode('', $this->process_arguments($lexed)));
114
  }
 
115
  return $result;
116
  }
117
  }
@@ -120,6 +128,7 @@ class SassScriptFunction {
120
  if (method_exists('SassScriptFunctions', $name) || method_exists('SassScriptFunctions', $name = '_' . $name)) {
121
  $sig = self::get_reflection(array('SassScriptFunctions', $name));
122
  list($args) = self::fill_parameters($sig, $this->args, SassScriptParser::$context, $this);
 
123
  return call_user_func_array(array('SassScriptFunctions', $name), $args);
124
  }
125
 
@@ -132,7 +141,6 @@ class SassScriptFunction {
132
  }
133
  }
134
 
135
-
136
  // CSS function: create a SassString that will emit the function into the CSS
137
  return new SassString($this->name . '(' . join(', ', $args) . ')');
138
  }
@@ -142,7 +150,8 @@ class SassScriptFunction {
142
  * @param string path to directory to import
143
  * @return array filenames imported
144
  */
145
- private function import($dir) {
 
146
  $files = array();
147
 
148
  foreach (array_slice(scandir($dir), 2) as $file) {
@@ -151,6 +160,7 @@ class SassScriptFunction {
151
  require_once($dir . DIRECTORY_SEPARATOR . $file);
152
  }
153
  } // foreach
 
154
  return $files;
155
  }
156
 
@@ -160,7 +170,8 @@ class SassScriptFunction {
160
  * @param string the subject string
161
  * @return mixed match at the start of the string or false if no match
162
  */
163
- public static function isa($subject) {
 
164
  if (!preg_match(self::MATCH, $subject, $matches))
165
  return false;
166
 
@@ -170,21 +181,22 @@ class SassScriptFunction {
170
  $strlen = strlen($subject);
171
  $subject_str = (string) $subject;
172
 
173
- while($paren && $strpos < $strlen) {
174
  $c = $subject_str[$strpos++];
175
 
176
  $match .= $c;
177
  if ($c === '(') {
178
  $paren += 1;
179
- }
180
- elseif ($c === ')') {
181
  $paren -= 1;
182
  }
183
  }
 
184
  return $match;
185
  }
186
 
187
- public static function extractArgs($string, $include_null = TRUE, $context) {
 
188
  $args = array();
189
  $arg = '';
190
  $paren = 0;
@@ -205,7 +217,7 @@ class SassScriptFunction {
205
 
206
  if (strpos($value, ':') !== false && preg_match(SassVariableNode::MATCH, $value, $match)) {
207
  $return[$match[SassVariableNode::NAME]] = $match[SassVariableNode::VALUE];
208
- } else if(substr($value, 0, 1) == '$' && $include_null) {
209
  $return[str_replace('$', '', $value)] = NULL;
210
  } elseif ($include_null || $value !== NULL) {
211
  $return[] = $value;
@@ -215,12 +227,12 @@ class SassScriptFunction {
215
  return $return;
216
  }
217
 
218
- public static function get_reflection($method) {
 
219
  if (is_array($method)) {
220
  $class = new ReflectionClass($method[0]);
221
  $function = $class->getMethod($method[1]);
222
- }
223
- else {
224
  $function = new ReflectionFunction($method);
225
  }
226
 
@@ -235,15 +247,16 @@ class SassScriptFunction {
235
  }
236
  $return[$parameter->getName()] = $parsed; # we evaluate the defaults to get Sass objects.
237
  }
 
238
  return $return;
239
  }
240
 
241
- public static function fill_parameters($required, $provided, $context, $source) {
 
242
  $context = new SassContext($context);
243
  $_required = array_merge(array(), $required); // need to array_merge?
244
  $fill = $_required;
245
 
246
-
247
  foreach ($required as $name=>$default) {
248
  // we require that named variables provide a default.
249
  if (isset($provided[$name]) && $default !== NULL) {
@@ -264,8 +277,7 @@ class SassScriptFunction {
264
  }
265
  if (count($provided)) {
266
  $arg = array_shift($provided);
267
- }
268
- elseif ($default !== NULL) {
269
  $arg = $default;
270
 
271
  // for mixins with default values that refer to other arguments
@@ -277,8 +289,7 @@ class SassScriptFunction {
277
  $arg = $provided_copy[$pos];
278
  }
279
  }
280
- }
281
- else {
282
  throw new SassMixinNodeException("Function::$name: Required variable ($name) not given.\nFunction defined: " . $source->token->filename . '::' . $source->token->line . "\nFunction used", $source);
283
  }
284
  // splats
8
  * @subpackage Sass.script
9
  */
10
 
11
+ require_once 'SassScriptFunctions.php';
12
 
13
  /**
14
  * SassScriptFunction class.
16
  * @package PHamlP
17
  * @subpackage Sass.script
18
  */
19
+ class SassScriptFunction
20
+ {
21
  /**@#+
22
  * Regexes for matching and extracting functions and arguments
23
  */
38
  * @param array arguments for the function
39
  * @return SassScriptFunction
40
  */
41
+ public function __construct($name, $args)
42
+ {
43
  $this->name = $name;
44
  $this->args = $args;
45
  }
46
 
47
+ private function process_arguments($input)
48
+ {
49
  if (is_array($input)) {
50
  $output = array();
51
  foreach ($input as $k => $token) {
52
  $output[$k] = trim($this->process_arguments($token), '\'"');
53
  }
54
+
55
  return $output;
56
  }
57
 
80
  * pre-defined functions, then try the pre-defined functions.
81
  * @return Function the value of this Function
82
  */
83
+ public function perform()
84
+ {
85
  self::$context = new SassContext(SassScriptParser::$context);
86
 
87
  $name = preg_replace('/[^a-z0-9_]/', '_', strtolower($this->name));
96
  try {
97
  if (SassScriptParser::$context->hasFunction($this->name)) {
98
  $return = SassScriptParser::$context->getFunction($this->name)->execute(SassScriptParser::$context, $this->args);
99
+
100
  return $return;
101
+ } elseif (SassScriptParser::$context->hasFunction($name)) {
 
102
  $return = SassScriptParser::$context->getFunction($name)->execute(SassScriptParser::$context, $this->args);
103
+
104
  return $return;
105
  }
106
  } catch (Exception $e) {
116
  if (count($lexed) === 1) {
117
  return $lexed[0];
118
  }
119
+
120
  return new SassString(implode('', $this->process_arguments($lexed)));
121
  }
122
+
123
  return $result;
124
  }
125
  }
128
  if (method_exists('SassScriptFunctions', $name) || method_exists('SassScriptFunctions', $name = '_' . $name)) {
129
  $sig = self::get_reflection(array('SassScriptFunctions', $name));
130
  list($args) = self::fill_parameters($sig, $this->args, SassScriptParser::$context, $this);
131
+
132
  return call_user_func_array(array('SassScriptFunctions', $name), $args);
133
  }
134
 
141
  }
142
  }
143
 
 
144
  // CSS function: create a SassString that will emit the function into the CSS
145
  return new SassString($this->name . '(' . join(', ', $args) . ')');
146
  }
150
  * @param string path to directory to import
151
  * @return array filenames imported
152
  */
153
+ private function import($dir)
154
+ {
155
  $files = array();
156
 
157
  foreach (array_slice(scandir($dir), 2) as $file) {
160
  require_once($dir . DIRECTORY_SEPARATOR . $file);
161
  }
162
  } // foreach
163
+
164
  return $files;
165
  }
166
 
170
  * @param string the subject string
171
  * @return mixed match at the start of the string or false if no match
172
  */
173
+ public static function isa($subject)
174
+ {
175
  if (!preg_match(self::MATCH, $subject, $matches))
176
  return false;
177
 
181
  $strlen = strlen($subject);
182
  $subject_str = (string) $subject;
183
 
184
+ while ($paren && $strpos < $strlen) {
185
  $c = $subject_str[$strpos++];
186
 
187
  $match .= $c;
188
  if ($c === '(') {
189
  $paren += 1;
190
+ } elseif ($c === ')') {
 
191
  $paren -= 1;
192
  }
193
  }
194
+
195
  return $match;
196
  }
197
 
198
+ public static function extractArgs($string, $include_null = TRUE, $context)
199
+ {
200
  $args = array();
201
  $arg = '';
202
  $paren = 0;
217
 
218
  if (strpos($value, ':') !== false && preg_match(SassVariableNode::MATCH, $value, $match)) {
219
  $return[$match[SassVariableNode::NAME]] = $match[SassVariableNode::VALUE];
220
+ } elseif (substr($value, 0, 1) == '$' && $include_null) {
221
  $return[str_replace('$', '', $value)] = NULL;
222
  } elseif ($include_null || $value !== NULL) {
223
  $return[] = $value;
227
  return $return;
228
  }
229
 
230
+ public static function get_reflection($method)
231
+ {
232
  if (is_array($method)) {
233
  $class = new ReflectionClass($method[0]);
234
  $function = $class->getMethod($method[1]);
235
+ } else {
 
236
  $function = new ReflectionFunction($method);
237
  }
238
 
247
  }
248
  $return[$parameter->getName()] = $parsed; # we evaluate the defaults to get Sass objects.
249
  }
250
+
251
  return $return;
252
  }
253
 
254
+ public static function fill_parameters($required, $provided, $context, $source)
255
+ {
256
  $context = new SassContext($context);
257
  $_required = array_merge(array(), $required); // need to array_merge?
258
  $fill = $_required;
259
 
 
260
  foreach ($required as $name=>$default) {
261
  // we require that named variables provide a default.
262
  if (isset($provided[$name]) && $default !== NULL) {
277
  }
278
  if (count($provided)) {
279
  $arg = array_shift($provided);
280
+ } elseif ($default !== NULL) {
 
281
  $arg = $default;
282
 
283
  // for mixins with default values that refer to other arguments
289
  $arg = $provided_copy[$pos];
290
  }
291
  }
292
+ } else {
 
293
  throw new SassMixinNodeException("Function::$name: Required variable ($name) not given.\nFunction defined: " . $source->token->filename . '::' . $source->token->line . "\nFunction used", $source);
294
  }
295
  // splats
lib/phpsass/script/SassScriptFunctions.php CHANGED
@@ -36,16 +36,19 @@
36
  * @package PHamlP
37
  * @subpackage Sass.script
38
  */
39
- class SassScriptFunctions {
 
40
  const DECREASE = false;
41
  const INCREASE = true;
42
 
43
  public static $parser = FALSE;
44
- public static function option($name) {
 
45
  $options = SassParser::$instance->getOptions();
46
  if (isset($options[$name->value])) {
47
  return new SassString($options[$name->value]);
48
  }
 
49
  return new SassBoolean(false);
50
  }
51
 
@@ -64,7 +67,8 @@ class SassScriptFunctions {
64
  * @return new SassColour SassColour object
65
  * @throws SassScriptFunctionException if red, green, or blue are out of bounds
66
  */
67
- public static function rgb($red, $green, $blue) {
 
68
  return self::rgba($red, $green, $blue, new SassNumber(1));
69
  }
70
 
@@ -90,7 +94,8 @@ class SassScriptFunctions {
90
  * colour components are out of bounds, or or the colour is not a colour, or
91
  * alpha is out of bounds
92
  */
93
- public static function rgba() {
 
94
  switch (func_num_args()) {
95
  case 2:
96
  $colour = func_get_arg(0);
@@ -98,19 +103,19 @@ class SassScriptFunctions {
98
  SassLiteral::assertType($colour, 'SassColour');
99
  SassLiteral::assertType($alpha, 'SassNumber');
100
  SassLiteral::assertInRange($alpha, 0, 1);
 
101
  return $colour->with(array('alpha' => $alpha->value));
102
  break;
103
  case 4:
104
  $rgba = array();
105
  $components = func_get_args();
106
  $alpha = array_pop($components);
107
- foreach($components as $component) {
108
  SassLiteral::assertType($component, 'SassNumber');
109
  if ($component->units == '%') {
110
  SassLiteral::assertInRange($component, 0, 100, '%');
111
  $rgba[] = $component->value * 2.55;
112
- }
113
- else {
114
  SassLiteral::assertInRange($component, 0, 255);
115
  $rgba[] = $component->value;
116
  }
@@ -118,6 +123,7 @@ class SassScriptFunctions {
118
  SassLiteral::assertType($alpha, 'SassNumber');
119
  SassLiteral::assertInRange($alpha, 0, 1);
120
  $rgba[] = $alpha->value;
 
121
  return new SassColour($rgba);
122
  break;
123
  default:
@@ -138,9 +144,11 @@ class SassScriptFunctions {
138
  * @return new SassColour The resulting colour
139
  * @throws SassScriptFunctionException if saturation or lightness are out of bounds
140
  */
141
- public static function hsl($h, $s, $l) {
 
142
  SassLiteral::assertInRange($s, 0, 100, '%');
143
  SassLiteral::assertInRange($l, 0, 100, '%');
 
144
  return self::hsla($h, $s, $l, new SassNumber(1));
145
  }
146
 
@@ -158,7 +166,8 @@ class SassScriptFunctions {
158
  * @throws SassScriptFunctionException if saturation, lightness or alpha are
159
  * out of bounds
160
  */
161
- public static function hsla($h, $s, $l, $a) {
 
162
  SassLiteral::assertType($h, 'SassNumber');
163
  SassLiteral::assertType($s, 'SassNumber');
164
  SassLiteral::assertType($l, 'SassNumber');
@@ -166,6 +175,7 @@ class SassScriptFunctions {
166
  SassLiteral::assertInRange($s, 0, 100, '%');
167
  SassLiteral::assertInRange($l, 0, 100, '%');
168
  SassLiteral::assertInRange($a, 0, 1);
 
169
  return new SassColour(array('hue' => $h, 'saturation' => $s, 'lightness' => $l, 'alpha' => $a));
170
  }
171
 
@@ -179,8 +189,10 @@ class SassScriptFunctions {
179
  * @return new SassNumber The red component of colour
180
  * @throws SassScriptFunctionException If $colour is not a colour
181
  */
182
- public static function red($colour) {
 
183
  SassLiteral::assertType($colour, 'SassColour');
 
184
  return new SassNumber($colour->red);
185
  }
186
 
@@ -190,8 +202,10 @@ class SassScriptFunctions {
190
  * @return new SassNumber The green component of colour
191
  * @throws SassScriptFunctionException If $colour is not a colour
192
  */
193
- public static function green($colour) {
 
194
  SassLiteral::assertType($colour, 'SassColour');
 
195
  return new SassNumber($colour->green);
196
  }
197
 
@@ -201,8 +215,10 @@ class SassScriptFunctions {
201
  * @return new SassNumber The blue component of colour
202
  * @throws SassScriptFunctionException If $colour is not a colour
203
  */
204
- public static function blue($colour) {
 
205
  SassLiteral::assertType($colour, 'SassColour');
 
206
  return new SassNumber($colour->blue);
207
  }
208
 
@@ -212,8 +228,10 @@ class SassScriptFunctions {
212
  * @return new SassNumber The hue component of colour
213
  * @throws SassScriptFunctionException If $colour is not a colour
214
  */
215
- public static function hue($colour) {
 
216
  SassLiteral::assertType($colour, 'SassColour');
 
217
  return new SassNumber($colour->getHue() . 'deg');
218
  }
219
 
@@ -223,8 +241,10 @@ class SassScriptFunctions {
223
  * @return new SassNumber The saturation component of colour
224
  * @throws SassScriptFunctionException If $colour is not a colour
225
  */
226
- public static function saturation($colour) {
 
227
  SassLiteral::assertType($colour, 'SassColour');
 
228
  return new SassNumber($colour->getSaturation() . '%');
229
  }
230
 
@@ -234,8 +254,10 @@ class SassScriptFunctions {
234
  * @return new SassNumber The lightness component of colour
235
  * @throws SassScriptFunctionException If $colour is not a colour
236
  */
237
- public static function lightness($colour) {
 
238
  SassLiteral::assertType($colour, 'SassColour');
 
239
  return new SassNumber($colour->getLightness() . '%');
240
  }
241
 
@@ -247,13 +269,14 @@ class SassScriptFunctions {
247
  *
248
  * RL modified so that the filter: alpha function doesn't bork
249
  */
250
- public static function alpha($colour) {
 
251
  try {
252
  SassLiteral::assertType($colour, 'SassColour');
253
- }
254
- catch (Exception $e) {
255
  return new SassString('alpha(100)');
256
  }
 
257
  return new SassNumber($colour->alpha);
258
  }
259
 
@@ -263,8 +286,10 @@ class SassScriptFunctions {
263
  * @return new SassNumber The alpha component (opacity) of colour
264
  * @throws SassScriptFunctionException If $colour is not a colour
265
  */
266
- public static function opacity($colour) {
 
267
  SassLiteral::assertType($colour, 'SassColour');
 
268
  return new SassNumber($colour->alpha);
269
  }
270
 
@@ -280,9 +305,11 @@ class SassScriptFunctions {
280
  * @throws SassScriptFunctionException If $colour is not a colour or
281
  * $degrees is not a number
282
  */
283
- public static function adjust_hue($colour, $degrees) {
 
284
  SassLiteral::assertType($colour, 'SassColour');
285
  SassLiteral::assertType($degrees, 'SassNumber');
 
286
  return $colour->with(array('hue' => $colour->getHue(true) + $degrees->value));
287
  }
288
 
@@ -302,7 +329,8 @@ class SassScriptFunctions {
302
  * $amount is not a number
303
  * @see lighten_rel
304
  */
305
- public static function lighten($colour, $amount, $ofCurrent = false) {
 
306
  return self::adjust($colour, $amount, $ofCurrent, 'lightness', self::INCREASE, 0, 100, '%');
307
  }
308
 
@@ -322,7 +350,8 @@ class SassScriptFunctions {
322
  * $amount is not a number
323
  * @see adjust
324
  */
325
- public static function darken($colour, $amount, $ofCurrent = false) {
 
326
  return self::adjust($colour, $amount, $ofCurrent, 'lightness', self::DECREASE, 0, 100, '%');
327
  }
328
 
@@ -342,7 +371,8 @@ class SassScriptFunctions {
342
  * $amount is not a number
343
  * @see adjust
344
  */
345
- public static function saturate($colour, $amount, $ofCurrent = false) {
 
346
  return self::adjust($colour, $amount, $ofCurrent, 'saturation', self::INCREASE, 0, 100, '%');
347
  }
348
 
@@ -362,7 +392,8 @@ class SassScriptFunctions {
362
  * $amount is not a number
363
  * @see adjust
364
  */
365
- public static function desaturate($colour, $amount, $ofCurrent = false) {
 
366
  return self::adjust($colour, $amount, $ofCurrent, 'saturation', self::DECREASE, 0, 100, '%');
367
  }
368
 
@@ -380,8 +411,10 @@ class SassScriptFunctions {
380
  * $amount is not a number
381
  * @see opacify_rel
382
  */
383
- public static function opacify($colour, $amount, $ofCurrent = false) {
 
384
  $units = self::units($amount);
 
385
  return self::adjust($colour, $amount, $ofCurrent, 'alpha', self::INCREASE, 0, ($units === '%' ? 100 : 1), $units);
386
  }
387
 
@@ -398,8 +431,10 @@ class SassScriptFunctions {
398
  * @throws SassScriptFunctionException If $colour is not a colour or
399
  * $amount is not a number
400
  */
401
- public static function transparentize($colour, $amount, $ofCurrent = false) {
 
402
  $units = self::units($amount);
 
403
  return self::adjust($colour, $amount, $ofCurrent, 'alpha', self::DECREASE, 0, ($units === '%' ? 100 : 1), $units);
404
  }
405
 
@@ -415,7 +450,8 @@ class SassScriptFunctions {
415
  * $amount is not a number
416
  * @see opacify
417
  */
418
- public static function fade_in($colour, $amount, $ofCurrent = false) {
 
419
  return self::opacify($colour, $amount, $ofCurrent);
420
  }
421
 
@@ -431,7 +467,8 @@ class SassScriptFunctions {
431
  * $amount is not a number
432
  * @see transparentize
433
  */
434
- public static function fade_out($colour, $amount, $ofCurrent = false) {
 
435
  return self::transparentize($colour, $amount, $ofCurrent);
436
  }
437
 
@@ -442,7 +479,8 @@ class SassScriptFunctions {
442
  * @return new SassColour The comlemented colour
443
  * @uses adjust_hue()
444
  */
445
- public static function complement($colour) {
 
446
  // return self::adjust($colour, new SassNumber('180deg'), true, 'hue', self::INCREASE, 0, 360, '');
447
  return self::adjust_hue($colour, new SassNumber('180deg'));
448
  }
@@ -453,7 +491,8 @@ class SassScriptFunctions {
453
  * @return new SassColour The greyscale colour
454
  * @see desaturate
455
  */
456
- public static function grayscale($colour) {
 
457
  return self::desaturate($colour, new SassNumber(100));
458
  }
459
 
@@ -464,7 +503,8 @@ class SassScriptFunctions {
464
  * @return new SassColour The greyscale colour
465
  * @see desaturate
466
  */
467
- public static function greyscale($colour) {
 
468
  return self::desaturate($colour, new SassNumber(100));
469
  }
470
 
@@ -474,8 +514,10 @@ class SassScriptFunctions {
474
  * @param SassColour: the colour
475
  * @return new SassColour: the inverted colour
476
  */
477
- public static function invert($colour) {
 
478
  SassLiteral::assertType($colour, 'SassColour');
 
479
  return $colour->with(array(
480
  'red' => 255 - $colour->getRed(true),
481
  'blue' => 255 - $colour->getBlue(true),
@@ -504,7 +546,8 @@ class SassScriptFunctions {
504
  * @throws SassScriptFunctionException If $colour1 or $colour2 is
505
  * not a colour
506
  */
507
- public static function mix($colour1, $colour2, $weight = '50%') {
 
508
  if (is_object($weight)) {
509
  $weight = new SassNumber($weight);
510
  }
@@ -560,7 +603,8 @@ class SassScriptFunctions {
560
  * @param SassNumber (red, green, blue, hue, saturation, lightness, alpha) - the amount(s) to adjust by
561
  * @return SassColour
562
  */
563
- public static function adjust_color($color, $red = 0, $green = 0, $blue = 0, $hue = 0, $saturation = 0, $lightness = 0, $alpha = 0) {
 
564
  foreach (array('red', 'green', 'blue', 'hue', 'saturation', 'lightness', 'alpha') as $property) {
565
  $obj = $$property;
566
  $color = self::adjust($color, $$property, FALSE, $property, self::INCREASE, 0, 255);
@@ -575,7 +619,8 @@ class SassScriptFunctions {
575
  * @param SassNumber (red, green, blue, saturation, lightness, alpha) - the amount(s) to scale by
576
  * @return SassColour
577
  */
578
- public static function scale_color($color, $red = 0, $green = 0, $blue = 0, $saturation = 0, $lightness = 0, $alpha = 0) {
 
579
  $maxes = array(
580
  'red' => 255,
581
  'green' => 255,
@@ -592,6 +637,7 @@ class SassScriptFunctions {
592
  $color->$property = $color->$property + $diff * $scale;
593
  }
594
  $color->hsl2rgb();
 
595
  return $color;
596
  }
597
 
@@ -601,7 +647,8 @@ class SassScriptFunctions {
601
  * @param SassNumber (red, green, blue, hue, saturation, lightness, alpha) - the amounts to scale by
602
  * @return SassColour
603
  */
604
- public static function change_color($color, $red = false, $green = false, $blue = false, $hue = false, $saturation = false, $lightness = false, $alpha = false) {
 
605
  $attrs = array();
606
  foreach (array('red', 'green', 'blue', 'hue', 'saturation', 'lightness', 'alpha') as $i => $property) {
607
  $obj = $$property;
@@ -609,6 +656,7 @@ class SassScriptFunctions {
609
  $attrs[$property] = $obj->value;
610
  }
611
  }
 
612
  return $color->with($attrs);
613
  }
614
 
@@ -624,7 +672,8 @@ class SassScriptFunctions {
624
  * @param float maximum value the amount can bemixed
625
  * @param string amount units
626
  */
627
- public static function adjust($colour, $amount, $ofCurrent, $att, $op, $min, $max, $units='') {
 
628
  SassLiteral::assertType($colour, 'SassColour');
629
  SassLiteral::assertType($amount, 'SassNumber');
630
  // SassLiteral::assertInRange($amount, $min, $max, $units);
@@ -640,13 +689,13 @@ class SassScriptFunctions {
640
  $colour->hsl2rgb();
641
  $colour->$att = $ofCurrent ? $colour->$att * (1 + ($amount * ($op === self::INCREASE ? 1 : -1))/100) : $colour->$att + ($amount * ($op === self::INCREASE ? 1 : -1));
642
  $colour->rgb2hsl();
643
- }
644
- else {
645
  $colour->rgb2hsl();
646
  $colour->$att = $ofCurrent ? $colour->$att * (1 + ($amount * ($op === self::INCREASE ? 1 : -1))/100) : $colour->$att + ($amount * ($op === self::INCREASE ? 1 : -1));
647
  $colour->$att = max($min, min($max, $colour->$att));
648
  $colour->hsl2rgb();
649
  }
 
650
  return $colour;
651
  }
652
 
@@ -654,13 +703,15 @@ class SassScriptFunctions {
654
  * returns an IE hex string for a color with an alpha channel
655
  * suitable for passing to IE filters.
656
  */
657
- public static function ie_hex_str($color) {
 
658
  if (!($color instanceof SassColour)) {
659
  $color = new SassColour($color);
660
  }
661
  $alpha = str_replace(',','.',round($color->alpha * 255));
662
  $alpha_str = str_pad(dechex($alpha), 2, '0', STR_PAD_LEFT);
663
  $col = $color->asHex(FALSE);
 
664
  return new SassString(strtoupper('#' . $alpha_str . $col));
665
  }
666
 
@@ -679,8 +730,10 @@ class SassScriptFunctions {
679
  * @return SassNumber The absolute value of the number
680
  * @throws SassScriptFunctionException If $number is not a number
681
  */
682
- public static function abs($number) {
 
683
  SassLiteral::assertType($number, 'SassNumber');
 
684
  return new SassNumber(abs($number->value).$number->units);
685
  }
686
 
@@ -694,8 +747,10 @@ class SassScriptFunctions {
694
  * @return new SassNumber The rounded number
695
  * @throws SassScriptFunctionException If $number is not a number
696
  */
697
- public static function ceil($number) {
 
698
  SassLiteral::assertType($number, 'SassNumber');
 
699
  return new SassNumber(ceil($number->value).$number->units);
700
  }
701
 
@@ -709,8 +764,10 @@ class SassScriptFunctions {
709
  * @return new SassNumber The rounded number
710
  * @throws SassScriptFunctionException If $value is not a number
711
  */
712
- public static function floor($number) {
 
713
  SassLiteral::assertType($number, 'SassNumber');
 
714
  return new SassNumber(floor($number->value).$number->units);
715
  }
716
 
@@ -724,8 +781,10 @@ class SassScriptFunctions {
724
  * @return new SassNumber The rounded number
725
  * @throws SassScriptFunctionException If $number is not a number
726
  */
727
- public static function round($number) {
 
728
  SassLiteral::assertType($number, 'SassNumber');
 
729
  return new SassNumber(str_replace(',','.',round($number->value)).$number->units);
730
  }
731
 
@@ -738,9 +797,11 @@ class SassScriptFunctions {
738
  * @throws SassScriptFunctionException If $number1 or $number2 is not
739
  * a number
740
  */
741
- public static function comparable($number1, $number2) {
 
742
  SassLiteral::assertType($number1, 'SassNumber');
743
  SassLiteral::assertType($number2, 'SassNumber');
 
744
  return new SassBoolean($number1->isComparableTo($number2));
745
  }
746
 
@@ -753,33 +814,38 @@ class SassScriptFunctions {
753
  * @return new SassNumber The number as a percentage
754
  * @throws SassScriptFunctionException If $number isn't a unitless number
755
  */
756
- public static function percentage($number) {
 
757
  $number->value *= 100;
758
  $number->units = '%';
 
759
  return $number;
760
  }
761
 
762
- public static function max() {
 
763
  $max = func_get_arg(0);
764
  foreach (func_get_args() as $var) {
765
  if ($var instanceOf SassNumber && $var->op_gt($max)->value) {
766
  $max = $var;
767
  }
768
  }
 
769
  return $max;
770
  }
771
 
772
- public static function min() {
 
773
  $min = func_get_arg(0);
774
  foreach (func_get_args() as $var) {
775
  if ($var instanceOf SassNumber && $var->op_lt($min)->value) {
776
  $min = $var;
777
  }
778
  }
 
779
  return $min;
780
  }
781
 
782
-
783
  /**
784
  * Inspects the unit of the number, returning it as a quoted string.
785
  * Alias for units.
@@ -788,7 +854,8 @@ class SassScriptFunctions {
788
  * @throws SassScriptFunctionException If $number is not a number
789
  * @see units
790
  */
791
- public static function unit($number) {
 
792
  return self::units($number);
793
  }
794
 
@@ -798,8 +865,10 @@ class SassScriptFunctions {
798
  * @return new SassString The units of the number
799
  * @throws SassScriptFunctionException If $number is not a number
800
  */
801
- public static function units($number) {
 
802
  SassLiteral::assertType($number, 'SassNumber');
 
803
  return new SassString($number->units);
804
  }
805
 
@@ -810,8 +879,10 @@ class SassScriptFunctions {
810
  * @return new SassBoolean True if the number is unitless, false if it has units.
811
  * @throws SassScriptFunctionException If $number is not a number
812
  */
813
- public static function unitless($number) {
 
814
  SassLiteral::assertType($number, 'SassNumber');
 
815
  return new SassBoolean($number->isUnitless());
816
  }
817
 
@@ -827,8 +898,10 @@ class SassScriptFunctions {
827
  * @throws SassScriptFunctionException If $string is not a string
828
  * @see unquote
829
  */
830
- public static function quote($string) {
 
831
  SassLiteral::assertType($string, 'SassString');
 
832
  return new SassString('"'.$string->value.'"');
833
  }
834
 
@@ -840,10 +913,12 @@ class SassScriptFunctions {
840
  * @throws SassScriptFunctionException If $string is not a string
841
  * @see quote
842
  */
843
- public static function unquote($string) {
 
844
  if ($string instanceof SassString) {
845
  return new SassString($string->value);
846
  }
 
847
  return $string;
848
  }
849
 
@@ -853,8 +928,10 @@ class SassScriptFunctions {
853
  * @return
854
  * @throws SassScriptFunctionException If $string is not a string
855
  */
856
- public static function get_var($string) {
 
857
  SassLiteral::assertType($string, 'SassString');
 
858
  return new SassString($string->toVar());
859
  }
860
 
@@ -867,10 +944,12 @@ class SassScriptFunctions {
867
  * @param SassList - the list to count
868
  * @return SassNumber
869
  */
870
- public static function length($list) {
 
871
  if ($list instanceOf SassString) {
872
  $list = new SassList($list->toString());
873
  }
 
874
  return new SassNumber($list->length());
875
  }
876
 
@@ -880,7 +959,8 @@ class SassScriptFunctions {
880
  * @param SassNumber - the value to get
881
  * @return anything
882
  */
883
- public static function nth($list, $n) {
 
884
  SassLiteral::assertType($n, 'SassNumber');
885
 
886
  if ($list instanceof SassString) {
@@ -890,28 +970,33 @@ class SassScriptFunctions {
890
  return $list->nth($n->value);
891
  }
892
 
893
- public static function join($one, $two, $sep = ', ') {
 
894
  return self::append($one, $two, $sep);
895
  }
896
 
897
- public static function append($list, $val, $sep = ', ') {
 
898
  if ($list instanceOf SassString) {
899
  $list = new SassList($list->toString());
900
  }
901
  $list->append($val, $sep);
 
902
  return $list;
903
  }
904
 
905
- public static function index($list, $value) {
 
906
  if (!($list instanceOf SassList)) {
907
  $list = new SassList($list->toString());
908
  }
 
909
  return $list->index($value);
910
  }
911
 
912
-
913
  // New function zip allows several lists to be combined into one list of lists. For example: zip(1px 1px 3px, solid dashed solid, red green blue) becomes 1px solid red, 1px dashed green, 3px solid blue
914
- function zip() {
 
915
  $result = new SassList('', ',');
916
  foreach (func_get_args() as $i => $arg) {
917
  $list = new SassList($arg);
@@ -920,6 +1005,7 @@ class SassScriptFunctions {
920
  $result->value[$j]->value[] = (string) $val;
921
  }
922
  }
 
923
  return $result;
924
  }
925
 
@@ -934,7 +1020,8 @@ class SassScriptFunctions {
934
  * @param anything - returns if Condition is true
935
  * @param anything - returns if Condition is false
936
  */
937
- public static function _if($condition, $if_true, $if_false) {
 
938
  return ($condition->value ? $if_true : $if_false);
939
  }
940
 
@@ -945,8 +1032,10 @@ class SassScriptFunctions {
945
  * @throws SassScriptFunctionException If $obj is not an instance of a
946
  * SassLiteral
947
  */
948
- public static function type_of($obj) {
 
949
  SassLiteral::assertType($obj, 'SassLiteral');
 
950
  return new SassString($obj->typeOf);
951
  }
952
 
@@ -957,7 +1046,8 @@ class SassScriptFunctions {
957
  * @param float the maximum value
958
  * @return the value clipped to the range
959
  */
960
- public static function inRange($value, $min, $max) {
 
961
  return ($value < $min ? $min : ($value > $max ? $max : $value));
962
  }
963
  }
36
  * @package PHamlP
37
  * @subpackage Sass.script
38
  */
39
+ class SassScriptFunctions
40
+ {
41
  const DECREASE = false;
42
  const INCREASE = true;
43
 
44
  public static $parser = FALSE;
45
+ public static function option($name)
46
+ {
47
  $options = SassParser::$instance->getOptions();
48
  if (isset($options[$name->value])) {
49
  return new SassString($options[$name->value]);
50
  }
51
+
52
  return new SassBoolean(false);
53
  }
54
 
67
  * @return new SassColour SassColour object
68
  * @throws SassScriptFunctionException if red, green, or blue are out of bounds
69
  */
70
+ public static function rgb($red, $green, $blue)
71
+ {
72
  return self::rgba($red, $green, $blue, new SassNumber(1));
73
  }
74
 
94
  * colour components are out of bounds, or or the colour is not a colour, or
95
  * alpha is out of bounds
96
  */
97
+ public static function rgba()
98
+ {
99
  switch (func_num_args()) {
100
  case 2:
101
  $colour = func_get_arg(0);
103
  SassLiteral::assertType($colour, 'SassColour');
104
  SassLiteral::assertType($alpha, 'SassNumber');
105
  SassLiteral::assertInRange($alpha, 0, 1);
106
+
107
  return $colour->with(array('alpha' => $alpha->value));
108
  break;
109
  case 4:
110
  $rgba = array();
111
  $components = func_get_args();
112
  $alpha = array_pop($components);
113
+ foreach ($components as $component) {
114
  SassLiteral::assertType($component, 'SassNumber');
115
  if ($component->units == '%') {
116
  SassLiteral::assertInRange($component, 0, 100, '%');
117
  $rgba[] = $component->value * 2.55;
118
+ } else {
 
119
  SassLiteral::assertInRange($component, 0, 255);
120
  $rgba[] = $component->value;
121
  }
123
  SassLiteral::assertType($alpha, 'SassNumber');
124
  SassLiteral::assertInRange($alpha, 0, 1);
125
  $rgba[] = $alpha->value;
126
+
127
  return new SassColour($rgba);
128
  break;
129
  default:
144
  * @return new SassColour The resulting colour
145
  * @throws SassScriptFunctionException if saturation or lightness are out of bounds
146
  */
147
+ public static function hsl($h, $s, $l)
148
+ {
149
  SassLiteral::assertInRange($s, 0, 100, '%');
150
  SassLiteral::assertInRange($l, 0, 100, '%');
151
+
152
  return self::hsla($h, $s, $l, new SassNumber(1));
153
  }
154
 
166
  * @throws SassScriptFunctionException if saturation, lightness or alpha are
167
  * out of bounds
168
  */
169
+ public static function hsla($h, $s, $l, $a)
170
+ {
171
  SassLiteral::assertType($h, 'SassNumber');
172
  SassLiteral::assertType($s, 'SassNumber');
173
  SassLiteral::assertType($l, 'SassNumber');
175
  SassLiteral::assertInRange($s, 0, 100, '%');
176
  SassLiteral::assertInRange($l, 0, 100, '%');
177
  SassLiteral::assertInRange($a, 0, 1);
178
+
179
  return new SassColour(array('hue' => $h, 'saturation' => $s, 'lightness' => $l, 'alpha' => $a));
180
  }
181
 
189
  * @return new SassNumber The red component of colour
190
  * @throws SassScriptFunctionException If $colour is not a colour
191
  */
192
+ public static function red($colour)
193
+ {
194
  SassLiteral::assertType($colour, 'SassColour');
195
+
196
  return new SassNumber($colour->red);
197
  }
198
 
202
  * @return new SassNumber The green component of colour
203
  * @throws SassScriptFunctionException If $colour is not a colour
204
  */
205
+ public static function green($colour)
206
+ {
207
  SassLiteral::assertType($colour, 'SassColour');
208
+
209
  return new SassNumber($colour->green);
210
  }
211
 
215
  * @return new SassNumber The blue component of colour
216
  * @throws SassScriptFunctionException If $colour is not a colour
217
  */
218
+ public static function blue($colour)
219
+ {
220
  SassLiteral::assertType($colour, 'SassColour');
221
+
222
  return new SassNumber($colour->blue);
223
  }
224
 
228
  * @return new SassNumber The hue component of colour
229
  * @throws SassScriptFunctionException If $colour is not a colour
230
  */
231
+ public static function hue($colour)
232
+ {
233
  SassLiteral::assertType($colour, 'SassColour');
234
+
235
  return new SassNumber($colour->getHue() . 'deg');
236
  }
237
 
241
  * @return new SassNumber The saturation component of colour
242
  * @throws SassScriptFunctionException If $colour is not a colour
243
  */
244
+ public static function saturation($colour)
245
+ {
246
  SassLiteral::assertType($colour, 'SassColour');
247
+
248
  return new SassNumber($colour->getSaturation() . '%');
249
  }
250
 
254
  * @return new SassNumber The lightness component of colour
255
  * @throws SassScriptFunctionException If $colour is not a colour
256
  */
257
+ public static function lightness($colour)
258
+ {
259
  SassLiteral::assertType($colour, 'SassColour');
260
+
261
  return new SassNumber($colour->getLightness() . '%');
262
  }
263
 
269
  *
270
  * RL modified so that the filter: alpha function doesn't bork
271
  */
272
+ public static function alpha($colour)
273
+ {
274
  try {
275
  SassLiteral::assertType($colour, 'SassColour');
276
+ } catch (Exception $e) {
 
277
  return new SassString('alpha(100)');
278
  }
279
+
280
  return new SassNumber($colour->alpha);
281
  }
282
 
286
  * @return new SassNumber The alpha component (opacity) of colour
287
  * @throws SassScriptFunctionException If $colour is not a colour
288
  */
289
+ public static function opacity($colour)
290
+ {
291
  SassLiteral::assertType($colour, 'SassColour');
292
+
293
  return new SassNumber($colour->alpha);
294
  }
295
 
305
  * @throws SassScriptFunctionException If $colour is not a colour or
306
  * $degrees is not a number
307
  */
308
+ public static function adjust_hue($colour, $degrees)
309
+ {
310
  SassLiteral::assertType($colour, 'SassColour');
311
  SassLiteral::assertType($degrees, 'SassNumber');
312
+
313
  return $colour->with(array('hue' => $colour->getHue(true) + $degrees->value));
314
  }
315
 
329
  * $amount is not a number
330
  * @see lighten_rel
331
  */
332
+ public static function lighten($colour, $amount, $ofCurrent = false)
333
+ {
334
  return self::adjust($colour, $amount, $ofCurrent, 'lightness', self::INCREASE, 0, 100, '%');
335
  }
336
 
350
  * $amount is not a number
351
  * @see adjust
352
  */
353
+ public static function darken($colour, $amount, $ofCurrent = false)
354
+ {
355
  return self::adjust($colour, $amount, $ofCurrent, 'lightness', self::DECREASE, 0, 100, '%');
356
  }
357
 
371
  * $amount is not a number
372
  * @see adjust
373
  */
374
+ public static function saturate($colour, $amount, $ofCurrent = false)
375
+ {
376
  return self::adjust($colour, $amount, $ofCurrent, 'saturation', self::INCREASE, 0, 100, '%');
377
  }
378
 
392
  * $amount is not a number
393
  * @see adjust
394
  */
395
+ public static function desaturate($colour, $amount, $ofCurrent = false)
396
+ {
397
  return self::adjust($colour, $amount, $ofCurrent, 'saturation', self::DECREASE, 0, 100, '%');
398
  }
399
 
411
  * $amount is not a number
412
  * @see opacify_rel
413
  */
414
+ public static function opacify($colour, $amount, $ofCurrent = false)
415
+ {
416
  $units = self::units($amount);
417
+
418
  return self::adjust($colour, $amount, $ofCurrent, 'alpha', self::INCREASE, 0, ($units === '%' ? 100 : 1), $units);
419
  }
420
 
431
  * @throws SassScriptFunctionException If $colour is not a colour or
432
  * $amount is not a number
433
  */
434
+ public static function transparentize($colour, $amount, $ofCurrent = false)
435
+ {
436
  $units = self::units($amount);
437
+
438
  return self::adjust($colour, $amount, $ofCurrent, 'alpha', self::DECREASE, 0, ($units === '%' ? 100 : 1), $units);
439
  }
440
 
450
  * $amount is not a number
451
  * @see opacify
452
  */
453
+ public static function fade_in($colour, $amount, $ofCurrent = false)
454
+ {
455
  return self::opacify($colour, $amount, $ofCurrent);
456
  }
457
 
467
  * $amount is not a number
468
  * @see transparentize
469
  */
470
+ public static function fade_out($colour, $amount, $ofCurrent = false)
471
+ {
472
  return self::transparentize($colour, $amount, $ofCurrent);
473
  }
474
 
479
  * @return new SassColour The comlemented colour
480
  * @uses adjust_hue()
481
  */
482
+ public static function complement($colour)
483
+ {
484
  // return self::adjust($colour, new SassNumber('180deg'), true, 'hue', self::INCREASE, 0, 360, '');
485
  return self::adjust_hue($colour, new SassNumber('180deg'));
486
  }
491
  * @return new SassColour The greyscale colour
492
  * @see desaturate
493
  */
494
+ public static function grayscale($colour)
495
+ {
496
  return self::desaturate($colour, new SassNumber(100));
497
  }
498
 
503
  * @return new SassColour The greyscale colour
504
  * @see desaturate
505
  */
506
+ public static function greyscale($colour)
507
+ {
508
  return self::desaturate($colour, new SassNumber(100));
509
  }
510
 
514
  * @param SassColour: the colour
515
  * @return new SassColour: the inverted colour
516
  */
517
+ public static function invert($colour)
518
+ {
519
  SassLiteral::assertType($colour, 'SassColour');
520
+
521
  return $colour->with(array(
522
  'red' => 255 - $colour->getRed(true),
523
  'blue' => 255 - $colour->getBlue(true),
546
  * @throws SassScriptFunctionException If $colour1 or $colour2 is
547
  * not a colour
548
  */
549
+ public static function mix($colour1, $colour2, $weight = '50%')
550
+ {
551
  if (is_object($weight)) {
552
  $weight = new SassNumber($weight);
553
  }
603
  * @param SassNumber (red, green, blue, hue, saturation, lightness, alpha) - the amount(s) to adjust by
604
  * @return SassColour
605
  */
606
+ public static function adjust_color($color, $red = 0, $green = 0, $blue = 0, $hue = 0, $saturation = 0, $lightness = 0, $alpha = 0)
607
+ {
608
  foreach (array('red', 'green', 'blue', 'hue', 'saturation', 'lightness', 'alpha') as $property) {
609
  $obj = $$property;
610
  $color = self::adjust($color, $$property, FALSE, $property, self::INCREASE, 0, 255);
619
  * @param SassNumber (red, green, blue, saturation, lightness, alpha) - the amount(s) to scale by
620
  * @return SassColour
621
  */
622
+ public static function scale_color($color, $red = 0, $green = 0, $blue = 0, $saturation = 0, $lightness = 0, $alpha = 0)
623
+ {
624
  $maxes = array(
625
  'red' => 255,
626
  'green' => 255,
637
  $color->$property = $color->$property + $diff * $scale;
638
  }
639
  $color->hsl2rgb();
640
+
641
  return $color;
642
  }
643
 
647
  * @param SassNumber (red, green, blue, hue, saturation, lightness, alpha) - the amounts to scale by
648
  * @return SassColour
649
  */
650
+ public static function change_color($color, $red = false, $green = false, $blue = false, $hue = false, $saturation = false, $lightness = false, $alpha = false)
651
+ {
652
  $attrs = array();
653
  foreach (array('red', 'green', 'blue', 'hue', 'saturation', 'lightness', 'alpha') as $i => $property) {
654
  $obj = $$property;
656
  $attrs[$property] = $obj->value;
657
  }
658
  }
659
+
660
  return $color->with($attrs);
661
  }
662
 
672
  * @param float maximum value the amount can bemixed
673
  * @param string amount units
674
  */
675
+ public static function adjust($colour, $amount, $ofCurrent, $att, $op, $min, $max, $units='')
676
+ {
677
  SassLiteral::assertType($colour, 'SassColour');
678
  SassLiteral::assertType($amount, 'SassNumber');
679
  // SassLiteral::assertInRange($amount, $min, $max, $units);
689
  $colour->hsl2rgb();
690
  $colour->$att = $ofCurrent ? $colour->$att * (1 + ($amount * ($op === self::INCREASE ? 1 : -1))/100) : $colour->$att + ($amount * ($op === self::INCREASE ? 1 : -1));
691
  $colour->rgb2hsl();
692
+ } else {
 
693
  $colour->rgb2hsl();
694
  $colour->$att = $ofCurrent ? $colour->$att * (1 + ($amount * ($op === self::INCREASE ? 1 : -1))/100) : $colour->$att + ($amount * ($op === self::INCREASE ? 1 : -1));
695
  $colour->$att = max($min, min($max, $colour->$att));
696
  $colour->hsl2rgb();
697
  }
698
+
699
  return $colour;
700
  }
701
 
703
  * returns an IE hex string for a color with an alpha channel
704
  * suitable for passing to IE filters.
705
  */
706
+ public static function ie_hex_str($color)
707
+ {
708
  if (!($color instanceof SassColour)) {
709
  $color = new SassColour($color);
710
  }
711
  $alpha = str_replace(',','.',round($color->alpha * 255));
712
  $alpha_str = str_pad(dechex($alpha), 2, '0', STR_PAD_LEFT);
713
  $col = $color->asHex(FALSE);
714
+
715
  return new SassString(strtoupper('#' . $alpha_str . $col));
716
  }
717
 
730
  * @return SassNumber The absolute value of the number
731
  * @throws SassScriptFunctionException If $number is not a number
732
  */
733
+ public static function abs($number)
734
+ {
735
  SassLiteral::assertType($number, 'SassNumber');
736
+
737
  return new SassNumber(abs($number->value).$number->units);
738
  }
739
 
747
  * @return new SassNumber The rounded number
748
  * @throws SassScriptFunctionException If $number is not a number
749
  */
750
+ public static function ceil($number)
751
+ {
752
  SassLiteral::assertType($number, 'SassNumber');
753
+
754
  return new SassNumber(ceil($number->value).$number->units);
755
  }
756
 
764
  * @return new SassNumber The rounded number
765
  * @throws SassScriptFunctionException If $value is not a number
766
  */
767
+ public static function floor($number)
768
+ {
769
  SassLiteral::assertType($number, 'SassNumber');
770
+
771
  return new SassNumber(floor($number->value).$number->units);
772
  }
773
 
781
  * @return new SassNumber The rounded number
782
  * @throws SassScriptFunctionException If $number is not a number
783
  */
784
+ public static function round($number)
785
+ {
786
  SassLiteral::assertType($number, 'SassNumber');
787
+
788
  return new SassNumber(str_replace(',','.',round($number->value)).$number->units);
789
  }
790
 
797
  * @throws SassScriptFunctionException If $number1 or $number2 is not
798
  * a number
799
  */
800
+ public static function comparable($number1, $number2)
801
+ {
802
  SassLiteral::assertType($number1, 'SassNumber');
803
  SassLiteral::assertType($number2, 'SassNumber');
804
+
805
  return new SassBoolean($number1->isComparableTo($number2));
806
  }
807
 
814
  * @return new SassNumber The number as a percentage
815
  * @throws SassScriptFunctionException If $number isn't a unitless number
816
  */
817
+ public static function percentage($number)
818
+ {
819
  $number->value *= 100;
820
  $number->units = '%';
821
+
822
  return $number;
823
  }
824
 
825
+ public static function max()
826
+ {
827
  $max = func_get_arg(0);
828
  foreach (func_get_args() as $var) {
829
  if ($var instanceOf SassNumber && $var->op_gt($max)->value) {
830
  $max = $var;
831
  }
832
  }
833
+
834
  return $max;
835
  }
836
 
837
+ public static function min()
838
+ {
839
  $min = func_get_arg(0);
840
  foreach (func_get_args() as $var) {
841
  if ($var instanceOf SassNumber && $var->op_lt($min)->value) {
842
  $min = $var;
843
  }
844
  }
845
+
846
  return $min;
847
  }
848
 
 
849
  /**
850
  * Inspects the unit of the number, returning it as a quoted string.
851
  * Alias for units.
854
  * @throws SassScriptFunctionException If $number is not a number
855
  * @see units
856
  */
857
+ public static function unit($number)
858
+ {
859
  return self::units($number);
860
  }
861
 
865
  * @return new SassString The units of the number
866
  * @throws SassScriptFunctionException If $number is not a number
867
  */
868
+ public static function units($number)
869
+ {
870
  SassLiteral::assertType($number, 'SassNumber');
871
+
872
  return new SassString($number->units);
873
  }
874
 
879
  * @return new SassBoolean True if the number is unitless, false if it has units.
880
  * @throws SassScriptFunctionException If $number is not a number
881
  */
882
+ public static function unitless($number)
883
+ {
884
  SassLiteral::assertType($number, 'SassNumber');
885
+
886
  return new SassBoolean($number->isUnitless());
887
  }
888
 
898
  * @throws SassScriptFunctionException If $string is not a string
899
  * @see unquote
900
  */
901
+ public static function quote($string)
902
+ {
903
  SassLiteral::assertType($string, 'SassString');
904
+
905
  return new SassString('"'.$string->value.'"');
906
  }
907
 
913
  * @throws SassScriptFunctionException If $string is not a string
914
  * @see quote
915
  */
916
+ public static function unquote($string)
917
+ {
918
  if ($string instanceof SassString) {
919
  return new SassString($string->value);
920
  }
921
+
922
  return $string;
923
  }
924
 
928
  * @return
929
  * @throws SassScriptFunctionException If $string is not a string
930
  */
931
+ public static function get_var($string)
932
+ {
933
  SassLiteral::assertType($string, 'SassString');
934
+
935
  return new SassString($string->toVar());
936
  }
937
 
944
  * @param SassList - the list to count
945
  * @return SassNumber
946
  */
947
+ public static function length($list)
948
+ {
949
  if ($list instanceOf SassString) {
950
  $list = new SassList($list->toString());
951
  }
952
+
953
  return new SassNumber($list->length());
954
  }
955
 
959
  * @param SassNumber - the value to get
960
  * @return anything
961
  */
962
+ public static function nth($list, $n)
963
+ {
964
  SassLiteral::assertType($n, 'SassNumber');
965
 
966
  if ($list instanceof SassString) {
970
  return $list->nth($n->value);
971
  }
972
 
973
+ public static function join($one, $two, $sep = ', ')
974
+ {
975
  return self::append($one, $two, $sep);
976
  }
977
 
978
+ public static function append($list, $val, $sep = ', ')
979
+ {
980
  if ($list instanceOf SassString) {
981
  $list = new SassList($list->toString());
982
  }
983
  $list->append($val, $sep);
984
+
985
  return $list;
986
  }
987
 
988
+ public static function index($list, $value)
989
+ {
990
  if (!($list instanceOf SassList)) {
991
  $list = new SassList($list->toString());
992
  }
993
+
994
  return $list->index($value);
995
  }
996
 
 
997
  // New function zip allows several lists to be combined into one list of lists. For example: zip(1px 1px 3px, solid dashed solid, red green blue) becomes 1px solid red, 1px dashed green, 3px solid blue
998
+ public function zip()
999
+ {
1000
  $result = new SassList('', ',');
1001
  foreach (func_get_args() as $i => $arg) {
1002
  $list = new SassList($arg);
1005
  $result->value[$j]->value[] = (string) $val;
1006
  }
1007
  }
1008
+
1009
  return $result;
1010
  }
1011
 
1020
  * @param anything - returns if Condition is true
1021
  * @param anything - returns if Condition is false
1022
  */
1023
+ public static function _if($condition, $if_true, $if_false)
1024
+ {
1025
  return ($condition->value ? $if_true : $if_false);
1026
  }
1027
 
1032
  * @throws SassScriptFunctionException If $obj is not an instance of a
1033
  * SassLiteral
1034
  */
1035
+ public static function type_of($obj)
1036
+ {
1037
  SassLiteral::assertType($obj, 'SassLiteral');
1038
+
1039
  return new SassString($obj->typeOf);
1040
  }
1041
 
1046
  * @param float the maximum value
1047
  * @return the value clipped to the range
1048
  */
1049
+ public static function inRange($value, $min, $max)
1050
+ {
1051
  return ($value < $min ? $min : ($value > $max ? $max : $value));
1052
  }
1053
  }
lib/phpsass/script/SassScriptLexer.php CHANGED
@@ -9,14 +9,14 @@
9
  * @subpackage Sass.script
10
  */
11
 
12
- require_once('literals/SassBoolean.php');
13
- require_once('literals/SassColour.php');
14
- require_once('literals/SassNumber.php');
15
- require_once('literals/SassString.php');
16
- require_once('literals/SassList.php');
17
- require_once('SassScriptFunction.php');
18
- require_once('SassScriptOperation.php');
19
- require_once('SassScriptVariable.php');
20
 
21
  /**
22
  * SassScriptLexer class.
@@ -26,13 +26,14 @@ require_once('SassScriptVariable.php');
26
  * @package PHamlP
27
  * @subpackage Sass.script
28
  */
29
- class SassScriptLexer {
 
30
  const MATCH_WHITESPACE = '/^\s+/';
31
 
32
  /**
33
  * Static holder for last instance of SassScriptLexer
34
  */
35
- static public $instance;
36
 
37
  /**
38
  * @var SassScriptParser the parser object
@@ -43,7 +44,8 @@ class SassScriptLexer {
43
  * SassScriptLexer constructor.
44
  * @return SassScriptLexer
45
  */
46
- public function __construct($parser) {
 
47
  $this->parser = $parser;
48
  self::$instance = $this;
49
  }
@@ -54,7 +56,8 @@ class SassScriptLexer {
54
  * @param SassContext the context in which the expression is lexed
55
  * @return array tokens
56
  */
57
- public function lex($string, $context) {
 
58
  // if it's already lexed, just return it as-is
59
  if (is_object($string)) {
60
  return array($string);
@@ -66,43 +69,34 @@ class SassScriptLexer {
66
  while ($string !== false) {
67
  if (($match = $this->isWhitespace($string)) !== false) {
68
  $tokens[] = null;
69
- }
70
- elseif (($match = SassScriptFunction::isa($string)) !== false) {
71
  preg_match(SassScriptFunction::MATCH_FUNC, $match, $matches);
72
  $args = array();
73
  foreach (SassScriptFunction::extractArgs($matches[SassScriptFunction::ARGS], false, $context) as $key => $expression) {
74
  $args[$key] = $this->parser->evaluate($expression, $context);
75
  }
76
  $tokens[] = new SassScriptFunction($matches[SassScriptFunction::NAME], $args);
77
- }
78
- elseif (($match = SassBoolean::isa($string)) !== false) {
79
  $tokens[] = new SassBoolean($match);
80
- }
81
- elseif (($match = SassColour::isa($string)) !== false) {
82
  $tokens[] = new SassColour($match);
83
- }
84
- elseif (($match = SassNumber::isa($string)) !== false) {
85
  $tokens[] = new SassNumber($match);
86
- }
87
- elseif (($match = SassString::isa($string)) !== false) {
88
  $stringed = new SassString($match);
89
  if (strlen($stringed->quote) == 0 && SassList::isa($string) !== false) {
90
  $tokens[] = new SassList($string);
91
  } else {
92
  $tokens[] = $stringed;
93
  }
94
- }
95
- elseif ($string == '()') {
96
  $match = $string;
97
  $tokens[] = new SassList($match);
98
- }
99
- elseif (($match = SassScriptOperation::isa($string)) !== false) {
100
  $tokens[] = new SassScriptOperation($match);
101
- }
102
- elseif (($match = SassScriptVariable::isa($string)) !== false) {
103
  $tokens[] = new SassScriptVariable($match);
104
- }
105
- else {
106
  $_string = $string;
107
  $match = '';
108
  while (strlen($_string) && !$this->isWhitespace($_string)) {
@@ -118,6 +112,7 @@ class SassScriptLexer {
118
  }
119
  $string = substr($string, strlen($match));
120
  }
 
121
  return $tokens;
122
  }
123
 
@@ -127,7 +122,8 @@ class SassScriptLexer {
127
  * @param string the subject string
128
  * @return mixed match at the start of the string or false if no match
129
  */
130
- public function isWhitespace($subject) {
 
131
  return (preg_match(self::MATCH_WHITESPACE, $subject, $matches) ? $matches[0] : false);
132
  }
133
  }
9
  * @subpackage Sass.script
10
  */
11
 
12
+ require_once 'literals/SassBoolean.php';
13
+ require_once 'literals/SassColour.php';
14
+ require_once 'literals/SassNumber.php';
15
+ require_once 'literals/SassString.php';
16
+ require_once 'literals/SassList.php';
17
+ require_once 'SassScriptFunction.php';
18
+ require_once 'SassScriptOperation.php';
19
+ require_once 'SassScriptVariable.php';
20
 
21
  /**
22
  * SassScriptLexer class.
26
  * @package PHamlP
27
  * @subpackage Sass.script
28
  */
29
+ class SassScriptLexer
30
+ {
31
  const MATCH_WHITESPACE = '/^\s+/';
32
 
33
  /**
34
  * Static holder for last instance of SassScriptLexer
35
  */
36
+ public static $instance;
37
 
38
  /**
39
  * @var SassScriptParser the parser object
44
  * SassScriptLexer constructor.
45
  * @return SassScriptLexer
46
  */
47
+ public function __construct($parser)
48
+ {
49
  $this->parser = $parser;
50
  self::$instance = $this;
51
  }
56
  * @param SassContext the context in which the expression is lexed
57
  * @return array tokens
58
  */
59
+ public function lex($string, $context)
60
+ {
61
  // if it's already lexed, just return it as-is
62
  if (is_object($string)) {
63
  return array($string);
69
  while ($string !== false) {
70
  if (($match = $this->isWhitespace($string)) !== false) {
71
  $tokens[] = null;
72
+ } elseif (($match = SassScriptFunction::isa($string)) !== false) {
 
73
  preg_match(SassScriptFunction::MATCH_FUNC, $match, $matches);
74
  $args = array();
75
  foreach (SassScriptFunction::extractArgs($matches[SassScriptFunction::ARGS], false, $context) as $key => $expression) {
76
  $args[$key] = $this->parser->evaluate($expression, $context);
77
  }
78
  $tokens[] = new SassScriptFunction($matches[SassScriptFunction::NAME], $args);
79
+ } elseif (($match = SassBoolean::isa($string)) !== false) {
 
80
  $tokens[] = new SassBoolean($match);
81
+ } elseif (($match = SassColour::isa($string)) !== false) {
 
82
  $tokens[] = new SassColour($match);
83
+ } elseif (($match = SassNumber::isa($string)) !== false) {
 
84
  $tokens[] = new SassNumber($match);
85
+ } elseif (($match = SassString::isa($string)) !== false) {
 
86
  $stringed = new SassString($match);
87
  if (strlen($stringed->quote) == 0 && SassList::isa($string) !== false) {
88
  $tokens[] = new SassList($string);
89
  } else {
90
  $tokens[] = $stringed;
91
  }
92
+ } elseif ($string == '()') {
 
93
  $match = $string;
94
  $tokens[] = new SassList($match);
95
+ } elseif (($match = SassScriptOperation::isa($string)) !== false) {
 
96
  $tokens[] = new SassScriptOperation($match);
97
+ } elseif (($match = SassScriptVariable::isa($string)) !== false) {
 
98
  $tokens[] = new SassScriptVariable($match);
99
+ } else {
 
100
  $_string = $string;
101
  $match = '';
102
  while (strlen($_string) && !$this->isWhitespace($_string)) {
112
  }
113
  $string = substr($string, strlen($match));
114
  }
115
+
116
  return $tokens;
117
  }
118
 
122
  * @param string the subject string
123
  * @return mixed match at the start of the string or false if no match
124
  */
125
+ public function isWhitespace($subject)
126
+ {
127
  return (preg_match(self::MATCH_WHITESPACE, $subject, $matches) ? $matches[0] : false);
128
  }
129
  }
lib/phpsass/script/SassScriptOperation.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.script
17
  */
18
- class SassScriptOperation {
 
19
  const MATCH = '/^(\(|\)|\+|-|\*|\/|%|<=|>=|<|>|==|!=|=|#{|}|,|and\b|or\b|xor\b|not\b)/';
20
 
21
  /**
@@ -82,7 +83,8 @@ class SassScriptOperation {
82
  * @param mixed string: operator symbol; array: operator token
83
  * @return SassScriptOperation
84
  */
85
- public function __construct($operation) {
 
86
  if (is_string($operation)) {
87
  $operation = self::$operators[$operation];
88
  }
@@ -100,11 +102,11 @@ class SassScriptOperation {
100
  * @return mixed value of the property
101
  * @throws SassScriptOperationException if the property does not exist
102
  */
103
- public function __get($name) {
 
104
  if (property_exists($this, $name)) {
105
  return $this->$name;
106
- }
107
- else {
108
  throw new SassScriptOperationException('Unknown property: ' . $name, SassScriptParser::$context->node);
109
  }
110
  }
@@ -116,7 +118,8 @@ class SassScriptOperation {
116
  * @throws SassScriptOperationException if the oprand count is incorrect or
117
  * the operation is undefined
118
  */
119
- public function perform($operands) {
 
120
  if (count($operands) !== $this->operandCount) {
121
  throw new SassScriptOperationException('Incorrect operand count for ' . get_class($operands[0]) . '; expected ' . $this->operandCount . ', received ' . count($operands), SassScriptParser::$context->node);
122
  }
@@ -136,8 +139,7 @@ class SassScriptOperation {
136
 
137
  if (count($operands) > 1 && is_null($operands[1])) {
138
  $operation = 'op_unary_' . $this->operator;
139
- }
140
- else {
141
  $operation = 'op_' . $this->operator;
142
  if ($this->associativity == 'l') {
143
  $operands = array_reverse($operands);
@@ -146,6 +148,7 @@ class SassScriptOperation {
146
 
147
  if (method_exists($operands[0], $operation)) {
148
  $op = clone $operands[0];
 
149
  return $op->$operation(!empty($operands[1]) ? $operands[1] : null);
150
  }
151
 
@@ -168,19 +171,22 @@ class SassScriptOperation {
168
  * @param string the subject string
169
  * @return mixed match at the start of the string or false if no match
170
  */
171
- public static function isa($subject) {
 
172
  # begins with a "/x", almost always a path without quotes.
173
  if (preg_match('/^\/[^0-9\.\-\s]+/', $subject)) {
174
  return FALSE;
175
  }
 
176
  return (preg_match(self::MATCH, $subject, $matches) ? trim($matches[1]) : false);
177
  }
178
 
179
  /**
180
  * Converts the operation back into it's SASS representation
181
  */
182
- public function __toString() {
183
- foreach(SassScriptOperation::$operators as $char => $operator) {
 
184
  if ($operator[0] == trim($this->operator)) {
185
  return $char;
186
  }
15
  * @package PHamlP
16
  * @subpackage Sass.script
17
  */
18
+ class SassScriptOperation
19
+ {
20
  const MATCH = '/^(\(|\)|\+|-|\*|\/|%|<=|>=|<|>|==|!=|=|#{|}|,|and\b|or\b|xor\b|not\b)/';
21
 
22
  /**
83
  * @param mixed string: operator symbol; array: operator token
84
  * @return SassScriptOperation
85
  */
86
+ public function __construct($operation)
87
+ {
88
  if (is_string($operation)) {
89
  $operation = self::$operators[$operation];
90
  }
102
  * @return mixed value of the property
103
  * @throws SassScriptOperationException if the property does not exist
104
  */
105
+ public function __get($name)
106
+ {
107
  if (property_exists($this, $name)) {
108
  return $this->$name;
109
+ } else {
 
110
  throw new SassScriptOperationException('Unknown property: ' . $name, SassScriptParser::$context->node);
111
  }
112
  }
118
  * @throws SassScriptOperationException if the oprand count is incorrect or
119
  * the operation is undefined
120
  */
121
+ public function perform($operands)
122
+ {
123
  if (count($operands) !== $this->operandCount) {
124
  throw new SassScriptOperationException('Incorrect operand count for ' . get_class($operands[0]) . '; expected ' . $this->operandCount . ', received ' . count($operands), SassScriptParser::$context->node);
125
  }
139
 
140
  if (count($operands) > 1 && is_null($operands[1])) {
141
  $operation = 'op_unary_' . $this->operator;
142
+ } else {
 
143
  $operation = 'op_' . $this->operator;
144
  if ($this->associativity == 'l') {
145
  $operands = array_reverse($operands);
148
 
149
  if (method_exists($operands[0], $operation)) {
150
  $op = clone $operands[0];
151
+
152
  return $op->$operation(!empty($operands[1]) ? $operands[1] : null);
153
  }
154
 
171
  * @param string the subject string
172
  * @return mixed match at the start of the string or false if no match
173
  */
174
+ public static function isa($subject)
175
+ {
176
  # begins with a "/x", almost always a path without quotes.
177
  if (preg_match('/^\/[^0-9\.\-\s]+/', $subject)) {
178
  return FALSE;
179
  }
180
+
181
  return (preg_match(self::MATCH, $subject, $matches) ? trim($matches[1]) : false);
182
  }
183
 
184
  /**
185
  * Converts the operation back into it's SASS representation
186
  */
187
+ public function __toString()
188
+ {
189
+ foreach (SassScriptOperation::$operators as $char => $operator) {
190
  if ($operator[0] == trim($this->operator)) {
191
  return $char;
192
  }
lib/phpsass/script/SassScriptParser.php CHANGED
@@ -9,8 +9,8 @@
9
  * @subpackage Sass.script
10
  */
11
 
12
- require_once('SassScriptLexer.php');
13
- require_once('SassScriptParserExceptions.php');
14
 
15
  /**
16
  * SassScriptParser class.
@@ -19,7 +19,8 @@ require_once('SassScriptParserExceptions.php');
19
  * @package PHamlP
20
  * @subpackage Sass.script
21
  */
22
- class SassScriptParser {
 
23
  const MATCH_INTERPOLATION = '/(?<!\\\\)#\{(.*?)\}/';
24
  const DEFAULT_ENV = 0;
25
  const CSS_RULE = 1;
@@ -44,7 +45,8 @@ class SassScriptParser {
44
  * SassScriptParser constructor.
45
  * @return SassScriptParser
46
  */
47
- public function __construct() {
 
48
  $this->lexer = new SassScriptLexer($this);
49
  self::$instance = $this;
50
  }
@@ -55,7 +57,8 @@ class SassScriptParser {
55
  * @param SassContext the context in which the string is interpolated
56
  * @return string the interpolated text
57
  */
58
- public function interpolate($string, $context) {
 
59
  for ($i = 0, $n = preg_match_all(self::MATCH_INTERPOLATION, $string, $matches); $i < $n; $i++) {
60
  $var = $this->evaluate($matches[1][$i], $context);
61
 
@@ -65,20 +68,18 @@ class SassScriptParser {
65
  $var = $var->toString();
66
  }
67
 
68
- if(preg_match('/^unquote\((["\'])(.*)\1\)$/', $var, $match)){
69
  $val = $match[2];
70
- }
71
- else if($var == '""'){
72
  $val = "";
73
- }
74
- else if(preg_match('/^(["\'])(.*)\1$/', $var, $match)){
75
  $val = $match[2];
76
- }
77
- else {
78
  $val = $var;
79
  }
80
  $matches[1][$i] = $val;
81
  }
 
82
  return str_replace($matches[0], $matches[1], $string);
83
  }
84
 
@@ -89,7 +90,8 @@ class SassScriptParser {
89
  * @param integer the environment in which the expression is evaluated
90
  * @return SassLiteral parsed value
91
  */
92
- public function evaluate($expression, $context, $environment = self::DEFAULT_ENV) {
 
93
  self::$context = $context;
94
  $operands = array();
95
 
@@ -100,14 +102,12 @@ class SassScriptParser {
100
  if ($token instanceof SassScriptFunction) {
101
  $perform = $token->perform();
102
  array_push($operands, $perform);
103
- }
104
- elseif ($token instanceof SassLiteral) {
105
  if ($token instanceof SassString) {
106
  $token = new SassString($this->interpolate($token->toString(), self::$context));
107
  }
108
  array_push($operands, $token);
109
- }
110
- else {
111
  $args = array();
112
  for ($i = 0, $c = $token->operandCount; $i < $c; $i++) {
113
  $args[] = array_pop($operands);
@@ -127,27 +127,26 @@ class SassScriptParser {
127
  * @param integer the environment in which the expression is parsed
128
  * @return array tokens in RPN
129
  */
130
- public function parse($expression, $context, $environment=self::DEFAULT_ENV) {
 
131
  $outputQueue = array();
132
  $operatorStack = array();
133
  $parenthesis = 0;
134
 
135
  $tokens = $this->lexer->lex($expression, $context);
136
 
137
- foreach($tokens as $i=>$token) {
138
  // If two literals/expessions are seperated by whitespace use the concat operator
139
  if (empty($token)) {
140
  if (isset($tokens[$i+1])) {
141
  if ($i > 0 && (!$tokens[$i-1] instanceof SassScriptOperation || $tokens[$i-1]->operator === SassScriptOperation::$operators[')'][0]) &&
142
  (!$tokens[$i+1] instanceof SassScriptOperation || $tokens[$i+1]->operator === SassScriptOperation::$operators['('][0])) {
143
  $token = new SassScriptOperation(SassScriptOperation::$defaultOperator, $context);
144
- }
145
- else {
146
  continue;
147
  }
148
  }
149
- }
150
- elseif ($token instanceof SassScriptVariable) {
151
  $token = $token->evaluate($context);
152
  $environment = self::DEFAULT_ENV;
153
  }
@@ -213,8 +212,7 @@ class SassScriptParser {
213
  while ($c = count($operatorStack)) { // While there are operators on the stack:
214
  if ($operatorStack[$c - 1]->operator !== SassScriptOperation::$operators['('][0]) {
215
  array_push($outputQueue, array_pop($operatorStack));
216
- }
217
- else {
218
  throw new SassScriptParserException('Unmatched parentheses', $context->node);
219
  }
220
  }
@@ -225,7 +223,8 @@ class SassScriptParser {
225
  /**
226
  * Reduces a set down to a singular form
227
  */
228
- public static function makeSingular($operands) {
 
229
  if (count($operands) == 1) {
230
  return $operands[0];
231
  }
@@ -239,12 +238,10 @@ class SassScriptParser {
239
  }
240
  if ($result instanceOf SassString) {
241
  $result = $result->op_concat($operand);
242
- }
243
- else {
244
  $result = $result->op_plus($operand);
245
  }
246
- }
247
- else {
248
  $string = new SassString(' ');
249
  if (!$result) {
250
  $result = $string;
9
  * @subpackage Sass.script
10
  */
11
 
12
+ require_once 'SassScriptLexer.php';
13
+ require_once 'SassScriptParserExceptions.php';
14
 
15
  /**
16
  * SassScriptParser class.
19
  * @package PHamlP
20
  * @subpackage Sass.script
21
  */
22
+ class SassScriptParser
23
+ {
24
  const MATCH_INTERPOLATION = '/(?<!\\\\)#\{(.*?)\}/';
25
  const DEFAULT_ENV = 0;
26
  const CSS_RULE = 1;
45
  * SassScriptParser constructor.
46
  * @return SassScriptParser
47
  */
48
+ public function __construct()
49
+ {
50
  $this->lexer = new SassScriptLexer($this);
51
  self::$instance = $this;
52
  }
57
  * @param SassContext the context in which the string is interpolated
58
  * @return string the interpolated text
59
  */
60
+ public function interpolate($string, $context)
61
+ {
62
  for ($i = 0, $n = preg_match_all(self::MATCH_INTERPOLATION, $string, $matches); $i < $n; $i++) {
63
  $var = $this->evaluate($matches[1][$i], $context);
64
 
68
  $var = $var->toString();
69
  }
70
 
71
+ if (preg_match('/^unquote\((["\'])(.*)\1\)$/', $var, $match)) {
72
  $val = $match[2];
73
+ } elseif ($var == '""') {
 
74
  $val = "";
75
+ } elseif (preg_match('/^(["\'])(.*)\1$/', $var, $match)) {
 
76
  $val = $match[2];
77
+ } else {
 
78
  $val = $var;
79
  }
80
  $matches[1][$i] = $val;
81
  }
82
+
83
  return str_replace($matches[0], $matches[1], $string);
84
  }
85
 
90
  * @param integer the environment in which the expression is evaluated
91
  * @return SassLiteral parsed value
92
  */
93
+ public function evaluate($expression, $context, $environment = self::DEFAULT_ENV)
94
+ {
95
  self::$context = $context;
96
  $operands = array();
97
 
102
  if ($token instanceof SassScriptFunction) {
103
  $perform = $token->perform();
104
  array_push($operands, $perform);
105
+ } elseif ($token instanceof SassLiteral) {
 
106
  if ($token instanceof SassString) {
107
  $token = new SassString($this->interpolate($token->toString(), self::$context));
108
  }
109
  array_push($operands, $token);
110
+ } else {
 
111
  $args = array();
112
  for ($i = 0, $c = $token->operandCount; $i < $c; $i++) {
113
  $args[] = array_pop($operands);
127
  * @param integer the environment in which the expression is parsed
128
  * @return array tokens in RPN
129
  */
130
+ public function parse($expression, $context, $environment=self::DEFAULT_ENV)
131
+ {
132
  $outputQueue = array();
133
  $operatorStack = array();
134
  $parenthesis = 0;
135
 
136
  $tokens = $this->lexer->lex($expression, $context);
137
 
138
+ foreach ($tokens as $i=>$token) {
139
  // If two literals/expessions are seperated by whitespace use the concat operator
140
  if (empty($token)) {
141
  if (isset($tokens[$i+1])) {
142
  if ($i > 0 && (!$tokens[$i-1] instanceof SassScriptOperation || $tokens[$i-1]->operator === SassScriptOperation::$operators[')'][0]) &&
143
  (!$tokens[$i+1] instanceof SassScriptOperation || $tokens[$i+1]->operator === SassScriptOperation::$operators['('][0])) {
144
  $token = new SassScriptOperation(SassScriptOperation::$defaultOperator, $context);
145
+ } else {
 
146
  continue;
147
  }
148
  }
149
+ } elseif ($token instanceof SassScriptVariable) {
 
150
  $token = $token->evaluate($context);
151
  $environment = self::DEFAULT_ENV;
152
  }
212
  while ($c = count($operatorStack)) { // While there are operators on the stack:
213
  if ($operatorStack[$c - 1]->operator !== SassScriptOperation::$operators['('][0]) {
214
  array_push($outputQueue, array_pop($operatorStack));
215
+ } else {
 
216
  throw new SassScriptParserException('Unmatched parentheses', $context->node);
217
  }
218
  }
223
  /**
224
  * Reduces a set down to a singular form
225
  */
226
+ public static function makeSingular($operands)
227
+ {
228
  if (count($operands) == 1) {
229
  return $operands[0];
230
  }
238
  }
239
  if ($result instanceOf SassString) {
240
  $result = $result->op_concat($operand);
241
+ } else {
 
242
  $result = $result->op_plus($operand);
243
  }
244
+ } else {
 
245
  $string = new SassString(' ');
246
  if (!$result) {
247
  $result = $string;
lib/phpsass/script/SassScriptParserExceptions.php CHANGED
@@ -37,4 +37,4 @@ class SassScriptOperationException extends SassScriptParserException {}
37
  * @package PHamlP
38
  * @subpackage Sass.script
39
  */
40
- class SassScriptFunctionException extends SassScriptParserException {}
37
  * @package PHamlP
38
  * @subpackage Sass.script
39
  */
40
+ class SassScriptFunctionException extends SassScriptParserException {}
lib/phpsass/script/SassScriptVariable.php CHANGED
@@ -8,18 +8,19 @@
8
  * @package PHamlP
9
  * @subpackage Sass.script.literals
10
  */
11
-
12
  /**
13
  * SassVariable class.
14
  * @package PHamlP
15
  * @subpackage Sass.script.literals
16
  */
17
- class SassScriptVariable {
 
18
  /**
19
  * Regex for matching and extracting Variables
20
  */
21
  const MATCH = '/^(?<!\\\\)(?(?!!important\b)[!\$]([\w-]+))/';
22
-
23
  /**
24
  * @var string name of variable
25
  */
@@ -30,7 +31,8 @@ class SassScriptVariable {
30
  * @param string value of the Variable type
31
  * @return SassVariable
32
  */
33
- public function __construct($value) {
 
34
  $this->name = substr($value, 1);
35
  }
36
 
@@ -39,7 +41,8 @@ class SassScriptVariable {
39
  * @param SassContext context of the variable
40
  * @return SassLiteral the SassScript object for this variable
41
  */
42
- public function evaluate($context) {
 
43
  return $context->getVariable($this->name);
44
  }
45
 
@@ -49,9 +52,10 @@ class SassScriptVariable {
49
  * @param string the subject string
50
  * @return mixed match at the start of the string or false if no match
51
  */
52
- public static function isa($subject) {
 
53
  // we need to do the check as preg_match returns a count of 1 if
54
  // subject == '!important'; the match being an empty match
55
  return (preg_match(self::MATCH, $subject, $matches) ? (empty($matches[0]) ? false : $matches[0]) : false);
56
  }
57
- }
8
  * @package PHamlP
9
  * @subpackage Sass.script.literals
10
  */
11
+
12
  /**
13
  * SassVariable class.
14
  * @package PHamlP
15
  * @subpackage Sass.script.literals
16
  */
17
+ class SassScriptVariable
18
+ {
19
  /**
20
  * Regex for matching and extracting Variables
21
  */
22
  const MATCH = '/^(?<!\\\\)(?(?!!important\b)[!\$]([\w-]+))/';
23
+
24
  /**
25
  * @var string name of variable
26
  */
31
  * @param string value of the Variable type
32
  * @return SassVariable
33
  */
34
+ public function __construct($value)
35
+ {
36
  $this->name = substr($value, 1);
37
  }
38
 
41
  * @param SassContext context of the variable
42
  * @return SassLiteral the SassScript object for this variable
43
  */
44
+ public function evaluate($context)
45
+ {
46
  return $context->getVariable($this->name);
47
  }
48
 
52
  * @param string the subject string
53
  * @return mixed match at the start of the string or false if no match
54
  */
55
+ public static function isa($subject)
56
+ {
57
  // we need to do the check as preg_match returns a count of 1 if
58
  // subject == '!important'; the match being an empty match
59
  return (preg_match(self::MATCH, $subject, $matches) ? (empty($matches[0]) ? false : $matches[0]) : false);
60
  }
61
+ }
lib/phpsass/script/literals/SassBoolean.php CHANGED
@@ -9,14 +9,15 @@
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
- require_once('SassLiteral.php');
13
 
14
  /**
15
  * SassBoolean class.
16
  * @package PHamlP
17
  * @subpackage Sass.script.literals
18
  */
19
- class SassBoolean extends SassLiteral {
 
20
  /**@#+
21
  * Regex for matching and extracting booleans
22
  */
@@ -27,14 +28,13 @@ class SassBoolean extends SassLiteral {
27
  * @param string value of the boolean type
28
  * @return SassBoolean
29
  */
30
- public function __construct($value) {
 
31
  if (is_bool($value)) {
32
  $this->value = $value;
33
- }
34
- elseif ($value === 'true' || $value === 'false') {
35
  $this->value = ($value === 'true' ? true : false);
36
- }
37
- else {
38
  throw new SassBooleanException('Invalid SassBoolean', SassScriptParser::$context->node);
39
  }
40
  }
@@ -43,7 +43,8 @@ class SassBoolean extends SassLiteral {
43
  * Returns the value of this boolean.
44
  * @return boolean the value of this boolean
45
  */
46
- public function getValue() {
 
47
  return $this->value;
48
  }
49
 
@@ -51,18 +52,22 @@ class SassBoolean extends SassLiteral {
51
  * Returns a string representation of the value.
52
  * @return string string representation of the value.
53
  */
54
- public function toString() {
 
55
  return $this->getValue() ? 'true' : 'false';
56
  }
57
 
58
- public function length() {
 
59
  return 1;
60
  }
61
 
62
- public function nth($i) {
 
63
  if ($i == 1 && isset($this->value)) {
64
  return new SassBoolean($this->value);
65
  }
 
66
  return new SassBoolean(false);
67
  }
68
 
@@ -72,7 +77,8 @@ class SassBoolean extends SassLiteral {
72
  * @param string the subject string
73
  * @return mixed match at the start of the string or false if no match
74
  */
75
- public static function isa($subject) {
 
76
  return (preg_match(self::MATCH, $subject, $matches) ? $matches[0] : false);
77
  }
78
  }
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
+ require_once 'SassLiteral.php';
13
 
14
  /**
15
  * SassBoolean class.
16
  * @package PHamlP
17
  * @subpackage Sass.script.literals
18
  */
19
+ class SassBoolean extends SassLiteral
20
+ {
21
  /**@#+
22
  * Regex for matching and extracting booleans
23
  */
28
  * @param string value of the boolean type
29
  * @return SassBoolean
30
  */
31
+ public function __construct($value)
32
+ {
33
  if (is_bool($value)) {
34
  $this->value = $value;
35
+ } elseif ($value === 'true' || $value === 'false') {
 
36
  $this->value = ($value === 'true' ? true : false);
37
+ } else {
 
38
  throw new SassBooleanException('Invalid SassBoolean', SassScriptParser::$context->node);
39
  }
40
  }
43
  * Returns the value of this boolean.
44
  * @return boolean the value of this boolean
45
  */
46
+ public function getValue()
47
+ {
48
  return $this->value;
49
  }
50
 
52
  * Returns a string representation of the value.
53
  * @return string string representation of the value.
54
  */
55
+ public function toString()
56
+ {
57
  return $this->getValue() ? 'true' : 'false';
58
  }
59
 
60
+ public function length()
61
+ {
62
  return 1;
63
  }
64
 
65
+ public function nth($i)
66
+ {
67
  if ($i == 1 && isset($this->value)) {
68
  return new SassBoolean($this->value);
69
  }
70
+
71
  return new SassBoolean(false);
72
  }
73
 
77
  * @param string the subject string
78
  * @return mixed match at the start of the string or false if no match
79
  */
80
+ public static function isa($subject)
81
+ {
82
  return (preg_match(self::MATCH, $subject, $matches) ? $matches[0] : false);
83
  }
84
  }
lib/phpsass/script/literals/SassColour.php CHANGED
@@ -9,7 +9,7 @@
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
- require_once('SassLiteral.php');
13
 
14
  /**
15
  * SassColour class.
@@ -35,7 +35,8 @@ require_once('SassLiteral.php');
35
  * @package PHamlP
36
  * @subpackage Sass.script.literals
37
  */
38
- class SassColour extends SassLiteral {
 
39
  /**@#+
40
  * Regexes for matching and extracting colours
41
  */
@@ -46,7 +47,7 @@ class SassColour extends SassLiteral {
46
  /**@#-*/
47
 
48
  /**@#-*/
49
- static public $svgColours = array(
50
  'aliceblue' => '#f0f8ff',
51
  'antiquewhite' => '#faebd7',
52
  'aqua' => '#00ffff',
@@ -197,12 +198,12 @@ class SassColour extends SassLiteral {
197
  /**
198
  * @var array reverse array (value => name) of named SVG1.0 colours
199
  */
200
- static public $_svgColours;
201
 
202
  /**
203
  * @var array reverse array (value => name) of named HTML4 colours
204
  */
205
- static public $_html4Colours = array(
206
  '#000000' => 'black',
207
  '#000080' => 'navy',
208
  '#0000ff' => 'blue',
@@ -221,7 +222,7 @@ class SassColour extends SassLiteral {
221
  '#ffffff' => 'white',
222
  );
223
 
224
- static public $regex;
225
 
226
  /**@#+
227
  * RGB colour components
@@ -229,7 +230,7 @@ class SassColour extends SassLiteral {
229
  /**
230
  * @var array RGB colour components. Used to check for RGB attributes.
231
  */
232
- static public $rgb = array('red', 'green', 'blue');
233
  /**
234
  * @var integer red component. 0 - 255
235
  */
@@ -249,7 +250,7 @@ class SassColour extends SassLiteral {
249
  /**
250
  * @var array HSL colour components. Used to check for HSL attributes.
251
  */
252
- static public $hsl = array('hue', 'saturation', 'lightness');
253
  /**
254
  * @var float hue component. 0 - 360
255
  */
@@ -282,7 +283,8 @@ class SassColour extends SassLiteral {
282
  * @param mixed the colour
283
  * @return SassColour
284
  */
285
- public function __construct($colour) {
 
286
  if (is_string($colour)) {
287
  $colour = strtolower($colour);
288
  if ($colour === self::TRANSPARENT) {
@@ -290,8 +292,7 @@ class SassColour extends SassLiteral {
290
  $this->green = 0;
291
  $this->blue = 0;
292
  $this->alpha = 0;
293
- }
294
- else {
295
  if (array_key_exists($colour, self::$svgColours)) {
296
  $colour = self::$svgColours[$colour];
297
  }
@@ -299,8 +300,7 @@ class SassColour extends SassLiteral {
299
  for ($i = 1; $i < 4; $i++) {
300
  $matches[$i] = str_repeat($matches[$i], 2);
301
  }
302
- }
303
- else {
304
  preg_match(self::EXTRACT_6, $colour, $matches);
305
  }
306
 
@@ -312,29 +312,25 @@ class SassColour extends SassLiteral {
312
  $this->blue = intval($matches[3], 16);
313
  $this->alpha = 1;
314
  }
315
- }
316
- elseif (is_array($colour)) {
317
  $scheme = $this->assertValid($colour);
318
  if ($scheme == 'rgb') {
319
  $this->red = $colour['red'];
320
  $this->green = $colour['green'];
321
  $this->blue = $colour['blue'];
322
  $this->alpha = (isset($colour['alpha']) ? $colour['alpha'] : 1);
323
- }
324
- elseif ($scheme == 'hsl') {
325
  $this->hue = $colour['hue'];
326
  $this->saturation = $colour['saturation'];
327
  $this->lightness = $colour['lightness'];
328
  $this->alpha = (isset($colour['alpha']) ? $colour['alpha'] : 1);
329
- }
330
- else {
331
  $this->red = $colour[0];
332
  $this->green = $colour[1];
333
  $this->blue = $colour[2];
334
  $this->alpha = (isset($colour[3]) ? $colour[3] : 1);
335
  }
336
- }
337
- else {
338
  throw new SassColourException('Colour must be a array', SassScriptParser::$context->node);
339
  }
340
  }
@@ -344,7 +340,8 @@ class SassColour extends SassLiteral {
344
  * @param mixed SassColour|SassNumber value to add
345
  * @return sassColour the colour result
346
  */
347
- public function op_plus($other) {
 
348
  if ($other instanceof SassNumber) {
349
  if (!$other->isUnitless()) {
350
  return new SassString($this->toString() . $other->value);
@@ -353,16 +350,15 @@ class SassColour extends SassLiteral {
353
  $this->red = $this->getRed() + $other->value;
354
  $this->green = $this->getGreen() + $other->value;
355
  $this->blue = $this->getBlue() + $other->value;
356
- }
357
- elseif (!$other instanceof SassColour) {
358
  return new SassString($this->toString() . $other->value);
359
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
360
- }
361
- else {
362
  $this->red = $this->getRed() + $other->getRed();
363
  $this->green = $this->getGreen() + $other->getGreen();
364
  $this->blue = $this->getBlue() + $other->getBlue();
365
  }
 
366
  return $this;
367
  }
368
 
@@ -371,7 +367,8 @@ class SassColour extends SassLiteral {
371
  * @param mixed value (SassColour or SassNumber) to subtract
372
  * @return sassColour the colour result
373
  */
374
- public function op_minus($other) {
 
375
  if ($other instanceof SassNumber) {
376
  if (!$other->isUnitless()) {
377
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
@@ -379,15 +376,14 @@ class SassColour extends SassLiteral {
379
  $this->red = $this->getRed() - $other->value;
380
  $this->green = $this->getGreen() - $other->value;
381
  $this->blue = $this->getBlue() - $other->value;
382
- }
383
- elseif (!$other instanceof SassColour) {
384
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
385
- }
386
- else {
387
  $this->red = $this->getRed() - $other->getRed();
388
  $this->green = $this->getGreen() - $other->getGreen();
389
  $this->blue = $this->getBlue() - $other->getBlue();
390
  }
 
391
  return $this;
392
  }
393
 
@@ -396,7 +392,8 @@ class SassColour extends SassLiteral {
396
  * @param mixed SassColour|SassNumber value to multiply by
397
  * @return sassColour the colour result
398
  */
399
- public function op_times($other) {
 
400
  if ($other instanceof SassNumber) {
401
  if (!$other->isUnitless()) {
402
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
@@ -404,15 +401,14 @@ class SassColour extends SassLiteral {
404
  $this->red = $this->getRed() * $other->value;
405
  $this->green = $this->getGreen() * $other->value;
406
  $this->blue = $this->getBlue() * $other->value;
407
- }
408
- elseif (!$other instanceof SassColour) {
409
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
410
- }
411
- else {
412
  $this->red = $this->getRed() * $other->getRed();
413
  $this->green = $this->getGreen() * $other->getGreen();
414
  $this->blue = $this->getBlue() * $other->getBlue();
415
  }
 
416
  return $this;
417
  }
418
 
@@ -421,7 +417,8 @@ class SassColour extends SassLiteral {
421
  * @param mixed value (SassColour or SassNumber) to divide by
422
  * @return sassColour the colour result
423
  */
424
- public function op_div($other) {
 
425
  if ($other instanceof SassNumber) {
426
  if (!$other->isUnitless()) {
427
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
@@ -429,15 +426,14 @@ class SassColour extends SassLiteral {
429
  $this->red = $this->getRed() / $other->value;
430
  $this->green = $this->getGreen() / $other->value;
431
  $this->blue = $this->getBlue() / $other->value;
432
- }
433
- elseif (!$other instanceof SassColour) {
434
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
435
- }
436
- else {
437
  $this->red = $this->getRed() / $other->getRed();
438
  $this->green = $this->getGreen() / $other->getGreen();
439
  $this->blue = $this->getBlue() / $other->getBlue();
440
  }
 
441
  return $this;
442
  }
443
 
@@ -446,7 +442,8 @@ class SassColour extends SassLiteral {
446
  * @param mixed value (SassColour or SassNumber) to divide by
447
  * @return sassColour the colour result
448
  */
449
- public function op_modulo($other) {
 
450
  if ($other instanceof SassNumber) {
451
  if (!$other->isUnitless()) {
452
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
@@ -454,15 +451,14 @@ class SassColour extends SassLiteral {
454
  $this->red = fmod($this->getRed(), $other->value);
455
  $this->green = fmod($this->getGreen(), $other->value);
456
  $this->blue = fmod($this->getBlue(), $other->value);
457
- }
458
- elseif (!$other instanceof SassColour) {
459
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
460
- }
461
- else {
462
  $this->red = fmod($this->getRed(), $other->getRed());
463
  $this->green = fmod($this->getGreen(), $other->getGreen());
464
  $this->blue = fmod($this->getBlue(), $other->getBlue());
465
  }
 
466
  return $this;
467
  }
468
 
@@ -471,7 +467,8 @@ class SassColour extends SassLiteral {
471
  * @param mixed value (SassColour or SassNumber) to bitwise AND with
472
  * @return sassColour the colour result
473
  */
474
- public function op_bw_and($other) {
 
475
  if ($other instanceof SassNumber) {
476
  if (!$other->isUnitless()) {
477
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
@@ -479,15 +476,14 @@ class SassColour extends SassLiteral {
479
  $this->red = $this->getRed() & $other->value;
480
  $this->green = $this->getGreen() & $other->value;
481
  $this->blue = $this->getBlue() & $other->value;
482
- }
483
- elseif (!$other instanceof SassColour) {
484
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
485
- }
486
- else {
487
  $this->red = $this->getRed() & $other->getRed();
488
  $this->green = $this->getGreen() & $other->getGreen();
489
  $this->blue = $this->getBlue() & $other->getBlue();
490
  }
 
491
  return $this;
492
  }
493
 
@@ -496,7 +492,8 @@ class SassColour extends SassLiteral {
496
  * @param mixed value (SassColour or SassNumber) to bitwise OR with
497
  * @return sassColour the colour result
498
  */
499
- public function op_bw_or($other) {
 
500
  if ($other instanceof SassNumber) {
501
  if (!$other->isUnitless()) {
502
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
@@ -504,15 +501,14 @@ class SassColour extends SassLiteral {
504
  $this->red = $this->getRed() | $other->value;
505
  $this->green = $this->getGreen() | $other->value;
506
  $this->blue = $this->getBlue() | $other->value;
507
- }
508
- elseif (!$other instanceof SassColour) {
509
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
510
- }
511
- else {
512
  $this->red = $this->getRed() | $other->getRed();
513
  $this->green = $this->getGreen() | $other->getGreen();
514
  $this->blue = $this->getBlue() | $other->getBlue();
515
  }
 
516
  return $this;
517
  }
518
 
@@ -521,7 +517,8 @@ class SassColour extends SassLiteral {
521
  * @param mixed value (SassColour or SassNumber) to bitwise XOR with
522
  * @return sassColour the colour result
523
  */
524
- public function op_bw_xor($other) {
 
525
  if ($other instanceof SassNumber) {
526
  if (!$other->isUnitless()) {
527
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
@@ -529,15 +526,14 @@ class SassColour extends SassLiteral {
529
  $this->red = $this->getRed() ^ $other->value;
530
  $this->green = $this->getGreen() ^ $other->value;
531
  $this->blue = $this->getBlue() ^ $other->value;
532
- }
533
- elseif (!$other instanceof SassColour) {
534
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
535
- }
536
- else {
537
  $this->red = $this->getRed() ^ $other->getRed();
538
  $this->green = $this->getGreen() ^ $other->getGreen();
539
  $this->blue = $this->getBlue() ^ $other->getBlue();
540
  }
 
541
  return $this;
542
  }
543
 
@@ -545,10 +541,12 @@ class SassColour extends SassLiteral {
545
  * Colour bitwise NOT
546
  * @return sassColour the colour result
547
  */
548
- public function op_not() {
 
549
  $this->red = ~$this->getRed();
550
  $this->green = ~$this->getGreen();
551
  $this->blue = ~$this->getBlue();
 
552
  return $this;
553
  }
554
 
@@ -557,13 +555,15 @@ class SassColour extends SassLiteral {
557
  * @param sassNumber amount to shift left by
558
  * @return sassColour the colour result
559
  */
560
- public function op_shiftl($other) {
 
561
  if (!$other instanceof SassNumber ||!$other->isUnitless()) {
562
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
563
  }
564
  $this->red = $this->getRed() << $other->value;
565
  $this->green = $this->getGreen() << $other->value;
566
  $this->blue = $this->getBlue() << $other->value;
 
567
  return $this;
568
  }
569
 
@@ -572,13 +572,15 @@ class SassColour extends SassLiteral {
572
  * @param sassNumber amount to shift right by
573
  * @return sassColour the colour result
574
  */
575
- public function op_shiftr($other) {
 
576
  if (!$other instanceof SassNumber || !$other->isUnitless()) {
577
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
578
  }
579
  $this->red = $this->getRed() >> $other->value;
580
  $this->green = $this->getGreen() >> $other->value;
581
  $this->blue = $this->getBlue() >> $other->value;
 
582
  return $this;
583
  }
584
 
@@ -587,7 +589,8 @@ class SassColour extends SassLiteral {
587
  * RGB or HSL attributes may be changed, but not both at once.
588
  * @param array attributes to change
589
  */
590
- public function with($attributes) {
 
591
  if ($this->assertValid($attributes, false) === 'hsl') {
592
  $colour = array_merge(array(
593
  'hue' => $this->getHue(),
@@ -595,8 +598,7 @@ class SassColour extends SassLiteral {
595
  'lightness' => $this->getLightness(),
596
  'alpha' => $this->alpha
597
  ), $attributes);
598
- }
599
- else {
600
  $colour = array_merge(array(
601
  'red' => $this->getRed(),
602
  'green' => $this->getGreen(),
@@ -605,9 +607,9 @@ class SassColour extends SassLiteral {
605
  ), $attributes);
606
  }
607
 
608
-
609
  $colour = new SassColour($colour);
610
  $colour->getRed(); # will get RGB and HSL
 
611
  return $colour;
612
  }
613
 
@@ -615,10 +617,12 @@ class SassColour extends SassLiteral {
615
  * Returns the alpha component (opacity) of this colour.
616
  * @return float the alpha component (opacity) of this colour.
617
  */
618
- public function getAlpha($value = false) {
 
619
  if ($value && isset($this->alpha->$value)) {
620
  return $this->alpha->value;
621
  }
 
622
  return $this->alpha;
623
  }
624
 
@@ -626,13 +630,15 @@ class SassColour extends SassLiteral {
626
  * Returns the hue of this colour.
627
  * @return float the hue of this colour.
628
  */
629
- public function getHue($value = false) {
 
630
  if (is_null($this->hue)) {
631
  $this->rgb2hsl();
632
  }
633
  if ($value && isset($this->hue->value)) {
634
  return $this->hue->value;
635
  }
 
636
  return $this->hue;
637
  }
638
 
@@ -640,13 +646,15 @@ class SassColour extends SassLiteral {
640
  * Returns the saturation of this colour.
641
  * @return float the saturation of this colour.
642
  */
643
- public function getSaturation($value = false) {
 
644
  if (is_null($this->saturation)) {
645
  $this->rgb2hsl();
646
  }
647
  if ($value && isset($this->saturation->value)) {
648
  return $this->saturation->value;
649
  }
 
650
  return $this->saturation;
651
  }
652
 
@@ -654,13 +662,15 @@ class SassColour extends SassLiteral {
654
  * Returns the lightness of this colour.
655
  * @return float the lightness of this colour.
656
  */
657
- public function getLightness($value = false) {
 
658
  if (is_null($this->lightness)) {
659
  $this->rgb2hsl();
660
  }
661
  if ($value && isset($this->lightness->value)) {
662
  return $this->lightness->value;
663
  }
 
664
  return $this->lightness;
665
  }
666
 
@@ -668,13 +678,15 @@ class SassColour extends SassLiteral {
668
  * Returns the blue component of this colour.
669
  * @return integer the blue component of this colour.
670
  */
671
- public function getBlue($value = false) {
 
672
  if (is_null($this->blue)) {
673
  $this->hsl2rgb();
674
  }
675
  if ($value && isset($this->blue->value)) {
676
  return $this->blue->value;
677
  }
 
678
  return max(0, min(255, str_replace(',','.',round($this->blue))));
679
  }
680
 
@@ -682,13 +694,15 @@ class SassColour extends SassLiteral {
682
  * Returns the green component of this colour.
683
  * @return integer the green component of this colour.
684
  */
685
- public function getGreen($value = false) {
 
686
  if (is_null($this->green)) {
687
  $this->hsl2rgb();
688
  }
689
  if ($value && isset($this->green->value)) {
690
  return $this->green->value;
691
  }
 
692
  return max(0, min(255, str_replace(',','.',round($this->green))));
693
  }
694
 
@@ -696,13 +710,15 @@ class SassColour extends SassLiteral {
696
  * Returns the red component of this colour.
697
  * @return integer the red component of this colour.
698
  */
699
- public function getRed($value = false) {
 
700
  if (is_null($this->red)) {
701
  $this->hsl2rgb();
702
  }
703
  if ($value && isset($this->red->value)) {
704
  return $this->red->value;
705
  }
 
706
  return max(0, min(255, str_replace(',','.',round($this->red))));
707
  }
708
 
@@ -710,7 +726,8 @@ class SassColour extends SassLiteral {
710
  * Returns an array with the RGB components of this colour.
711
  * @return array the RGB components of this colour
712
  */
713
- public function getRgb() {
 
714
  return array($this->red, $this->green, $this->blue);
715
  }
716
 
@@ -718,7 +735,8 @@ class SassColour extends SassLiteral {
718
  * Returns an array with the RGB and alpha components of this colour.
719
  * @return array the RGB and alpha components of this colour
720
  */
721
- public function getRgba() {
 
722
  return array($this->getRed(), $this->getGreen(), $this->getBlue(), $this->alpha);
723
  }
724
 
@@ -726,7 +744,8 @@ class SassColour extends SassLiteral {
726
  * Returns an array with the HSL components of this colour.
727
  * @return array the HSL components of this colour
728
  */
729
- public function getHsl() {
 
730
  return array($this->getHue(), $this->getSaturation(), $this->getLightness());
731
  }
732
 
@@ -734,7 +753,8 @@ class SassColour extends SassLiteral {
734
  * Returns an array with the HSL and alpha components of this colour.
735
  * @return array the HSL and alpha components of this colour
736
  */
737
- public function getHsla() {
 
738
  return array($this->getHue(), $this->getSaturation(), $this->getLightness(), $this->alpha);
739
  }
740
 
@@ -743,7 +763,8 @@ class SassColour extends SassLiteral {
743
  * @return array the colour
744
  * @deprecated
745
  */
746
- public function getValue() {
 
747
  return $this->rgb;
748
  }
749
 
@@ -751,7 +772,8 @@ class SassColour extends SassLiteral {
751
  * Returns whether this colour object is translucent; that is, whether the alpha channel is non-1.
752
  * @return boolean true if this colour is translucent, false if not
753
  */
754
- public function isTranslucent() {
 
755
  return $this->alpha < 1;
756
  }
757
 
@@ -760,7 +782,8 @@ class SassColour extends SassLiteral {
760
  * @param boolean whether to use CSS3 SVG1.0 colour names
761
  * @return string the colour as a named colour, rgba(r,g,g,a) or #rrggbb
762
  */
763
- public function toString($css3 = true) {
 
764
  $rgba = $this->getRgba();
765
 
766
  foreach ($rgba as $k => $v) {
@@ -771,12 +794,11 @@ class SassColour extends SassLiteral {
771
 
772
  if ($rgba[3] == 0) {
773
  return 'transparent';
774
- }
775
- elseif ($rgba[3] < 1) {
776
  $rgba[3] = str_replace(',','.',round($rgba[3], 2));
 
777
  return sprintf('rgba(%d, %d, %d, %s)', $rgba[0], $rgba[1], $rgba[2], $rgba[3]);
778
- }
779
- else {
780
  $colour = sprintf('#%02x%02x%02x', str_replace(',','.',round($rgba[0])), str_replace(',','.',round($rgba[1])), str_replace(',','.',round($rgba[2])));
781
  }
782
 
@@ -784,15 +806,15 @@ class SassColour extends SassLiteral {
784
  if (empty(self::$_svgColours)) {
785
  self::$_svgColours = array_flip(self::$svgColours);
786
  }
 
787
  return (array_key_exists($colour, self::$_svgColours) ? self::$_svgColours[$colour] : $colour);
788
- }
789
- else {
790
  return (array_key_exists($colour, self::$_html4Colours) ? self::$_html4Colours[$colour] : $colour);
791
  }
792
  }
793
 
794
-
795
- public function asHex($inc_hash = TRUE) {
796
  return sprintf(($inc_hash ? '#' : '') . '%02x%02x%02x', str_replace(',','.',round($this->red)), str_replace(',','.',round($this->green)), str_replace(',','.',round($this->blue)));
797
  }
798
 
@@ -801,7 +823,8 @@ class SassColour extends SassLiteral {
801
  * Algorithm from the CSS3 spec: {@link http://www.w3.org/TR/css3-color/#hsl-color}
802
  * @uses hue2rgb()
803
  */
804
- public function hsl2rgb() {
 
805
  $h = $this->getHue(true) / 360;
806
  $s = $this->getSaturation(true) / 100;
807
  $l = $this->getLightness(true) / 100;
@@ -818,7 +841,8 @@ class SassColour extends SassLiteral {
818
  /**
819
  * Converts from hue to RGB colourspace
820
  */
821
- public function hue2rgb($p, $q, $t) {
 
822
  if ($t < 0)
823
  $t += 1;
824
  if ($t > 1)
@@ -838,7 +862,8 @@ class SassColour extends SassLiteral {
838
  * Converts from RGB to HSL colourspace
839
  * Algorithm adapted from {@link http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript}
840
  */
841
- public function rgb2hsl() {
 
842
  list($r, $g, $b) = array($this->red / 255, $this->green / 255, $this->blue / 255);
843
 
844
  $max = max($r, $g, $b);
@@ -848,8 +873,7 @@ class SassColour extends SassLiteral {
848
  if ($max == $min) {
849
  $h = 0;
850
  $s = 0;
851
- }
852
- else if ($max == $r)
853
  $h = 60 * ($g - $b) / $d;
854
  else if ($max == $g)
855
  $h = 60 * ($b - $r) / $d + 120;
@@ -881,7 +905,8 @@ class SassColour extends SassLiteral {
881
  * @throws SassColourException if mixed colour space keys given or not all
882
  * keys for a colour space are required but not given (contructor)
883
  */
884
- public function assertValid($colour, $all = true) {
 
885
  if (array_key_exists('red', $colour) || array_key_exists('green', $colour) || array_key_exists('blue', $colour)) {
886
  if (array_key_exists('hue', $colour) || array_key_exists('saturation', $colour) || array_key_exists('lightness', $colour)) {
887
  throw new SassColourException('SassColour can not have HSL and RGB keys specified', SassScriptParser::$context->node);
@@ -889,15 +914,15 @@ class SassColour extends SassLiteral {
889
  if ($all && (!array_key_exists('red', $colour) || !array_key_exists('green', $colour) || !array_key_exists('blue', $colour))) {
890
  throw new SassColourException('SassColour must have all RGB keys specified', SassScriptParser::$context->node);
891
  }
 
892
  return 'rgb';
893
- }
894
- elseif (array_key_exists('hue', $colour) || array_key_exists('saturation', $colour) || array_key_exists('lightness', $colour)) {
895
  if ($all && (!array_key_exists('hue', $colour) || !array_key_exists('saturation', $colour) || !array_key_exists('lightness', $colour))) {
896
  throw new SassColourException('SassColour must have all HSL keys specified', SassScriptParser::$context->node);
897
  }
 
898
  return 'hsl';
899
- }
900
- elseif ($all && sizeof($colour) < 3) {
901
  throw new SassColourException('SassColour array must have at least 3 elements', SassScriptParser::$context->node);
902
  }
903
  }
@@ -908,20 +933,24 @@ class SassColour extends SassLiteral {
908
  * @param string the subject string
909
  * @return mixed match at the start of the string or false if no match
910
  */
911
- static public function isa($subject) {
 
912
  if (empty(self::$regex)) {
913
  self::$regex = str_replace('{CSS_COLOURS}', join('|', array_reverse(array_keys(self::$svgColours))), self::MATCH);
914
  }
 
915
  return (preg_match(self::$regex, strtolower($subject), $matches) ?
916
  $matches[0] : false);
917
  }
918
 
919
- public function nth($i) {
 
920
  if ($i == 1) return clone $this;
921
  return new SassBoolean(false);
922
  }
923
 
924
- public function length() {
 
925
  return 1;
926
  }
927
  }
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
+ require_once 'SassLiteral.php';
13
 
14
  /**
15
  * SassColour class.
35
  * @package PHamlP
36
  * @subpackage Sass.script.literals
37
  */
38
+ class SassColour extends SassLiteral
39
+ {
40
  /**@#+
41
  * Regexes for matching and extracting colours
42
  */
47
  /**@#-*/
48
 
49
  /**@#-*/
50
+ public static $svgColours = array(
51
  'aliceblue' => '#f0f8ff',
52
  'antiquewhite' => '#faebd7',
53
  'aqua' => '#00ffff',
198
  /**
199
  * @var array reverse array (value => name) of named SVG1.0 colours
200
  */
201
+ public static $_svgColours;
202
 
203
  /**
204
  * @var array reverse array (value => name) of named HTML4 colours
205
  */
206
+ public static $_html4Colours = array(
207
  '#000000' => 'black',
208
  '#000080' => 'navy',
209
  '#0000ff' => 'blue',
222
  '#ffffff' => 'white',
223
  );
224
 
225
+ public static $regex;
226
 
227
  /**@#+
228
  * RGB colour components
230
  /**
231
  * @var array RGB colour components. Used to check for RGB attributes.
232
  */
233
+ public static $rgb = array('red', 'green', 'blue');
234
  /**
235
  * @var integer red component. 0 - 255
236
  */
250
  /**
251
  * @var array HSL colour components. Used to check for HSL attributes.
252
  */
253
+ public static $hsl = array('hue', 'saturation', 'lightness');
254
  /**
255
  * @var float hue component. 0 - 360
256
  */
283
  * @param mixed the colour
284
  * @return SassColour
285
  */
286
+ public function __construct($colour)
287
+ {
288
  if (is_string($colour)) {
289
  $colour = strtolower($colour);
290
  if ($colour === self::TRANSPARENT) {
292
  $this->green = 0;
293
  $this->blue = 0;
294
  $this->alpha = 0;
295
+ } else {
 
296
  if (array_key_exists($colour, self::$svgColours)) {
297
  $colour = self::$svgColours[$colour];
298
  }
300
  for ($i = 1; $i < 4; $i++) {
301
  $matches[$i] = str_repeat($matches[$i], 2);
302
  }
303
+ } else {
 
304
  preg_match(self::EXTRACT_6, $colour, $matches);
305
  }
306
 
312
  $this->blue = intval($matches[3], 16);
313
  $this->alpha = 1;
314
  }
315
+ } elseif (is_array($colour)) {
 
316
  $scheme = $this->assertValid($colour);
317
  if ($scheme == 'rgb') {
318
  $this->red = $colour['red'];
319
  $this->green = $colour['green'];
320
  $this->blue = $colour['blue'];
321
  $this->alpha = (isset($colour['alpha']) ? $colour['alpha'] : 1);
322
+ } elseif ($scheme == 'hsl') {
 
323
  $this->hue = $colour['hue'];
324
  $this->saturation = $colour['saturation'];
325
  $this->lightness = $colour['lightness'];
326
  $this->alpha = (isset($colour['alpha']) ? $colour['alpha'] : 1);
327
+ } else {
 
328
  $this->red = $colour[0];
329
  $this->green = $colour[1];
330
  $this->blue = $colour[2];
331
  $this->alpha = (isset($colour[3]) ? $colour[3] : 1);
332
  }
333
+ } else {
 
334
  throw new SassColourException('Colour must be a array', SassScriptParser::$context->node);
335
  }
336
  }
340
  * @param mixed SassColour|SassNumber value to add
341
  * @return sassColour the colour result
342
  */
343
+ public function op_plus($other)
344
+ {
345
  if ($other instanceof SassNumber) {
346
  if (!$other->isUnitless()) {
347
  return new SassString($this->toString() . $other->value);
350
  $this->red = $this->getRed() + $other->value;
351
  $this->green = $this->getGreen() + $other->value;
352
  $this->blue = $this->getBlue() + $other->value;
353
+ } elseif (!$other instanceof SassColour) {
 
354
  return new SassString($this->toString() . $other->value);
355
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
356
+ } else {
 
357
  $this->red = $this->getRed() + $other->getRed();
358
  $this->green = $this->getGreen() + $other->getGreen();
359
  $this->blue = $this->getBlue() + $other->getBlue();
360
  }
361
+
362
  return $this;
363
  }
364
 
367
  * @param mixed value (SassColour or SassNumber) to subtract
368
  * @return sassColour the colour result
369
  */
370
+ public function op_minus($other)
371
+ {
372
  if ($other instanceof SassNumber) {
373
  if (!$other->isUnitless()) {
374
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
376
  $this->red = $this->getRed() - $other->value;
377
  $this->green = $this->getGreen() - $other->value;
378
  $this->blue = $this->getBlue() - $other->value;
379
+ } elseif (!$other instanceof SassColour) {
 
380
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
381
+ } else {
 
382
  $this->red = $this->getRed() - $other->getRed();
383
  $this->green = $this->getGreen() - $other->getGreen();
384
  $this->blue = $this->getBlue() - $other->getBlue();
385
  }
386
+
387
  return $this;
388
  }
389
 
392
  * @param mixed SassColour|SassNumber value to multiply by
393
  * @return sassColour the colour result
394
  */
395
+ public function op_times($other)
396
+ {
397
  if ($other instanceof SassNumber) {
398
  if (!$other->isUnitless()) {
399
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
401
  $this->red = $this->getRed() * $other->value;
402
  $this->green = $this->getGreen() * $other->value;
403
  $this->blue = $this->getBlue() * $other->value;
404
+ } elseif (!$other instanceof SassColour) {
 
405
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
406
+ } else {
 
407
  $this->red = $this->getRed() * $other->getRed();
408
  $this->green = $this->getGreen() * $other->getGreen();
409
  $this->blue = $this->getBlue() * $other->getBlue();
410
  }
411
+
412
  return $this;
413
  }
414
 
417
  * @param mixed value (SassColour or SassNumber) to divide by
418
  * @return sassColour the colour result
419
  */
420
+ public function op_div($other)
421
+ {
422
  if ($other instanceof SassNumber) {
423
  if (!$other->isUnitless()) {
424
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
426
  $this->red = $this->getRed() / $other->value;
427
  $this->green = $this->getGreen() / $other->value;
428
  $this->blue = $this->getBlue() / $other->value;
429
+ } elseif (!$other instanceof SassColour) {
 
430
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
431
+ } else {
 
432
  $this->red = $this->getRed() / $other->getRed();
433
  $this->green = $this->getGreen() / $other->getGreen();
434
  $this->blue = $this->getBlue() / $other->getBlue();
435
  }
436
+
437
  return $this;
438
  }
439
 
442
  * @param mixed value (SassColour or SassNumber) to divide by
443
  * @return sassColour the colour result
444
  */
445
+ public function op_modulo($other)
446
+ {
447
  if ($other instanceof SassNumber) {
448
  if (!$other->isUnitless()) {
449
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
451
  $this->red = fmod($this->getRed(), $other->value);
452
  $this->green = fmod($this->getGreen(), $other->value);
453
  $this->blue = fmod($this->getBlue(), $other->value);
454
+ } elseif (!$other instanceof SassColour) {
 
455
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
456
+ } else {
 
457
  $this->red = fmod($this->getRed(), $other->getRed());
458
  $this->green = fmod($this->getGreen(), $other->getGreen());
459
  $this->blue = fmod($this->getBlue(), $other->getBlue());
460
  }
461
+
462
  return $this;
463
  }
464
 
467
  * @param mixed value (SassColour or SassNumber) to bitwise AND with
468
  * @return sassColour the colour result
469
  */
470
+ public function op_bw_and($other)
471
+ {
472
  if ($other instanceof SassNumber) {
473
  if (!$other->isUnitless()) {
474
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
476
  $this->red = $this->getRed() & $other->value;
477
  $this->green = $this->getGreen() & $other->value;
478
  $this->blue = $this->getBlue() & $other->value;
479
+ } elseif (!$other instanceof SassColour) {
 
480
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
481
+ } else {
 
482
  $this->red = $this->getRed() & $other->getRed();
483
  $this->green = $this->getGreen() & $other->getGreen();
484
  $this->blue = $this->getBlue() & $other->getBlue();
485
  }
486
+
487
  return $this;
488
  }
489
 
492
  * @param mixed value (SassColour or SassNumber) to bitwise OR with
493
  * @return sassColour the colour result
494
  */
495
+ public function op_bw_or($other)
496
+ {
497
  if ($other instanceof SassNumber) {
498
  if (!$other->isUnitless()) {
499
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
501
  $this->red = $this->getRed() | $other->value;
502
  $this->green = $this->getGreen() | $other->value;
503
  $this->blue = $this->getBlue() | $other->value;
504
+ } elseif (!$other instanceof SassColour) {
 
505
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
506
+ } else {
 
507
  $this->red = $this->getRed() | $other->getRed();
508
  $this->green = $this->getGreen() | $other->getGreen();
509
  $this->blue = $this->getBlue() | $other->getBlue();
510
  }
511
+
512
  return $this;
513
  }
514
 
517
  * @param mixed value (SassColour or SassNumber) to bitwise XOR with
518
  * @return sassColour the colour result
519
  */
520
+ public function op_bw_xor($other)
521
+ {
522
  if ($other instanceof SassNumber) {
523
  if (!$other->isUnitless()) {
524
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
526
  $this->red = $this->getRed() ^ $other->value;
527
  $this->green = $this->getGreen() ^ $other->value;
528
  $this->blue = $this->getBlue() ^ $other->value;
529
+ } elseif (!$other instanceof SassColour) {
 
530
  throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
531
+ } else {
 
532
  $this->red = $this->getRed() ^ $other->getRed();
533
  $this->green = $this->getGreen() ^ $other->getGreen();
534
  $this->blue = $this->getBlue() ^ $other->getBlue();
535
  }
536
+
537
  return $this;
538
  }
539
 
541
  * Colour bitwise NOT
542
  * @return sassColour the colour result
543
  */
544
+ public function op_not()
545
+ {
546
  $this->red = ~$this->getRed();
547
  $this->green = ~$this->getGreen();
548
  $this->blue = ~$this->getBlue();
549
+
550
  return $this;
551
  }
552
 
555
  * @param sassNumber amount to shift left by
556
  * @return sassColour the colour result
557
  */
558
+ public function op_shiftl($other)
559
+ {
560
  if (!$other instanceof SassNumber ||!$other->isUnitless()) {
561
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
562
  }
563
  $this->red = $this->getRed() << $other->value;
564
  $this->green = $this->getGreen() << $other->value;
565
  $this->blue = $this->getBlue() << $other->value;
566
+
567
  return $this;
568
  }
569
 
572
  * @param sassNumber amount to shift right by
573
  * @return sassColour the colour result
574
  */
575
+ public function op_shiftr($other)
576
+ {
577
  if (!$other instanceof SassNumber || !$other->isUnitless()) {
578
  throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
579
  }
580
  $this->red = $this->getRed() >> $other->value;
581
  $this->green = $this->getGreen() >> $other->value;
582
  $this->blue = $this->getBlue() >> $other->value;
583
+
584
  return $this;
585
  }
586
 
589
  * RGB or HSL attributes may be changed, but not both at once.
590
  * @param array attributes to change
591
  */
592
+ public function with($attributes)
593
+ {
594
  if ($this->assertValid($attributes, false) === 'hsl') {
595
  $colour = array_merge(array(
596
  'hue' => $this->getHue(),
598
  'lightness' => $this->getLightness(),
599
  'alpha' => $this->alpha
600
  ), $attributes);
601
+ } else {
 
602
  $colour = array_merge(array(
603
  'red' => $this->getRed(),
604
  'green' => $this->getGreen(),
607
  ), $attributes);
608
  }
609
 
 
610
  $colour = new SassColour($colour);
611
  $colour->getRed(); # will get RGB and HSL
612
+
613
  return $colour;
614
  }
615
 
617
  * Returns the alpha component (opacity) of this colour.
618
  * @return float the alpha component (opacity) of this colour.
619
  */
620
+ public function getAlpha($value = false)
621
+ {
622
  if ($value && isset($this->alpha->$value)) {
623
  return $this->alpha->value;
624
  }
625
+
626
  return $this->alpha;
627
  }
628
 
630
  * Returns the hue of this colour.
631
  * @return float the hue of this colour.
632
  */
633
+ public function getHue($value = false)
634
+ {
635
  if (is_null($this->hue)) {
636
  $this->rgb2hsl();
637
  }
638
  if ($value && isset($this->hue->value)) {
639
  return $this->hue->value;
640
  }
641
+
642
  return $this->hue;
643
  }
644
 
646
  * Returns the saturation of this colour.
647
  * @return float the saturation of this colour.
648
  */
649
+ public function getSaturation($value = false)
650
+ {
651
  if (is_null($this->saturation)) {
652
  $this->rgb2hsl();
653
  }
654
  if ($value && isset($this->saturation->value)) {
655
  return $this->saturation->value;
656
  }
657
+
658
  return $this->saturation;
659
  }
660
 
662
  * Returns the lightness of this colour.
663
  * @return float the lightness of this colour.
664
  */
665
+ public function getLightness($value = false)
666
+ {
667
  if (is_null($this->lightness)) {
668
  $this->rgb2hsl();
669
  }
670
  if ($value && isset($this->lightness->value)) {
671
  return $this->lightness->value;
672
  }
673
+
674
  return $this->lightness;
675
  }
676
 
678
  * Returns the blue component of this colour.
679
  * @return integer the blue component of this colour.
680
  */
681
+ public function getBlue($value = false)
682
+ {
683
  if (is_null($this->blue)) {
684
  $this->hsl2rgb();
685
  }
686
  if ($value && isset($this->blue->value)) {
687
  return $this->blue->value;
688
  }
689
+
690
  return max(0, min(255, str_replace(',','.',round($this->blue))));
691
  }
692
 
694
  * Returns the green component of this colour.
695
  * @return integer the green component of this colour.
696
  */
697
+ public function getGreen($value = false)
698
+ {
699
  if (is_null($this->green)) {
700
  $this->hsl2rgb();
701
  }
702
  if ($value && isset($this->green->value)) {
703
  return $this->green->value;
704
  }
705
+
706
  return max(0, min(255, str_replace(',','.',round($this->green))));
707
  }
708
 
710
  * Returns the red component of this colour.
711
  * @return integer the red component of this colour.
712
  */
713
+ public function getRed($value = false)
714
+ {
715
  if (is_null($this->red)) {
716
  $this->hsl2rgb();
717
  }
718
  if ($value && isset($this->red->value)) {
719
  return $this->red->value;
720
  }
721
+
722
  return max(0, min(255, str_replace(',','.',round($this->red))));
723
  }
724
 
726
  * Returns an array with the RGB components of this colour.
727
  * @return array the RGB components of this colour
728
  */
729
+ public function getRgb()
730
+ {
731
  return array($this->red, $this->green, $this->blue);
732
  }
733
 
735
  * Returns an array with the RGB and alpha components of this colour.
736
  * @return array the RGB and alpha components of this colour
737
  */
738
+ public function getRgba()
739
+ {
740
  return array($this->getRed(), $this->getGreen(), $this->getBlue(), $this->alpha);
741
  }
742
 
744
  * Returns an array with the HSL components of this colour.
745
  * @return array the HSL components of this colour
746
  */
747
+ public function getHsl()
748
+ {
749
  return array($this->getHue(), $this->getSaturation(), $this->getLightness());
750
  }
751
 
753
  * Returns an array with the HSL and alpha components of this colour.
754
  * @return array the HSL and alpha components of this colour
755
  */
756
+ public function getHsla()
757
+ {
758
  return array($this->getHue(), $this->getSaturation(), $this->getLightness(), $this->alpha);
759
  }
760
 
763
  * @return array the colour
764
  * @deprecated
765
  */
766
+ public function getValue()
767
+ {
768
  return $this->rgb;
769
  }
770
 
772
  * Returns whether this colour object is translucent; that is, whether the alpha channel is non-1.
773
  * @return boolean true if this colour is translucent, false if not
774
  */
775
+ public function isTranslucent()
776
+ {
777
  return $this->alpha < 1;
778
  }
779
 
782
  * @param boolean whether to use CSS3 SVG1.0 colour names
783
  * @return string the colour as a named colour, rgba(r,g,g,a) or #rrggbb
784
  */
785
+ public function toString($css3 = true)
786
+ {
787
  $rgba = $this->getRgba();
788
 
789
  foreach ($rgba as $k => $v) {
794
 
795
  if ($rgba[3] == 0) {
796
  return 'transparent';
797
+ } elseif ($rgba[3] < 1) {
 
798
  $rgba[3] = str_replace(',','.',round($rgba[3], 2));
799
+
800
  return sprintf('rgba(%d, %d, %d, %s)', $rgba[0], $rgba[1], $rgba[2], $rgba[3]);
801
+ } else {
 
802
  $colour = sprintf('#%02x%02x%02x', str_replace(',','.',round($rgba[0])), str_replace(',','.',round($rgba[1])), str_replace(',','.',round($rgba[2])));
803
  }
804
 
806
  if (empty(self::$_svgColours)) {
807
  self::$_svgColours = array_flip(self::$svgColours);
808
  }
809
+
810
  return (array_key_exists($colour, self::$_svgColours) ? self::$_svgColours[$colour] : $colour);
811
+ } else {
 
812
  return (array_key_exists($colour, self::$_html4Colours) ? self::$_html4Colours[$colour] : $colour);
813
  }
814
  }
815
 
816
+ public function asHex($inc_hash = TRUE)
817
+ {
818
  return sprintf(($inc_hash ? '#' : '') . '%02x%02x%02x', str_replace(',','.',round($this->red)), str_replace(',','.',round($this->green)), str_replace(',','.',round($this->blue)));
819
  }
820
 
823
  * Algorithm from the CSS3 spec: {@link http://www.w3.org/TR/css3-color/#hsl-color}
824
  * @uses hue2rgb()
825
  */
826
+ public function hsl2rgb()
827
+ {
828
  $h = $this->getHue(true) / 360;
829
  $s = $this->getSaturation(true) / 100;
830
  $l = $this->getLightness(true) / 100;
841
  /**
842
  * Converts from hue to RGB colourspace
843
  */
844
+ public function hue2rgb($p, $q, $t)
845
+ {
846
  if ($t < 0)
847
  $t += 1;
848
  if ($t > 1)
862
  * Converts from RGB to HSL colourspace
863
  * Algorithm adapted from {@link http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript}
864
  */
865
+ public function rgb2hsl()
866
+ {
867
  list($r, $g, $b) = array($this->red / 255, $this->green / 255, $this->blue / 255);
868
 
869
  $max = max($r, $g, $b);
873
  if ($max == $min) {
874
  $h = 0;
875
  $s = 0;
876
+ } elseif ($max == $r)
 
877
  $h = 60 * ($g - $b) / $d;
878
  else if ($max == $g)
879
  $h = 60 * ($b - $r) / $d + 120;
905
  * @throws SassColourException if mixed colour space keys given or not all
906
  * keys for a colour space are required but not given (contructor)
907
  */
908
+ public function assertValid($colour, $all = true)
909
+ {
910
  if (array_key_exists('red', $colour) || array_key_exists('green', $colour) || array_key_exists('blue', $colour)) {
911
  if (array_key_exists('hue', $colour) || array_key_exists('saturation', $colour) || array_key_exists('lightness', $colour)) {
912
  throw new SassColourException('SassColour can not have HSL and RGB keys specified', SassScriptParser::$context->node);
914
  if ($all && (!array_key_exists('red', $colour) || !array_key_exists('green', $colour) || !array_key_exists('blue', $colour))) {
915
  throw new SassColourException('SassColour must have all RGB keys specified', SassScriptParser::$context->node);
916
  }
917
+
918
  return 'rgb';
919
+ } elseif (array_key_exists('hue', $colour) || array_key_exists('saturation', $colour) || array_key_exists('lightness', $colour)) {
 
920
  if ($all && (!array_key_exists('hue', $colour) || !array_key_exists('saturation', $colour) || !array_key_exists('lightness', $colour))) {
921
  throw new SassColourException('SassColour must have all HSL keys specified', SassScriptParser::$context->node);
922
  }
923
+
924
  return 'hsl';
925
+ } elseif ($all && sizeof($colour) < 3) {
 
926
  throw new SassColourException('SassColour array must have at least 3 elements', SassScriptParser::$context->node);
927
  }
928
  }
933
  * @param string the subject string
934
  * @return mixed match at the start of the string or false if no match
935
  */
936
+ public static function isa($subject)
937
+ {
938
  if (empty(self::$regex)) {
939
  self::$regex = str_replace('{CSS_COLOURS}', join('|', array_reverse(array_keys(self::$svgColours))), self::MATCH);
940
  }
941
+
942
  return (preg_match(self::$regex, strtolower($subject), $matches) ?
943
  $matches[0] : false);
944
  }
945
 
946
+ public function nth($i)
947
+ {
948
  if ($i == 1) return clone $this;
949
  return new SassBoolean(false);
950
  }
951
 
952
+ public function length()
953
+ {
954
  return 1;
955
  }
956
  }
lib/phpsass/script/literals/SassList.php CHANGED
@@ -9,74 +9,76 @@
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
- require_once('SassLiteral.php');
13
 
14
  /**
15
  * SassBoolean class.
16
  * @package PHamlP
17
  * @subpackage Sass.script.literals
18
  */
19
- class SassList extends SassLiteral {
20
-
21
- var $separator = ' ';
22
 
23
  /**
24
  * SassBoolean constructor
25
  * @param string value of the boolean type
26
  * @return SassBoolean
27
  */
28
- public function __construct($value, $separator = 'auto') {
 
29
  if (is_array($value)) {
30
  $this->value = $value;
31
  $this->separator = ($separator == 'auto' ? ', ' : $separator);
32
- }
33
- else if ($value == '()'){
34
  $this->value = array();
35
  $this->separator = ($separator == 'auto' ? ', ' : $separator);
36
- }
37
- else if (list($list, $separator) = $this->_parse_list($value, $separator, true, SassScriptParser::$context)) {
38
  $this->value = $list;
39
  $this->separator = ($separator == ',' ? ', ' : ' ');
40
- }
41
- else {
42
  throw new SassListException('Invalid SassList', SassScriptParser::$context->node);
43
  }
44
  }
45
 
46
- function nth($i) {
 
47
  $i = $i - 1; # SASS uses 1-offset arrays
48
  if (isset($this->value[$i])) {
49
  return $this->value[$i];
50
  }
 
51
  return new SassBoolean(false);
52
  }
53
 
54
- function length() {
 
55
  return count($this->value);
56
  }
57
 
58
- function append($other, $separator = null) {
 
59
  if ($separator) {
60
  $this->separator = $separator;
61
  }
62
  if ($other instanceof SassList) {
63
  $this->value = array_merge($this->value, $other->value);
64
- }
65
- else if ($other instanceof SassLiteral) {
66
  $this->value[] = $other;
67
- }
68
- else {
69
  throw new SassListException('Appendation can only occur with literals', SassScriptParser::$context->node);
70
  }
71
  }
72
 
73
  // New function index returns the list index of a value within a list. For example: index(1px solid red, solid) returns 2. When the value is not found false is returned.
74
- function index($value) {
 
75
  for ($i = 0; $i < count($this->value); $i++) {
76
  if (trim((string) $value) == trim((string) $this->value[$i])) {
77
  return new SassNumber($i);
78
  }
79
  }
 
80
  return new SassBoolean(false);
81
  }
82
 
@@ -84,7 +86,8 @@ class SassList extends SassLiteral {
84
  * Returns the value of this boolean.
85
  * @return boolean the value of this boolean
86
  */
87
- public function getValue() {
 
88
  $result = array();
89
  foreach ($this->value as $k => $v) {
90
  if ($v instanceOf SassString) {
@@ -103,6 +106,7 @@ class SassList extends SassLiteral {
103
  }
104
  }
105
  $this->value = $result;
 
106
  return $this->value;
107
  }
108
 
@@ -110,7 +114,8 @@ class SassList extends SassLiteral {
110
  * Returns a string representation of the value.
111
  * @return string string representation of the value.
112
  */
113
- public function toString() {
 
114
  $aliases = array(
115
  'comma' => ',',
116
  'space' => '',
@@ -119,6 +124,7 @@ class SassList extends SassLiteral {
119
  if (isset($aliases[$this->separator])) {
120
  $this->separator = $aliases[$this->separator];
121
  }
 
122
  return implode($this->separator . ' ', $this->getValue());
123
  }
124
 
@@ -128,12 +134,15 @@ class SassList extends SassLiteral {
128
  * @param string the subject string
129
  * @return mixed match at the start of the string or false if no match
130
  */
131
- public static function isa($subject) {
 
132
  list($list, $separator) = self::_parse_list($subject, 'auto', false);
 
133
  return count($list) > 1 ? $subject : FALSE;
134
  }
135
 
136
- public static function _parse_list($list, $separator = 'auto', $lex = true, $context = null) {
 
137
  if ($lex) {
138
  $context = new SassContext($context);
139
  $list = SassScriptParser::$instance->evaluate($list, $context);
@@ -146,8 +155,7 @@ class SassList extends SassLiteral {
146
  $separator = ' ';
147
  $list = self::_build_list($list, ' ');
148
  }
149
- }
150
- else {
151
  $list = self::_build_list($list, $separator);
152
  }
153
 
@@ -157,10 +165,12 @@ class SassList extends SassLiteral {
157
  $list[$k] = SassScriptParser::$instance->evaluate($v, $context);
158
  }
159
  }
 
160
  return array($list, $separator);
161
  }
162
 
163
- public static function _build_list($list, $separator = ',') {
 
164
  if (is_object($list)) {
165
  $list = $list->value;
166
  }
@@ -178,15 +188,14 @@ class SassList extends SassLiteral {
178
  $braces = 0;
179
  $quotes = false;
180
  $stack = '';
181
- for($i = 0; $i < strlen($list); $i++) {
182
  $char = substr($list, $i, 1);
183
  switch ($char) {
184
  case '"':
185
  case "'":
186
  if (!$quotes) {
187
  $quotes = $char;
188
- }
189
- else if ($quotes && $quotes == $char) {
190
  $quotes = false;
191
  }
192
  $stack .= $char;
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
+ require_once 'SassLiteral.php';
13
 
14
  /**
15
  * SassBoolean class.
16
  * @package PHamlP
17
  * @subpackage Sass.script.literals
18
  */
19
+ class SassList extends SassLiteral
20
+ {
21
+ public $separator = ' ';
22
 
23
  /**
24
  * SassBoolean constructor
25
  * @param string value of the boolean type
26
  * @return SassBoolean
27
  */
28
+ public function __construct($value, $separator = 'auto')
29
+ {
30
  if (is_array($value)) {
31
  $this->value = $value;
32
  $this->separator = ($separator == 'auto' ? ', ' : $separator);
33
+ } elseif ($value == '()') {
 
34
  $this->value = array();
35
  $this->separator = ($separator == 'auto' ? ', ' : $separator);
36
+ } elseif (list($list, $separator) = $this->_parse_list($value, $separator, true, SassScriptParser::$context)) {
 
37
  $this->value = $list;
38
  $this->separator = ($separator == ',' ? ', ' : ' ');
39
+ } else {
 
40
  throw new SassListException('Invalid SassList', SassScriptParser::$context->node);
41
  }
42
  }
43
 
44
+ public function nth($i)
45
+ {
46
  $i = $i - 1; # SASS uses 1-offset arrays
47
  if (isset($this->value[$i])) {
48
  return $this->value[$i];
49
  }
50
+
51
  return new SassBoolean(false);
52
  }
53
 
54
+ public function length()
55
+ {
56
  return count($this->value);
57
  }
58
 
59
+ public function append($other, $separator = null)
60
+ {
61
  if ($separator) {
62
  $this->separator = $separator;
63
  }
64
  if ($other instanceof SassList) {
65
  $this->value = array_merge($this->value, $other->value);
66
+ } elseif ($other instanceof SassLiteral) {
 
67
  $this->value[] = $other;
68
+ } else {
 
69
  throw new SassListException('Appendation can only occur with literals', SassScriptParser::$context->node);
70
  }
71
  }
72
 
73
  // New function index returns the list index of a value within a list. For example: index(1px solid red, solid) returns 2. When the value is not found false is returned.
74
+ public function index($value)
75
+ {
76
  for ($i = 0; $i < count($this->value); $i++) {
77
  if (trim((string) $value) == trim((string) $this->value[$i])) {
78
  return new SassNumber($i);
79
  }
80
  }
81
+
82
  return new SassBoolean(false);
83
  }
84
 
86
  * Returns the value of this boolean.
87
  * @return boolean the value of this boolean
88
  */
89
+ public function getValue()
90
+ {
91
  $result = array();
92
  foreach ($this->value as $k => $v) {
93
  if ($v instanceOf SassString) {
106
  }
107
  }
108
  $this->value = $result;
109
+
110
  return $this->value;
111
  }
112
 
114
  * Returns a string representation of the value.
115
  * @return string string representation of the value.
116
  */
117
+ public function toString()
118
+ {
119
  $aliases = array(
120
  'comma' => ',',
121
  'space' => '',
124
  if (isset($aliases[$this->separator])) {
125
  $this->separator = $aliases[$this->separator];
126
  }
127
+
128
  return implode($this->separator . ' ', $this->getValue());
129
  }
130
 
134
  * @param string the subject string
135
  * @return mixed match at the start of the string or false if no match
136
  */
137
+ public static function isa($subject)
138
+ {
139
  list($list, $separator) = self::_parse_list($subject, 'auto', false);
140
+
141
  return count($list) > 1 ? $subject : FALSE;
142
  }
143
 
144
+ public static function _parse_list($list, $separator = 'auto', $lex = true, $context = null)
145
+ {
146
  if ($lex) {
147
  $context = new SassContext($context);
148
  $list = SassScriptParser::$instance->evaluate($list, $context);
155
  $separator = ' ';
156
  $list = self::_build_list($list, ' ');
157
  }
158
+ } else {
 
159
  $list = self::_build_list($list, $separator);
160
  }
161
 
165
  $list[$k] = SassScriptParser::$instance->evaluate($v, $context);
166
  }
167
  }
168
+
169
  return array($list, $separator);
170
  }
171
 
172
+ public static function _build_list($list, $separator = ',')
173
+ {
174
  if (is_object($list)) {
175
  $list = $list->value;
176
  }
188
  $braces = 0;
189
  $quotes = false;
190
  $stack = '';
191
+ for ($i = 0; $i < strlen($list); $i++) {
192
  $char = substr($list, $i, 1);
193
  switch ($char) {
194
  case '"':
195
  case "'":
196
  if (!$quotes) {
197
  $quotes = $char;
198
+ } elseif ($quotes && $quotes == $char) {
 
199
  $quotes = false;
200
  }
201
  $stack .= $char;
lib/phpsass/script/literals/SassLiteral.php CHANGED
@@ -9,7 +9,7 @@
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
- require_once('SassLiteralExceptions.php');
13
 
14
  /**
15
  * SassLiteral class.
@@ -19,11 +19,12 @@ require_once('SassLiteralExceptions.php');
19
  * @package PHamlP
20
  * @subpackage Sass.script.literals
21
  */
22
- abstract class SassLiteral {
 
23
  /**
24
  * @var array maps class names to data types
25
  */
26
- static public $typeOf = array(
27
  'SassBoolean' => 'bool',
28
  'SassColour' => 'color',
29
  'SassNumber' => 'number',
@@ -41,7 +42,8 @@ abstract class SassLiteral {
41
  * @param string value of the literal type
42
  * @return SassLiteral
43
  */
44
- public function __construct($value = null, $context) {
 
45
  $this->value = $value;
46
  $this->context = $context;
47
  }
@@ -51,17 +53,18 @@ abstract class SassLiteral {
51
  * @param string name of property to get
52
  * @return mixed return value of getter function
53
  */
54
- public function __get($name) {
 
55
  $getter = 'get' . ucfirst($name);
56
  if (method_exists($this, $getter)) {
57
  return $this->$getter();
58
- }
59
- else {
60
  throw new SassLiteralException('No getter function for ' . $name, SassScriptParser::$context->node);
61
  }
62
  }
63
 
64
- public function __toString() {
 
65
  return $this->toString();
66
  }
67
 
@@ -69,15 +72,17 @@ abstract class SassLiteral {
69
  * Returns the boolean representation of the value of this
70
  * @return boolean the boolean representation of the value of this
71
  */
72
- public function toBoolean() {
73
- return (boolean)$this->value || $this->value === null;
 
74
  }
75
 
76
  /**
77
  * Returns the type of this
78
  * @return string the type of this
79
  */
80
- public function getTypeOf() {
 
81
  return self::$typeOf[get_class($this)];
82
  }
83
 
@@ -85,11 +90,13 @@ abstract class SassLiteral {
85
  * Returns the value of this
86
  * @return mixed the value of this
87
  */
88
- public function getValue() {
 
89
  throw new SassLiteralException('Child classes must override this method', SassScriptParser::$context->node);
90
  }
91
 
92
- public function getChildren() {
 
93
  return array();
94
  }
95
 
@@ -97,7 +104,8 @@ abstract class SassLiteral {
97
  * Adds a child object to this.
98
  * @param sassLiteral the child object
99
  */
100
- public function addChild($sassLiteral) {
 
101
  $this->children[] = $sassLiteral;
102
  }
103
 
@@ -106,7 +114,8 @@ abstract class SassLiteral {
106
  * @param sassLiteral value to add
107
  * @return sassString the string values of this and other with no seperation
108
  */
109
- public function op_plus($other) {
 
110
  return new SassString($this->toString().$other->toString());
111
  }
112
 
@@ -115,7 +124,8 @@ abstract class SassLiteral {
115
  * @param SassLiteral value to subtract
116
  * @return sassString the string values of this and other seperated by '-'
117
  */
118
- public function op_minus($other) {
 
119
  return new SassString($this->toString().'-'.$other->toString());
120
  }
121
 
@@ -124,7 +134,8 @@ abstract class SassLiteral {
124
  * @param SassLiteral value to multiply by
125
  * @return sassString the string values of this and other seperated by '*'
126
  */
127
- public function op_times($other) {
 
128
  return new SassString($this->toString().'*'.$other->toString());
129
  }
130
 
@@ -133,7 +144,8 @@ abstract class SassLiteral {
133
  * @param SassLiteral value to divide by
134
  * @return sassString the string values of this and other seperated by '/'
135
  */
136
- public function op_div($other) {
 
137
  return new SassString($this->toString().' / '.$other->toString());
138
  }
139
 
@@ -143,7 +155,8 @@ abstract class SassLiteral {
143
  * @return SassLiteral result
144
  * @throws Exception if modulo not supported for the data type
145
  */
146
- public function op_modulo($other) {
 
147
  throw new SassLiteralException(get_class($this) . ' does not support Modulus', SassScriptParser::$context->node);
148
  }
149
 
@@ -153,7 +166,8 @@ abstract class SassLiteral {
153
  * @return string result
154
  * @throws Exception if bitwise AND not supported for the data type
155
  */
156
- public function op_bw_and($other) {
 
157
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise AND', SassScriptParser::$context->node);
158
  }
159
 
@@ -163,7 +177,8 @@ abstract class SassLiteral {
163
  * @return string result
164
  * @throws Exception if bitwise OR not supported for the data type
165
  */
166
- public function op_bw_or($other) {
 
167
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise OR', SassScriptParser::$context->node);
168
  }
169
 
@@ -173,7 +188,8 @@ abstract class SassLiteral {
173
  * @return string result
174
  * @throws Exception if bitwise XOR not supported for the data type
175
  */
176
- public function op_bw_xor($other) {
 
177
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise XOR', SassScriptParser::$context->node);
178
  }
179
 
@@ -183,7 +199,8 @@ abstract class SassLiteral {
183
  * @return string result
184
  * @throws Exception if bitwise NOT not supported for the data type
185
  */
186
- public function op_bw_not() {
 
187
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise NOT', SassScriptParser::$context->node);
188
  }
189
 
@@ -193,7 +210,8 @@ abstract class SassLiteral {
193
  * @return string result
194
  * @throws Exception if bitwise Shift Left not supported for the data type
195
  */
196
- public function op_shiftl($other) {
 
197
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise Shift Left', SassScriptParser::$context->node);
198
  }
199
 
@@ -203,7 +221,8 @@ abstract class SassLiteral {
203
  * @return string result
204
  * @throws Exception if bitwise Shift Right not supported for the data type
205
  */
206
- public function op_shiftr($other) {
 
207
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise Shift Right', SassScriptParser::$context->node);
208
  }
209
 
@@ -212,7 +231,8 @@ abstract class SassLiteral {
212
  * @param sassLiteral the value to and with this
213
  * @return SassLiteral other if this is boolean true, this if false
214
  */
215
- public function op_and($other) {
 
216
  return ($this->toBoolean() ? $other : $this);
217
  }
218
 
@@ -221,11 +241,13 @@ abstract class SassLiteral {
221
  * @param sassLiteral the value to or with this
222
  * @return SassLiteral this if this is boolean true, other if false
223
  */
224
- public function op_or($other) {
 
225
  return ($this->toBoolean() ? $this : $other);
226
  }
227
 
228
- public function op_assign($other) {
 
229
  return $other;
230
  }
231
 
@@ -235,7 +257,8 @@ abstract class SassLiteral {
235
  * @return SassBoolean SassBoolean object with the value true if this or
236
  * other, but not both, are true, false if not
237
  */
238
- public function op_xor($other) {
 
239
  return new SassBoolean($this->toBoolean() xor $other->toBoolean());
240
  }
241
 
@@ -244,7 +267,8 @@ abstract class SassLiteral {
244
  * @return SassBoolean SassBoolean object with the value true if the
245
  * boolean of this is false or false if it is true
246
  */
247
- public function op_not() {
 
248
  return new SassBoolean(!$this->toBoolean());
249
  }
250
 
@@ -254,7 +278,8 @@ abstract class SassLiteral {
254
  * @return SassBoolean SassBoolean object with the value true if the values
255
  * of this is greater than the value of other, false if it is not
256
  */
257
- public function op_gt($other) {
 
258
  return new SassBoolean($this->value > $other->value);
259
  }
260
 
@@ -264,7 +289,8 @@ abstract class SassLiteral {
264
  * @return SassBoolean SassBoolean object with the value true if the values
265
  * of this is greater than or equal to the value of other, false if it is not
266
  */
267
- public function op_gte($other) {
 
268
  return new SassBoolean($this->value >= $other->value);
269
  }
270
 
@@ -274,7 +300,8 @@ abstract class SassLiteral {
274
  * @return SassBoolean SassBoolean object with the value true if the values
275
  * of this is less than the value of other, false if it is not
276
  */
277
- public function op_lt($other) {
 
278
  return new SassBoolean($this->value < $other->value);
279
  }
280
 
@@ -284,7 +311,8 @@ abstract class SassLiteral {
284
  * @return SassBoolean SassBoolean object with the value true if the values
285
  * of this is less than or equal to the value of other, false if it is not
286
  */
287
- public function op_lte($other) {
 
288
  return new SassBoolean($this->value <= $other->value);
289
  }
290
 
@@ -294,7 +322,8 @@ abstract class SassLiteral {
294
  * @return SassBoolean SassBoolean object with the value true if this and
295
  * other are equal, false if they are not
296
  */
297
- public function op_eq($other) {
 
298
  return new SassBoolean($this == $other);
299
  }
300
 
@@ -304,7 +333,8 @@ abstract class SassLiteral {
304
  * @return SassBoolean SassBoolean object with the value true if this and
305
  * other are not equal, false if they are
306
  */
307
- public function op_neq($other) {
 
308
  return new SassBoolean(!$this->op_eq($other)->toBoolean());
309
  }
310
 
@@ -313,7 +343,8 @@ abstract class SassLiteral {
313
  * @param sassLiteral the value to concatenate with a space to this
314
  * @return sassString the string values of this and other seperated by " "
315
  */
316
- public function op_concat($other) {
 
317
  return new SassString($this->toString().' '.$other->toString());
318
  }
319
 
@@ -322,7 +353,8 @@ abstract class SassLiteral {
322
  * @param sassLiteral the value to concatenate with a comma to this
323
  * @return sassString the string values of this and other seperated by ","
324
  */
325
- public function op_comma($other) {
 
326
  return new SassString($this->toString().', '.$other->toString());
327
  }
328
 
@@ -332,7 +364,8 @@ abstract class SassLiteral {
332
  * @param string expected type
333
  * @throws SassScriptFunctionException if value is not the expected type
334
  */
335
- public static function assertType($literal, $type) {
 
336
  if (!$literal instanceof $type) {
337
  throw new SassScriptFunctionException(($literal instanceof SassLiteral ? get_class($literal) : 'literal') . ' must be a ' . $type, SassScriptParser::$context->node);
338
  }
@@ -346,7 +379,8 @@ abstract class SassLiteral {
346
  * @param string the units.
347
  * @throws SassScriptFunctionException if value is not the expected type
348
  */
349
- public static function assertInRange($literal, $min, $max, $units = '') {
 
350
  if ($literal->value < $min || $literal->value > $max) {
351
  throw new SassScriptFunctionException($literal->typeOf . ' must be between ' . $min.$units . ' and ' . $max.$units . ' inclusive', SassScriptParser::$context->node);
352
  }
@@ -358,7 +392,8 @@ abstract class SassLiteral {
358
  */
359
  abstract public function toString();
360
 
361
- public function render() {
 
362
  return $this->toString();
363
  }
364
 
@@ -368,7 +403,8 @@ abstract class SassLiteral {
368
  * @param string the subject string
369
  * @return mixed match at the start of the string or false if no match
370
  */
371
- public static function isa($subject){
 
372
  throw new SassLiteralException('Child classes must override this method');
373
  }
374
  }
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
+ require_once 'SassLiteralExceptions.php';
13
 
14
  /**
15
  * SassLiteral class.
19
  * @package PHamlP
20
  * @subpackage Sass.script.literals
21
  */
22
+ abstract class SassLiteral
23
+ {
24
  /**
25
  * @var array maps class names to data types
26
  */
27
+ public static $typeOf = array(
28
  'SassBoolean' => 'bool',
29
  'SassColour' => 'color',
30
  'SassNumber' => 'number',
42
  * @param string value of the literal type
43
  * @return SassLiteral
44
  */
45
+ public function __construct($value = null, $context)
46
+ {
47
  $this->value = $value;
48
  $this->context = $context;
49
  }
53
  * @param string name of property to get
54
  * @return mixed return value of getter function
55
  */
56
+ public function __get($name)
57
+ {
58
  $getter = 'get' . ucfirst($name);
59
  if (method_exists($this, $getter)) {
60
  return $this->$getter();
61
+ } else {
 
62
  throw new SassLiteralException('No getter function for ' . $name, SassScriptParser::$context->node);
63
  }
64
  }
65
 
66
+ public function __toString()
67
+ {
68
  return $this->toString();
69
  }
70
 
72
  * Returns the boolean representation of the value of this
73
  * @return boolean the boolean representation of the value of this
74
  */
75
+ public function toBoolean()
76
+ {
77
+ return (boolean) $this->value || $this->value === null;
78
  }
79
 
80
  /**
81
  * Returns the type of this
82
  * @return string the type of this
83
  */
84
+ public function getTypeOf()
85
+ {
86
  return self::$typeOf[get_class($this)];
87
  }
88
 
90
  * Returns the value of this
91
  * @return mixed the value of this
92
  */
93
+ public function getValue()
94
+ {
95
  throw new SassLiteralException('Child classes must override this method', SassScriptParser::$context->node);
96
  }
97
 
98
+ public function getChildren()
99
+ {
100
  return array();
101
  }
102
 
104
  * Adds a child object to this.
105
  * @param sassLiteral the child object
106
  */
107
+ public function addChild($sassLiteral)
108
+ {
109
  $this->children[] = $sassLiteral;
110
  }
111
 
114
  * @param sassLiteral value to add
115
  * @return sassString the string values of this and other with no seperation
116
  */
117
+ public function op_plus($other)
118
+ {
119
  return new SassString($this->toString().$other->toString());
120
  }
121
 
124
  * @param SassLiteral value to subtract
125
  * @return sassString the string values of this and other seperated by '-'
126
  */
127
+ public function op_minus($other)
128
+ {
129
  return new SassString($this->toString().'-'.$other->toString());
130
  }
131
 
134
  * @param SassLiteral value to multiply by
135
  * @return sassString the string values of this and other seperated by '*'
136
  */
137
+ public function op_times($other)
138
+ {
139
  return new SassString($this->toString().'*'.$other->toString());
140
  }
141
 
144
  * @param SassLiteral value to divide by
145
  * @return sassString the string values of this and other seperated by '/'
146
  */
147
+ public function op_div($other)
148
+ {
149
  return new SassString($this->toString().' / '.$other->toString());
150
  }
151
 
155
  * @return SassLiteral result
156
  * @throws Exception if modulo not supported for the data type
157
  */
158
+ public function op_modulo($other)
159
+ {
160
  throw new SassLiteralException(get_class($this) . ' does not support Modulus', SassScriptParser::$context->node);
161
  }
162
 
166
  * @return string result
167
  * @throws Exception if bitwise AND not supported for the data type
168
  */
169
+ public function op_bw_and($other)
170
+ {
171
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise AND', SassScriptParser::$context->node);
172
  }
173
 
177
  * @return string result
178
  * @throws Exception if bitwise OR not supported for the data type
179
  */
180
+ public function op_bw_or($other)
181
+ {
182
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise OR', SassScriptParser::$context->node);
183
  }
184
 
188
  * @return string result
189
  * @throws Exception if bitwise XOR not supported for the data type
190
  */
191
+ public function op_bw_xor($other)
192
+ {
193
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise XOR', SassScriptParser::$context->node);
194
  }
195
 
199
  * @return string result
200
  * @throws Exception if bitwise NOT not supported for the data type
201
  */
202
+ public function op_bw_not()
203
+ {
204
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise NOT', SassScriptParser::$context->node);
205
  }
206
 
210
  * @return string result
211
  * @throws Exception if bitwise Shift Left not supported for the data type
212
  */
213
+ public function op_shiftl($other)
214
+ {
215
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise Shift Left', SassScriptParser::$context->node);
216
  }
217
 
221
  * @return string result
222
  * @throws Exception if bitwise Shift Right not supported for the data type
223
  */
224
+ public function op_shiftr($other)
225
+ {
226
  throw new SassLiteralException(get_class($this) . ' does not support Bitwise Shift Right', SassScriptParser::$context->node);
227
  }
228
 
231
  * @param sassLiteral the value to and with this
232
  * @return SassLiteral other if this is boolean true, this if false
233
  */
234
+ public function op_and($other)
235
+ {
236
  return ($this->toBoolean() ? $other : $this);
237
  }
238
 
241
  * @param sassLiteral the value to or with this
242
  * @return SassLiteral this if this is boolean true, other if false
243
  */
244
+ public function op_or($other)
245
+ {
246
  return ($this->toBoolean() ? $this : $other);
247
  }
248
 
249
+ public function op_assign($other)
250
+ {
251
  return $other;
252
  }
253
 
257
  * @return SassBoolean SassBoolean object with the value true if this or
258
  * other, but not both, are true, false if not
259
  */
260
+ public function op_xor($other)
261
+ {
262
  return new SassBoolean($this->toBoolean() xor $other->toBoolean());
263
  }
264
 
267
  * @return SassBoolean SassBoolean object with the value true if the
268
  * boolean of this is false or false if it is true
269
  */
270
+ public function op_not()
271
+ {
272
  return new SassBoolean(!$this->toBoolean());
273
  }
274
 
278
  * @return SassBoolean SassBoolean object with the value true if the values
279
  * of this is greater than the value of other, false if it is not
280
  */
281
+ public function op_gt($other)
282
+ {
283
  return new SassBoolean($this->value > $other->value);
284
  }
285
 
289
  * @return SassBoolean SassBoolean object with the value true if the values
290
  * of this is greater than or equal to the value of other, false if it is not
291
  */
292
+ public function op_gte($other)
293
+ {
294
  return new SassBoolean($this->value >= $other->value);
295
  }
296
 
300
  * @return SassBoolean SassBoolean object with the value true if the values
301
  * of this is less than the value of other, false if it is not
302
  */
303
+ public function op_lt($other)
304
+ {
305
  return new SassBoolean($this->value < $other->value);
306
  }
307
 
311
  * @return SassBoolean SassBoolean object with the value true if the values
312
  * of this is less than or equal to the value of other, false if it is not
313
  */
314
+ public function op_lte($other)
315
+ {
316
  return new SassBoolean($this->value <= $other->value);
317
  }
318
 
322
  * @return SassBoolean SassBoolean object with the value true if this and
323
  * other are equal, false if they are not
324
  */
325
+ public function op_eq($other)
326
+ {
327
  return new SassBoolean($this == $other);
328
  }
329
 
333
  * @return SassBoolean SassBoolean object with the value true if this and
334
  * other are not equal, false if they are
335
  */
336
+ public function op_neq($other)
337
+ {
338
  return new SassBoolean(!$this->op_eq($other)->toBoolean());
339
  }
340
 
343
  * @param sassLiteral the value to concatenate with a space to this
344
  * @return sassString the string values of this and other seperated by " "
345
  */
346
+ public function op_concat($other)
347
+ {
348
  return new SassString($this->toString().' '.$other->toString());
349
  }
350
 
353
  * @param sassLiteral the value to concatenate with a comma to this
354
  * @return sassString the string values of this and other seperated by ","
355
  */
356
+ public function op_comma($other)
357
+ {
358
  return new SassString($this->toString().', '.$other->toString());
359
  }
360
 
364
  * @param string expected type
365
  * @throws SassScriptFunctionException if value is not the expected type
366
  */
367
+ public static function assertType($literal, $type)
368
+ {
369
  if (!$literal instanceof $type) {
370
  throw new SassScriptFunctionException(($literal instanceof SassLiteral ? get_class($literal) : 'literal') . ' must be a ' . $type, SassScriptParser::$context->node);
371
  }
379
  * @param string the units.
380
  * @throws SassScriptFunctionException if value is not the expected type
381
  */
382
+ public static function assertInRange($literal, $min, $max, $units = '')
383
+ {
384
  if ($literal->value < $min || $literal->value > $max) {
385
  throw new SassScriptFunctionException($literal->typeOf . ' must be between ' . $min.$units . ' and ' . $max.$units . ' inclusive', SassScriptParser::$context->node);
386
  }
392
  */
393
  abstract public function toString();
394
 
395
+ public function render()
396
+ {
397
  return $this->toString();
398
  }
399
 
403
  * @param string the subject string
404
  * @return mixed match at the start of the string or false if no match
405
  */
406
+ public static function isa($subject)
407
+ {
408
  throw new SassLiteralException('Child classes must override this method');
409
  }
410
  }
lib/phpsass/script/literals/SassLiteralExceptions.php CHANGED
@@ -44,4 +44,4 @@ class SassNumberException extends SassLiteralException {}
44
  * @package PHamlP
45
  * @subpackage Sass.script.literals
46
  */
47
- class SassStringException extends SassLiteralException {}
44
  * @package PHamlP
45
  * @subpackage Sass.script.literals
46
  */
47
+ class SassStringException extends SassLiteralException {}
lib/phpsass/script/literals/SassNumber.php CHANGED
@@ -9,7 +9,7 @@
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
- require_once('SassLiteral.php');
13
 
14
  /**
15
  * SassNumber class.
@@ -19,7 +19,8 @@ require_once('SassLiteral.php');
19
  * @package PHamlP
20
  * @subpackage Sass.script.literals
21
  */
22
- class SassNumber extends SassLiteral {
 
23
  /**
24
  * Regx for matching and extracting numbers
25
  */
@@ -45,7 +46,7 @@ class SassNumber extends SassLiteral {
45
  * pc: picas — 1 pica = 12 points
46
  * pt: points — 1 point = 1/72nd of an inch
47
  */
48
- static private $unitConversion = array(
49
  'in' => 1,
50
  'cm' => 2.54,
51
  'mm' => 25.4,
@@ -53,7 +54,7 @@ class SassNumber extends SassLiteral {
53
  'pt' => 72,
54
  'px' => 96
55
  );
56
- static private $validUnits = array(
57
  'in', 'cm', 'mm', 'pc', 'pt', 'em', 'rem', 'ex', 'px', '%', 's', 'deg'
58
  );
59
 
@@ -79,7 +80,8 @@ class SassNumber extends SassLiteral {
79
  * @param string number
80
  * @return SassNumber
81
  */
82
- public function __construct($value) {
 
83
  preg_match(self::MATCH, $value, $matches);
84
 
85
  $matches += array(null,null,'','');
@@ -109,20 +111,20 @@ class SassNumber extends SassLiteral {
109
  * @return mixed SassNumber if other is a SassNumber or
110
  * SassColour if it is a SassColour
111
  */
112
- public function op_plus($other) {
 
113
  if ($other instanceof SassColour) {
114
  return $other->op_plus($this);
115
- }
116
- else if ($other instanceOf SassString) {
117
  $other = clone $other;
118
  $other->value = $this->value . $other->value;
 
119
  return $other;
120
- }
121
- elseif (!$other instanceof SassNumber) {
122
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
123
- }
124
- else {
125
  $other = $this->convert($other);
 
126
  return new SassNumber(($this->value + $other->value).$this->units);
127
  }
128
  }
@@ -131,7 +133,8 @@ class SassNumber extends SassLiteral {
131
  * Unary + operator
132
  * @return SassNumber the value of this number
133
  */
134
- public function op_unary_plus() {
 
135
  return $this;
136
  }
137
 
@@ -141,15 +144,15 @@ class SassNumber extends SassLiteral {
141
  * @return mixed SassNumber if other is a SassNumber or
142
  * SassColour if it is a SassColour
143
  */
144
- public function op_minus($other) {
 
145
  if ($other instanceof SassColour) {
146
  return $other->op_minus($this);
147
- }
148
- elseif (!$other instanceof SassNumber) {
149
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
150
- }
151
- else {
152
  $other = $this->convert($other);
 
153
  return new SassNumber(($this->value - $other->value) . $this->units);
154
  }
155
  }
@@ -158,11 +161,13 @@ class SassNumber extends SassLiteral {
158
  * Unary - operator
159
  * @return SassNumber the negative value of this number
160
  */
161
- public function op_unary_minus() {
 
162
  return new SassNumber(($this->value * -1) . $this->units);
163
  }
164
 
165
- public function op_unary_concat() {
 
166
  return $this;
167
  }
168
 
@@ -172,14 +177,13 @@ class SassNumber extends SassLiteral {
172
  * @return mixed SassNumber if other is a SassNumber or
173
  * SassColour if it is a SassColour
174
  */
175
- public function op_times($other) {
 
176
  if ($other instanceof SassColour) {
177
  return $other->op_times($this);
178
- }
179
- elseif (!$other instanceof SassNumber) {
180
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
181
- }
182
- else {
183
  return new SassNumber(($this->value * $other->value).$this->unitString(
184
  array_merge($this->numeratorUnits, $other->numeratorUnits),
185
  array_merge($this->denominatorUnits, $other->denominatorUnits)
@@ -193,20 +197,18 @@ class SassNumber extends SassLiteral {
193
  * @return mixed SassNumber if other is a SassNumber or
194
  * SassColour if it is a SassColour
195
  */
196
- public function op_div($other) {
 
197
  if ($other instanceof SassColour) {
198
  return $other->op_div($this);
199
- }
200
- elseif (!$other instanceof SassNumber) {
201
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
202
- }
203
- elseif ($this->inExpression || $other->inExpression) {
204
  return new SassNumber(($this->value / $other->value).$this->unitString(
205
  array_merge($this->numeratorUnits, $other->denominatorUnits),
206
  array_merge($this->denominatorUnits, $other->numeratorUnits)
207
  ));
208
- }
209
- else {
210
  return new SassNumber(($this->value / $other->value).$this->unitString(
211
  array_merge($this->numeratorUnits, $other->denominatorUnits),
212
  $this->denominatorUnits
@@ -219,14 +221,14 @@ class SassNumber extends SassLiteral {
219
  * @return SassBoolean SassBoolean object with the value true if the values
220
  * of this and other are equal, false if they are not
221
  */
222
- public function op_eq($other) {
 
223
  if (!$other instanceof SassNumber) {
224
  return new SassBoolean(false);
225
  }
226
  try {
227
  return new SassBoolean($this->value == $this->convert($other)->value);
228
- }
229
- catch (Exception $e) {
230
  return new SassBoolean(false);
231
  }
232
  }
@@ -237,10 +239,12 @@ class SassNumber extends SassLiteral {
237
  * @return SassBoolean SassBoolean object with the value true if the values
238
  * of this is greater than the value of other, false if it is not
239
  */
240
- public function op_gt($other) {
 
241
  if (!$other instanceof SassNumber) {
242
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
243
  }
 
244
  return new SassBoolean($this->value > $this->convert($other)->value);
245
  }
246
 
@@ -250,10 +254,12 @@ class SassNumber extends SassLiteral {
250
  * @return SassBoolean SassBoolean object with the value true if the values
251
  * of this is greater than or equal to the value of other, false if it is not
252
  */
253
- public function op_gte($other) {
 
254
  if (!$other instanceof SassNumber) {
255
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
256
  }
 
257
  return new SassBoolean($this->value >= $this->convert($other)->value);
258
  }
259
 
@@ -263,10 +269,12 @@ class SassNumber extends SassLiteral {
263
  * @return SassBoolean SassBoolean object with the value true if the values
264
  * of this is less than the value of other, false if it is not
265
  */
266
- public function op_lt($other) {
 
267
  if (!$other instanceof SassNumber) {
268
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
269
  }
 
270
  return new SassBoolean($this->value < $this->convert($other)->value);
271
  }
272
 
@@ -276,10 +284,12 @@ class SassNumber extends SassLiteral {
276
  * @return SassBoolean SassBoolean object with the value true if the values
277
  * of this is less than or equal to the value of other, false if it is not
278
  */
279
- public function op_lte($other) {
 
280
  if (!$other instanceof SassNumber) {
281
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
282
  }
 
283
  return new SassBoolean($this->value <= $this->convert($other)->value);
284
  }
285
 
@@ -289,11 +299,13 @@ class SassNumber extends SassLiteral {
289
  * @return mixed SassNumber if other is a SassNumber or
290
  * SassColour if it is a SassColour
291
  */
292
- public function op_modulo($other) {
 
293
  if (!$other instanceof SassNumber || !$other->isUnitless()) {
294
  throw new SassNumberException('Number must be a unitless number', SassScriptParser::$context->node);
295
  }
296
  $this->value %= $this->convert($other)->value;
 
297
  return $this;
298
  }
299
 
@@ -305,14 +317,15 @@ class SassNumber extends SassLiteral {
305
  * @return SassNumber the other number with its value and units coerced if neccessary
306
  * @throws SassNumberException if the units are incompatible
307
  */
308
- private function convert($other) {
 
309
  if ($this->isUnitless()) {
310
  $this->numeratorUnits = $other->numeratorUnits;
311
  $this->denominatorUnits = $other->denominatorUnits;
312
- }
313
- else {
314
  $other = $other->coerce($this->numeratorUnits, $this->denominatorUnits);
315
  }
 
316
  return $other;
317
  }
318
 
@@ -326,7 +339,8 @@ class SassNumber extends SassLiteral {
326
  * @param array $denominatorUnits
327
  * @return SassNumber
328
  */
329
- public function coerce($numeratorUnits, $denominatorUnits) {
 
330
  return new SassNumber(($this->isUnitless() ?
331
  $this->value : $this->value *
332
  $this->coercionFactor($this->numeratorUnits, $numeratorUnits) /
@@ -340,7 +354,8 @@ class SassNumber extends SassLiteral {
340
  * @param array units being converted to
341
  * @return float the coercion factor to apply
342
  */
343
- private function coercionFactor($fromUnits, $toUnits) {
 
344
  $units = $this->removeCommonUnits($fromUnits, $toUnits);
345
  $fromUnits = $units[0];
346
  $toUnits = $units[1];
@@ -357,11 +372,11 @@ class SassNumber extends SassLiteral {
357
  foreach ($fromUnits as $i=>$from) {
358
  if (array_key_exists($i, $toUnits) && array_key_exists($toUnits[$i], self::$unitConversion)) {
359
  $coercionFactor *= self::$unitConversion[$toUnits[$i]] / self::$unitConversion[$from];
360
- }
361
- else {
362
  throw new SassNumberException("Incompatible units: '" . join(' * ', $fromUnits) . "' and '" . join(' * ', $toUnits) . "'", SassScriptParser::$context->node);
363
  }
364
  }
 
365
  return $coercionFactor;
366
  }
367
 
@@ -370,13 +385,15 @@ class SassNumber extends SassLiteral {
370
  * @param array units to test
371
  * @return boolean true if all units can be converted, false if not
372
  */
373
- private function areConvertable($units) {
 
374
  $convertable = array_keys(self::$unitConversion);
375
  foreach ($units as $unit) {
376
  if (!in_array($unit, $convertable)) {
377
  return false;
378
  }
379
  }
 
380
  return true;
381
  }
382
 
@@ -388,18 +405,19 @@ class SassNumber extends SassLiteral {
388
  * @param array second set of units
389
  * @return array both sets of units with common units removed
390
  */
391
- private function removeCommonUnits($u1, $u2) {
 
392
  $_u1 = array();
393
  while (!empty($u1)) {
394
  $u = array_shift($u1);
395
  $i = array_search($u, $u2);
396
  if ($i !== false) {
397
  unset($u2[$i]);
398
- }
399
- else {
400
  $_u1[] = $u;
401
  }
402
  }
 
403
  return (array($_u1, $u2));
404
  }
405
 
@@ -407,7 +425,8 @@ class SassNumber extends SassLiteral {
407
  * Returns a value indicating if this number is unitless.
408
  * @return boolean true if this number is unitless, false if not
409
  */
410
- public function isUnitless() {
 
411
  return empty($this->numeratorUnits) && empty($this->denominatorUnits);
412
  }
413
 
@@ -415,7 +434,8 @@ class SassNumber extends SassLiteral {
415
  * Returns a value indicating if this number has units.
416
  * @return boolean true if this number has, false if not
417
  */
418
- public function hasUnits() {
 
419
  return !$this->isUnitless();
420
  }
421
 
@@ -425,7 +445,8 @@ class SassNumber extends SassLiteral {
425
  * @return boolean true if this number has units that can be represented in
426
  * CSS, false if not
427
  */
428
- public function hasLegalUnits() {
 
429
  return (empty($this->numeratorUnits) || count($this->numeratorUnits) === 1) && empty($this->denominatorUnits);
430
  }
431
 
@@ -433,7 +454,8 @@ class SassNumber extends SassLiteral {
433
  * Returns a string representation of the units.
434
  * @return string the units
435
  */
436
- public function unitString($numeratorUnits, $denominatorUnits) {
 
437
  foreach ($numeratorUnits as $i => $unit) {
438
  if (!in_array($unit, self::$validUnits)) {
439
  unset($numeratorUnits[$i]);
@@ -444,6 +466,7 @@ class SassNumber extends SassLiteral {
444
  unset($denominatorUnits[$i]);
445
  }
446
  }
 
447
  return join(' * ', $numeratorUnits) . (!empty($denominatorUnits) ? ' / ' . join(' * ', $denominatorUnits) : '');
448
  }
449
 
@@ -451,7 +474,8 @@ class SassNumber extends SassLiteral {
451
  * Returns the units of this number.
452
  * @return string the units of this number
453
  */
454
- public function getUnits() {
 
455
  return $this->unitString($this->numeratorUnits, $this->denominatorUnits);
456
  }
457
 
@@ -459,7 +483,8 @@ class SassNumber extends SassLiteral {
459
  * Returns the denominator units of this number.
460
  * @return string the denominator units of this number
461
  */
462
- public function getDenominatorUnits() {
 
463
  return join(' * ', $this->denominatorUnits);
464
  }
465
 
@@ -467,7 +492,8 @@ class SassNumber extends SassLiteral {
467
  * Returns the numerator units of this number.
468
  * @return string the numerator units of this number
469
  */
470
- public function getNumeratorUnits() {
 
471
  return join(' * ', $this->numeratorUnits);
472
  }
473
 
@@ -475,12 +501,13 @@ class SassNumber extends SassLiteral {
475
  * Returns a value indicating if this number can be compared to other.
476
  * @return boolean true if this number can be compared to other, false if not
477
  */
478
- public function isComparableTo($other) {
 
479
  try {
480
  $this->op_plus($other);
 
481
  return true;
482
- }
483
- catch (Exception $e) {
484
  return false;
485
  }
486
  }
@@ -489,7 +516,8 @@ class SassNumber extends SassLiteral {
489
  * Returns a value indicating if this number is an integer.
490
  * @return boolean true if this number is an integer, false if not
491
  */
492
- public function isInt() {
 
493
  return $this->value % 1 === 0;
494
  }
495
 
@@ -497,7 +525,8 @@ class SassNumber extends SassLiteral {
497
  * Returns the value of this number.
498
  * @return float the value of this number.
499
  */
500
- public function getValue() {
 
501
  return $this->value;
502
  }
503
 
@@ -506,10 +535,12 @@ class SassNumber extends SassLiteral {
506
  * @return integer the integer value.
507
  * @throws SassNumberException if the number is not an integer
508
  */
509
- public function toInt() {
510
- if (!$this->isInt()) {
 
511
  throw new SassNumberException('Not an integer: ' . $this->value, SassScriptParser::$context->node);
512
  }
 
513
  return intval($this->value);
514
  }
515
 
@@ -519,10 +550,12 @@ class SassNumber extends SassLiteral {
519
  * otherwise the result is rounded to the specified precision.
520
  * @return string number as a string with it's units if any
521
  */
522
- public function toString() {
 
523
  if (!isset($this->units)) {
524
  $this->units = $this->getUnits();
525
  }
 
526
  return ($this->units == 'px' ? floor($this->value) : str_replace(',','.',round($this->value, self::PRECISION))) . $this->units;
527
  }
528
 
@@ -532,7 +565,8 @@ class SassNumber extends SassLiteral {
532
  * @param string the subject string
533
  * @return mixed match at the start of the string or false if no match
534
  */
535
- public static function isa($subject) {
 
536
  return (preg_match(self::MATCH, $subject, $matches) ? $matches[0] : false);
537
  }
538
 
@@ -540,7 +574,8 @@ class SassNumber extends SassLiteral {
540
  * Returns the number of values of SassNumber
541
  * @return int
542
  */
543
- public function length() {
 
544
  return count($this->value);
545
  }
546
 
@@ -549,10 +584,12 @@ class SassNumber extends SassLiteral {
549
  * @param int - the nth position of value
550
  * @return SassBoolean|SassNumber
551
  */
552
- public function nth($i) {
 
553
  if ($i == 1 && isset($this->value)) {
554
  return new SassNumber($this->value);
555
  }
 
556
  return new SassBoolean(false);
557
  }
558
 
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
+ require_once 'SassLiteral.php';
13
 
14
  /**
15
  * SassNumber class.
19
  * @package PHamlP
20
  * @subpackage Sass.script.literals
21
  */
22
+ class SassNumber extends SassLiteral
23
+ {
24
  /**
25
  * Regx for matching and extracting numbers
26
  */
46
  * pc: picas — 1 pica = 12 points
47
  * pt: points — 1 point = 1/72nd of an inch
48
  */
49
+ private static $unitConversion = array(
50
  'in' => 1,
51
  'cm' => 2.54,
52
  'mm' => 25.4,
54
  'pt' => 72,
55
  'px' => 96
56
  );
57
+ private static $validUnits = array(
58
  'in', 'cm', 'mm', 'pc', 'pt', 'em', 'rem', 'ex', 'px', '%', 's', 'deg'
59
  );
60
 
80
  * @param string number
81
  * @return SassNumber
82
  */
83
+ public function __construct($value)
84
+ {
85
  preg_match(self::MATCH, $value, $matches);
86
 
87
  $matches += array(null,null,'','');
111
  * @return mixed SassNumber if other is a SassNumber or
112
  * SassColour if it is a SassColour
113
  */
114
+ public function op_plus($other)
115
+ {
116
  if ($other instanceof SassColour) {
117
  return $other->op_plus($this);
118
+ } elseif ($other instanceOf SassString) {
 
119
  $other = clone $other;
120
  $other->value = $this->value . $other->value;
121
+
122
  return $other;
123
+ } elseif (!$other instanceof SassNumber) {
 
124
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
125
+ } else {
 
126
  $other = $this->convert($other);
127
+
128
  return new SassNumber(($this->value + $other->value).$this->units);
129
  }
130
  }
133
  * Unary + operator
134
  * @return SassNumber the value of this number
135
  */
136
+ public function op_unary_plus()
137
+ {
138
  return $this;
139
  }
140
 
144
  * @return mixed SassNumber if other is a SassNumber or
145
  * SassColour if it is a SassColour
146
  */
147
+ public function op_minus($other)
148
+ {
149
  if ($other instanceof SassColour) {
150
  return $other->op_minus($this);
151
+ } elseif (!$other instanceof SassNumber) {
 
152
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
153
+ } else {
 
154
  $other = $this->convert($other);
155
+
156
  return new SassNumber(($this->value - $other->value) . $this->units);
157
  }
158
  }
161
  * Unary - operator
162
  * @return SassNumber the negative value of this number
163
  */
164
+ public function op_unary_minus()
165
+ {
166
  return new SassNumber(($this->value * -1) . $this->units);
167
  }
168
 
169
+ public function op_unary_concat()
170
+ {
171
  return $this;
172
  }
173
 
177
  * @return mixed SassNumber if other is a SassNumber or
178
  * SassColour if it is a SassColour
179
  */
180
+ public function op_times($other)
181
+ {
182
  if ($other instanceof SassColour) {
183
  return $other->op_times($this);
184
+ } elseif (!$other instanceof SassNumber) {
 
185
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
186
+ } else {
 
187
  return new SassNumber(($this->value * $other->value).$this->unitString(
188
  array_merge($this->numeratorUnits, $other->numeratorUnits),
189
  array_merge($this->denominatorUnits, $other->denominatorUnits)
197
  * @return mixed SassNumber if other is a SassNumber or
198
  * SassColour if it is a SassColour
199
  */
200
+ public function op_div($other)
201
+ {
202
  if ($other instanceof SassColour) {
203
  return $other->op_div($this);
204
+ } elseif (!$other instanceof SassNumber) {
 
205
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
206
+ } elseif ($this->inExpression || $other->inExpression) {
 
207
  return new SassNumber(($this->value / $other->value).$this->unitString(
208
  array_merge($this->numeratorUnits, $other->denominatorUnits),
209
  array_merge($this->denominatorUnits, $other->numeratorUnits)
210
  ));
211
+ } else {
 
212
  return new SassNumber(($this->value / $other->value).$this->unitString(
213
  array_merge($this->numeratorUnits, $other->denominatorUnits),
214
  $this->denominatorUnits
221
  * @return SassBoolean SassBoolean object with the value true if the values
222
  * of this and other are equal, false if they are not
223
  */
224
+ public function op_eq($other)
225
+ {
226
  if (!$other instanceof SassNumber) {
227
  return new SassBoolean(false);
228
  }
229
  try {
230
  return new SassBoolean($this->value == $this->convert($other)->value);
231
+ } catch (Exception $e) {
 
232
  return new SassBoolean(false);
233
  }
234
  }
239
  * @return SassBoolean SassBoolean object with the value true if the values
240
  * of this is greater than the value of other, false if it is not
241
  */
242
+ public function op_gt($other)
243
+ {
244
  if (!$other instanceof SassNumber) {
245
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
246
  }
247
+
248
  return new SassBoolean($this->value > $this->convert($other)->value);
249
  }
250
 
254
  * @return SassBoolean SassBoolean object with the value true if the values
255
  * of this is greater than or equal to the value of other, false if it is not
256
  */
257
+ public function op_gte($other)
258
+ {
259
  if (!$other instanceof SassNumber) {
260
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
261
  }
262
+
263
  return new SassBoolean($this->value >= $this->convert($other)->value);
264
  }
265
 
269
  * @return SassBoolean SassBoolean object with the value true if the values
270
  * of this is less than the value of other, false if it is not
271
  */
272
+ public function op_lt($other)
273
+ {
274
  if (!$other instanceof SassNumber) {
275
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
276
  }
277
+
278
  return new SassBoolean($this->value < $this->convert($other)->value);
279
  }
280
 
284
  * @return SassBoolean SassBoolean object with the value true if the values
285
  * of this is less than or equal to the value of other, false if it is not
286
  */
287
+ public function op_lte($other)
288
+ {
289
  if (!$other instanceof SassNumber) {
290
  throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
291
  }
292
+
293
  return new SassBoolean($this->value <= $this->convert($other)->value);
294
  }
295
 
299
  * @return mixed SassNumber if other is a SassNumber or
300
  * SassColour if it is a SassColour
301
  */
302
+ public function op_modulo($other)
303
+ {
304
  if (!$other instanceof SassNumber || !$other->isUnitless()) {
305
  throw new SassNumberException('Number must be a unitless number', SassScriptParser::$context->node);
306
  }
307
  $this->value %= $this->convert($other)->value;
308
+
309
  return $this;
310
  }
311
 
317
  * @return SassNumber the other number with its value and units coerced if neccessary
318
  * @throws SassNumberException if the units are incompatible
319
  */
320
+ private function convert($other)
321
+ {
322
  if ($this->isUnitless()) {
323
  $this->numeratorUnits = $other->numeratorUnits;
324
  $this->denominatorUnits = $other->denominatorUnits;
325
+ } else {
 
326
  $other = $other->coerce($this->numeratorUnits, $this->denominatorUnits);
327
  }
328
+
329
  return $other;
330
  }
331
 
339
  * @param array $denominatorUnits
340
  * @return SassNumber
341
  */
342
+ public function coerce($numeratorUnits, $denominatorUnits)
343
+ {
344
  return new SassNumber(($this->isUnitless() ?
345
  $this->value : $this->value *
346
  $this->coercionFactor($this->numeratorUnits, $numeratorUnits) /
354
  * @param array units being converted to
355
  * @return float the coercion factor to apply
356
  */
357
+ private function coercionFactor($fromUnits, $toUnits)
358
+ {
359
  $units = $this->removeCommonUnits($fromUnits, $toUnits);
360
  $fromUnits = $units[0];
361
  $toUnits = $units[1];
372
  foreach ($fromUnits as $i=>$from) {
373
  if (array_key_exists($i, $toUnits) && array_key_exists($toUnits[$i], self::$unitConversion)) {
374
  $coercionFactor *= self::$unitConversion[$toUnits[$i]] / self::$unitConversion[$from];
375
+ } else {
 
376
  throw new SassNumberException("Incompatible units: '" . join(' * ', $fromUnits) . "' and '" . join(' * ', $toUnits) . "'", SassScriptParser::$context->node);
377
  }
378
  }
379
+
380
  return $coercionFactor;
381
  }
382
 
385
  * @param array units to test
386
  * @return boolean true if all units can be converted, false if not
387
  */
388
+ private function areConvertable($units)
389
+ {
390
  $convertable = array_keys(self::$unitConversion);
391
  foreach ($units as $unit) {
392
  if (!in_array($unit, $convertable)) {
393
  return false;
394
  }
395
  }
396
+
397
  return true;
398
  }
399
 
405
  * @param array second set of units
406
  * @return array both sets of units with common units removed
407
  */
408
+ private function removeCommonUnits($u1, $u2)
409
+ {
410
  $_u1 = array();
411
  while (!empty($u1)) {
412
  $u = array_shift($u1);
413
  $i = array_search($u, $u2);
414
  if ($i !== false) {
415
  unset($u2[$i]);
416
+ } else {
 
417
  $_u1[] = $u;
418
  }
419
  }
420
+
421
  return (array($_u1, $u2));
422
  }
423
 
425
  * Returns a value indicating if this number is unitless.
426
  * @return boolean true if this number is unitless, false if not
427
  */
428
+ public function isUnitless()
429
+ {
430
  return empty($this->numeratorUnits) && empty($this->denominatorUnits);
431
  }
432
 
434
  * Returns a value indicating if this number has units.
435
  * @return boolean true if this number has, false if not
436
  */
437
+ public function hasUnits()
438
+ {
439
  return !$this->isUnitless();
440
  }
441
 
445
  * @return boolean true if this number has units that can be represented in
446
  * CSS, false if not
447
  */
448
+ public function hasLegalUnits()
449
+ {
450
  return (empty($this->numeratorUnits) || count($this->numeratorUnits) === 1) && empty($this->denominatorUnits);
451
  }
452
 
454
  * Returns a string representation of the units.
455
  * @return string the units
456
  */
457
+ public function unitString($numeratorUnits, $denominatorUnits)
458
+ {
459
  foreach ($numeratorUnits as $i => $unit) {
460
  if (!in_array($unit, self::$validUnits)) {
461
  unset($numeratorUnits[$i]);
466
  unset($denominatorUnits[$i]);
467
  }
468
  }
469
+
470
  return join(' * ', $numeratorUnits) . (!empty($denominatorUnits) ? ' / ' . join(' * ', $denominatorUnits) : '');
471
  }
472
 
474
  * Returns the units of this number.
475
  * @return string the units of this number
476
  */
477
+ public function getUnits()
478
+ {
479
  return $this->unitString($this->numeratorUnits, $this->denominatorUnits);
480
  }
481
 
483
  * Returns the denominator units of this number.
484
  * @return string the denominator units of this number
485
  */
486
+ public function getDenominatorUnits()
487
+ {
488
  return join(' * ', $this->denominatorUnits);
489
  }
490
 
492
  * Returns the numerator units of this number.
493
  * @return string the numerator units of this number
494
  */
495
+ public function getNumeratorUnits()
496
+ {
497
  return join(' * ', $this->numeratorUnits);
498
  }
499
 
501
  * Returns a value indicating if this number can be compared to other.
502
  * @return boolean true if this number can be compared to other, false if not
503
  */
504
+ public function isComparableTo($other)
505
+ {
506
  try {
507
  $this->op_plus($other);
508
+
509
  return true;
510
+ } catch (Exception $e) {
 
511
  return false;
512
  }
513
  }
516
  * Returns a value indicating if this number is an integer.
517
  * @return boolean true if this number is an integer, false if not
518
  */
519
+ public function isInt()
520
+ {
521
  return $this->value % 1 === 0;
522
  }
523
 
525
  * Returns the value of this number.
526
  * @return float the value of this number.
527
  */
528
+ public function getValue()
529
+ {
530
  return $this->value;
531
  }
532
 
535
  * @return integer the integer value.
536
  * @throws SassNumberException if the number is not an integer
537
  */
538
+ public function toInt()
539
+ {
540
+ if (!$this->isInt()) {
541
  throw new SassNumberException('Not an integer: ' . $this->value, SassScriptParser::$context->node);
542
  }
543
+
544
  return intval($this->value);
545
  }
546
 
550
  * otherwise the result is rounded to the specified precision.
551
  * @return string number as a string with it's units if any
552
  */
553
+ public function toString()
554
+ {
555
  if (!isset($this->units)) {
556
  $this->units = $this->getUnits();
557
  }
558
+
559
  return ($this->units == 'px' ? floor($this->value) : str_replace(',','.',round($this->value, self::PRECISION))) . $this->units;
560
  }
561
 
565
  * @param string the subject string
566
  * @return mixed match at the start of the string or false if no match
567
  */
568
+ public static function isa($subject)
569
+ {
570
  return (preg_match(self::MATCH, $subject, $matches) ? $matches[0] : false);
571
  }
572
 
574
  * Returns the number of values of SassNumber
575
  * @return int
576
  */
577
+ public function length()
578
+ {
579
  return count($this->value);
580
  }
581
 
584
  * @param int - the nth position of value
585
  * @return SassBoolean|SassNumber
586
  */
587
+ public function nth($i)
588
+ {
589
  if ($i == 1 && isset($this->value)) {
590
  return new SassNumber($this->value);
591
  }
592
+
593
  return new SassBoolean(false);
594
  }
595
 
lib/phpsass/script/literals/SassString.php CHANGED
@@ -9,7 +9,7 @@
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
- require_once('SassLiteral.php');
13
 
14
  /**
15
  * SassString class.
@@ -17,7 +17,8 @@ require_once('SassLiteral.php');
17
  * @package PHamlP
18
  * @subpackage Sass.script.literals
19
  */
20
- class SassString extends SassLiteral {
 
21
  const MATCH = '/^(((["\'])(.*?)(\3))|(-[a-zA-Z-]+[^\s]*?))/i';
22
  const _MATCH = '/^(["\'])(.*?)(\1)?$/'; // Used to match strings such as "Times New Roman",serif
23
  const VALUE = 2;
@@ -33,13 +34,13 @@ class SassString extends SassLiteral {
33
  * @param string string
34
  * @return SassString
35
  */
36
- public function __construct($value) {
 
37
  preg_match(self::_MATCH, $value, $matches);
38
  if ((isset($matches[self::QUOTE]))) {
39
  $this->quote = $matches[self::QUOTE];
40
  $this->value = $matches[self::VALUE];
41
- }
42
- else {
43
  $this->quote = '';
44
  $this->value = $value;
45
  }
@@ -52,8 +53,10 @@ class SassString extends SassLiteral {
52
  * @param sassString string to add to this
53
  * @return sassString the string result
54
  */
55
- public function op_plus($other) {
 
56
  $this->value .= $other->value;
 
57
  return $this;
58
  }
59
 
@@ -63,29 +66,34 @@ class SassString extends SassLiteral {
63
  * @param sassNumber the number of times to repeat this
64
  * @return sassString the string result
65
  */
66
- public function op_times($other) {
 
67
  if (!($other instanceof SassNumber) || !$other->isUnitless()) {
68
  throw new SassStringException('Value must be a unitless number', SassScriptParser::$context->node);
69
  }
70
  $this->value = str_repeat($this->value, $other->value);
 
71
  return $this;
72
  }
73
 
74
  /**
75
  * Equals - works better
76
  */
77
- public function op_eq($other) {
 
78
  return new SassBoolean($this->value == $other->value || $this->toString() == $other->toString());
79
  }
80
 
81
  /**
82
  * Evaluates the value as a boolean.
83
  */
84
- public function toBoolean() {
 
85
  $value = strtolower(trim($this->value, ' "\''));
86
  if (!$value || in_array($value, array('false', 'null', '0'))) {
87
  return FALSE;
88
  }
 
89
  return TRUE;
90
  }
91
 
@@ -93,7 +101,8 @@ class SassString extends SassLiteral {
93
  * Returns the value of this string.
94
  * @return string the string
95
  */
96
- public function getValue() {
 
97
  return $this->value;
98
  }
99
 
@@ -101,24 +110,28 @@ class SassString extends SassLiteral {
101
  * Returns a string representation of the value.
102
  * @return string string representation of the value.
103
  */
104
- public function toString() {
 
105
  if ($this->quote) {
106
  $value = $this->quote . $this->value . $this->quote;
107
- }
108
- else {
109
  $value = strlen(trim($this->value)) ? trim($this->value) : $this->value;
110
  }
 
111
  return $value;
112
  }
113
 
114
- public function toVar() {
 
115
  return SassScriptParser::$context->getVariable($this->value);
116
  }
117
 
118
- public function getTypeOf() {
 
119
  if (SassList::isa($this->toString())) {
120
  return 'list';
121
  }
 
122
  return 'string';
123
  }
124
 
@@ -128,7 +141,8 @@ class SassString extends SassLiteral {
128
  * @param string the subject string
129
  * @return mixed match at the start of the string or false if no match
130
  */
131
- public static function isa($subject) {
 
132
  return (preg_match(self::MATCH, $subject, $matches) ? $matches[0] : false);
133
  }
134
  }
9
  * @subpackage Sass.script.literals
10
  */
11
 
12
+ require_once 'SassLiteral.php';
13
 
14
  /**
15
  * SassString class.
17
  * @package PHamlP
18
  * @subpackage Sass.script.literals
19
  */
20
+ class SassString extends SassLiteral
21
+ {
22
  const MATCH = '/^(((["\'])(.*?)(\3))|(-[a-zA-Z-]+[^\s]*?))/i';
23
  const _MATCH = '/^(["\'])(.*?)(\1)?$/'; // Used to match strings such as "Times New Roman",serif
24
  const VALUE = 2;
34
  * @param string string
35
  * @return SassString
36
  */
37
+ public function __construct($value)
38
+ {
39
  preg_match(self::_MATCH, $value, $matches);
40
  if ((isset($matches[self::QUOTE]))) {
41
  $this->quote = $matches[self::QUOTE];
42
  $this->value = $matches[self::VALUE];
43
+ } else {
 
44
  $this->quote = '';
45
  $this->value = $value;
46
  }
53
  * @param sassString string to add to this
54
  * @return sassString the string result
55
  */
56
+ public function op_plus($other)
57
+ {
58
  $this->value .= $other->value;
59
+
60
  return $this;
61
  }
62
 
66
  * @param sassNumber the number of times to repeat this
67
  * @return sassString the string result
68
  */
69
+ public function op_times($other)
70
+ {
71
  if (!($other instanceof SassNumber) || !$other->isUnitless()) {
72
  throw new SassStringException('Value must be a unitless number', SassScriptParser::$context->node);
73
  }
74
  $this->value = str_repeat($this->value, $other->value);
75
+
76
  return $this;
77
  }
78
 
79
  /**
80
  * Equals - works better
81
  */
82
+ public function op_eq($other)
83
+ {
84
  return new SassBoolean($this->value == $other->value || $this->toString() == $other->toString());
85
  }
86
 
87
  /**
88
  * Evaluates the value as a boolean.
89
  */
90
+ public function toBoolean()
91
+ {
92
  $value = strtolower(trim($this->value, ' "\''));
93
  if (!$value || in_array($value, array('false', 'null', '0'))) {
94
  return FALSE;
95
  }
96
+
97
  return TRUE;
98
  }
99
 
101
  * Returns the value of this string.
102
  * @return string the string
103
  */
104
+ public function getValue()
105
+ {
106
  return $this->value;
107
  }
108
 
110
  * Returns a string representation of the value.
111
  * @return string string representation of the value.
112
  */
113
+ public function toString()
114
+ {
115
  if ($this->quote) {
116
  $value = $this->quote . $this->value . $this->quote;
117
+ } else {
 
118
  $value = strlen(trim($this->value)) ? trim($this->value) : $this->value;
119
  }
120
+
121
  return $value;
122
  }
123
 
124
+ public function toVar()
125
+ {
126
  return SassScriptParser::$context->getVariable($this->value);
127
  }
128
 
129
+ public function getTypeOf()
130
+ {
131
  if (SassList::isa($this->toString())) {
132
  return 'list';
133
  }
134
+
135
  return 'string';
136
  }
137
 
141
  * @param string the subject string
142
  * @return mixed match at the start of the string or false if no match
143
  */
144
+ public static function isa($subject)
145
+ {
146
  return (preg_match(self::MATCH, $subject, $matches) ? $matches[0] : false);
147
  }
148
  }
lib/phpsass/tests/alt.css CHANGED
@@ -1,15 +1,16 @@
1
  h1 {
2
- float: left;
3
- width: 274px;
4
- height: 75px;
5
- margin: 0;
6
- background-repeat: no-repeat;
7
- background-image: none; }
8
- h1 a:hover, h1 a:visited {
9
- color: green; }
10
- h1 b:hover {
11
- color: red;
12
- background-color: green; }
13
- h1 const {
14
- nosp: 6/2;
15
- sp: 3; }
 
1
  h1 {
2
+ float: left;
3
+ width: 274px;
4
+ height: 75px;
5
+ margin: 0;
6
+ background-repeat: no-repeat;
7
+ background-image: none; }
8
+ h1 a:hover,
9
+ h1 a:visited {
10
+ color: green; }
11
+ h1 b:hover {
12
+ color: red;
13
+ background-color: green; }
14
+ h1 const {
15
+ nosp: 3;
16
+ sp: 3; }
lib/phpsass/tests/extend_included.css DELETED
@@ -1,3 +0,0 @@
1
- .error {
2
- border: 1px #f00;
3
- background-color: #fdd; }
 
 
 
lib/phpsass/tests/functions.css CHANGED
@@ -1,69 +1,9 @@
1
- /*
2
- Syntax error: Positional arguments must come before keyword arguments.
3
- on line 14 of functions.scss
4
-
5
- 9: #{test()} {
6
- 10: content: x() if(x() == 'one two', true, false);
7
- 11: content: x('foo', 'bar') if(x('foo', 'bar') == 'foo bar', true, false);
8
- 12: content: x('foo') if(x('foo') == 'foo two', true, false);
9
- 13: content: x($two: 'foo') if(x($two: 'foo') == 'one foo', true, false);
10
- 14: content: x($two: 'foo', bar) if(x($two: 'foo', bar) == bar foo, true, false);
11
- 15: adjust-color: adjust-color(#00F, $blue: -15);
12
- 16: }
13
-
14
- Backtrace:
15
- functions.scss:14
16
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:395:in `arglist'
17
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:370:in `fn_arglist'
18
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:332:in `funcall'
19
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:320:in `ident'
20
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:228:in `unary_not'
21
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:228:in `unary_div'
22
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:228:in `unary_minus'
23
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:228:in `unary_plus'
24
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:209:in `times_div_or_mod'
25
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:209:in `plus_or_minus'
26
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:209:in `relational'
27
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:209:in `eq_or_neq'
28
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:209:in `and_expr'
29
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:209:in `or_expr'
30
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:299:in `space'
31
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:284:in `interpolation'
32
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:247:in `expr'
33
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:470:in `assert_expr'
34
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/script/parser.rb:49:in `parse'
35
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:1008:in `sass_script'
36
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:868:in `value!'
37
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:845:in `declaration'
38
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:568:in `block in declaration_or_ruleset'
39
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:1108:in `call'
40
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:1108:in `rethrow'
41
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:578:in `declaration_or_ruleset'
42
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:540:in `block_child'
43
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:532:in `block_contents'
44
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:521:in `block'
45
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:515:in `ruleset'
46
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:539:in `block_child'
47
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:532:in `block_contents'
48
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:70:in `stylesheet'
49
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/scss/parser.rb:27:in `parse'
50
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/engine.rb:342:in `_to_tree'
51
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/engine.rb:315:in `_render'
52
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/engine.rb:262:in `render'
53
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/plugin/compiler.rb:341:in `update_stylesheet'
54
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/plugin/compiler.rb:203:in `block in update_stylesheets'
55
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/plugin/compiler.rb:201:in `each'
56
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/plugin/compiler.rb:201:in `update_stylesheets'
57
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/plugin.rb:81:in `update_stylesheets'
58
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/exec.rb:424:in `watch_or_update'
59
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/exec.rb:307:in `process_result'
60
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/exec.rb:41:in `parse'
61
- /var/lib/gems/1.9.1/gems/sass-3.2.3/lib/sass/exec.rb:21:in `parse!'
62
- /var/lib/gems/1.9.1/gems/sass-3.2.3/bin/scss:8:in `<top (required)>'
63
- /usr/local/bin/scss:23:in `load'
64
- /usr/local/bin/scss:23:in `<main>'
65
- */
66
- body:before {
67
- white-space: pre;
68
- font-family: monospace;
69
- content: "Syntax error: Positional arguments must come before keyword arguments.\A on line 14 of functions.scss\A \A 9: #{test()} {\A 10: content: x() if(x() == 'one two', true, false);\A 11: content: x('foo', 'bar') if(x('foo', 'bar') == 'foo bar', true, false);\A 12: content: x('foo') if(x('foo') == 'foo two', true, false);\A 13: content: x($two: 'foo') if(x($two: 'foo') == 'one foo', true, false);\A 14: content: x($two: 'foo', bar) if(x($two: 'foo', bar) == bar foo, true, false);\A 15: adjust-color: adjust-color(#00F, $blue: -15);\A 16: }"; }
1
+ foo,
2
+ bar,
3
+ foo + bar {
4
+ content: 'one two' true;
5
+ content: 'foo bar' true;
6
+ content: 'foo two' true;
7
+ content: 'one foo' true;
8
+ content: bar foo true;
9
+ adjust-color: #0000f0; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/phpSassTest.php CHANGED
@@ -4,19 +4,20 @@
4
  * PHP Sass tests.
5
  * @group sass
6
  */
7
- class PHPSass_TestCase extends PHPUnit_Framework_TestCase {
8
-
9
  /**
10
  * This is the path to a directory of SASS, SCSS and CSS files used in tests.
11
  */
12
- var $css_tests_path;
13
 
14
  /**
15
  * This is the location of the PHPSass library being used.
16
  */
17
- var $phpsass_library_path;
18
 
19
- protected function setUp() {
 
20
  parent::setUp();
21
 
22
  $this->requirePHPSassLibrary();
@@ -30,8 +31,8 @@ class PHPSass_TestCase extends PHPUnit_Framework_TestCase {
30
  * few known locations, and then failing all of that we fall back to
31
  * downloading it from the web.
32
  */
33
- protected function requirePHPSassLibrary() {
34
-
35
  // Allow people to specify the library before we are called.
36
  if (isset($this->phpsass_library_path)) {
37
 
@@ -43,13 +44,13 @@ class PHPSass_TestCase extends PHPUnit_Framework_TestCase {
43
 
44
  if (isset($this->phpsass_library_path)) {
45
  require_once($this->phpsass_library_path . '/SassParser.php');
46
- }
47
- else {
48
  throw new Exception('Could not find PHPSass compiler.');
49
  }
50
  }
51
 
52
- protected function runSassTest($input, $output = FALSE, $settings = array()) {
 
53
  $name = $input;
54
 
55
  $path = $this->css_tests_path;
@@ -93,256 +94,316 @@ class PHPSass_TestCase extends PHPUnit_Framework_TestCase {
93
  /**
94
  * Logging callback for PHPSass debug messages.
95
  */
96
- public function sassParserDebug($message, $context) {
97
-
98
  }
99
 
100
  /**
101
  * Logging callback for PHPSass warning messages.
102
  */
103
- public function sassParserWarning($message, $context) {
104
-
105
  }
106
 
107
- protected function trimResult(&$input) {
 
108
  $trim = preg_replace('/[\s;]+/', '', $input);
109
  $trim = preg_replace('/\/\*.+?\*\//m', '', $trim);
 
110
  return $trim;
111
  }
112
 
113
- public function testAlt() {
 
114
  $this->runSassTest('alt.sass');
115
  $this->runSassTest('alt.scss');
116
  }
117
 
118
- public function testBasic() {
 
119
  $this->runSassTest('basic.sass');
120
  }
121
 
122
 
123
- public function testComments() {
 
124
  $this->runSassTest('comments.sass');
125
  }
126
 
127
- public function testCompact() {
 
128
  $this->runSassTest('compact.sass');
129
  }
130
 
131
- public function testComplex() {
 
132
  $this->runSassTest('complex.sass');
133
  }
134
 
135
- public function testCompressed() {
 
136
  $this->runSassTest('compressed.sass');
137
  }
138
 
139
- public function testContent() {
 
140
  $this->runSassTest('content.scss');
141
  }
142
 
143
- public function testCss3() {
 
144
  $this->runSassTest('css3.scss');
145
  }
146
 
147
- public function testDefault() {
 
148
  $this->runSassTest('default.sass');
149
  }
150
 
151
- public function testEach() {
 
152
  $this->runSassTest('each.scss');
153
  }
154
 
155
- public function testExpanded() {
 
156
  $this->runSassTest('expanded.sass');
157
  }
158
 
159
- public function testExtend() {
 
160
  $this->runSassTest('extend.sass');
161
  }
162
 
163
- public function testExtendPlaceholders() {
 
164
  $this->runSassTest('extend_placeholders.scss');
165
  }
166
 
167
- public function testFilters() {
 
168
  $this->runSassTest('filters.scss');
169
  }
170
 
171
- public function testFunctions() {
 
172
  $this->runSassTest('functions.scss');
173
  }
174
 
175
- public function testHolmes() {
 
176
  $this->runSassTest('holmes.sass');
177
  }
178
 
179
- public function testHSLFunction() {
 
180
  $this->runSassTest('hsl-functions.scss');
181
  }
182
 
183
- public function testIf() {
 
184
  $this->runSassTest('if.sass');
185
  }
186
 
187
- public function testImportedContent() {
 
188
  $this->runSassTest('import_content.sass');
189
  }
190
 
191
- public function testInterpolation() {
 
192
  $this->runSassTest('interpolation.scss');
193
  }
194
 
195
- public function testIntrospection() {
 
196
  $this->runSassTest('introspection.scss');
197
  }
198
 
199
- public function testImport() {
 
200
  $this->runSassTest('import.sass');
201
  }
202
 
203
- public function testLineNumbers() {
 
204
  $this->runSassTest('line_numbers.sass');
205
  }
206
 
207
- public function testList() {
 
208
  $this->runSassTest('list.scss');
209
  }
210
 
211
- public function testMedia() {
 
212
  $this->runSassTest('media.scss');
213
  }
214
 
215
- public function testMiscFunctions() {
 
216
  $this->runSassTest('misc-functions.scss');
217
  }
218
 
219
- public function testMisc() {
 
220
  $this->runSassTest('misc.scss');
221
  }
222
 
223
- public function testMixinContent() {
 
224
  $this->runSassTest('mixin-content.sass');
225
  $this->runSassTest('mixin-content.scss');
226
  }
227
 
228
- public function testMixinJa1() {
 
229
  $this->runSassTest('mixin-ja1.sass');
230
  }
231
 
232
- public function testMixinParams() {
 
233
  $this->runSassTest('mixin-params.scss');
234
  }
235
 
236
- public function testMixins() {
 
237
  $this->runSassTest('mixins.sass');
238
  }
239
 
240
- public function testMixinInMixin() {
 
241
  $this->runSassTest('mixin_in_mixin.scss');
242
  }
243
 
244
- public function testMultiline() {
 
245
  $this->runSassTest('multiline.sass');
246
  }
247
 
248
- public function testNestedImport() {
 
249
  $this->runSassTest('nested_import.sass');
250
  }
251
 
252
- public function testNested() {
 
253
  $this->runSassTest('nested.sass');
254
  }
255
 
256
- public function testNestedMedia() {
 
257
  $this->runSassTest('nested_media.scss');
258
  }
259
 
260
- public function testNestedPseudo() {
 
261
  $this->runSassTest('nested_pseudo.scss');
262
  }
263
 
264
- public function testNumber() {
 
265
  $this->runSassTest('number.scss');
266
  }
267
 
268
- public function testOpacity() {
 
269
  $this->runSassTest('opacity.scss');
270
  }
271
 
272
- public function testOtherColor() {
 
273
  $this->runSassTest('other-color.scss');
274
  }
275
 
276
- public function testParentRef() {
 
277
  $this->runSassTest('parent_ref.sass');
278
  }
279
 
280
- public function testProprietarySelector() {
 
281
  $this->runSassTest('proprietary-selector.scss');
282
  }
283
 
284
- public function testRGBFunctions() {
 
285
  $this->runSassTest('rgb-functions.scss');
286
  }
287
 
288
- public function testScssImportee() {
 
289
  $this->runSassTest('scss_importee.scss');
290
  }
291
 
292
- public function testScssImport() {
 
293
  $this->runSassTest('scss_import.scss');
294
  }
295
 
296
- public function testSplats() {
 
297
  $this->runSassTest('splats.scss');
298
  }
299
 
300
- public function testString() {
 
301
  $this->runSassTest('string.scss');
302
  }
303
 
304
- public function testUnits() {
 
305
  $this->runSassTest('units.sass');
306
  }
307
 
308
- public function testListVariable() {
 
309
  $this->runSassTest('list_variable.scss');
310
  }
311
 
312
- public function testMediaInFor() {
 
313
  $this->runSassTest('media_in_for.scss');
314
  }
315
 
316
- public function testMediaInMixin() {
 
317
  $this->runSassTest('media_in_mixin.scss');
318
  }
319
 
320
- public function testMediaInTwoMixins() {
 
321
  $this->runSassTest('media_in_mixin_in_mixin.scss');
322
  }
323
 
324
- public function testIfParentheses() {
 
325
  $this->runSassTest('if_parentheses.scss');
326
  }
327
 
328
- public function testListEmpty() {
 
329
  $this->runSassTest('list_empty.scss');
330
  }
331
 
332
- public function testWarnImported() {
 
333
  $this->markTestIncomplete('This test has not been implemented yet.');
334
  //$this->runSassTest('warn_imported.sass');
335
  }
336
 
337
- public function testWarn() {
 
338
  $this->runSassTest('warn.sass');
339
  }
340
 
341
- public function testColour() {
 
342
  $this->runSassTest('colour-nth.scss');
343
  }
344
 
345
- public function testMixinSetvar() {
 
346
  $this->runSassTest('mixin_setvar.scss');
347
  }
348
  }
4
  * PHP Sass tests.
5
  * @group sass
6
  */
7
+ class PHPSass_TestCase extends PHPUnit_Framework_TestCase
8
+ {
9
  /**
10
  * This is the path to a directory of SASS, SCSS and CSS files used in tests.
11
  */
12
+ public $css_tests_path;
13
 
14
  /**
15
  * This is the location of the PHPSass library being used.
16
  */
17
+ public $phpsass_library_path;
18
 
19
+ protected function setUp()
20
+ {
21
  parent::setUp();
22
 
23
  $this->requirePHPSassLibrary();
31
  * few known locations, and then failing all of that we fall back to
32
  * downloading it from the web.
33
  */
34
+ protected function requirePHPSassLibrary()
35
+ {
36
  // Allow people to specify the library before we are called.
37
  if (isset($this->phpsass_library_path)) {
38
 
44
 
45
  if (isset($this->phpsass_library_path)) {
46
  require_once($this->phpsass_library_path . '/SassParser.php');
47
+ } else {
 
48
  throw new Exception('Could not find PHPSass compiler.');
49
  }
50
  }
51
 
52
+ protected function runSassTest($input, $output = FALSE, $settings = array())
53
+ {
54
  $name = $input;
55
 
56
  $path = $this->css_tests_path;
94
  /**
95
  * Logging callback for PHPSass debug messages.
96
  */
97
+ public function sassParserDebug($message, $context)
98
+ {
99
  }
100
 
101
  /**
102
  * Logging callback for PHPSass warning messages.
103
  */
104
+ public function sassParserWarning($message, $context)
105
+ {
106
  }
107
 
108
+ protected function trimResult(&$input)
109
+ {
110
  $trim = preg_replace('/[\s;]+/', '', $input);
111
  $trim = preg_replace('/\/\*.+?\*\//m', '', $trim);
112
+
113
  return $trim;
114
  }
115
 
116
+ public function testAlt()
117
+ {
118
  $this->runSassTest('alt.sass');
119
  $this->runSassTest('alt.scss');
120
  }
121
 
122
+ public function testBasic()
123
+ {
124
  $this->runSassTest('basic.sass');
125
  }
126
 
127
 
128
+ public function testComments()
129
+ {
130
  $this->runSassTest('comments.sass');
131
  }
132
 
133
+ public function testCompact()
134
+ {
135
  $this->runSassTest('compact.sass');
136
  }
137
 
138
+ public function testComplex()
139
+ {
140
  $this->runSassTest('complex.sass');
141
  }
142
 
143
+ public function testCompressed()
144
+ {
145
  $this->runSassTest('compressed.sass');
146
  }
147
 
148
+ public function testContent()
149
+ {
150
  $this->runSassTest('content.scss');
151
  }
152
 
153
+ public function testCss3()
154
+ {
155
  $this->runSassTest('css3.scss');
156
  }
157
 
158
+ public function testDefault()
159
+ {
160
  $this->runSassTest('default.sass');
161
  }
162
 
163
+ public function testEach()
164
+ {
165
  $this->runSassTest('each.scss');
166
  }
167
 
168
+ public function testExpanded()
169
+ {
170
  $this->runSassTest('expanded.sass');
171
  }
172
 
173
+ public function testExtend()
174
+ {
175
  $this->runSassTest('extend.sass');
176
  }
177
 
178
+ public function testExtendPlaceholders()
179
+ {
180
  $this->runSassTest('extend_placeholders.scss');
181
  }
182
 
183
+ public function testFilters()
184
+ {
185
  $this->runSassTest('filters.scss');
186
  }
187
 
188
+ public function testFunctions()
189
+ {
190
  $this->runSassTest('functions.scss');
191
  }
192
 
193
+ public function testHolmes()
194
+ {
195
  $this->runSassTest('holmes.sass');
196
  }
197
 
198
+ public function testHSLFunction()
199
+ {
200
  $this->runSassTest('hsl-functions.scss');
201
  }
202
 
203
+ public function testIf()
204
+ {
205
  $this->runSassTest('if.sass');
206
  }
207
 
208
+ public function testImportedContent()
209
+ {
210
  $this->runSassTest('import_content.sass');
211
  }
212
 
213
+ public function testInterpolation()
214
+ {
215
  $this->runSassTest('interpolation.scss');
216
  }
217
 
218
+ public function testIntrospection()
219
+ {
220
  $this->runSassTest('introspection.scss');
221
  }
222
 
223
+ public function testImport()
224
+ {
225
  $this->runSassTest('import.sass');
226
  }
227
 
228
+ public function testLineNumbers()
229
+ {
230
  $this->runSassTest('line_numbers.sass');
231
  }
232
 
233
+ public function testList()
234
+ {
235
  $this->runSassTest('list.scss');
236
  }
237
 
238
+ public function testMedia()
239
+ {
240
  $this->runSassTest('media.scss');
241
  }
242
 
243
+ public function testMiscFunctions()
244
+ {
245
  $this->runSassTest('misc-functions.scss');
246
  }
247
 
248
+ public function testMisc()
249
+ {
250
  $this->runSassTest('misc.scss');
251
  }
252
 
253
+ public function testMixinContent()
254
+ {
255
  $this->runSassTest('mixin-content.sass');
256
  $this->runSassTest('mixin-content.scss');
257
  }
258
 
259
+ public function testMixinJa1()
260
+ {
261
  $this->runSassTest('mixin-ja1.sass');
262
  }
263
 
264
+ public function testMixinParams()
265
+ {
266
  $this->runSassTest('mixin-params.scss');
267
  }
268
 
269
+ public function testMixins()
270
+ {
271
  $this->runSassTest('mixins.sass');
272
  }
273
 
274
+ public function testMixinInMixin()
275
+ {
276
  $this->runSassTest('mixin_in_mixin.scss');
277
  }
278
 
279
+ public function testMultiline()
280
+ {
281
  $this->runSassTest('multiline.sass');
282
  }
283
 
284
+ public function testNestedImport()
285
+ {
286
  $this->runSassTest('nested_import.sass');
287
  }
288
 
289
+ public function testNested()
290
+ {
291
  $this->runSassTest('nested.sass');
292
  }
293
 
294
+ public function testNestedMedia()
295
+ {
296
  $this->runSassTest('nested_media.scss');
297
  }
298
 
299
+ public function testNestedPseudo()
300
+ {
301
  $this->runSassTest('nested_pseudo.scss');
302
  }
303
 
304
+ public function testNumber()
305
+ {
306
  $this->runSassTest('number.scss');
307
  }
308
 
309
+ public function testOpacity()
310
+ {
311
  $this->runSassTest('opacity.scss');
312
  }
313
 
314
+ public function testOtherColor()
315
+ {
316
  $this->runSassTest('other-color.scss');
317
  }
318
 
319
+ public function testParentRef()
320
+ {
321
  $this->runSassTest('parent_ref.sass');
322
  }
323
 
324
+ public function testProprietarySelector()
325
+ {
326
  $this->runSassTest('proprietary-selector.scss');
327
  }
328
 
329
+ public function testRGBFunctions()
330
+ {
331
  $this->runSassTest('rgb-functions.scss');
332
  }
333
 
334
+ public function testScssImportee()
335
+ {
336
  $this->runSassTest('scss_importee.scss');
337
  }
338
 
339
+ public function testScssImport()
340
+ {
341
  $this->runSassTest('scss_import.scss');
342
  }
343
 
344
+ public function testSplats()
345
+ {
346
  $this->runSassTest('splats.scss');
347
  }
348
 
349
+ public function testString()
350
+ {
351
  $this->runSassTest('string.scss');
352
  }
353
 
354
+ public function testUnits()
355
+ {
356
  $this->runSassTest('units.sass');
357
  }
358
 
359
+ public function testListVariable()
360
+ {
361
  $this->runSassTest('list_variable.scss');
362
  }
363
 
364
+ public function testMediaInFor()
365
+ {
366
  $this->runSassTest('media_in_for.scss');
367
  }
368
 
369
+ public function testMediaInMixin()
370
+ {
371
  $this->runSassTest('media_in_mixin.scss');
372
  }
373
 
374
+ public function testMediaInTwoMixins()
375
+ {
376
  $this->runSassTest('media_in_mixin_in_mixin.scss');
377
  }
378
 
379
+ public function testIfParentheses()
380
+ {
381
  $this->runSassTest('if_parentheses.scss');
382
  }
383
 
384
+ public function testListEmpty()
385
+ {
386
  $this->runSassTest('list_empty.scss');
387
  }
388
 
389
+ public function testWarnImported()
390
+ {
391
  $this->markTestIncomplete('This test has not been implemented yet.');
392
  //$this->runSassTest('warn_imported.sass');
393
  }
394
 
395
+ public function testWarn()
396
+ {
397
  $this->runSassTest('warn.sass');
398
  }
399
 
400
+ public function testColour()
401
+ {
402
  $this->runSassTest('colour-nth.scss');
403
  }
404
 
405
+ public function testMixinSetvar()
406
+ {
407
  $this->runSassTest('mixin_setvar.scss');
408
  }
409
  }
lib/phpsass/tree/SassCommentNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassCommentNode extends SassNode {
 
19
  const NODE_IDENTIFIER = '/';
20
  const MATCH = '%^/\*\s*?(.*?)\s*?(\*/)?$%s';
21
  const COMMENT = 1;
@@ -27,13 +28,15 @@ class SassCommentNode extends SassNode {
27
  * @param object source token
28
  * @return CommentNode
29
  */
30
- public function __construct($token) {
 
31
  parent::__construct($token);
32
  preg_match(self::MATCH, $token->source, $matches);
33
  $this->value = $matches[self::COMMENT];
34
  }
35
 
36
- protected function getValue() {
 
37
  return $this->value;
38
  }
39
 
@@ -41,7 +44,8 @@ class SassCommentNode extends SassNode {
41
  * Parse this node.
42
  * @return array the parsed node - an empty array
43
  */
44
- public function parse($context) {
 
45
  return array($this);
46
  }
47
 
@@ -49,7 +53,8 @@ class SassCommentNode extends SassNode {
49
  * Render this node.
50
  * @return string the rendered node
51
  */
52
- public function render() {
 
53
  return $this->renderer->renderComment($this);
54
  }
55
 
@@ -58,7 +63,8 @@ class SassCommentNode extends SassNode {
58
  * @param object token
59
  * @return boolean true if the token represents this type of node, false if not
60
  */
61
- public static function isa($token) {
 
62
  return $token->source[0] === self::NODE_IDENTIFIER;
63
  }
64
  }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassCommentNode extends SassNode
19
+ {
20
  const NODE_IDENTIFIER = '/';
21
  const MATCH = '%^/\*\s*?(.*?)\s*?(\*/)?$%s';
22
  const COMMENT = 1;
28
  * @param object source token
29
  * @return CommentNode
30
  */
31
+ public function __construct($token)
32
+ {
33
  parent::__construct($token);
34
  preg_match(self::MATCH, $token->source, $matches);
35
  $this->value = $matches[self::COMMENT];
36
  }
37
 
38
+ protected function getValue()
39
+ {
40
  return $this->value;
41
  }
42
 
44
  * Parse this node.
45
  * @return array the parsed node - an empty array
46
  */
47
+ public function parse($context)
48
+ {
49
  return array($this);
50
  }
51
 
53
  * Render this node.
54
  * @return string the rendered node
55
  */
56
+ public function render()
57
+ {
58
  return $this->renderer->renderComment($this);
59
  }
60
 
63
  * @param object token
64
  * @return boolean true if the token represents this type of node, false if not
65
  */
66
+ public static function isa($token)
67
+ {
68
  return $token->source[0] === self::NODE_IDENTIFIER;
69
  }
70
  }
lib/phpsass/tree/SassContentNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassContentNode extends SassNode {
 
19
  const MATCH = '/^(@content)(.*)$/i';
20
  const IDENTIFIER = 1;
21
 
@@ -29,7 +30,8 @@ class SassContentNode extends SassNode {
29
  * @param object source token
30
  * @return SassContentNode
31
  */
32
- public function __construct($token) {
 
33
  parent::__construct($token);
34
  preg_match(self::MATCH, $token->source, $matches);
35
 
@@ -45,7 +47,8 @@ class SassContentNode extends SassNode {
45
  * @param SassContext the context in which this node is parsed
46
  * @return array the parsed node
47
  */
48
- public function parse($pcontext) {
 
49
  $return = $this;
50
  $context = new SassContext($pcontext);
51
 
@@ -56,6 +59,7 @@ class SassContentNode extends SassNode {
56
  $ctx->variables = $pcontext->variables;
57
  $children = array_merge($children, $child->parse($ctx));
58
  }
 
59
  return $children;
60
  }
61
 
@@ -64,7 +68,8 @@ class SassContentNode extends SassNode {
64
  * @param object token
65
  * @return boolean true if the token represents this type of node, false if not
66
  */
67
- public static function isa($token) {
 
68
  return $token->source[0] === self::NODE_IDENTIFIER;
69
  }
70
  }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassContentNode extends SassNode
19
+ {
20
  const MATCH = '/^(@content)(.*)$/i';
21
  const IDENTIFIER = 1;
22
 
30
  * @param object source token
31
  * @return SassContentNode
32
  */
33
+ public function __construct($token)
34
+ {
35
  parent::__construct($token);
36
  preg_match(self::MATCH, $token->source, $matches);
37
 
47
  * @param SassContext the context in which this node is parsed
48
  * @return array the parsed node
49
  */
50
+ public function parse($pcontext)
51
+ {
52
  $return = $this;
53
  $context = new SassContext($pcontext);
54
 
59
  $ctx->variables = $pcontext->variables;
60
  $children = array_merge($children, $child->parse($ctx));
61
  }
62
+
63
  return $children;
64
  }
65
 
68
  * @param object token
69
  * @return boolean true if the token represents this type of node, false if not
70
  */
71
+ public static function isa($token)
72
+ {
73
  return $token->source[0] === self::NODE_IDENTIFIER;
74
  }
75
  }
lib/phpsass/tree/SassContext.php CHANGED
@@ -17,7 +17,8 @@
17
  * @package PHamlP
18
  * @subpackage Sass.tree
19
  */
20
- class SassContext {
 
21
  /**
22
  * @var SassContext enclosing context
23
  */
@@ -53,14 +54,16 @@ class SassContext {
53
  * @param SassContext - the enclosing context
54
  * @return SassContext
55
  */
56
- public function __construct($parent = null) {
 
57
  $this->parent = $parent;
58
  }
59
 
60
  /**
61
  *
62
  */
63
- public function getContent() {
 
64
  if ($this->content) {
65
  return $this->content;
66
  }
@@ -75,8 +78,10 @@ class SassContext {
75
  * @param string name of mixin
76
  * @return SassMixinDefinitionNode the mixin
77
  */
78
- public function addMixin($name, $mixin) {
 
79
  $this->mixins[$name] = $mixin;
 
80
  return $this;
81
  }
82
 
@@ -86,11 +91,11 @@ class SassContext {
86
  * @return SassMixinDefinitionNode the mixin
87
  * @throws SassContextException if mixin not defined in this context
88
  */
89
- public function getMixin($name) {
 
90
  if (isset($this->mixins[$name])) {
91
  return $this->mixins[$name];
92
- }
93
- elseif (!empty($this->parent)) {
94
  return $this->parent->getMixin($name);
95
  }
96
  throw new SassContextException('Undefined Mixin: ' . $name, $this->node);
@@ -101,11 +106,13 @@ class SassContext {
101
  * @param string name of function
102
  * @return SassFunctionDefinitionNode the function
103
  */
104
- public function addFunction($name, $function) {
 
105
  $this->functions[$name] = $function;
106
  if (!empty($this->parent)) {
107
  $this->parent->addFunction($name);
108
  }
 
109
  return $this;
110
  }
111
 
@@ -115,7 +122,8 @@ class SassContext {
115
  * @return SassFunctionDefinitionNode the mixin
116
  * @throws SassContextException if function not defined in this context
117
  */
118
- public function getFunction($name) {
 
119
  if ($fn = $this->hasFunction($name)) {
120
  return $fn;
121
  }
@@ -127,12 +135,14 @@ class SassContext {
127
  * @param string name of function to check for
128
  * @return boolean
129
  */
130
- public function hasFunction($name) {
 
131
  if (isset($this->functions[$name])) {
132
  return $this->functions[$name];
133
- } else if (!empty($this->parent)) {
134
  return $this->parent->hasFunction($name);
135
  }
 
136
  return FALSE;
137
  }
138
 
@@ -142,15 +152,14 @@ class SassContext {
142
  * @return string the variable
143
  * @throws SassContextException if variable not defined in this context
144
  */
145
- public function getVariable($name) {
 
146
  $name = str_replace('-', '_', $name);
147
  if ($this->hasVariable($name)) {
148
  return $this->variables[$name];
149
- }
150
- elseif (!empty($this->parent)) {
151
  return $this->parent->getVariable($name);
152
- }
153
- else {
154
  // Return false instead of throwing an exception.
155
  // throw new SassContextException('Undefined Variable: ' . $name, $this->node);
156
  return new SassBoolean('false');
@@ -162,8 +171,10 @@ class SassContext {
162
  * @param string name of variable to test
163
  * @return boolean true if the variable exists in this context, false if not
164
  */
165
- public function hasVariable($name) {
 
166
  $name = str_replace('-', '_', $name);
 
167
  return isset($this->variables[$name]);
168
  }
169
 
@@ -172,13 +183,16 @@ class SassContext {
172
  * @param string name of variable
173
  * @param sassLiteral value of variable
174
  */
175
- public function setVariable($name, $value) {
 
176
  $name = str_replace('-', '_', $name);
177
  $this->variables[$name] = $value;
 
178
  return $this;
179
  }
180
 
181
- public function setVariables($vars) {
 
182
  foreach ($vars as $key => $value) {
183
  if ($value !== NULL) {
184
  $this->setVariable($key, $value);
@@ -191,7 +205,8 @@ class SassContext {
191
  * Note that if there are variables or mixins with the same name in the two
192
  * contexts they will be set to that defined in this context.
193
  */
194
- public function merge() {
 
195
  $this->parent->variables = array_merge($this->parent->variables, $this->variables);
196
  $this->parent->mixins = array_merge($this->parent->mixins, $this->mixins);
197
  }
17
  * @package PHamlP
18
  * @subpackage Sass.tree
19
  */
20
+ class SassContext
21
+ {
22
  /**
23
  * @var SassContext enclosing context
24
  */
54
  * @param SassContext - the enclosing context
55
  * @return SassContext
56
  */
57
+ public function __construct($parent = null)
58
+ {
59
  $this->parent = $parent;
60
  }
61
 
62
  /**
63
  *
64
  */
65
+ public function getContent()
66
+ {
67
  if ($this->content) {
68
  return $this->content;
69
  }
78
  * @param string name of mixin
79
  * @return SassMixinDefinitionNode the mixin
80
  */
81
+ public function addMixin($name, $mixin)
82
+ {
83
  $this->mixins[$name] = $mixin;
84
+
85
  return $this;
86
  }
87
 
91
  * @return SassMixinDefinitionNode the mixin
92
  * @throws SassContextException if mixin not defined in this context
93
  */
94
+ public function getMixin($name)
95
+ {
96
  if (isset($this->mixins[$name])) {
97
  return $this->mixins[$name];
98
+ } elseif (!empty($this->parent)) {
 
99
  return $this->parent->getMixin($name);
100
  }
101
  throw new SassContextException('Undefined Mixin: ' . $name, $this->node);
106
  * @param string name of function
107
  * @return SassFunctionDefinitionNode the function
108
  */
109
+ public function addFunction($name, $function)
110
+ {
111
  $this->functions[$name] = $function;
112
  if (!empty($this->parent)) {
113
  $this->parent->addFunction($name);
114
  }
115
+
116
  return $this;
117
  }
118
 
122
  * @return SassFunctionDefinitionNode the mixin
123
  * @throws SassContextException if function not defined in this context
124
  */
125
+ public function getFunction($name)
126
+ {
127
  if ($fn = $this->hasFunction($name)) {
128
  return $fn;
129
  }
135
  * @param string name of function to check for
136
  * @return boolean
137
  */
138
+ public function hasFunction($name)
139
+ {
140
  if (isset($this->functions[$name])) {
141
  return $this->functions[$name];
142
+ } elseif (!empty($this->parent)) {
143
  return $this->parent->hasFunction($name);
144
  }
145
+
146
  return FALSE;
147
  }
148
 
152
  * @return string the variable
153
  * @throws SassContextException if variable not defined in this context
154
  */
155
+ public function getVariable($name)
156
+ {
157
  $name = str_replace('-', '_', $name);
158
  if ($this->hasVariable($name)) {
159
  return $this->variables[$name];
160
+ } elseif (!empty($this->parent)) {
 
161
  return $this->parent->getVariable($name);
162
+ } else {
 
163
  // Return false instead of throwing an exception.
164
  // throw new SassContextException('Undefined Variable: ' . $name, $this->node);
165
  return new SassBoolean('false');
171
  * @param string name of variable to test
172
  * @return boolean true if the variable exists in this context, false if not
173
  */
174
+ public function hasVariable($name)
175
+ {
176
  $name = str_replace('-', '_', $name);
177
+
178
  return isset($this->variables[$name]);
179
  }
180
 
183
  * @param string name of variable
184
  * @param sassLiteral value of variable
185
  */
186
+ public function setVariable($name, $value)
187
+ {
188
  $name = str_replace('-', '_', $name);
189
  $this->variables[$name] = $value;
190
+
191
  return $this;
192
  }
193
 
194
+ public function setVariables($vars)
195
+ {
196
  foreach ($vars as $key => $value) {
197
  if ($value !== NULL) {
198
  $this->setVariable($key, $value);
205
  * Note that if there are variables or mixins with the same name in the two
206
  * contexts they will be set to that defined in this context.
207
  */
208
+ public function merge()
209
+ {
210
  $this->parent->variables = array_merge($this->parent->variables, $this->variables);
211
  $this->parent->mixins = array_merge($this->parent->mixins, $this->mixins);
212
  }
lib/phpsass/tree/SassDebugNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassDebugNode extends SassNode {
 
19
  const IDENTIFIER = '@';
20
  const MATCH = '/^@(?:debug|warn)\s+(.+?)\s*;?$/';
21
  const MESSAGE = 1;
@@ -44,13 +45,13 @@ class SassDebugNode extends SassNode {
44
  * @param array parameters for the message
45
  * @return SassDebugNode
46
  */
47
- public function __construct($token, $message = false) {
 
48
  parent::__construct($token);
49
  if (is_string($message)) {
50
  $this->message = $message;
51
  $this->warning = true;
52
- }
53
- else {
54
  preg_match(self::MATCH, $token->source, $matches);
55
  $this->message = $matches[self::MESSAGE];
56
  $this->warning = $message;
@@ -62,7 +63,8 @@ class SassDebugNode extends SassNode {
62
  * This raises an error.
63
  * @return array An empty array
64
  */
65
- public function parse($context) {
 
66
  if (!$this->warning) {
67
  $result = $this->evaluate($this->message, $context)->toString();
68
 
@@ -84,7 +86,8 @@ class SassDebugNode extends SassNode {
84
  * @param int Error number
85
  * @param string Message
86
  */
87
- public function errorHandler($errno, $message) {
 
88
  echo '<div style="background-color:#ce4dd6;border-bottom:1px dashed #88338d;color:white;font:10pt verdana;margin:0;padding:0.5em 2%;width:96%;"><p style="height:auto;margin:0.25em 0;padding:0;width:100%;"><span style="font-weight:bold;">SASS '.($this->warning ? 'WARNING' : 'DEBUG').":</span> $message</p><p style=\"margin:0.1em;padding:0;padding-left:0.5em;width:100%;\">{$this->filename}::{$this->line}</p><p style=\"margin:0.1em;padding:0;padding-left:0.5em;width:100%;\">Source: {$this->source}</p></div>";
89
  }
90
  }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassDebugNode extends SassNode
19
+ {
20
  const IDENTIFIER = '@';
21
  const MATCH = '/^@(?:debug|warn)\s+(.+?)\s*;?$/';
22
  const MESSAGE = 1;
45
  * @param array parameters for the message
46
  * @return SassDebugNode
47
  */
48
+ public function __construct($token, $message = false)
49
+ {
50
  parent::__construct($token);
51
  if (is_string($message)) {
52
  $this->message = $message;
53
  $this->warning = true;
54
+ } else {
 
55
  preg_match(self::MATCH, $token->source, $matches);
56
  $this->message = $matches[self::MESSAGE];
57
  $this->warning = $message;
63
  * This raises an error.
64
  * @return array An empty array
65
  */
66
+ public function parse($context)
67
+ {
68
  if (!$this->warning) {
69
  $result = $this->evaluate($this->message, $context)->toString();
70
 
86
  * @param int Error number
87
  * @param string Message
88
  */
89
+ public function errorHandler($errno, $message)
90
+ {
91
  echo '<div style="background-color:#ce4dd6;border-bottom:1px dashed #88338d;color:white;font:10pt verdana;margin:0;padding:0.5em 2%;width:96%;"><p style="height:auto;margin:0.25em 0;padding:0;width:100%;"><span style="font-weight:bold;">SASS '.($this->warning ? 'WARNING' : 'DEBUG').":</span> $message</p><p style=\"margin:0.1em;padding:0;padding-left:0.5em;width:100%;\">{$this->filename}::{$this->line}</p><p style=\"margin:0.1em;padding:0;padding-left:0.5em;width:100%;\">Source: {$this->source}</p></div>";
92
  }
93
  }
lib/phpsass/tree/SassDirectiveNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassDirectiveNode extends SassNode {
 
19
  const NODE_IDENTIFIER = '@';
20
  const MATCH = '/^(@[\w-]+)/';
21
 
@@ -26,15 +27,18 @@ class SassDirectiveNode extends SassNode {
26
  * @param object source token
27
  * @return SassDirectiveNode
28
  */
29
- public function __construct($token) {
 
30
  parent::__construct($token);
31
  }
32
 
33
- protected function getDirective() {
 
34
  return $this->token->source;
35
  preg_match('/^(@[\w-]+)(?:\s*(\w+))*/', $this->token->source, $matches);
36
  array_shift($matches);
37
  $parts = implode(' ', $matches);
 
38
  return strtolower($parts);
39
  }
40
 
@@ -43,10 +47,12 @@ class SassDirectiveNode extends SassNode {
43
  * @param SassContext the context in which this node is parsed
44
  * @return array the parsed node
45
  */
46
- public function parse($context) {
 
47
  $this->token->source = self::interpolate_nonstrict($this->token->source, $context);
48
 
49
  $this->children = $this->parseChildren($context);
 
50
  return array($this);
51
  }
52
 
@@ -54,7 +60,8 @@ class SassDirectiveNode extends SassNode {
54
  * Render this node.
55
  * @return string the rendered node
56
  */
57
- public function render() {
 
58
  $properties = array();
59
  foreach ($this->children as $child) {
60
  $properties[] = $child->render();
@@ -68,7 +75,8 @@ class SassDirectiveNode extends SassNode {
68
  * @param object token
69
  * @return boolean true if the token represents this type of node, false if not
70
  */
71
- public static function isa($token) {
 
72
  return $token->source[0] === self::NODE_IDENTIFIER;
73
  }
74
 
@@ -77,13 +85,15 @@ class SassDirectiveNode extends SassNode {
77
  * @param object token
78
  * @return string the directive
79
  */
80
- public static function extractDirective($token) {
81
-
82
  preg_match(self::MATCH, $token->source, $matches);
 
83
  return strtolower($matches[1]);
84
  }
85
 
86
- public static function interpolate_nonstrict($string, $context) {
 
87
  for ($i = 0, $n = preg_match_all(self::INTERPOLATION_MATCH, $string, $matches); $i < $n; $i++) {
88
  $var = SassScriptParser::$instance->evaluate($matches[0][$i], $context);
89
 
@@ -93,16 +103,13 @@ class SassDirectiveNode extends SassNode {
93
  $var = $var->toString();
94
  }
95
 
96
- if(preg_match('/^unquote\((["\'])(.*)\1\)$/', $var, $match)){
97
  $val = $match[2];
98
- }
99
- else if($var == '""'){
100
  $val = "";
101
- }
102
- else if(preg_match('/^(["\'])(.*)\1$/', $var, $match)){
103
  $val = $match[2];
104
- }
105
- else {
106
  $val = $var;
107
  }
108
  $matches[1][$i] = $val;
@@ -111,6 +118,7 @@ class SassDirectiveNode extends SassNode {
111
  $matches[0][] = '}';
112
  $matches[1][] = '';
113
  $matches[1][] = '';
 
114
  return str_replace($matches[0], $matches[1], $string);
115
  }
116
  }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassDirectiveNode extends SassNode
19
+ {
20
  const NODE_IDENTIFIER = '@';
21
  const MATCH = '/^(@[\w-]+)/';
22
 
27
  * @param object source token
28
  * @return SassDirectiveNode
29
  */
30
+ public function __construct($token)
31
+ {
32
  parent::__construct($token);
33
  }
34
 
35
+ protected function getDirective()
36
+ {
37
  return $this->token->source;
38
  preg_match('/^(@[\w-]+)(?:\s*(\w+))*/', $this->token->source, $matches);
39
  array_shift($matches);
40
  $parts = implode(' ', $matches);
41
+
42
  return strtolower($parts);
43
  }
44
 
47
  * @param SassContext the context in which this node is parsed
48
  * @return array the parsed node
49
  */
50
+ public function parse($context)
51
+ {
52
  $this->token->source = self::interpolate_nonstrict($this->token->source, $context);
53
 
54
  $this->children = $this->parseChildren($context);
55
+
56
  return array($this);
57
  }
58
 
60
  * Render this node.
61
  * @return string the rendered node
62
  */
63
+ public function render()
64
+ {
65
  $properties = array();
66
  foreach ($this->children as $child) {
67
  $properties[] = $child->render();
75
  * @param object token
76
  * @return boolean true if the token represents this type of node, false if not
77
  */
78
+ public static function isa($token)
79
+ {
80
  return $token->source[0] === self::NODE_IDENTIFIER;
81
  }
82
 
85
  * @param object token
86
  * @return string the directive
87
  */
88
+ public static function extractDirective($token)
89
+ {
90
  preg_match(self::MATCH, $token->source, $matches);
91
+
92
  return strtolower($matches[1]);
93
  }
94
 
95
+ public static function interpolate_nonstrict($string, $context)
96
+ {
97
  for ($i = 0, $n = preg_match_all(self::INTERPOLATION_MATCH, $string, $matches); $i < $n; $i++) {
98
  $var = SassScriptParser::$instance->evaluate($matches[0][$i], $context);
99
 
103
  $var = $var->toString();
104
  }
105
 
106
+ if (preg_match('/^unquote\((["\'])(.*)\1\)$/', $var, $match)) {
107
  $val = $match[2];
108
+ } elseif ($var == '""') {
 
109
  $val = "";
110
+ } elseif (preg_match('/^(["\'])(.*)\1$/', $var, $match)) {
 
111
  $val = $match[2];
112
+ } else {
 
113
  $val = $var;
114
  }
115
  $matches[1][$i] = $val;
118
  $matches[0][] = '}';
119
  $matches[1][] = '';
120
  $matches[1][] = '';
121
+
122
  return str_replace($matches[0], $matches[1], $string);
123
  }
124
  }
lib/phpsass/tree/SassEachNode.php CHANGED
@@ -22,7 +22,8 @@
22
  * @package PHamlP
23
  * @subpackage Sass.tree
24
  */
25
- class SassEachNode extends SassNode {
 
26
  const MATCH = '/@each\s+[!\$](.+?)in\s+(.+)$/i';
27
 
28
  const VARIABLE = 1;
@@ -42,12 +43,12 @@ class SassEachNode extends SassNode {
42
  * @param object source token
43
  * @return SassEachNode
44
  */
45
- public function __construct($token) {
 
46
  parent::__construct($token);
47
  if (!preg_match(self::MATCH, $token->source, $matches)) {
48
  throw new SassEachNodeException('Invalid @each directive', $this);
49
- }
50
- else {
51
  $this->variable = trim($matches[self::VARIABLE]);
52
  $this->in = $matches[self::IN];
53
  }
@@ -58,7 +59,8 @@ class SassEachNode extends SassNode {
58
  * @param SassContext the context in which this node is parsed
59
  * @return array parsed child nodes
60
  */
61
- public function parse($context) {
 
62
  $children = array();
63
 
64
  if ($this->variable && $this->in) {
@@ -71,6 +73,7 @@ class SassEachNode extends SassNode {
71
  }
72
  }
73
  $context->merge();
 
74
  return $children;
75
  }
76
  }
22
  * @package PHamlP
23
  * @subpackage Sass.tree
24
  */
25
+ class SassEachNode extends SassNode
26
+ {
27
  const MATCH = '/@each\s+[!\$](.+?)in\s+(.+)$/i';
28
 
29
  const VARIABLE = 1;
43
  * @param object source token
44
  * @return SassEachNode
45
  */
46
+ public function __construct($token)
47
+ {
48
  parent::__construct($token);
49
  if (!preg_match(self::MATCH, $token->source, $matches)) {
50
  throw new SassEachNodeException('Invalid @each directive', $this);
51
+ } else {
 
52
  $this->variable = trim($matches[self::VARIABLE]);
53
  $this->in = $matches[self::IN];
54
  }
59
  * @param SassContext the context in which this node is parsed
60
  * @return array parsed child nodes
61
  */
62
+ public function parse($context)
63
+ {
64
  $children = array();
65
 
66
  if ($this->variable && $this->in) {
73
  }
74
  }
75
  $context->merge();
76
+
77
  return $children;
78
  }
79
  }
lib/phpsass/tree/SassElseNode.php CHANGED
@@ -16,13 +16,15 @@
16
  * @package PHamlP
17
  * @subpackage Sass.tree
18
  */
19
- class SassElseNode extends SassIfNode {
 
20
  /**
21
  * SassElseNode constructor.
22
  * @param object source token
23
  * @return SassElseNode
24
  */
25
- public function __construct($token) {
 
26
  parent::__construct($token, false);
27
  }
28
- }
16
  * @package PHamlP
17
  * @subpackage Sass.tree
18
  */
19
+ class SassElseNode extends SassIfNode
20
+ {
21
  /**
22
  * SassElseNode constructor.
23
  * @param object source token
24
  * @return SassElseNode
25
  */
26
+ public function __construct($token)
27
+ {
28
  parent::__construct($token, false);
29
  }
30
+ }
lib/phpsass/tree/SassExtendNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassExtendNode extends SassNode {
 
19
  const IDENTIFIER = '@';
20
  const MATCH = '/^@extend\s+(.+)/i';
21
  const VALUE = 1;
@@ -30,7 +31,8 @@ class SassExtendNode extends SassNode {
30
  * @param object source token
31
  * @return SassExtendNode
32
  */
33
- public function __construct($token) {
 
34
  parent::__construct($token);
35
  preg_match(self::MATCH, $token->source, $matches);
36
  $this->value = $matches[self::VALUE];
@@ -40,10 +42,12 @@ class SassExtendNode extends SassNode {
40
  * Parse this node.
41
  * @return array An empty array
42
  */
43
- public function parse($context) {
 
44
  # resolve selectors in relation to variables
45
  # allows extend inside nested loops.
46
  $this->root->extend($this->value, $this->parent->resolveSelectors($context));
 
47
  return array();
48
  }
49
- }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassExtendNode extends SassNode
19
+ {
20
  const IDENTIFIER = '@';
21
  const MATCH = '/^@extend\s+(.+)/i';
22
  const VALUE = 1;
31
  * @param object source token
32
  * @return SassExtendNode
33
  */
34
+ public function __construct($token)
35
+ {
36
  parent::__construct($token);
37
  preg_match(self::MATCH, $token->source, $matches);
38
  $this->value = $matches[self::VALUE];
42
  * Parse this node.
43
  * @return array An empty array
44
  */
45
+ public function parse($context)
46
+ {
47
  # resolve selectors in relation to variables
48
  # allows extend inside nested loops.
49
  $this->root->extend($this->value, $this->parent->resolveSelectors($context));
50
+
51
  return array();
52
  }
53
+ }
lib/phpsass/tree/SassForNode.php CHANGED
@@ -25,7 +25,8 @@
25
  * @package PHamlP
26
  * @subpackage Sass.tree
27
  */
28
- class SassForNode extends SassNode {
 
29
  const MATCH = '/@for\s+[!\$](\w+)\s+from\s+(.+?)\s+(through|to)\s+(.+?)(?:\s+step\s+(.+))?$/i';
30
 
31
  const VARIABLE = 1;
@@ -62,7 +63,8 @@ class SassForNode extends SassNode {
62
  * @param object source token
63
  * @return SassForNode
64
  */
65
- public function __construct($token) {
 
66
  parent::__construct($token);
67
  if (!preg_match(self::MATCH, $token->source, $matches)) {
68
  throw new SassForNodeException('Invalid @for directive', $this);
@@ -79,11 +81,12 @@ class SassForNode extends SassNode {
79
  * @param SassContext the context in which this node is parsed
80
  * @return array parsed child nodes
81
  */
82
- public function parse($context) {
 
83
  $children = array();
84
- $from = (float)$this->evaluate($this->from, $context)->value;
85
- $to = (float)$this->evaluate($this->to, $context)->value;
86
- $step = (float)$this->evaluate($this->step, $context)->value * ($to > $from ? 1 : -1);
87
 
88
  if ($this->inclusive) {
89
  $to += ($from < $to ? 1 : -1);
@@ -94,6 +97,7 @@ class SassForNode extends SassNode {
94
  $context->setVariable($this->variable, new SassNumber($i));
95
  $children = array_merge($children, $this->parseChildren($context));
96
  }
 
97
  return $children;
98
  }
99
- }
25
  * @package PHamlP
26
  * @subpackage Sass.tree
27
  */
28
+ class SassForNode extends SassNode
29
+ {
30
  const MATCH = '/@for\s+[!\$](\w+)\s+from\s+(.+?)\s+(through|to)\s+(.+?)(?:\s+step\s+(.+))?$/i';
31
 
32
  const VARIABLE = 1;
63
  * @param object source token
64
  * @return SassForNode
65
  */
66
+ public function __construct($token)
67
+ {
68
  parent::__construct($token);
69
  if (!preg_match(self::MATCH, $token->source, $matches)) {
70
  throw new SassForNodeException('Invalid @for directive', $this);
81
  * @param SassContext the context in which this node is parsed
82
  * @return array parsed child nodes
83
  */
84
+ public function parse($context)
85
+ {
86
  $children = array();
87
+ $from = (float) $this->evaluate($this->from, $context)->value;
88
+ $to = (float) $this->evaluate($this->to, $context)->value;
89
+ $step = (float) $this->evaluate($this->step, $context)->value * ($to > $from ? 1 : -1);
90
 
91
  if ($this->inclusive) {
92
  $to += ($from < $to ? 1 : -1);
97
  $context->setVariable($this->variable, new SassNumber($i));
98
  $children = array_merge($children, $this->parseChildren($context));
99
  }
100
+
101
  return $children;
102
  }
103
+ }
lib/phpsass/tree/SassFunctionDefinitionNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassFunctionDefinitionNode extends SassNode {
 
19
  const NODE_IDENTIFIER = FALSE;
20
  const MATCH = '/^@function\s+([_-\w]+)\s*(?:\((.*?)\))?\s*$/im';
21
  const IDENTIFIER = 1;
@@ -39,7 +40,8 @@ class SassFunctionDefinitionNode extends SassNode {
39
  * @param object source token
40
  * @return SassFunctionDefinitionNode
41
  */
42
- public function __construct($token) {
 
43
  // if ($token->level !== 0) {
44
  // throw new SassFunctionDefinitionNodeException('Functions can only be defined at root level', $token);
45
  // }
@@ -66,8 +68,10 @@ class SassFunctionDefinitionNode extends SassNode {
66
  * @param SassContext the context in which this node is parsed
67
  * @return array the parsed node - an empty array
68
  */
69
- public function parse($context) {
 
70
  $context->addFunction($this->name, $this);
 
71
  return array();
72
  }
73
 
@@ -75,7 +79,8 @@ class SassFunctionDefinitionNode extends SassNode {
75
  * Returns the arguments with default values for this function
76
  * @return array the arguments with default values for this function
77
  */
78
- public function getArgs() {
 
79
  return $this->args;
80
  }
81
 
@@ -84,7 +89,8 @@ class SassFunctionDefinitionNode extends SassNode {
84
  * @param object token
85
  * @return boolean true if the token represents this type of node, false if not
86
  */
87
- public static function isa($token) {
 
88
  return $token->source[0] === self::NODE_IDENTIFIER;
89
  }
90
 
@@ -95,7 +101,8 @@ class SassFunctionDefinitionNode extends SassNode {
95
  * @throws SassReturn - if the @return is fired then this is thrown to break early
96
  * @return SassBoolean(false) - if no @return was fired, return false
97
  */
98
- public function execute($pcontext, $provided) {
 
99
  list($arguments, $context) = SassScriptFunction::fill_parameters($this->args, $provided, $pcontext, $this);
100
  $context->setVariables($arguments);
101
 
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassFunctionDefinitionNode extends SassNode
19
+ {
20
  const NODE_IDENTIFIER = FALSE;
21
  const MATCH = '/^@function\s+([_-\w]+)\s*(?:\((.*?)\))?\s*$/im';
22
  const IDENTIFIER = 1;
40
  * @param object source token
41
  * @return SassFunctionDefinitionNode
42
  */
43
+ public function __construct($token)
44
+ {
45
  // if ($token->level !== 0) {
46
  // throw new SassFunctionDefinitionNodeException('Functions can only be defined at root level', $token);
47
  // }
68
  * @param SassContext the context in which this node is parsed
69
  * @return array the parsed node - an empty array
70
  */
71
+ public function parse($context)
72
+ {
73
  $context->addFunction($this->name, $this);
74
+
75
  return array();
76
  }
77
 
79
  * Returns the arguments with default values for this function
80
  * @return array the arguments with default values for this function
81
  */
82
+ public function getArgs()
83
+ {
84
  return $this->args;
85
  }
86
 
89
  * @param object token
90
  * @return boolean true if the token represents this type of node, false if not
91
  */
92
+ public static function isa($token)
93
+ {
94
  return $token->source[0] === self::NODE_IDENTIFIER;
95
  }
96
 
101
  * @throws SassReturn - if the @return is fired then this is thrown to break early
102
  * @return SassBoolean(false) - if no @return was fired, return false
103
  */
104
+ public function execute($pcontext, $provided)
105
+ {
106
  list($arguments, $context) = SassScriptFunction::fill_parameters($this->args, $provided, $pcontext, $this);
107
  $context->setVariables($arguments);
108
 
lib/phpsass/tree/SassIfNode.php CHANGED
@@ -16,9 +16,10 @@
16
  * @package PHamlP
17
  * @subpackage Sass.tree
18
  */
19
- class SassIfNode extends SassNode {
20
- const MATCH_IF = '/^@if\s+(.+)$/i';
21
- const MATCH_ELSE = '/@else(\s+if\s+(.+))?/i';
 
22
  const IF_EXPRESSION = 1;
23
  const ELSE_IF = 1;
24
  const ELSE_EXPRESSION = 2;
@@ -37,13 +38,13 @@ class SassIfNode extends SassNode {
37
  * @param boolean true for an "if" node, false for an "else if | else" node
38
  * @return SassIfNode
39
  */
40
- public function __construct($token, $if=true) {
 
41
  parent::__construct($token);
42
  if ($if) {
43
  preg_match(self::MATCH_IF, $token->source, $matches);
44
  $this->expression = $matches[SassIfNode::IF_EXPRESSION];
45
- }
46
- else {
47
  preg_match(self::MATCH_ELSE, $token->source, $matches);
48
  $this->expression = (sizeof($matches)==1 ? null : $matches[SassIfNode::ELSE_EXPRESSION]);
49
  }
@@ -54,15 +55,16 @@ class SassIfNode extends SassNode {
54
  * @param SassIfNode "else" statement node to add
55
  * @return SassIfNode this node
56
  */
57
- public function addElse($node) {
 
58
  if (is_null($this->else)) {
59
  $node->parent = $this;
60
  $node->root = $this->root;
61
  $this->else = $node;
62
- }
63
- else {
64
  $this->else->addElse($node);
65
  }
 
66
  return $this;
67
  }
68
 
@@ -71,16 +73,16 @@ class SassIfNode extends SassNode {
71
  * @param SassContext the context in which this node is parsed
72
  * @return array parsed child nodes
73
  */
74
- public function parse($context) {
 
75
  if ($this->isElse() || $this->evaluate($this->expression, $context)->toBoolean()) {
76
  $children = $this->parseChildren($context);
77
- }
78
- elseif (!empty($this->else)) {
79
  $children = $this->else->parse($context);
80
- }
81
- else {
82
  $children = array();
83
  }
 
84
  return $children;
85
  }
86
 
@@ -89,7 +91,8 @@ class SassIfNode extends SassNode {
89
  * @return true if this node is an "else" node, false if this node is an "if"
90
  * or "else if" node
91
  */
92
- private function isElse() {
 
93
  return ($this->expression=='');
94
  }
95
- }
16
  * @package PHamlP
17
  * @subpackage Sass.tree
18
  */
19
+ class SassIfNode extends SassNode
20
+ {
21
+ const MATCH_IF = '/^@if\s*(.+)$/i';
22
+ const MATCH_ELSE = '/@else(\s*if\s*(.+))?/i';
23
  const IF_EXPRESSION = 1;
24
  const ELSE_IF = 1;
25
  const ELSE_EXPRESSION = 2;
38
  * @param boolean true for an "if" node, false for an "else if | else" node
39
  * @return SassIfNode
40
  */
41
+ public function __construct($token, $if=true)
42
+ {
43
  parent::__construct($token);
44
  if ($if) {
45
  preg_match(self::MATCH_IF, $token->source, $matches);
46
  $this->expression = $matches[SassIfNode::IF_EXPRESSION];
47
+ } else {
 
48
  preg_match(self::MATCH_ELSE, $token->source, $matches);
49
  $this->expression = (sizeof($matches)==1 ? null : $matches[SassIfNode::ELSE_EXPRESSION]);
50
  }
55
  * @param SassIfNode "else" statement node to add
56
  * @return SassIfNode this node
57
  */
58
+ public function addElse($node)
59
+ {
60
  if (is_null($this->else)) {
61
  $node->parent = $this;
62
  $node->root = $this->root;
63
  $this->else = $node;
64
+ } else {
 
65
  $this->else->addElse($node);
66
  }
67
+
68
  return $this;
69
  }
70
 
73
  * @param SassContext the context in which this node is parsed
74
  * @return array parsed child nodes
75
  */
76
+ public function parse($context)
77
+ {
78
  if ($this->isElse() || $this->evaluate($this->expression, $context)->toBoolean()) {
79
  $children = $this->parseChildren($context);
80
+ } elseif (!empty($this->else)) {
 
81
  $children = $this->else->parse($context);
82
+ } else {
 
83
  $children = array();
84
  }
85
+
86
  return $children;
87
  }
88
 
91
  * @return true if this node is an "else" node, false if this node is an "if"
92
  * or "else if" node
93
  */
94
+ private function isElse()
95
+ {
96
  return ($this->expression=='');
97
  }
98
+ }
lib/phpsass/tree/SassImportNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassImportNode extends SassNode {
 
19
  const IDENTIFIER = '@';
20
  const MATCH = '/^@import\s+(.+)/i';
21
  const MATCH_CSS = '/^((url)\((.+)\)|.+" \w+|http|.+\.css$)/im';
@@ -31,7 +32,8 @@ class SassImportNode extends SassNode {
31
  * @param object source token
32
  * @return SassImportNode
33
  */
34
- public function __construct($token, $parent) {
 
35
  parent::__construct($token);
36
  $this->parent = $parent;
37
  preg_match(self::MATCH, $token->source, $matches);
@@ -48,7 +50,8 @@ class SassImportNode extends SassNode {
48
  * @param SassContext the context in which this node is parsed
49
  * @return array the parsed node
50
  */
51
- public function parse($context) {
 
52
  $imported = array();
53
  foreach ($this->files as $file) {
54
  if (preg_match(self::MATCH_CSS, $file, $matches)) {
@@ -57,6 +60,7 @@ class SassImportNode extends SassNode {
57
  } else {
58
  $file = "url('$file')";
59
  }
 
60
  return array(new SassString("@import $file;"), new SassString("\n"));
61
  }
62
  $file = trim($file, '\'"');
@@ -78,11 +82,10 @@ class SassImportNode extends SassNode {
78
  foreach ($files as $subfile) {
79
  if (preg_match(self::MATCH_CSS, $subfile)) {
80
  $tree->addChild(new SassString("@import url('$subfile');"));
81
- }
82
- else {
83
  $this->parser->filename = $subfile;
84
  $subtree = SassFile::get_tree($subfile, $this->parser);
85
- foreach($subtree->getChildren() as $child) {
86
  $tree->addChild($child);
87
  }
88
  }
@@ -100,6 +103,7 @@ class SassImportNode extends SassNode {
100
  }
101
  }
102
  }
 
103
  return $imported;
104
  }
105
  }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassImportNode extends SassNode
19
+ {
20
  const IDENTIFIER = '@';
21
  const MATCH = '/^@import\s+(.+)/i';
22
  const MATCH_CSS = '/^((url)\((.+)\)|.+" \w+|http|.+\.css$)/im';
32
  * @param object source token
33
  * @return SassImportNode
34
  */
35
+ public function __construct($token, $parent)
36
+ {
37
  parent::__construct($token);
38
  $this->parent = $parent;
39
  preg_match(self::MATCH, $token->source, $matches);
50
  * @param SassContext the context in which this node is parsed
51
  * @return array the parsed node
52
  */
53
+ public function parse($context)
54
+ {
55
  $imported = array();
56
  foreach ($this->files as $file) {
57
  if (preg_match(self::MATCH_CSS, $file, $matches)) {
60
  } else {
61
  $file = "url('$file')";
62
  }
63
+
64
  return array(new SassString("@import $file;"), new SassString("\n"));
65
  }
66
  $file = trim($file, '\'"');
82
  foreach ($files as $subfile) {
83
  if (preg_match(self::MATCH_CSS, $subfile)) {
84
  $tree->addChild(new SassString("@import url('$subfile');"));
85
+ } else {
 
86
  $this->parser->filename = $subfile;
87
  $subtree = SassFile::get_tree($subfile, $this->parser);
88
+ foreach ($subtree->getChildren() as $child) {
89
  $tree->addChild($child);
90
  }
91
  }
103
  }
104
  }
105
  }
106
+
107
  return $imported;
108
  }
109
  }
lib/phpsass/tree/SassMediaNode.php CHANGED
@@ -15,12 +15,12 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassMediaNode extends SassNode {
 
19
  const IDENTIFIER = '@';
20
  const MATCH = '/^@(media)\s+(.+?)\s*;?$/';
21
  const MEDIA = 1;
22
 
23
-
24
  public $token;
25
 
26
  /**
@@ -47,7 +47,8 @@ class SassMediaNode extends SassNode {
47
  * @param array parameters for the message
48
  * @return SassMediaNode
49
  */
50
- public function __construct($token) {
 
51
  parent::__construct($token);
52
 
53
  preg_match(self::MATCH, $token->source, $matches);
@@ -60,7 +61,8 @@ class SassMediaNode extends SassNode {
60
  * This raises an error.
61
  * @return array An empty array
62
  */
63
- public function parse($context) {
 
64
  // If we are in a loop, function or mixin then the parent isn't what should
65
  // go inside the media node. Walk up the parent tree to find the rule node
66
  // to put inside the media node or the root node if the media node should be
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassMediaNode extends SassNode
19
+ {
20
  const IDENTIFIER = '@';
21
  const MATCH = '/^@(media)\s+(.+?)\s*;?$/';
22
  const MEDIA = 1;
23
 
 
24
  public $token;
25
 
26
  /**
47
  * @param array parameters for the message
48
  * @return SassMediaNode
49
  */
50
+ public function __construct($token)
51
+ {
52
  parent::__construct($token);
53
 
54
  preg_match(self::MATCH, $token->source, $matches);
61
  * This raises an error.
62
  * @return array An empty array
63
  */
64
+ public function parse($context)
65
+ {
66
  // If we are in a loop, function or mixin then the parent isn't what should
67
  // go inside the media node. Walk up the parent tree to find the rule node
68
  // to put inside the media node or the root node if the media node should be
lib/phpsass/tree/SassMixinDefinitionNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassMixinDefinitionNode extends SassNode {
 
19
  const NODE_IDENTIFIER = '=';
20
  const MATCH = '/^(=|@mixin\s+)([-\w]+)\s*(?:\((.*?)\))?\s*$/im';
21
  const IDENTIFIER = 1;
@@ -37,7 +38,8 @@ class SassMixinDefinitionNode extends SassNode {
37
  * @param object source token
38
  * @return SassMixinDefinitionNode
39
  */
40
- public function __construct($token) {
 
41
  preg_match(self::MATCH, $token->source, $matches);
42
  parent::__construct($token);
43
  if (empty($matches)) {
@@ -55,8 +57,10 @@ class SassMixinDefinitionNode extends SassNode {
55
  * @param SassContext the context in which this node is parsed
56
  * @return array the parsed node - an empty array
57
  */
58
- public function parse($context) {
 
59
  $context->addMixin($this->name, $this);
 
60
  return array();
61
  }
62
 
@@ -64,7 +68,8 @@ class SassMixinDefinitionNode extends SassNode {
64
  * Returns the arguments with default values for this mixin
65
  * @return array the arguments with default values for this mixin
66
  */
67
- public function getArgs() {
 
68
  return $this->args;
69
  }
70
 
@@ -73,7 +78,8 @@ class SassMixinDefinitionNode extends SassNode {
73
  * @param object token
74
  * @return boolean true if the token represents this type of node, false if not
75
  */
76
- public static function isa($token) {
 
77
  return $token->source[0] === self::NODE_IDENTIFIER;
78
  }
79
  }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassMixinDefinitionNode extends SassNode
19
+ {
20
  const NODE_IDENTIFIER = '=';
21
  const MATCH = '/^(=|@mixin\s+)([-\w]+)\s*(?:\((.*?)\))?\s*$/im';
22
  const IDENTIFIER = 1;
38
  * @param object source token
39
  * @return SassMixinDefinitionNode
40
  */
41
+ public function __construct($token)
42
+ {
43
  preg_match(self::MATCH, $token->source, $matches);
44
  parent::__construct($token);
45
  if (empty($matches)) {
57
  * @param SassContext the context in which this node is parsed
58
  * @return array the parsed node - an empty array
59
  */
60
+ public function parse($context)
61
+ {
62
  $context->addMixin($this->name, $this);
63
+
64
  return array();
65
  }
66
 
68
  * Returns the arguments with default values for this mixin
69
  * @return array the arguments with default values for this mixin
70
  */
71
+ public function getArgs()
72
+ {
73
  return $this->args;
74
  }
75
 
78
  * @param object token
79
  * @return boolean true if the token represents this type of node, false if not
80
  */
81
+ public static function isa($token)
82
+ {
83
  return $token->source[0] === self::NODE_IDENTIFIER;
84
  }
85
  }
lib/phpsass/tree/SassMixinNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassMixinNode extends SassNode {
 
19
  const NODE_IDENTIFIER = '+';
20
  const MATCH = '/^(\+|@include\s+)([a-z0-9_-]+)\s*(?:\((.*?)\))?\s*$/i';
21
  const IDENTIFIER = 1;
@@ -36,7 +37,8 @@ class SassMixinNode extends SassNode {
36
  * @param object source token
37
  * @return SassMixinNode
38
  */
39
- public function __construct($token) {
 
40
  parent::__construct($token);
41
  preg_match(self::MATCH, $token->source, $matches);
42
 
@@ -56,7 +58,8 @@ class SassMixinNode extends SassNode {
56
  * @param SassContext the context in which this node is parsed
57
  * @return array the parsed node
58
  */
59
- public function parse($pcontext) {
 
60
  $mixin = $pcontext->getMixin($this->name);
61
  $context = new SassContext($pcontext);
62
  $context->content = $this->children;
@@ -83,7 +86,8 @@ class SassMixinNode extends SassNode {
83
  * @param object token
84
  * @return boolean true if the token represents this type of node, false if not
85
  */
86
- public static function isa($token) {
 
87
  return $token->source[0] === self::NODE_IDENTIFIER;
88
  }
89
  }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassMixinNode extends SassNode
19
+ {
20
  const NODE_IDENTIFIER = '+';
21
  const MATCH = '/^(\+|@include\s+)([a-z0-9_-]+)\s*(?:\((.*?)\))?\s*$/i';
22
  const IDENTIFIER = 1;
37
  * @param object source token
38
  * @return SassMixinNode
39
  */
40
+ public function __construct($token)
41
+ {
42
  parent::__construct($token);
43
  preg_match(self::MATCH, $token->source, $matches);
44
 
58
  * @param SassContext the context in which this node is parsed
59
  * @return array the parsed node
60
  */
61
+ public function parse($pcontext)
62
+ {
63
  $mixin = $pcontext->getMixin($this->name);
64
  $context = new SassContext($pcontext);
65
  $context->content = $this->children;
86
  * @param object token
87
  * @return boolean true if the token represents this type of node, false if not
88
  */
89
+ public static function isa($token)
90
+ {
91
  return $token->source[0] === self::NODE_IDENTIFIER;
92
  }
93
  }
lib/phpsass/tree/SassNode.php CHANGED
@@ -9,30 +9,30 @@
9
  * @subpackage Sass.tree
10
  */
11
 
12
- require_once('SassContext.php');
13
- require_once('SassCommentNode.php');
14
- require_once('SassDebugNode.php');
15
- require_once('SassDirectiveNode.php');
16
- require_once('SassImportNode.php');
17
- require_once('SassMixinNode.php');
18
- require_once('SassMixinDefinitionNode.php');
19
- require_once('SassPropertyNode.php');
20
- require_once('SassRootNode.php');
21
- require_once('SassRuleNode.php');
22
- require_once('SassVariableNode.php');
23
- require_once('SassExtendNode.php');
24
- require_once('SassEachNode.php');
25
- require_once('SassForNode.php');
26
- require_once('SassIfNode.php');
27
- require_once('SassElseNode.php');
28
- require_once('SassWhileNode.php');
29
- require_once('SassNodeExceptions.php');
30
-
31
- require_once('SassFunctionDefinitionNode.php');
32
- require_once('SassReturnNode.php');
33
- require_once('SassContentNode.php');
34
- require_once('SassWarnNode.php');
35
- require_once('SassMediaNode.php');
36
 
37
  /**
38
  * SassNode class.
@@ -40,7 +40,8 @@ require_once('SassMediaNode.php');
40
  * @package PHamlP
41
  * @subpackage Sass.tree
42
  */
43
- class SassNode {
 
44
  /**
45
  * @var SassNode parent of this node
46
  */
@@ -63,7 +64,8 @@ class SassNode {
63
  * @param object source token
64
  * @return SassNode
65
  */
66
- public function __construct($token) {
 
67
  $this->token = $token;
68
  }
69
 
@@ -72,7 +74,8 @@ class SassNode {
72
  * @param string name of property to get
73
  * @return mixed return value of getter function
74
  */
75
- public function __get($name) {
 
76
  $getter = 'get' . ucfirst($name);
77
  if (method_exists($this, $getter)) {
78
  return $this->$getter();
@@ -86,10 +89,12 @@ class SassNode {
86
  * @return mixed value of property
87
  * @return SassNode this node
88
  */
89
- public function __set($name, $value) {
 
90
  $setter = 'set' . ucfirst($name);
91
  if (method_exists($this, $setter)) {
92
  $this->$setter($value);
 
93
  return $this;
94
  }
95
  throw new SassNodeException('No setter function for ' . $name, $this);
@@ -99,7 +104,8 @@ class SassNode {
99
  * Resets children when cloned
100
  * @see parse
101
  */
102
- public function __clone() {
 
103
  $this->children = array();
104
  }
105
 
@@ -107,7 +113,8 @@ class SassNode {
107
  * Return a value indicating if this node has a parent
108
  * @return array the node's parent
109
  */
110
- public function hasParent() {
 
111
  return !empty($this->parent);
112
  }
113
 
@@ -115,7 +122,8 @@ class SassNode {
115
  * Returns the node's parent
116
  * @return array the node's parent
117
  */
118
- public function getParent() {
 
119
  return $this->parent;
120
  }
121
 
@@ -123,14 +131,14 @@ class SassNode {
123
  * Adds a child to this node.
124
  * @return SassNode the child to add
125
  */
126
- public function addChild($child) {
 
127
  if ($child instanceof SassElseNode) {
128
  if (!$this->lastChild instanceof SassIfNode) {
129
  throw new SassException('@else(if) directive must come after @(else)if', $child);
130
  }
131
  $this->lastChild->addElse($child);
132
- }
133
- else {
134
  $this->children[] = $child;
135
  $child->parent = $this;
136
  $child->root = $this->root;
@@ -145,7 +153,8 @@ class SassNode {
145
  * Returns a value indicating if this node has children
146
  * @return boolean true if the node has children, false if not
147
  */
148
- public function hasChildren() {
 
149
  return !empty($this->children);
150
  }
151
 
@@ -153,7 +162,8 @@ class SassNode {
153
  * Returns the node's children
154
  * @return array the node's children
155
  */
156
- public function getChildren() {
 
157
  return $this->children;
158
  }
159
 
@@ -163,7 +173,8 @@ class SassNode {
163
  * level than the passed node if is a child of it.
164
  * @return boolean true if the node is a child of the passed node, false if not
165
  */
166
- public function isChildOf($node) {
 
167
  return $this->level > $node->level;
168
  }
169
 
@@ -171,7 +182,8 @@ class SassNode {
171
  * Returns the last child node of this node.
172
  * @return SassNode the last child node of this node
173
  */
174
- public function getLastChild() {
 
175
  return $this->children[count($this->children) - 1];
176
  }
177
 
@@ -179,7 +191,8 @@ class SassNode {
179
  * Returns the level of this node.
180
  * @return integer the level of this node
181
  */
182
- public function getLevel() {
 
183
  return $this->token->level;
184
  }
185
 
@@ -187,7 +200,8 @@ class SassNode {
187
  * Returns the source for this node
188
  * @return string the source for this node
189
  */
190
- public function getSource() {
 
191
  return $this->token->source;
192
  }
193
 
@@ -195,7 +209,8 @@ class SassNode {
195
  * Returns the debug_info option setting for this node
196
  * @return boolean the debug_info option setting for this node
197
  */
198
- public function getDebug_info() {
 
199
  return $this->parser->debug_info;
200
  }
201
 
@@ -203,7 +218,8 @@ class SassNode {
203
  * Returns the line number for this node
204
  * @return string the line number for this node
205
  */
206
- public function getLine() {
 
207
  return $this->token->line;
208
  }
209
 
@@ -211,7 +227,8 @@ class SassNode {
211
  * Returns the line_numbers option setting for this node
212
  * @return boolean the line_numbers option setting for this node
213
  */
214
- public function getLine_numbers() {
 
215
  return $this->parser->line_numbers;
216
  }
217
 
@@ -219,7 +236,8 @@ class SassNode {
219
  * Returns the filename for this node
220
  * @return string the filename for this node
221
  */
222
- public function getFilename() {
 
223
  return $this->token->filename;
224
  }
225
 
@@ -227,7 +245,8 @@ class SassNode {
227
  * Returns the Sass parser.
228
  * @return SassParser the Sass parser
229
  */
230
- public function getParser() {
 
231
  return $this->root->parser;
232
  }
233
 
@@ -235,7 +254,8 @@ class SassNode {
235
  * Returns the property syntax being used.
236
  * @return string the property syntax being used
237
  */
238
- public function getPropertySyntax() {
 
239
  return $this->root->parser->propertySyntax;
240
  }
241
 
@@ -243,7 +263,8 @@ class SassNode {
243
  * Returns the SassScript parser.
244
  * @return SassScriptParser the SassScript parser
245
  */
246
- public function getScript() {
 
247
  return $this->root->script;
248
  }
249
 
@@ -251,7 +272,8 @@ class SassNode {
251
  * Returns the renderer.
252
  * @return SassRenderer the renderer
253
  */
254
- public function getRenderer() {
 
255
  return $this->root->renderer;
256
  }
257
 
@@ -259,7 +281,8 @@ class SassNode {
259
  * Returns the render style of the document tree.
260
  * @return string the render style of the document tree
261
  */
262
- public function getStyle() {
 
263
  return $this->root->parser->style;
264
  }
265
 
@@ -267,7 +290,8 @@ class SassNode {
267
  * Returns a value indicating whether this node is in a directive
268
  * @param boolean true if the node is in a directive, false if not
269
  */
270
- public function inDirective() {
 
271
  return $this->parent instanceof SassDirectiveNode ||
272
  $this->parent instanceof SassDirectiveNode;
273
  }
@@ -276,7 +300,8 @@ class SassNode {
276
  * Returns a value indicating whether this node is in a SassScript directive
277
  * @param boolean true if this node is in a SassScript directive, false if not
278
  */
279
- public function inSassScriptDirective() {
 
280
  return $this->parent instanceof SassEachNode ||
281
  $this->parent->parent instanceof SassEachNode ||
282
  $this->parent instanceof SassForNode ||
@@ -293,8 +318,10 @@ class SassNode {
293
  * @param SassContext the context in which the expression is evaluated
294
  * @return SassLiteral value of parsed expression
295
  */
296
- public function evaluate($expression, $context, $x=null) {
 
297
  $context->node = $this;
 
298
  return $this->script->evaluate($expression, $context, $x);
299
  }
300
 
@@ -304,8 +331,10 @@ class SassNode {
304
  * @param SassContext the context in which the string is interpolated
305
  * @return string the interpolated text
306
  */
307
- public function interpolate($expression, $context) {
 
308
  $context->node = $this;
 
309
  return $this->script->interpolate($expression, $context);
310
  }
311
 
@@ -314,7 +343,8 @@ class SassNode {
314
  * @param string warning message
315
  * @param array line
316
  */
317
- public function addWarning($message) {
 
318
  $warning = new SassDebugNode($this->token, $message);
319
  $this->addChild($warning);
320
  }
@@ -324,7 +354,8 @@ class SassNode {
324
  * @param SassContext the context in which the children are parsed
325
  * @return array the parsed child nodes
326
  */
327
- public function parseChildren($context) {
 
328
  $children = array();
329
  foreach ($this->children as $child) {
330
  # child could be a SassLiteral /or/ SassNode
@@ -335,6 +366,7 @@ class SassNode {
335
  }
336
  $children = array_merge($children, $kid);
337
  }
 
338
  return $children;
339
  }
340
 
@@ -343,7 +375,8 @@ class SassNode {
343
  * @param object token
344
  * @return boolean true if the token represents this type of node, false if not
345
  */
346
- public static function isa($token) {
 
347
  throw new SassNodeException('Child classes must override this method');
348
  }
349
 
9
  * @subpackage Sass.tree
10
  */
11
 
12
+ require_once 'SassContext.php';
13
+ require_once 'SassCommentNode.php';
14
+ require_once 'SassDebugNode.php';
15
+ require_once 'SassDirectiveNode.php';
16
+ require_once 'SassImportNode.php';
17
+ require_once 'SassMixinNode.php';
18
+ require_once 'SassMixinDefinitionNode.php';
19
+ require_once 'SassPropertyNode.php';
20
+ require_once 'SassRootNode.php';
21
+ require_once 'SassRuleNode.php';
22
+ require_once 'SassVariableNode.php';
23
+ require_once 'SassExtendNode.php';
24
+ require_once 'SassEachNode.php';
25
+ require_once 'SassForNode.php';
26
+ require_once 'SassIfNode.php';
27
+ require_once 'SassElseNode.php';
28
+ require_once 'SassWhileNode.php';
29
+ require_once 'SassNodeExceptions.php';
30
+
31
+ require_once 'SassFunctionDefinitionNode.php';
32
+ require_once 'SassReturnNode.php';
33
+ require_once 'SassContentNode.php';
34
+ require_once 'SassWarnNode.php';
35
+ require_once 'SassMediaNode.php';
36
 
37
  /**
38
  * SassNode class.
40
  * @package PHamlP
41
  * @subpackage Sass.tree
42
  */
43
+ class SassNode
44
+ {
45
  /**
46
  * @var SassNode parent of this node
47
  */
64
  * @param object source token
65
  * @return SassNode
66
  */
67
+ public function __construct($token)
68
+ {
69
  $this->token = $token;
70
  }
71
 
74
  * @param string name of property to get
75
  * @return mixed return value of getter function
76
  */
77
+ public function __get($name)
78
+ {
79
  $getter = 'get' . ucfirst($name);
80
  if (method_exists($this, $getter)) {
81
  return $this->$getter();
89
  * @return mixed value of property
90
  * @return SassNode this node
91
  */
92
+ public function __set($name, $value)
93
+ {
94
  $setter = 'set' . ucfirst($name);
95
  if (method_exists($this, $setter)) {
96
  $this->$setter($value);
97
+
98
  return $this;
99
  }
100
  throw new SassNodeException('No setter function for ' . $name, $this);
104
  * Resets children when cloned
105
  * @see parse
106
  */
107
+ public function __clone()
108
+ {
109
  $this->children = array();
110
  }
111
 
113
  * Return a value indicating if this node has a parent
114
  * @return array the node's parent
115
  */
116
+ public function hasParent()
117
+ {
118
  return !empty($this->parent);
119
  }
120
 
122
  * Returns the node's parent
123
  * @return array the node's parent
124
  */
125
+ public function getParent()
126
+ {
127
  return $this->parent;
128
  }
129
 
131
  * Adds a child to this node.
132
  * @return SassNode the child to add
133
  */
134
+ public function addChild($child)
135
+ {
136
  if ($child instanceof SassElseNode) {
137
  if (!$this->lastChild instanceof SassIfNode) {
138
  throw new SassException('@else(if) directive must come after @(else)if', $child);
139
  }
140
  $this->lastChild->addElse($child);
141
+ } else {
 
142
  $this->children[] = $child;
143
  $child->parent = $this;
144
  $child->root = $this->root;
153
  * Returns a value indicating if this node has children
154
  * @return boolean true if the node has children, false if not
155
  */
156
+ public function hasChildren()
157
+ {
158
  return !empty($this->children);
159
  }
160
 
162
  * Returns the node's children
163
  * @return array the node's children
164
  */
165
+ public function getChildren()
166
+ {
167
  return $this->children;
168
  }
169
 
173
  * level than the passed node if is a child of it.
174
  * @return boolean true if the node is a child of the passed node, false if not
175
  */
176
+ public function isChildOf($node)
177
+ {
178
  return $this->level > $node->level;
179
  }
180
 
182
  * Returns the last child node of this node.
183
  * @return SassNode the last child node of this node
184
  */
185
+ public function getLastChild()
186
+ {
187
  return $this->children[count($this->children) - 1];
188
  }
189
 
191
  * Returns the level of this node.
192
  * @return integer the level of this node
193
  */
194
+ public function getLevel()
195
+ {
196
  return $this->token->level;
197
  }
198
 
200
  * Returns the source for this node
201
  * @return string the source for this node
202
  */
203
+ public function getSource()
204
+ {
205
  return $this->token->source;
206
  }
207
 
209
  * Returns the debug_info option setting for this node
210
  * @return boolean the debug_info option setting for this node
211
  */
212
+ public function getDebug_info()
213
+ {
214
  return $this->parser->debug_info;
215
  }
216
 
218
  * Returns the line number for this node
219
  * @return string the line number for this node
220
  */
221
+ public function getLine()
222
+ {
223
  return $this->token->line;
224
  }
225
 
227
  * Returns the line_numbers option setting for this node
228
  * @return boolean the line_numbers option setting for this node
229
  */
230
+ public function getLine_numbers()
231
+ {
232
  return $this->parser->line_numbers;
233
  }
234
 
236
  * Returns the filename for this node
237
  * @return string the filename for this node
238
  */
239
+ public function getFilename()
240
+ {
241
  return $this->token->filename;
242
  }
243
 
245
  * Returns the Sass parser.
246
  * @return SassParser the Sass parser
247
  */
248
+ public function getParser()
249
+ {
250
  return $this->root->parser;
251
  }
252
 
254
  * Returns the property syntax being used.
255
  * @return string the property syntax being used
256
  */
257
+ public function getPropertySyntax()
258
+ {
259
  return $this->root->parser->propertySyntax;
260
  }
261
 
263
  * Returns the SassScript parser.
264
  * @return SassScriptParser the SassScript parser
265
  */
266
+ public function getScript()
267
+ {
268
  return $this->root->script;
269
  }
270
 
272
  * Returns the renderer.
273
  * @return SassRenderer the renderer
274
  */
275
+ public function getRenderer()
276
+ {
277
  return $this->root->renderer;
278
  }
279
 
281
  * Returns the render style of the document tree.
282
  * @return string the render style of the document tree
283
  */
284
+ public function getStyle()
285
+ {
286
  return $this->root->parser->style;
287
  }
288
 
290
  * Returns a value indicating whether this node is in a directive
291
  * @param boolean true if the node is in a directive, false if not
292
  */
293
+ public function inDirective()
294
+ {
295
  return $this->parent instanceof SassDirectiveNode ||
296
  $this->parent instanceof SassDirectiveNode;
297
  }
300
  * Returns a value indicating whether this node is in a SassScript directive
301
  * @param boolean true if this node is in a SassScript directive, false if not
302
  */
303
+ public function inSassScriptDirective()
304
+ {
305
  return $this->parent instanceof SassEachNode ||
306
  $this->parent->parent instanceof SassEachNode ||
307
  $this->parent instanceof SassForNode ||
318
  * @param SassContext the context in which the expression is evaluated
319
  * @return SassLiteral value of parsed expression
320
  */
321
+ public function evaluate($expression, $context, $x=null)
322
+ {
323
  $context->node = $this;
324
+
325
  return $this->script->evaluate($expression, $context, $x);
326
  }
327
 
331
  * @param SassContext the context in which the string is interpolated
332
  * @return string the interpolated text
333
  */
334
+ public function interpolate($expression, $context)
335
+ {
336
  $context->node = $this;
337
+
338
  return $this->script->interpolate($expression, $context);
339
  }
340
 
343
  * @param string warning message
344
  * @param array line
345
  */
346
+ public function addWarning($message)
347
+ {
348
  $warning = new SassDebugNode($this->token, $message);
349
  $this->addChild($warning);
350
  }
354
  * @param SassContext the context in which the children are parsed
355
  * @return array the parsed child nodes
356
  */
357
+ public function parseChildren($context)
358
+ {
359
  $children = array();
360
  foreach ($this->children as $child) {
361
  # child could be a SassLiteral /or/ SassNode
366
  }
367
  $children = array_merge($children, $kid);
368
  }
369
+
370
  return $children;
371
  }
372
 
375
  * @param object token
376
  * @return boolean true if the token represents this type of node, false if not
377
  */
378
+ public static function isa($token)
379
+ {
380
  throw new SassNodeException('Child classes must override this method');
381
  }
382
 
lib/phpsass/tree/SassNodeExceptions.php CHANGED
@@ -74,7 +74,6 @@ class SassForNodeException extends SassNodeException {}
74
  */
75
  class SassFunctionDefinitionNodeException extends SassNodeException {}
76
 
77
-
78
  /**
79
  * SassIfNodeException class.
80
  * @package PHamlP
74
  */
75
  class SassFunctionDefinitionNodeException extends SassNodeException {}
76
 
 
77
  /**
78
  * SassIfNodeException class.
79
  * @package PHamlP
lib/phpsass/tree/SassPropertyNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassPropertyNode extends SassNode {
 
19
  const MATCH_PROPERTY_SCSS = '/^([^\s=:"(\\\\:)]*)\s*(?:(= )|:)([^\:].*?)?(\s*!important.*)?$/';
20
  const MATCH_PROPERTY_NEW = '/^([^\s=:"]+)\s*(?:(= )|:)([^\:].*?)?(\s*!important.*)?$/';
21
  const MATCH_PROPERTY_OLD = '/^:([^\s=:]+)(?:\s*(=)\s*|\s+|$)(.*)(\s*!important.*)?/';
@@ -72,7 +73,6 @@ class SassPropertyNode extends SassNode {
72
  */
73
  public $value;
74
 
75
-
76
  /**
77
  * @var boolean, wether the property is important
78
  */
@@ -84,14 +84,14 @@ class SassPropertyNode extends SassNode {
84
  * @param string property syntax
85
  * @return SassPropertyNode
86
  */
87
- public function __construct($token, $syntax = 'new') {
 
88
  parent::__construct($token);
89
  $matches = self::match($token, $syntax);
90
  $this->name = @$matches[self::NAME];
91
  if (!isset($matches[self::VALUE])) {
92
  $this->value = '';
93
- }
94
- else {
95
  $this->value = $matches[self::VALUE];
96
  if ($matches[self::SCRIPT] === self::IS_SCRIPT) {
97
  $this->addWarning('Setting CSS properties with "=" is deprecated; use "{name}: {value};"',
@@ -109,7 +109,8 @@ class SassPropertyNode extends SassNode {
109
  * @param SassContext the context in which this node is parsed
110
  * @return array the parsed node
111
  */
112
- public function parse($context) {
 
113
  $return = array();
114
  if ($this->value !== "") {
115
  $node = clone $this;
@@ -123,6 +124,7 @@ class SassPropertyNode extends SassNode {
123
  if ($this->children) {
124
  $return = array_merge($return, $this->parseChildren($context));
125
  }
 
126
  return $return;
127
  }
128
 
@@ -130,7 +132,8 @@ class SassPropertyNode extends SassNode {
130
  * Render this node.
131
  * @return string the rendered node
132
  */
133
- public function render() {
 
134
  return $this->renderer->renderProperty($this);
135
  }
136
 
@@ -138,7 +141,8 @@ class SassPropertyNode extends SassNode {
138
  * Returns a value indicating if this node is in a namespace
139
  * @return boolean true if this node is in a property namespace, false if not
140
  */
141
- public function inNamespace() {
 
142
  $parent = $this->parent;
143
  do {
144
  if ($parent instanceof SassPropertyNode) {
@@ -146,6 +150,7 @@ class SassPropertyNode extends SassNode {
146
  }
147
  $parent = $parent->parent;
148
  } while (is_object($parent));
 
149
  return false;
150
  }
151
 
@@ -153,7 +158,8 @@ class SassPropertyNode extends SassNode {
153
  * Returns the namespace for this node
154
  * @return string the namespace for this node
155
  */
156
- public function getNamespace() {
 
157
  $namespace = array();
158
  $parent = $this->parent;
159
  do {
@@ -162,6 +168,7 @@ class SassPropertyNode extends SassNode {
162
  }
163
  $parent = $parent->parent;
164
  } while (is_object($parent));
 
165
  return join('-', array_reverse($namespace));
166
  }
167
 
@@ -170,7 +177,8 @@ class SassPropertyNode extends SassNode {
170
  * If the property is in a namespace the namespace is prepended
171
  * @return string the name of this property
172
  */
173
- public function getName() {
 
174
  return $this->name;
175
  }
176
 
@@ -178,7 +186,8 @@ class SassPropertyNode extends SassNode {
178
  * Returns the parsed value of this property.
179
  * @return string the parsed value of this property
180
  */
181
- public function getValue() {
 
182
  return $this->value;
183
  }
184
 
@@ -188,11 +197,11 @@ class SassPropertyNode extends SassNode {
188
  * @param string the property syntax being used
189
  * @return boolean true if the token represents this type of node, false if not
190
  */
191
- public static function isa($token) {
192
- if(!is_array($token)) {
 
193
  $syntax = 'old';
194
- }
195
- else {
196
  $syntax = $token['syntax'];
197
  $token = $token['token'];
198
  }
@@ -206,14 +215,13 @@ class SassPropertyNode extends SassNode {
206
  if ($token->level === 0) {
207
  # RL - if it's on the first level it's probably a false positive, not an error.
208
  # even if it is a genuine error, no need to kill the compiler about it.
 
209
  return false;
210
  // throw new SassPropertyNodeException('Properties can not be assigned at root level', $token);
211
- }
212
- else {
213
  return true;
214
  }
215
- }
216
- else {
217
  return false;
218
  }
219
  }
@@ -224,7 +232,8 @@ class SassPropertyNode extends SassNode {
224
  * @param string the property syntax being used
225
  * @return array matches
226
  */
227
- public static function match($token, $syntax) {
 
228
  switch ($syntax) {
229
  case 'scss':
230
  preg_match(self::MATCH_PROPERTY_SCSS, $token->source, $matches);
@@ -241,6 +250,7 @@ class SassPropertyNode extends SassNode {
241
  }
242
  break;
243
  }
 
244
  return $matches;
245
  }
246
 
@@ -255,8 +265,10 @@ class SassPropertyNode extends SassNode {
255
  * @param string the string to test
256
  * @return bool true if the string starts with a pseudo selector, false if not
257
  */
258
- public static function isPseudoSelector($string) {
 
259
  preg_match(self::MATCH_PSUEDO_SELECTOR, $string, $matches);
 
260
  return (isset($matches[0]) && in_array($matches[0], self::$psuedoSelectors)) ||
261
  preg_match(self::MATCH_INTERPOLATION, $string) ||
262
  preg_match(self::MATCH_PROPRIETARY_SELECTOR, $string);
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassPropertyNode extends SassNode
19
+ {
20
  const MATCH_PROPERTY_SCSS = '/^([^\s=:"(\\\\:)]*)\s*(?:(= )|:)([^\:].*?)?(\s*!important.*)?$/';
21
  const MATCH_PROPERTY_NEW = '/^([^\s=:"]+)\s*(?:(= )|:)([^\:].*?)?(\s*!important.*)?$/';
22
  const MATCH_PROPERTY_OLD = '/^:([^\s=:]+)(?:\s*(=)\s*|\s+|$)(.*)(\s*!important.*)?/';
73
  */
74
  public $value;
75
 
 
76
  /**
77
  * @var boolean, wether the property is important
78
  */
84
  * @param string property syntax
85
  * @return SassPropertyNode
86
  */
87
+ public function __construct($token, $syntax = 'new')
88
+ {
89
  parent::__construct($token);
90
  $matches = self::match($token, $syntax);
91
  $this->name = @$matches[self::NAME];
92
  if (!isset($matches[self::VALUE])) {
93
  $this->value = '';
94
+ } else {
 
95
  $this->value = $matches[self::VALUE];
96
  if ($matches[self::SCRIPT] === self::IS_SCRIPT) {
97
  $this->addWarning('Setting CSS properties with "=" is deprecated; use "{name}: {value};"',
109
  * @param SassContext the context in which this node is parsed
110
  * @return array the parsed node
111
  */
112
+ public function parse($context)
113
+ {
114
  $return = array();
115
  if ($this->value !== "") {
116
  $node = clone $this;
124
  if ($this->children) {
125
  $return = array_merge($return, $this->parseChildren($context));
126
  }
127
+
128
  return $return;
129
  }
130
 
132
  * Render this node.
133
  * @return string the rendered node
134
  */
135
+ public function render()
136
+ {
137
  return $this->renderer->renderProperty($this);
138
  }
139
 
141
  * Returns a value indicating if this node is in a namespace
142
  * @return boolean true if this node is in a property namespace, false if not
143
  */
144
+ public function inNamespace()
145
+ {
146
  $parent = $this->parent;
147
  do {
148
  if ($parent instanceof SassPropertyNode) {
150
  }
151
  $parent = $parent->parent;
152
  } while (is_object($parent));
153
+
154
  return false;
155
  }
156
 
158
  * Returns the namespace for this node
159
  * @return string the namespace for this node
160
  */
161
+ public function getNamespace()
162
+ {
163
  $namespace = array();
164
  $parent = $this->parent;
165
  do {
168
  }
169
  $parent = $parent->parent;
170
  } while (is_object($parent));
171
+
172
  return join('-', array_reverse($namespace));
173
  }
174
 
177
  * If the property is in a namespace the namespace is prepended
178
  * @return string the name of this property
179
  */
180
+ public function getName()
181
+ {
182
  return $this->name;
183
  }
184
 
186
  * Returns the parsed value of this property.
187
  * @return string the parsed value of this property
188
  */
189
+ public function getValue()
190
+ {
191
  return $this->value;
192
  }
193
 
197
  * @param string the property syntax being used
198
  * @return boolean true if the token represents this type of node, false if not
199
  */
200
+ public static function isa($token)
201
+ {
202
+ if (!is_array($token)) {
203
  $syntax = 'old';
204
+ } else {
 
205
  $syntax = $token['syntax'];
206
  $token = $token['token'];
207
  }
215
  if ($token->level === 0) {
216
  # RL - if it's on the first level it's probably a false positive, not an error.
217
  # even if it is a genuine error, no need to kill the compiler about it.
218
+
219
  return false;
220
  // throw new SassPropertyNodeException('Properties can not be assigned at root level', $token);
221
+ } else {
 
222
  return true;
223
  }
224
+ } else {
 
225
  return false;
226
  }
227
  }
232
  * @param string the property syntax being used
233
  * @return array matches
234
  */
235
+ public static function match($token, $syntax)
236
+ {
237
  switch ($syntax) {
238
  case 'scss':
239
  preg_match(self::MATCH_PROPERTY_SCSS, $token->source, $matches);
250
  }
251
  break;
252
  }
253
+
254
  return $matches;
255
  }
256
 
265
  * @param string the string to test
266
  * @return bool true if the string starts with a pseudo selector, false if not
267
  */
268
+ public static function isPseudoSelector($string)
269
+ {
270
  preg_match(self::MATCH_PSUEDO_SELECTOR, $string, $matches);
271
+
272
  return (isset($matches[0]) && in_array($matches[0], self::$psuedoSelectors)) ||
273
  preg_match(self::MATCH_INTERPOLATION, $string) ||
274
  preg_match(self::MATCH_PROPRIETARY_SELECTOR, $string);
lib/phpsass/tree/SassReturnNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassReturnNode extends SassNode {
 
19
  const NODE_IDENTIFIER = '+';
20
  const MATCH = '/^(@return\s+)(.*)$/i';
21
  const IDENTIFIER = 1;
@@ -31,10 +32,11 @@ class SassReturnNode extends SassNode {
31
  * @param object source token
32
  * @return SassReturnNode
33
  */
34
- public function __construct($token) {
 
35
  parent::__construct($token);
36
  preg_match(self::MATCH, $token->source, $matches);
37
-
38
  if (empty($matches)) {
39
  return new SassBoolean('false');
40
  }
@@ -49,7 +51,8 @@ class SassReturnNode extends SassNode {
49
  * @param SassContext the context in which this node is parsed
50
  * @return array the parsed node
51
  */
52
- public function parse($pcontext) {
 
53
  $return = $this;
54
  $context = new SassContext($pcontext);
55
  $statement = $this->statement;
@@ -59,7 +62,7 @@ class SassReturnNode extends SassNode {
59
  $lexer = $script->lexer;
60
 
61
  $result = $script->evaluate($statement, $context);
62
-
63
  throw new SassReturn($result);
64
  }
65
 
@@ -68,13 +71,16 @@ class SassReturnNode extends SassNode {
68
  * @param object token
69
  * @return boolean true if the token represents this type of node, false if not
70
  */
71
- public static function isa($token) {
 
72
  return $token->source[0] === self::NODE_IDENTIFIER;
73
  }
74
  }
75
 
76
- class SassReturn extends Exception {
77
- function __construct($value) {
 
 
78
  $this->value = $value;
79
  }
80
- }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassReturnNode extends SassNode
19
+ {
20
  const NODE_IDENTIFIER = '+';
21
  const MATCH = '/^(@return\s+)(.*)$/i';
22
  const IDENTIFIER = 1;
32
  * @param object source token
33
  * @return SassReturnNode
34
  */
35
+ public function __construct($token)
36
+ {
37
  parent::__construct($token);
38
  preg_match(self::MATCH, $token->source, $matches);
39
+
40
  if (empty($matches)) {
41
  return new SassBoolean('false');
42
  }
51
  * @param SassContext the context in which this node is parsed
52
  * @return array the parsed node
53
  */
54
+ public function parse($pcontext)
55
+ {
56
  $return = $this;
57
  $context = new SassContext($pcontext);
58
  $statement = $this->statement;
62
  $lexer = $script->lexer;
63
 
64
  $result = $script->evaluate($statement, $context);
65
+
66
  throw new SassReturn($result);
67
  }
68
 
71
  * @param object token
72
  * @return boolean true if the token represents this type of node, false if not
73
  */
74
+ public static function isa($token)
75
+ {
76
  return $token->source[0] === self::NODE_IDENTIFIER;
77
  }
78
  }
79
 
80
+ class SassReturn extends Exception
81
+ {
82
+ public function __construct($value)
83
+ {
84
  $this->value = $value;
85
  }
86
+ }
lib/phpsass/tree/SassRootNode.php CHANGED
@@ -18,7 +18,8 @@ require_once(dirname(__FILE__).'/../renderers/SassRenderer.php');
18
  * @package PHamlP
19
  * @subpackage Sass.tree
20
  */
21
- class SassRootNode extends SassNode {
 
22
  /**
23
  * @var SassScriptParser SassScript parser
24
  */
@@ -46,7 +47,8 @@ class SassRootNode extends SassNode {
46
  * @param SassParser Sass parser
47
  * @return SassNode
48
  */
49
- public function __construct($parser) {
 
50
  parent::__construct((object) array(
51
  'source' => '',
52
  'level' => -1,
@@ -66,9 +68,11 @@ class SassRootNode extends SassNode {
66
  * @param SassContext the context in which this node is parsed
67
  * @return SassNode root node of the render tree
68
  */
69
- public function parse($context) {
 
70
  $node = clone $this;
71
  $node->children = $this->parseChildren($context);
 
72
  return $node;
73
  }
74
 
@@ -76,17 +80,20 @@ class SassRootNode extends SassNode {
76
  * Render this node.
77
  * @return string the rendered node
78
  */
79
- public function render($context = null) {
 
80
  $context = new SassContext($context);
81
  $node = $this->parse($context);
82
  $output = '';
83
  foreach ($node->children as $child) {
84
  $output .= $child->render();
85
  } // foreach
 
86
  return $output;
87
  }
88
 
89
- public function extend($extendee, $selectors) {
 
90
  if ($this->extend_parent && method_exists($this->extend_parent, 'extend')) {
91
  return $this->extend_parent->extend($extendee, $selectors);
92
  }
@@ -94,10 +101,12 @@ class SassRootNode extends SassNode {
94
  ? array_merge($this->extenders[$extendee], $selectors) : $selectors);
95
  }
96
 
97
- public function getExtenders() {
 
98
  if ($this->extend_parent && method_exists($this->extend_parent, 'getExtenders')) {
99
  return $this->extend_parent->getExtenders();
100
  }
 
101
  return $this->extenders;
102
  }
103
 
@@ -106,7 +115,8 @@ class SassRootNode extends SassNode {
106
  * Child classes must override this method.
107
  * @throws SassNodeException if not overriden
108
  */
109
- public static function isa($line) {
 
110
  throw new SassNodeException('Child classes must override this method');
111
  }
112
  }
18
  * @package PHamlP
19
  * @subpackage Sass.tree
20
  */
21
+ class SassRootNode extends SassNode
22
+ {
23
  /**
24
  * @var SassScriptParser SassScript parser
25
  */
47
  * @param SassParser Sass parser
48
  * @return SassNode
49
  */
50
+ public function __construct($parser)
51
+ {
52
  parent::__construct((object) array(
53
  'source' => '',
54
  'level' => -1,
68
  * @param SassContext the context in which this node is parsed
69
  * @return SassNode root node of the render tree
70
  */
71
+ public function parse($context)
72
+ {
73
  $node = clone $this;
74
  $node->children = $this->parseChildren($context);
75
+
76
  return $node;
77
  }
78
 
80
  * Render this node.
81
  * @return string the rendered node
82
  */
83
+ public function render($context = null)
84
+ {
85
  $context = new SassContext($context);
86
  $node = $this->parse($context);
87
  $output = '';
88
  foreach ($node->children as $child) {
89
  $output .= $child->render();
90
  } // foreach
91
+
92
  return $output;
93
  }
94
 
95
+ public function extend($extendee, $selectors)
96
+ {
97
  if ($this->extend_parent && method_exists($this->extend_parent, 'extend')) {
98
  return $this->extend_parent->extend($extendee, $selectors);
99
  }
101
  ? array_merge($this->extenders[$extendee], $selectors) : $selectors);
102
  }
103
 
104
+ public function getExtenders()
105
+ {
106
  if ($this->extend_parent && method_exists($this->extend_parent, 'getExtenders')) {
107
  return $this->extend_parent->getExtenders();
108
  }
109
+
110
  return $this->extenders;
111
  }
112
 
115
  * Child classes must override this method.
116
  * @throws SassNodeException if not overriden
117
  */
118
+ public static function isa($line)
119
+ {
120
  throw new SassNodeException('Child classes must override this method');
121
  }
122
  }
lib/phpsass/tree/SassRuleNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassRuleNode extends SassNode {
 
19
  const MATCH = '/^(.+?)(?:\s*\{)?$/';
20
  const SELECTOR = 1;
21
  const CONTINUED = ',';
@@ -51,7 +52,8 @@ class SassRuleNode extends SassNode {
51
  * @param string rule selector
52
  * @return SassRuleNode
53
  */
54
- public function __construct($token) {
 
55
  parent::__construct($token);
56
  preg_match(self::MATCH, $token->source, $matches);
57
  $this->addSelectors($matches[SassRuleNode::SELECTOR]);
@@ -62,7 +64,8 @@ class SassRuleNode extends SassNode {
62
  * If the selectors are to continue for the rule the selector must end in a comma
63
  * @param string selector
64
  */
65
- public function addSelectors($selectors, $explode = true) {
 
66
  $this->isContinued = substr($selectors, -1) === self::CONTINUED;
67
  $this->selectors = array_merge($this->selectors, $explode ? $this->explode($selectors) : $selectors);
68
  }
@@ -72,7 +75,8 @@ class SassRuleNode extends SassNode {
72
  * @param boolean true if the selectors for this rule are to be continued,
73
  * false if not
74
  */
75
- public function getIsContinued() {
 
76
  return $this->isContinued;
77
  }
78
 
@@ -81,10 +85,12 @@ class SassRuleNode extends SassNode {
81
  * @param SassContext the context in which this node is parsed
82
  * @return array the parsed node and its children
83
  */
84
- public function parse($context) {
 
85
  $node = clone $this;
86
  $node->selectors = $this->resolveSelectors($context);
87
  $node->children = $this->parseChildren($context);
 
88
  return array($node);
89
  }
90
 
@@ -92,7 +98,8 @@ class SassRuleNode extends SassNode {
92
  * Render this node and its children to CSS.
93
  * @return string the rendered node
94
  */
95
- public function render() {
 
96
  $this->extend();
97
  $rules = '';
98
  $properties = array();
@@ -101,8 +108,7 @@ class SassRuleNode extends SassNode {
101
  $child->parent = $this;
102
  if ($child instanceof SassRuleNode) {
103
  $rules .= $child->render();
104
- }
105
- else {
106
  $properties[] = $child->render();
107
  }
108
  }
@@ -116,13 +122,13 @@ class SassRuleNode extends SassNode {
116
  * $extender is the selector that contains the @extend directive
117
  * $selector a selector or selector sequence that is to be extended
118
  */
119
- public function extend() {
 
120
  foreach ($this->root->getExtenders() as $extendee => $extenders) {
121
  if ($this->isPsuedo($extendee)) {
122
  $extendee = explode(':', $extendee);
123
  $pattern = preg_quote($extendee[0]).'((\.[-\w]+)*):'.preg_quote($extendee[1]);
124
- }
125
- else {
126
  $pattern = preg_quote($extendee);
127
  }
128
 
@@ -138,11 +144,9 @@ class SassRuleNode extends SassNode {
138
  }
139
  if (is_array($extendee)) {
140
  $this->selectors[] = preg_replace('/(.*?)'.$pattern.'([^a-zA-Z0-9_-]|$)/', '$1' . $extender . '$2', $selector);
141
- }
142
- elseif ($this->isSequence($extender) || $this->isSequence($selector)) {
143
  $this->selectors = array_merge($this->selectors, $this->mergeSequence($extender, $extendee, $selector));
144
- }
145
- else {
146
  $this->selectors[] = str_replace($extendee, $extender, $selector);
147
  }
148
  }
@@ -156,7 +160,8 @@ class SassRuleNode extends SassNode {
156
  * @param string selector to test
157
  * @return boolean true if the selector is a psuedo selector, false if not
158
  */
159
- private function isPsuedo($selector) {
 
160
  return strpos($selector, ':') !== false;
161
  }
162
 
@@ -165,11 +170,13 @@ class SassRuleNode extends SassNode {
165
  * @param string selector to test
166
  * @return boolean true if the selector is a sequence selector, false if not
167
  */
168
- private function isSequence($selector) {
 
169
  return strpos($selector, ' ') !== false;
170
  }
171
 
172
- public function isPlaceholder($selector) {
 
173
  return strpos($selector, '%') !== false;
174
  }
175
 
@@ -179,7 +186,8 @@ class SassRuleNode extends SassNode {
179
  * @param string selector to extend
180
  * @return array the merged sequences
181
  */
182
- private function mergeSequence($extender, $extendee, $selector) {
 
183
  // if it's a placeholder, be lazy. Needs tests.
184
  if ($extendee[0] == '%') {
185
  // need to stop things like a%foo accepting div { @extend %foo }
@@ -193,7 +201,7 @@ class SassRuleNode extends SassNode {
193
 
194
  $common = array();
195
  if (count($extender) && count($selector)) {
196
- while(trim($extender[0]) === trim($selector[0])) {
197
  $common[] = array_shift($selector);
198
  array_shift($extender);
199
  if (!count($extender)) {
@@ -207,6 +215,7 @@ class SassRuleNode extends SassNode {
207
  # Richard Lyon - 2011-10-25 - removes duplicates by uniquing and trimming.
208
  # regex removes whitespace from start and and end of string as well as removing
209
  # whitespace following whitespace. slightly quicker than a trim and simpler replace
 
210
  return array_unique(array(
211
  preg_replace('/(^\s+|(\s)\s+|\s+$)/', '$2', $beginning.join(' ', $selector).' '.join(' ', $extender). ' ' . $end),
212
  preg_replace('/(^\s+|(\s)\s+|\s+$)/', '$2', $beginning.join(' ', $extender).' '.join(' ', $selector). ' ' . $end)
@@ -217,7 +226,8 @@ class SassRuleNode extends SassNode {
217
  * Returns the selectors
218
  * @return array selectors
219
  */
220
- public function getSelectors() {
 
221
  return $this->selectors;
222
  }
223
 
@@ -229,7 +239,8 @@ class SassRuleNode extends SassNode {
229
  *
230
  * Change: 7/Dec/11 - change to make selector ordering conform to Ruby compiler.
231
  */
232
- public function resolveSelectors($context) {
 
233
  $resolvedSelectors = $normalSelectors = array();
234
  $this->parentSelectors = $this->getParentSelectors($context);
235
 
@@ -241,8 +252,7 @@ class SassRuleNode extends SassNode {
241
  $selector = trim($selector, ' \'"'); // strip whitespace and quotes, just-in-case.
242
  if ($this->hasParentReference($selector)) {
243
  $resolvedSelectors = array_merge($resolvedSelectors, $this->resolveParentReferences($selector, $context));
244
- }
245
- else {
246
  $normalSelectors[] = $selector;
247
  }
248
  }
@@ -269,7 +279,8 @@ class SassRuleNode extends SassNode {
269
  * This in an empty array if there is no parent selector.
270
  * @return array the parent selector for this node
271
  */
272
- protected function getParentSelectors($context) {
 
273
  $ancestor = $this->parent;
274
  while (!$ancestor instanceof SassRuleNode && $ancestor->hasParent()) {
275
  $ancestor = $ancestor->parent;
@@ -278,6 +289,7 @@ class SassRuleNode extends SassNode {
278
  if ($ancestor instanceof SassRuleNode) {
279
  return $ancestor->resolveSelectors($context);
280
  }
 
281
  return array();
282
  }
283
 
@@ -291,20 +303,20 @@ class SassRuleNode extends SassNode {
291
  * @return mixed integer: position of the the first parent reference,
292
  * boolean: false if there is no parent reference.
293
  */
294
- private function parentReferencePos($selector) {
 
295
  $inString = '';
296
  for ($i = 0, $l = strlen($selector); $i < $l; $i++) {
297
  $c = $selector[$i];
298
  if ($c === self::PARENT_REFERENCE && empty($inString)) {
299
  return $i;
300
- }
301
- elseif (empty($inString) && ($c === '"' || $c === "'")) {
302
  $inString = $c;
303
- }
304
- elseif ($c === $inString) {
305
  $inString = '';
306
  }
307
  }
 
308
  return false;
309
  }
310
 
@@ -313,7 +325,8 @@ class SassRuleNode extends SassNode {
313
  * @param string selector
314
  * @return boolean true if there is a parent reference in the selector
315
  */
316
- private function hasParentReference($selector) {
 
317
  return $this->parentReferencePos($selector) !== false;
318
  }
319
 
@@ -322,7 +335,8 @@ class SassRuleNode extends SassNode {
322
  * @param string selector
323
  * @return string selector with parent references resolved
324
  */
325
- private function resolveParentReferences($selector, $context) {
 
326
  $resolvedReferences = array();
327
  if (!count($this->parentSelectors)) {
328
  throw new SassRuleNodeException('Can not use parent selector (' . self::PARENT_REFERENCE . ') when no parent selectors', $this);
@@ -330,6 +344,7 @@ class SassRuleNode extends SassNode {
330
  foreach ($this->getParentSelectors($context) as $parentSelector) {
331
  $resolvedReferences[] = str_replace(self::PARENT_REFERENCE, $parentSelector, $selector);
332
  }
 
333
  return $resolvedReferences;
334
  }
335
 
@@ -340,7 +355,8 @@ class SassRuleNode extends SassNode {
340
  * @param string selectors
341
  * @return array selectors
342
  */
343
- private function explode($string) {
 
344
  $selectors = array();
345
  $inString = false;
346
  $interpolate = false;
@@ -351,16 +367,14 @@ class SassRuleNode extends SassNode {
351
  if ($c === self::CONTINUED && !$inString && !$interpolate) {
352
  $selectors[] = trim($selector);
353
  $selector = '';
354
- }
355
- else {
356
  $selector .= $c;
357
  if ($c === '"' || $c === "'") {
358
  do {
359
  $_c = $string[++$i];
360
  $selector .= $_c;
361
  } while ($_c !== $c && isset($string[$i+1]));
362
- }
363
- elseif ($c === '#' && $string[$i+1] === '{') {
364
  do {
365
  $c = $string[++$i];
366
  $selector .= $c;
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassRuleNode extends SassNode
19
+ {
20
  const MATCH = '/^(.+?)(?:\s*\{)?$/';
21
  const SELECTOR = 1;
22
  const CONTINUED = ',';
52
  * @param string rule selector
53
  * @return SassRuleNode
54
  */
55
+ public function __construct($token)
56
+ {
57
  parent::__construct($token);
58
  preg_match(self::MATCH, $token->source, $matches);
59
  $this->addSelectors($matches[SassRuleNode::SELECTOR]);
64
  * If the selectors are to continue for the rule the selector must end in a comma
65
  * @param string selector
66
  */
67
+ public function addSelectors($selectors, $explode = true)
68
+ {
69
  $this->isContinued = substr($selectors, -1) === self::CONTINUED;
70
  $this->selectors = array_merge($this->selectors, $explode ? $this->explode($selectors) : $selectors);
71
  }
75
  * @param boolean true if the selectors for this rule are to be continued,
76
  * false if not
77
  */
78
+ public function getIsContinued()
79
+ {
80
  return $this->isContinued;
81
  }
82
 
85
  * @param SassContext the context in which this node is parsed
86
  * @return array the parsed node and its children
87
  */
88
+ public function parse($context)
89
+ {
90
  $node = clone $this;
91
  $node->selectors = $this->resolveSelectors($context);
92
  $node->children = $this->parseChildren($context);
93
+
94
  return array($node);
95
  }
96
 
98
  * Render this node and its children to CSS.
99
  * @return string the rendered node
100
  */
101
+ public function render()
102
+ {
103
  $this->extend();
104
  $rules = '';
105
  $properties = array();
108
  $child->parent = $this;
109
  if ($child instanceof SassRuleNode) {
110
  $rules .= $child->render();
111
+ } else {
 
112
  $properties[] = $child->render();
113
  }
114
  }
122
  * $extender is the selector that contains the @extend directive
123
  * $selector a selector or selector sequence that is to be extended
124
  */
125
+ public function extend()
126
+ {
127
  foreach ($this->root->getExtenders() as $extendee => $extenders) {
128
  if ($this->isPsuedo($extendee)) {
129
  $extendee = explode(':', $extendee);
130
  $pattern = preg_quote($extendee[0]).'((\.[-\w]+)*):'.preg_quote($extendee[1]);
131
+ } else {
 
132
  $pattern = preg_quote($extendee);
133
  }
134
 
144
  }
145
  if (is_array($extendee)) {
146
  $this->selectors[] = preg_replace('/(.*?)'.$pattern.'([^a-zA-Z0-9_-]|$)/', '$1' . $extender . '$2', $selector);
147
+ } elseif ($this->isSequence($extender) || $this->isSequence($selector)) {
 
148
  $this->selectors = array_merge($this->selectors, $this->mergeSequence($extender, $extendee, $selector));
149
+ } else {
 
150
  $this->selectors[] = str_replace($extendee, $extender, $selector);
151
  }
152
  }
160
  * @param string selector to test
161
  * @return boolean true if the selector is a psuedo selector, false if not
162
  */
163
+ private function isPsuedo($selector)
164
+ {
165
  return strpos($selector, ':') !== false;
166
  }
167
 
170
  * @param string selector to test
171
  * @return boolean true if the selector is a sequence selector, false if not
172
  */
173
+ private function isSequence($selector)
174
+ {
175
  return strpos($selector, ' ') !== false;
176
  }
177
 
178
+ public function isPlaceholder($selector)
179
+ {
180
  return strpos($selector, '%') !== false;
181
  }
182
 
186
  * @param string selector to extend
187
  * @return array the merged sequences
188
  */
189
+ private function mergeSequence($extender, $extendee, $selector)
190
+ {
191
  // if it's a placeholder, be lazy. Needs tests.
192
  if ($extendee[0] == '%') {
193
  // need to stop things like a%foo accepting div { @extend %foo }
201
 
202
  $common = array();
203
  if (count($extender) && count($selector)) {
204
+ while (trim($extender[0]) === trim($selector[0])) {
205
  $common[] = array_shift($selector);
206
  array_shift($extender);
207
  if (!count($extender)) {
215
  # Richard Lyon - 2011-10-25 - removes duplicates by uniquing and trimming.
216
  # regex removes whitespace from start and and end of string as well as removing
217
  # whitespace following whitespace. slightly quicker than a trim and simpler replace
218
+
219
  return array_unique(array(
220
  preg_replace('/(^\s+|(\s)\s+|\s+$)/', '$2', $beginning.join(' ', $selector).' '.join(' ', $extender). ' ' . $end),
221
  preg_replace('/(^\s+|(\s)\s+|\s+$)/', '$2', $beginning.join(' ', $extender).' '.join(' ', $selector). ' ' . $end)
226
  * Returns the selectors
227
  * @return array selectors
228
  */
229
+ public function getSelectors()
230
+ {
231
  return $this->selectors;
232
  }
233
 
239
  *
240
  * Change: 7/Dec/11 - change to make selector ordering conform to Ruby compiler.
241
  */
242
+ public function resolveSelectors($context)
243
+ {
244
  $resolvedSelectors = $normalSelectors = array();
245
  $this->parentSelectors = $this->getParentSelectors($context);
246
 
252
  $selector = trim($selector, ' \'"'); // strip whitespace and quotes, just-in-case.
253
  if ($this->hasParentReference($selector)) {
254
  $resolvedSelectors = array_merge($resolvedSelectors, $this->resolveParentReferences($selector, $context));
255
+ } else {
 
256
  $normalSelectors[] = $selector;
257
  }
258
  }
279
  * This in an empty array if there is no parent selector.
280
  * @return array the parent selector for this node
281
  */
282
+ protected function getParentSelectors($context)
283
+ {
284
  $ancestor = $this->parent;
285
  while (!$ancestor instanceof SassRuleNode && $ancestor->hasParent()) {
286
  $ancestor = $ancestor->parent;
289
  if ($ancestor instanceof SassRuleNode) {
290
  return $ancestor->resolveSelectors($context);
291
  }
292
+
293
  return array();
294
  }
295
 
303
  * @return mixed integer: position of the the first parent reference,
304
  * boolean: false if there is no parent reference.
305
  */
306
+ private function parentReferencePos($selector)
307
+ {
308
  $inString = '';
309
  for ($i = 0, $l = strlen($selector); $i < $l; $i++) {
310
  $c = $selector[$i];
311
  if ($c === self::PARENT_REFERENCE && empty($inString)) {
312
  return $i;
313
+ } elseif (empty($inString) && ($c === '"' || $c === "'")) {
 
314
  $inString = $c;
315
+ } elseif ($c === $inString) {
 
316
  $inString = '';
317
  }
318
  }
319
+
320
  return false;
321
  }
322
 
325
  * @param string selector
326
  * @return boolean true if there is a parent reference in the selector
327
  */
328
+ private function hasParentReference($selector)
329
+ {
330
  return $this->parentReferencePos($selector) !== false;
331
  }
332
 
335
  * @param string selector
336
  * @return string selector with parent references resolved
337
  */
338
+ private function resolveParentReferences($selector, $context)
339
+ {
340
  $resolvedReferences = array();
341
  if (!count($this->parentSelectors)) {
342
  throw new SassRuleNodeException('Can not use parent selector (' . self::PARENT_REFERENCE . ') when no parent selectors', $this);
344
  foreach ($this->getParentSelectors($context) as $parentSelector) {
345
  $resolvedReferences[] = str_replace(self::PARENT_REFERENCE, $parentSelector, $selector);
346
  }
347
+
348
  return $resolvedReferences;
349
  }
350
 
355
  * @param string selectors
356
  * @return array selectors
357
  */
358
+ private function explode($string)
359
+ {
360
  $selectors = array();
361
  $inString = false;
362
  $interpolate = false;
367
  if ($c === self::CONTINUED && !$inString && !$interpolate) {
368
  $selectors[] = trim($selector);
369
  $selector = '';
370
+ } else {
 
371
  $selector .= $c;
372
  if ($c === '"' || $c === "'") {
373
  do {
374
  $_c = $string[++$i];
375
  $selector .= $_c;
376
  } while ($_c !== $c && isset($string[$i+1]));
377
+ } elseif ($c === '#' && $string[$i+1] === '{') {
 
378
  do {
379
  $c = $string[++$i];
380
  $selector .= $c;
lib/phpsass/tree/SassVariableNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassVariableNode extends SassNode {
 
19
  const MATCH = '/^([!$])([\w-]+)\s*:?\s*((\|\|)?=)?\s*(.+?)\s*(!default)?;?$/i';
20
  const IDENTIFIER = 1;
21
  const NAME = 2;
@@ -44,7 +45,8 @@ class SassVariableNode extends SassNode {
44
  * @param object source token
45
  * @return SassVariableNode
46
  */
47
- public function __construct($token) {
 
48
  parent::__construct($token);
49
  preg_match(self::MATCH, $token->source, $matches);
50
  if (empty($matches[self::NAME]) || ($matches[self::VALUE] === '')) {
@@ -70,13 +72,15 @@ class SassVariableNode extends SassNode {
70
  * @param SassContext the context in which this node is parsed
71
  * @return array the parsed node - an empty array
72
  */
73
- public function parse($context) {
 
74
  if (!$this->isDefault || !$context->hasVariable($this->name)) {
75
  $context->setVariable(
76
  $this->name, $this->evaluate($this->value, $context)
77
  );
78
  }
79
  $this->parseChildren($context); // Parse any warnings
 
80
  return array();
81
  }
82
 
@@ -85,7 +89,8 @@ class SassVariableNode extends SassNode {
85
  * @param object token
86
  * @return boolean true if the token represents this type of node, false if not
87
  */
88
- public static function isa($token) {
 
89
  return $token->source[0] === self::SASS_IDENTIFIER || $token->source[0] === self::SCSS_IDENTIFIER;
90
  }
91
- }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassVariableNode extends SassNode
19
+ {
20
  const MATCH = '/^([!$])([\w-]+)\s*:?\s*((\|\|)?=)?\s*(.+?)\s*(!default)?;?$/i';
21
  const IDENTIFIER = 1;
22
  const NAME = 2;
45
  * @param object source token
46
  * @return SassVariableNode
47
  */
48
+ public function __construct($token)
49
+ {
50
  parent::__construct($token);
51
  preg_match(self::MATCH, $token->source, $matches);
52
  if (empty($matches[self::NAME]) || ($matches[self::VALUE] === '')) {
72
  * @param SassContext the context in which this node is parsed
73
  * @return array the parsed node - an empty array
74
  */
75
+ public function parse($context)
76
+ {
77
  if (!$this->isDefault || !$context->hasVariable($this->name)) {
78
  $context->setVariable(
79
  $this->name, $this->evaluate($this->value, $context)
80
  );
81
  }
82
  $this->parseChildren($context); // Parse any warnings
83
+
84
  return array();
85
  }
86
 
89
  * @param object token
90
  * @return boolean true if the token represents this type of node, false if not
91
  */
92
+ public static function isa($token)
93
+ {
94
  return $token->source[0] === self::SASS_IDENTIFIER || $token->source[0] === self::SCSS_IDENTIFIER;
95
  }
96
+ }
lib/phpsass/tree/SassWarnNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassWarnNode extends SassNode {
 
19
  const NODE_IDENTIFIER = '+';
20
  const MATCH = '/^(@warn\s+)(["\']?)(.*?)(["\']?)$/i';
21
  const IDENTIFIER = 1;
@@ -31,7 +32,8 @@ class SassWarnNode extends SassNode {
31
  * @param object source token
32
  * @return SassReturnNode
33
  */
34
- public function __construct($token) {
 
35
  parent::__construct($token);
36
  preg_match(self::MATCH, $token->source, $matches);
37
 
@@ -49,14 +51,14 @@ class SassWarnNode extends SassNode {
49
  * @param SassContext the context in which this node is parsed
50
  * @return array the parsed node
51
  */
52
- public function parse($pcontext) {
 
53
  $context = new SassContext($pcontext);
54
  $statement = $this->statement;
55
 
56
  try {
57
  $statement = $this->evaluate($this->statement, $context)->toString();
58
- }
59
- catch (Exception $e) {}
60
 
61
  if (SassParser::$instance->options['callbacks']['warn']) {
62
  call_user_func(SassParser::$instance->options['callbacks']['warn'], $statement, $context);
@@ -64,8 +66,7 @@ class SassWarnNode extends SassNode {
64
 
65
  if (SassParser::$instance->getQuiet()) {
66
  return array(new SassString(''));
67
- }
68
- else {
69
  return array(new SassString('/* @warn: ' . str_replace('*/', '', $statement) . ' */'));
70
  }
71
  }
@@ -75,7 +76,8 @@ class SassWarnNode extends SassNode {
75
  * @param object token
76
  * @return boolean true if the token represents this type of node, false if not
77
  */
78
- public static function isa($token) {
 
79
  return $token->source[0] === self::NODE_IDENTIFIER;
80
  }
81
  }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassWarnNode extends SassNode
19
+ {
20
  const NODE_IDENTIFIER = '+';
21
  const MATCH = '/^(@warn\s+)(["\']?)(.*?)(["\']?)$/i';
22
  const IDENTIFIER = 1;
32
  * @param object source token
33
  * @return SassReturnNode
34
  */
35
+ public function __construct($token)
36
+ {
37
  parent::__construct($token);
38
  preg_match(self::MATCH, $token->source, $matches);
39
 
51
  * @param SassContext the context in which this node is parsed
52
  * @return array the parsed node
53
  */
54
+ public function parse($pcontext)
55
+ {
56
  $context = new SassContext($pcontext);
57
  $statement = $this->statement;
58
 
59
  try {
60
  $statement = $this->evaluate($this->statement, $context)->toString();
61
+ } catch (Exception $e) {}
 
62
 
63
  if (SassParser::$instance->options['callbacks']['warn']) {
64
  call_user_func(SassParser::$instance->options['callbacks']['warn'], $statement, $context);
66
 
67
  if (SassParser::$instance->getQuiet()) {
68
  return array(new SassString(''));
69
+ } else {
 
70
  return array(new SassString('/* @warn: ' . str_replace('*/', '', $statement) . ' */'));
71
  }
72
  }
76
  * @param object token
77
  * @return boolean true if the token represents this type of node, false if not
78
  */
79
+ public static function isa($token)
80
+ {
81
  return $token->source[0] === self::NODE_IDENTIFIER;
82
  }
83
  }
lib/phpsass/tree/SassWhileNode.php CHANGED
@@ -15,7 +15,8 @@
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
- class SassWhileNode extends SassNode {
 
19
  const MATCH = '/^@(do|while)\s+(.+)$/i';
20
  const LOOP = 1;
21
  const EXPRESSION = 2;
@@ -35,7 +36,8 @@ class SassWhileNode extends SassNode {
35
  * @param object source token
36
  * @return SassWhileNode
37
  */
38
- public function __construct($token) {
 
39
  parent::__construct($token);
40
  preg_match(self::MATCH, $token->source, $matches);
41
  $this->expression = $matches[self::EXPRESSION];
@@ -47,18 +49,19 @@ class SassWhileNode extends SassNode {
47
  * @param SassContext the context in which this node is parsed
48
  * @return array the parsed child nodes
49
  */
50
- public function parse($context) {
 
51
  $children = array();
52
  if ($this->isDo) {
53
  do {
54
  $children = array_merge($children, $this->parseChildren($context));
55
  } while ($this->evaluate($this->expression, $context)->toBoolean());
56
- }
57
- else {
58
  while ($this->evaluate($this->expression, $context)->toBoolean()) {
59
  $children = array_merge($children, $this->parseChildren($context));
60
  }
61
  }
 
62
  return $children;
63
  }
64
- }
15
  * @package PHamlP
16
  * @subpackage Sass.tree
17
  */
18
+ class SassWhileNode extends SassNode
19
+ {
20
  const MATCH = '/^@(do|while)\s+(.+)$/i';
21
  const LOOP = 1;
22
  const EXPRESSION = 2;
36
  * @param object source token
37
  * @return SassWhileNode
38
  */
39
+ public function __construct($token)
40
+ {
41
  parent::__construct($token);
42
  preg_match(self::MATCH, $token->source, $matches);
43
  $this->expression = $matches[self::EXPRESSION];
49
  * @param SassContext the context in which this node is parsed
50
  * @return array the parsed child nodes
51
  */
52
+ public function parse($context)
53
+ {
54
  $children = array();
55
  if ($this->isDo) {
56
  do {
57
  $children = array_merge($children, $this->parseChildren($context));
58
  } while ($this->evaluate($this->expression, $context)->toBoolean());
59
+ } else {
 
60
  while ($this->evaluate($this->expression, $context)->toBoolean()) {
61
  $children = array_merge($children, $this->parseChildren($context));
62
  }
63
  }
64
+
65
  return $children;
66
  }
67
+ }
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Sass</name>
4
- <version>1.1.3</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL 3.0)</license>
7
  <channel>community</channel>
@@ -12,11 +12,12 @@
12
  You just need to create you sass file and add it to your layout like default css file.&#xD;
13
  &#xD;
14
  This extension will then convert it to css file using phpSass or sass in command line if available</description>
15
- <notes>phpsass library updated.</notes>
 
16
  <authors><author><name>Laurent Clouet</name><user>laurent35240</user><email>laurent35240@gmail.com</email></author></authors>
17
- <date>2013-06-08</date>
18
- <time>16:32:41</time>
19
- <contents><target name="magecommunity"><dir name="Laurent"><dir name="Sass"><dir name="Helper"><file name="Data.php" hash="9c43132dba73d4b3f37ccfb91f0d5dbe"/></dir><dir name="Model"><dir name="Config"><file name="Style.php" hash="413571124dcf58d950200499a144420d"/></dir><dir name="Design"><file name="Package.php" hash="3c83af4c43fd94359541b7242852ca06"/></dir></dir><dir name="etc"><file name="config.xml" hash="1e99b16cb4ca540ae8cd207825f9a269"/><file name="system.xml" hash="a2db1af0d9bae017b46805a80aedb442"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Laurent_Sass.xml" hash="4ad004de851457681610553228973c30"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Laurent_Sass.csv" hash="d9e8c184cbe72e810c7da9154581e1e4"/></dir><dir name="fr_FR"><file name="Laurent_Sass.csv" hash="676b2c597fe0b829fb2c48c1428c295f"/></dir></target><target name="magelib"><dir name="phpsass"><dir name="Extensions"><dir name="Compass"><file name="Compass.php" hash="3bc8aaa37ae61b7bce0dc5fc0f16112e"/><dir name="stylesheets"><file name="_compass.scss" hash="bc769e7b7e94a717f9f4439978543900"/><file name="_lemonade.scss" hash="92e7ec85f14f46cf399a64115707dfe1"/><dir name="compass"><file name="_css3.scss" hash="7688063612bb668fffd22c32b95a2f5c"/><file name="_layout.scss" hash="d7445d578d56b5f0d6482d5df0b28a7b"/><file name="_reset-legacy.scss" hash="322b2e4617c8bf9e6c1ad02bef42ac18"/><file name="_reset.scss" hash="b3d1130413650cdc98b24777bf15afff"/><file name="_support.scss" hash="200db7d3bd7cd633b35c73c7d724a275"/><file name="_typography.scss" hash="73c901f7f8afd26c65dbadedffb87c1a"/><file name="_utilities.scss" hash="adb9de208e608e5bdd25189b4d4790a6"/><dir name="css3"><file name="_appearance.scss" hash="b624212e8f27e260b89e7aa84e598432"/><file name="_background-clip.scss" hash="9eab5a21f351b22e565278af805382b3"/><file name="_background-origin.scss" hash="57e96581316421882118c0d155a4a74f"/><file name="_background-size.scss" hash="674b66cc99bf60400b44f130d0c9d00d"/><file name="_border-radius.scss" hash="02749463ff3b0d0e68e42c76e6c18b66"/><file name="_box-shadow.scss" hash="13cb3d1733c1f7a60c542c44e639af55"/><file name="_box-sizing.scss" hash="5bc8b4f482fb878518d28a18dd453df9"/><file name="_box.scss" hash="ca45bf6d49507d042e5928cf1058909c"/><file name="_columns.scss" hash="b809552667f5876e115881ece27cbc8e"/><file name="_filter.scss" hash="ddc12210cb1d9cdcaad890e9d02601de"/><file name="_font-face.scss" hash="dfc84cb70f83cdbcde9dd3e51789363b"/><file name="_hyphenation.scss" hash="d3cf84dec3da60b4259fe2a9276421b5"/><file name="_images.scss" hash="c4d2fc1c4a1c78a68952de2694939fd2"/><file name="_inline-block.scss" hash="0ddfde10e192213f01dfa122d15bf473"/><file name="_opacity.scss" hash="36a24354a3b62b9b9c82690d1c008963"/><file name="_pie.scss" hash="8ec8261b6cdfef171774d6ad294dbcb7"/><file name="_regions.scss" hash="84db6e13237909b8c05e60c5735f43cc"/><file name="_shared.scss" hash="2a19ef6064fadd0c7bc1213878172ca2"/><file name="_text-shadow.scss" hash="b8dda78c05f393266e002b85885737af"/><file name="_transform-legacy.scss" hash="8d7c4ab98d1a165271ba64e859454c9f"/><file name="_transform.scss" hash="63d14c83ad4ebe0a25fe62b2e9b3a840"/><file name="_transition.scss" hash="ae7b441207aede5e831fd58d13d09103"/><file name="_user-interface.scss" hash="4293d8e1b99b864b6f1a1e341d281fbb"/></dir><dir name="layout"><file name="_grid-background.scss" hash="ebbb0813eeb27f1b102396275cd35e2b"/><file name="_sticky-footer.scss" hash="c10c67d6ebe9ca67709c982bbfed7178"/><file name="_stretching.scss" hash="3f59f9138e25943e4a7def3aa22704e5"/></dir><dir name="reset"><file name="_utilities-legacy.scss" hash="b3a4fd8ac50ace1aa1e607d4d926be45"/><file name="_utilities.scss" hash="c84668ad95fd7c53b77bd015452dd416"/></dir><dir name="typography"><file name="_links.scss" hash="862a5096f3a03597aab1be4e9dc76c64"/><file name="_lists.scss" hash="0e8662119de52a98ac3e601e086bbf53"/><file name="_text.scss" hash="4d3e129baa58fb176ded67c97bbf5b0a"/><file name="_vertical_rhythm.scss" hash="80869e4543f6f4e7ec93e52419d9a6e9"/><dir name="links"><file name="_hover-link.scss" hash="329c8ea4f1460cadf695e8d830c33a80"/><file name="_link-colors.scss" hash="9a4a09d3f9121c10f403a1fa333725dc"/><file name="_unstyled-link.scss" hash="3439d86d2f28c345864a7337c99db069"/></dir><dir name="lists"><file name="_bullets.scss" hash="9d733d179b5dcc005ef07535c16abe2a"/><file name="_horizontal-list.scss" hash="14a893eaa879be04e2ed636ab524b8f7"/><file name="_inline-block-list.scss" hash="f96c6c754473084d0af9d07b6d85cf44"/><file name="_inline-list.scss" hash="898ffa6ae6c13c5df2730172d618dece"/></dir><dir name="text"><file name="_ellipsis.scss" hash="a4765ddc9555f114ff59ae1a582f3caa"/><file name="_force-wrap.scss" hash="def5a5579399a9d35d845d3133338e3c"/><file name="_nowrap.scss" hash="e2cf48586ed5a33ab90a09e346020afc"/><file name="_replacement.scss" hash="e20cb6a854d0a9adb9bd7a879cb257a3"/></dir></dir><dir name="utilities"><file name="_color.scss" hash="4f6252c899a6f25c57ec1b4e9052e55b"/><file name="_general.scss" hash="7a90acc34a01d65ccc38f6dd6225229a"/><file name="_print.scss" hash="eb1d910e8aea90d23b76adf27323abe8"/><file name="_sprites.scss" hash="5f57e9b3f79df0ed70b7321aa55a1a2d"/><file name="_tables.scss" hash="836327d928e513dc737897356d7ba15b"/><dir name="color"><file name="_contrast.scss" hash="735478c5e04e31030afca1e36bf8e398"/></dir><dir name="general"><file name="_clearfix.scss" hash="58fd0d07999140b25bddb4e5c1d49a17"/><file name="_float.scss" hash="5c273f43ca3a3d409c08151ac4f86786"/><file name="_hacks.scss" hash="98ede0f56175f5fb08b3ecd982c27309"/><file name="_min.scss" hash="26a0f6fdad1f7ff71f40ff92eda4f56c"/><file name="_tabs.scss" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="_tag-cloud.scss" hash="ae7c8c97b4b3142eac7d3c279a5a729c"/></dir><dir name="sprites"><file name="_base.scss" hash="cc4f45b711e8d7fc11aaecd5a54f3744"/><file name="_sprite-img.scss" hash="2deeab732747a9da12f965e133fd795f"/></dir><dir name="tables"><file name="_alternating-rows-and-columns.scss" hash="aa6884db2666742519eb7a4c399767b3"/><file name="_borders.scss" hash="2ac334630de78ae00941857bcbf098d5"/><file name="_scaffolding.scss" hash="4144e427ff1f2a6a9ffdfd3bd641e477"/></dir></dir></dir></dir></dir><file name="ExtensionInterface.php" hash="f02f77afac08968fca0ca8f7cd750456"/><dir name="Own"><file name="Own.php" hash="b8e662147759f28279b575ec753c4eb5"/><dir name="css"><dir name="test"><dir name="test2"><file name="test.scss" hash="b406241e81f4cbd2509a3a7daa50ba6e"/></dir></dir></dir></dir><file name="README.md" hash="0adcca717d8c0113986c95cfa6fa341f"/><dir name="Susy"><file name="Susy.php" hash="5e3068256f5b17c32ac5cc544137ac80"/><dir name="stylesheets"><file name="_susy.scss" hash="e60bb0cc5234c86628f4e0345bd2d48a"/><dir name="susy"><file name="_background.scss" hash="e7125e6d00deae7955c61ef9ce5b7557"/><file name="_functions.scss" hash="33d52f0bb6a333da77ac8c4482a1d862"/><file name="_grid.scss" hash="687c942dcaba8b87dac49db2d734e594"/><file name="_isolation.scss" hash="8e097d991625106869a96101bdc2bde4"/><file name="_margin.scss" hash="cb03e121a2800a47d569b456f247a0e4"/><file name="_media.scss" hash="89c7da945f0159b5e97ce705e8d06ae6"/><file name="_padding.scss" hash="b775d9b8f5465ae985da128e31818342"/><file name="_settings.scss" hash="e9942cc79f66826c45c525705aca4c5b"/><file name="_support.scss" hash="7c51df6bd18e85e6954b46e37b47db48"/><file name="_units.scss" hash="fea6309f28d01dc5cbf3fa8503f6bfae"/></dir></dir></dir><file name="example.php" hash="1b0d47697d1a85bbfb92cff187a51c4d"/><file name="example.scss" hash="1c36b8695ac3d22afa9caa72a5e0a96f"/><file name="theme.scss" hash="7210d729d56c93a23b91d4d280570e17"/></dir><file name="README.md" hash="f680aedff15c35475551bf0e0652be57"/><file name="SassException.php" hash="ae7482e7d574a36156671b4575d8c0b9"/><file name="SassFile.php" hash="61671ca2d00c771a031372243b9ad7b1"/><file name="SassParser.php" hash="de29cac49e715943a4b6a9590a4600ef"/><file name="VERSION" hash="989e91af7fc25340430a23b0cafe3f1d"/><file name="compile-apache.php" hash="7a95ffbe3baf88cd27260645e51d326d"/><file name="composer.json" hash="fb5dad84d70d71d3ad3ea36e06238c21"/><dir name="renderers"><file name="SassCompactRenderer.php" hash="d06cc6830ab426eacb6758b6b7e60db8"/><file name="SassCompressedRenderer.php" hash="ebbb33ce5f0c205fe96f80d452cdc75e"/><file name="SassExpandedRenderer.php" hash="f7d4dfa1a46748a50f212ab1b4c39cf9"/><file name="SassNestedRenderer.php" hash="ae57a3b8da86ae7c8560f71fc7cf69c4"/><file name="SassRenderer.php" hash="2f9059ce82c1d73f3a386ba005457bde"/></dir><dir name="script"><file name="SassScriptFunction.php" hash="8097a8a37e561a1f119f623dfdf73610"/><file name="SassScriptFunctions.php" hash="99b290ce879e50b9414de4dd6187c1b0"/><file name="SassScriptLexer.php" hash="8e5a0180f4b24e5008223816a5855fd2"/><file name="SassScriptOperation.php" hash="0ed86bf58330c6d407d7fe73a3d72ee8"/><file name="SassScriptParser.php" hash="3d99f5d850767c11be70189ff33bb4e2"/><file name="SassScriptParserExceptions.php" hash="7adc8cdc2f8a343213de10fa9c89a9fb"/><file name="SassScriptVariable.php" hash="49a4b8e3d3d5d358e3361684d6717439"/><dir name="literals"><file name="SassBoolean.php" hash="b456eafe96ef49e55e4256787539a37a"/><file name="SassColour.php" hash="b8ff0c00e202a25c411b653de7df8db4"/><file name="SassList.php" hash="19f4efc813eb12b557f306d3a427ec74"/><file name="SassLiteral.php" hash="d4403c33ca7bac07035832e009df5df8"/><file name="SassLiteralExceptions.php" hash="37841fc5e291f83b053b46dff8fabb1d"/><file name="SassNumber.php" hash="c3881b5a953b2207b15dc446867f6fba"/><file name="SassString.php" hash="4403e9ba0973e3fd04acf2eba5657496"/></dir></dir><file name="test.css" hash="1655ffa4e91349bbe84d9e9f87b5ae39"/><file name="test.php" hash="811210b59e0b2b0e243a53c7328f9d26"/><dir name="tests"><file name="_imported_charset_ibm866.sass" hash="92b1d97a137e4219bb7796d7751aa847"/><file name="_imported_charset_utf8.sass" hash="51489125c07d0e8f2b055295d40d2549"/><file name="_imported_content.sass" hash="aafd4b9ba2de82e4f977e04934f204d7"/><file name="_partial.sass" hash="529fb954d7e0f6b42c484c869e60fbcf"/><file name="alt.css" hash="d33475aa3b976be630eb419996866ee6"/><file name="alt.sass" hash="66be58fb872cd96be90fb95425a0aadf"/><file name="alt.scss" hash="ec1074aaba9b4a1ef3933d091c547c63"/><file name="basic.css" hash="22c341ec6e41dba84606032a40ea21c3"/><file name="basic.sass" hash="450faf5ca8e4bacefd01a74509ae135c"/><file name="bork1.sass" hash="0608533ebc4c4a16ddff507f818a709e"/><file name="bork2.sass" hash="036c6e0bcebc36908f9093d1b536ceb1"/><file name="bork3.sass" hash="ad06e4551ead8422ac443ae0cad7994b"/><file name="bork4.sass" hash="0bd4b0aed58208f5abf4418eb9672ef9"/><file name="bork5.sass" hash="e467427a1e928d1d72ef8db10482e262"/><file name="colour-nth.css" hash="8e457058415890dd4aac86f75a6e39e4"/><file name="colour-nth.scss" hash="3de860789a01fa9b5cf2d9a74a85dba7"/><file name="comments.css" hash="0ca95a61ccc49717e465173fb0c2e6c6"/><file name="comments.sass" hash="41bb5d2d2e14e3dd16c8b0296608a00e"/><file name="compact.css" hash="96105d0147b6881651b723eabe303f65"/><file name="compact.sass" hash="d51cfe7db78fe0d81793c7e24cb32e46"/><file name="complex.css" hash="3ffea6ccf80b24cc136bb102b3b41a67"/><file name="complex.sass" hash="b1426382fb915456b5efc0877ae7072d"/><file name="compressed.css" hash="1975f89cc758e39302d317578fdfdedb"/><file name="compressed.sass" hash="d51cfe7db78fe0d81793c7e24cb32e46"/><file name="content.css" hash="0c0892c48d74761fee54e09ccba6e662"/><file name="content.scss" hash="e624a12355435c147c0772f9fd1fe065"/><file name="css3.css" hash="8b2a0df29de7f2158baa3e97e76d91f2"/><file name="css3.scss" hash="819f570dae1e0c8c77007a03a2642158"/><file name="default.css" hash="8296f416c47ae4b66fa6bdf3259b1015"/><file name="default.sass" hash="90e19da7fd8144eeab4d93e5d3adb3bd"/><file name="default_imported.sass" hash="dbea23754dce7bc6c0f7ff69863c05c5"/><file name="each.css" hash="3f84fdb19433d6c2fb0e63c60c06d072"/><file name="each.scss" hash="9661d8222338cfdd6ba8ff771f1c881c"/><file name="expanded.css" hash="88ee2a16c4d88965bcbcf573a2d7c0fa"/><file name="expanded.sass" hash="66dbccbf13e56c23c9b12401ef4edb2d"/><file name="extend.css" hash="c4e9ba7d8748202d2c1351d5b69e3353"/><file name="extend.sass" hash="f34bd79d09364600631ea4889232ad64"/><file name="extend_included.css" hash="3c3e70c49794a7ff76aeb9a3402cf7bc"/><file name="extend_included.scss" hash="be61d8166e45b16c08e49087985ed1fb"/><file name="extend_placeholders.css" hash="369b772056769bece364221f3c069a8e"/><file name="extend_placeholders.scss" hash="4af5f1ee5888e7cd6cf6c6de45dbfc17"/><file name="filters.css" hash="f37ab5406ea00310513ce2e114cf6f07"/><file name="filters.scss" hash="ea989dd11a1d2a147b72d748b3a9c8c9"/><file name="functions.css" hash="a9da72a84bba8729e82dac08190a79d2"/><file name="functions.scss" hash="c9669b01b11b3abe4d82f701180ac2b0"/><file name="holmes.css" hash="07772c914ace61121cba53beb6ad8ca6"/><file name="holmes.sass" hash="e2199b90032b5f14a4dfc5233a915223"/><file name="hsl-functions.css" hash="b90a44e5919a286a8a62040f211b3580"/><file name="hsl-functions.scss" hash="fa055c7d603b5436613ecac898351cae"/><file name="if.css" hash="82391ad41348b41fc209cca5412ed740"/><file name="if.sass" hash="c3a27a421eb7e3d463918e189195b573"/><file name="if_parentheses.css" hash="7f5bc7f906a7cd678c9598c2e5650833"/><file name="if_parentheses.scss" hash="5140ac11b185061d3c5f7dc238e8ee86"/><file name="import.css" hash="3c8abb5481ee0c0002916b49681af2a5"/><file name="import.sass" hash="4d43389aa785393a47d57734724dad2f"/><file name="import_content.css" hash="4b78a566882b2768336f603d54f73fa4"/><file name="import_content.sass" hash="2db9b7a5b9a581e9f44256b6c8dbedd1"/><file name="importee.sass" hash="606678a5d48f7653f6d8e2e327109310"/><file name="interpolation.css" hash="ef048c83424f05a9c0882007ba0f4958"/><file name="interpolation.scss" hash="ce66433664f7f37277a8d4726a39556c"/><file name="introspection.css" hash="0d9f0e64e263388ec0e87eadef41193e"/><file name="introspection.scss" hash="9d57f03789f7a947ce62d6ab0320f886"/><file name="line_numbers.css" hash="802e2285df194c362503f849647a1380"/><file name="line_numbers.sass" hash="4770a812ab401d2bd35b352408623a17"/><file name="list.css" hash="4dd913d85cf2a28cb12d8af0f622ce03"/><file name="list.scss" hash="24f96a097c84d0da64cb3e753e2439ee"/><file name="list_empty.css" hash="c2fae66e0a28506f1733ac469a1c95ec"/><file name="list_empty.scss" hash="25d245b57859102ba6b36c12e89f3e7e"/><file name="list_variable.css" hash="d10df2dc91b4221bbfe4c3464bd34d5b"/><file name="list_variable.scss" hash="17a541748f730b9da21275a75852cf4e"/><file name="media.css" hash="409f2c0c468598dc19067376a796828f"/><file name="media.scss" hash="1fadbcd19113ff5855d1137be0693799"/><file name="media_in_for.css" hash="fd8292f715cc999ba7b64f8224c40a8a"/><file name="media_in_for.scss" hash="ad7702a6b95e121da52b93d69d782683"/><file name="media_in_mixin.css" hash="8c2bd3f961ab4336c55a5249f78e6bf4"/><file name="media_in_mixin.scss" hash="084e6f0edd3da537020a43d7ce8dbac4"/><file name="media_in_mixin_in_mixin.css" hash="8adc138ca27531ac5693c7e2274fdf9f"/><file name="media_in_mixin_in_mixin.scss" hash="049301e720820f076ceec6cc08037ede"/><file name="misc-functions.css" hash="7da15f26cab9b6df784ce1e37e9a30f1"/><file name="misc-functions.scss" hash="b133df9bb8cf346a3e6d3b3612c1de64"/><file name="misc.css" hash="a05a0a6b49ddbfdd803e92c5abe97594"/><file name="misc.scss" hash="36b58121127544b6a8179ae8a0c90a35"/><file name="mixin-content.css" hash="1b2490ce75d60d2b0c495a5db87a9f49"/><file name="mixin-content.sass" hash="41fa6bbd93b8d0b4ea8826fdd5585381"/><file name="mixin-content.scss" hash="f3252f583aac7dd5bbb7017fbd5654df"/><file name="mixin-ja1.css" hash="c551c8ffd0723e1c9e5795708d5dbda5"/><file name="mixin-ja1.sass" hash="90d3f2653ccbccbc00a9009bd31f8071"/><file name="mixin-list-params.css" hash="47064a4d242dfec9debba53326e529f3"/><file name="mixin-list-params.scss" hash="34478559346aec44c56c867a6b898af3"/><file name="mixin-params.css" hash="1a1f609e66c1dbe24383fe6855e95526"/><file name="mixin-params.scss" hash="a874ab4cacc02475acc827c956275cfe"/><file name="mixin-rgba-param.css" hash="bc5dc6caac3c74b37b82b1ed3cc2e553"/><file name="mixin-rgba-param.scss" hash="961219de858ecf7c17f2f7df24cf68cb"/><file name="mixin_bork.sass" hash="259fd0cca5a94583c0d406646b3217eb"/><file name="mixin_in_mixin.css" hash="46690de92ec525f39d5568bc2e46ee54"/><file name="mixin_in_mixin.scss" hash="0a6bef40d3215b63bb9f972896784a89"/><file name="mixin_setvar.css" hash="757520a01eca279c109d494d7fb4cd02"/><file name="mixin_setvar.scss" hash="12cd65c514056b3c0df1e4e92640a808"/><file name="mixins.css" hash="76ea6005844a4339745b1afe66274c74"/><file name="mixins.sass" hash="55fb1a104a59d6e5411987447af96b55"/><file name="multiline.css" hash="4a3d9bfe75a3b98c52ed95f3d785b079"/><file name="multiline.sass" hash="2f4ff6cfefa20eece2830170e29ea25e"/><file name="nested-media.css" hash="4fc2c8503b918fe9add9fcb230215fe2"/><file name="nested-media.scss" hash="2ee9901f1413f1f0839cfdc9b2ea00af"/><file name="nested.css" hash="26bd112a486652342cbfd55060552576"/><file name="nested.sass" hash="0bdc5d64efc02766544553f968bb82fd"/><file name="nested_bork1.sass" hash="56fa9072b6cc553909bfbd18f571a11d"/><file name="nested_bork2.sass" hash="999ae47bdbc6190972f0f52958870130"/><file name="nested_bork3.sass" hash="ccb998041d90cfe54a39f01afc4c4cc0"/><file name="nested_bork4.sass" hash="eed6453ea8564978c35d60f26a9bbb25"/><file name="nested_bork5.sass" hash="d6de98aee6d80aaecc1aa97311136003"/><file name="nested_import.css" hash="de8bc2a3cd89496c22ff564e65c2b046"/><file name="nested_import.sass" hash="b4493203dae52b5757ca91e17dd42e42"/><file name="nested_media.css" hash="d910a2026928133ce7235e8e1143a425"/><file name="nested_media.scss" hash="6e2dceddb572a0caa6f3959e00d332f4"/><file name="nested_mixin_bork.sass" hash="d9f57da9545e6c9a54d89bebe2f750b9"/><file name="nested_pseudo.css" hash="435b969153bc5030ceb8c251d241d358"/><file name="nested_pseudo.scss" hash="145d425a42541236d8952ea9f5e68ae7"/><file name="number.css" hash="000ca28603c30a49647d53bc5aabed94"/><file name="number.scss" hash="c585efaf419263809a1c91b76d8a0799"/><file name="opacity.css" hash="f54a7fbecddad66df7a6dae52bea4c21"/><file name="opacity.scss" hash="3a20a779e1becfcfaba90758d907c05e"/><file name="other-color.css" hash="45d9e1061d0e71b1c55362c2974b7bdf"/><file name="other-color.scss" hash="e2b8b86016461cbcdae6365ee14b0a5d"/><file name="parent_ref.css" hash="cbecced10861e9c060fa05187f94ee5f"/><file name="parent_ref.sass" hash="b5a3fe6fd3384b0853211e3515427796"/><file name="phpSassTest.php" hash="ce7206b374b0d65762851a6e3423658d"/><file name="phpunit.xml.dist" hash="3f11a2a97eb3d9b8bb48f60915daefda"/><file name="proprietary-selector.css" hash="6da7ab22184ed10ec679065835fc0f5f"/><file name="proprietary-selector.scss" hash="a7fa95fad2ae9aa0b93d8b49101eaf5f"/><file name="rgb-functions.css" hash="24177c2bc7b35526bf06334ea4174e27"/><file name="rgb-functions.scss" hash="7ad824885f782f15738ef67bbf00ae2a"/><file name="scss_import.css" hash="9eeec339e1ce59cbf3f2d29efab1382b"/><file name="scss_import.scss" hash="7ae409e52a06ad89582fe89063cf6bdd"/><file name="scss_importee.css" hash="7cad5194c7f7bb18e50f1ca093597033"/><file name="scss_importee.scss" hash="20c55fb516c7b137eadc6462f74cfa94"/><file name="splats.css" hash="3d11bc1d58858e4967ed498a3d75d008"/><file name="splats.scss" hash="4fab47d7391ff72a2e8d6de13c5e1b80"/><file name="string.css" hash="9f1482fe5b4964e96d24c00765c2503d"/><file name="string.scss" hash="f89f2aad48738bb1fa33a67f733e2e90"/><dir name="subdir"><dir name="nested_subdir"><file name="_nested_partial.sass" hash="24985866e9414ee4ef69621b738833ee"/><file name="nested_subdir.css" hash="759df6872a88c4174a39c32fe7d95a04"/><file name="nested_subdir.sass" hash="9e5e623f6765e28d5bec3bb2d3944eac"/></dir><file name="subdir.css" hash="ddd9dd41c2b72164a7ba634e359c2872"/><file name="subdir.sass" hash="acde24bd965d15ae3f19bf74b1f1c2a8"/></dir><file name="units.css" hash="ebc7390d227439bf2694a3ce29c54a6d"/><file name="units.sass" hash="040de247b027e6368c7edbc57d6e331f"/><file name="warn.css" hash="31c098880201803dc33c8785ecf3de26"/><file name="warn.sass" hash="47c7543a6a374523514669e108249f41"/><file name="warn_imported.sass" hash="2b7455acd686bf2511fce0b710874b01"/></dir><dir name="tree"><file name="SassCommentNode.php" hash="642f1a815d0e7dfc1106a518e8d87b31"/><file name="SassContentNode.php" hash="9e89188216cfe645bc0550e40027051b"/><file name="SassContext.php" hash="20760243da06e897f9c21d7ba1672fd4"/><file name="SassDebugNode.php" hash="9acd25b3581aa8d18313f3ac3d9e6e9a"/><file name="SassDirectiveNode.php" hash="039a39f8662e2131b2c0018a80337fde"/><file name="SassEachNode.php" hash="63aa2d6a2ade5a9a966f45edc70fabec"/><file name="SassElseNode.php" hash="6a6426a9d34047ac81eed7add893a179"/><file name="SassExtendNode.php" hash="02252a9b29559a959348fb87bb586d0e"/><file name="SassForNode.php" hash="0322a55c38b6f7fa0d4382f7e3972f4d"/><file name="SassFunctionDefinitionNode.php" hash="97b6440a715ce30922f1d3fafb7cfc3a"/><file name="SassIfNode.php" hash="af42d33a38ed91a5f5181b2458a2fa60"/><file name="SassImportNode.php" hash="a0b2c5b200cff2262e66327458054878"/><file name="SassMediaNode.php" hash="824aedfdb70bb658cbdb19e7e8fec1e1"/><file name="SassMixinDefinitionNode.php" hash="40763d3f0db2bcccd24e26262b2cc244"/><file name="SassMixinNode.php" hash="058bf4b74bcd7e99be00ff7890081881"/><file name="SassNode.php" hash="89f8a631e0381b736770c5b0da126f41"/><file name="SassNodeExceptions.php" hash="c8acde883ff1f08c56aaea36d3878c69"/><file name="SassPropertyNode.php" hash="388d56d83ab2e05909e8d04d849d786c"/><file name="SassReturnNode.php" hash="c951be13c91fad525b69fc09764e45ee"/><file name="SassRootNode.php" hash="423c2c19d8ad01638b42bf81b19a88fc"/><file name="SassRuleNode.php" hash="0828b0d29742e5e62f006a18961caa48"/><file name="SassVariableNode.php" hash="e4ab9cc2baab946a5b3cfc561baaf5cf"/><file name="SassWarnNode.php" hash="ba0da120f75efd07c57d040adf96a95d"/><file name="SassWhileNode.php" hash="b2c1328c15a28b4e37fed4d998d60dc9"/></dir><file name=".travis.yml" hash="d0ac6ce1cf8465183941fa3ac326a54e"/></dir></target></contents>
20
  <compatible/>
21
- <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
22
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Sass</name>
4
+ <version>1.1.4</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL 3.0)</license>
7
  <channel>community</channel>
12
  You just need to create you sass file and add it to your layout like default css file.&#xD;
13
  &#xD;
14
  This extension will then convert it to css file using phpSass or sass in command line if available</description>
15
+ <notes>Support of Magento CE 1.8&#xD;
16
+ phpsass library updated.</notes>
17
  <authors><author><name>Laurent Clouet</name><user>laurent35240</user><email>laurent35240@gmail.com</email></author></authors>
18
+ <date>2013-11-17</date>
19
+ <time>14:00:12</time>
20
+ <contents><target name="magecommunity"><dir name="Laurent"><dir name="Sass"><dir name="Helper"><file name="Data.php" hash="9c43132dba73d4b3f37ccfb91f0d5dbe"/></dir><dir name="Model"><dir name="Config"><file name="Style.php" hash="413571124dcf58d950200499a144420d"/></dir><dir name="Design"><file name="Package.php" hash="3c83af4c43fd94359541b7242852ca06"/></dir></dir><dir name="etc"><file name="config.xml" hash="e3f9875a014b5ed2f229b0d88a1654d1"/><file name="system.xml" hash="a2db1af0d9bae017b46805a80aedb442"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Laurent_Sass.xml" hash="4ad004de851457681610553228973c30"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Laurent_Sass.csv" hash="d9e8c184cbe72e810c7da9154581e1e4"/></dir><dir name="fr_FR"><file name="Laurent_Sass.csv" hash="676b2c597fe0b829fb2c48c1428c295f"/></dir></target><target name="magelib"><dir name="phpsass"><dir name="Extensions"><dir name="Compass"><file name="Compass.php" hash="ebb4044bcf18ec93da6c5a1d088304b6"/><dir name="stylesheets"><file name="_compass.scss" hash="bc769e7b7e94a717f9f4439978543900"/><file name="_lemonade.scss" hash="92e7ec85f14f46cf399a64115707dfe1"/><dir name="compass"><file name="_css3.scss" hash="7688063612bb668fffd22c32b95a2f5c"/><file name="_layout.scss" hash="d7445d578d56b5f0d6482d5df0b28a7b"/><file name="_reset-legacy.scss" hash="322b2e4617c8bf9e6c1ad02bef42ac18"/><file name="_reset.scss" hash="b3d1130413650cdc98b24777bf15afff"/><file name="_support.scss" hash="200db7d3bd7cd633b35c73c7d724a275"/><file name="_typography.scss" hash="73c901f7f8afd26c65dbadedffb87c1a"/><file name="_utilities.scss" hash="adb9de208e608e5bdd25189b4d4790a6"/><dir name="css3"><file name="_appearance.scss" hash="b624212e8f27e260b89e7aa84e598432"/><file name="_background-clip.scss" hash="9eab5a21f351b22e565278af805382b3"/><file name="_background-origin.scss" hash="57e96581316421882118c0d155a4a74f"/><file name="_background-size.scss" hash="674b66cc99bf60400b44f130d0c9d00d"/><file name="_border-radius.scss" hash="02749463ff3b0d0e68e42c76e6c18b66"/><file name="_box-shadow.scss" hash="13cb3d1733c1f7a60c542c44e639af55"/><file name="_box-sizing.scss" hash="5bc8b4f482fb878518d28a18dd453df9"/><file name="_box.scss" hash="ca45bf6d49507d042e5928cf1058909c"/><file name="_columns.scss" hash="b809552667f5876e115881ece27cbc8e"/><file name="_filter.scss" hash="ddc12210cb1d9cdcaad890e9d02601de"/><file name="_font-face.scss" hash="dfc84cb70f83cdbcde9dd3e51789363b"/><file name="_hyphenation.scss" hash="d3cf84dec3da60b4259fe2a9276421b5"/><file name="_images.scss" hash="c4d2fc1c4a1c78a68952de2694939fd2"/><file name="_inline-block.scss" hash="0ddfde10e192213f01dfa122d15bf473"/><file name="_opacity.scss" hash="36a24354a3b62b9b9c82690d1c008963"/><file name="_pie.scss" hash="8ec8261b6cdfef171774d6ad294dbcb7"/><file name="_regions.scss" hash="84db6e13237909b8c05e60c5735f43cc"/><file name="_shared.scss" hash="2a19ef6064fadd0c7bc1213878172ca2"/><file name="_text-shadow.scss" hash="b8dda78c05f393266e002b85885737af"/><file name="_transform-legacy.scss" hash="8d7c4ab98d1a165271ba64e859454c9f"/><file name="_transform.scss" hash="63d14c83ad4ebe0a25fe62b2e9b3a840"/><file name="_transition.scss" hash="ae7b441207aede5e831fd58d13d09103"/><file name="_user-interface.scss" hash="4293d8e1b99b864b6f1a1e341d281fbb"/></dir><dir name="layout"><file name="_grid-background.scss" hash="ebbb0813eeb27f1b102396275cd35e2b"/><file name="_sticky-footer.scss" hash="c10c67d6ebe9ca67709c982bbfed7178"/><file name="_stretching.scss" hash="3f59f9138e25943e4a7def3aa22704e5"/></dir><dir name="reset"><file name="_utilities-legacy.scss" hash="b3a4fd8ac50ace1aa1e607d4d926be45"/><file name="_utilities.scss" hash="c84668ad95fd7c53b77bd015452dd416"/></dir><dir name="typography"><file name="_links.scss" hash="862a5096f3a03597aab1be4e9dc76c64"/><file name="_lists.scss" hash="0e8662119de52a98ac3e601e086bbf53"/><file name="_text.scss" hash="4d3e129baa58fb176ded67c97bbf5b0a"/><file name="_vertical_rhythm.scss" hash="80869e4543f6f4e7ec93e52419d9a6e9"/><dir name="links"><file name="_hover-link.scss" hash="329c8ea4f1460cadf695e8d830c33a80"/><file name="_link-colors.scss" hash="9a4a09d3f9121c10f403a1fa333725dc"/><file name="_unstyled-link.scss" hash="3439d86d2f28c345864a7337c99db069"/></dir><dir name="lists"><file name="_bullets.scss" hash="9d733d179b5dcc005ef07535c16abe2a"/><file name="_horizontal-list.scss" hash="14a893eaa879be04e2ed636ab524b8f7"/><file name="_inline-block-list.scss" hash="f96c6c754473084d0af9d07b6d85cf44"/><file name="_inline-list.scss" hash="898ffa6ae6c13c5df2730172d618dece"/></dir><dir name="text"><file name="_ellipsis.scss" hash="a4765ddc9555f114ff59ae1a582f3caa"/><file name="_force-wrap.scss" hash="def5a5579399a9d35d845d3133338e3c"/><file name="_nowrap.scss" hash="e2cf48586ed5a33ab90a09e346020afc"/><file name="_replacement.scss" hash="e20cb6a854d0a9adb9bd7a879cb257a3"/></dir></dir><dir name="utilities"><file name="_color.scss" hash="4f6252c899a6f25c57ec1b4e9052e55b"/><file name="_general.scss" hash="7a90acc34a01d65ccc38f6dd6225229a"/><file name="_print.scss" hash="eb1d910e8aea90d23b76adf27323abe8"/><file name="_sprites.scss" hash="5f57e9b3f79df0ed70b7321aa55a1a2d"/><file name="_tables.scss" hash="836327d928e513dc737897356d7ba15b"/><dir name="color"><file name="_contrast.scss" hash="735478c5e04e31030afca1e36bf8e398"/></dir><dir name="general"><file name="_clearfix.scss" hash="58fd0d07999140b25bddb4e5c1d49a17"/><file name="_float.scss" hash="5c273f43ca3a3d409c08151ac4f86786"/><file name="_hacks.scss" hash="98ede0f56175f5fb08b3ecd982c27309"/><file name="_min.scss" hash="26a0f6fdad1f7ff71f40ff92eda4f56c"/><file name="_tabs.scss" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="_tag-cloud.scss" hash="ae7c8c97b4b3142eac7d3c279a5a729c"/></dir><dir name="sprites"><file name="_base.scss" hash="cc4f45b711e8d7fc11aaecd5a54f3744"/><file name="_sprite-img.scss" hash="2deeab732747a9da12f965e133fd795f"/></dir><dir name="tables"><file name="_alternating-rows-and-columns.scss" hash="aa6884db2666742519eb7a4c399767b3"/><file name="_borders.scss" hash="2ac334630de78ae00941857bcbf098d5"/><file name="_scaffolding.scss" hash="4144e427ff1f2a6a9ffdfd3bd641e477"/></dir></dir></dir></dir></dir><file name="ExtensionInterface.php" hash="f02f77afac08968fca0ca8f7cd750456"/><dir name="Own"><file name="Own.php" hash="fb185a20331ce4f185d7fdc318bf0b50"/><dir name="css"><dir name="test"><dir name="test2"><file name="test.scss" hash="b406241e81f4cbd2509a3a7daa50ba6e"/></dir></dir></dir></dir><file name="README.md" hash="0adcca717d8c0113986c95cfa6fa341f"/><dir name="Susy"><file name="Susy.php" hash="36a66b10b093bfa6d09e10f84f5c7d18"/><dir name="stylesheets"><file name="_susy.scss" hash="e60bb0cc5234c86628f4e0345bd2d48a"/><dir name="susy"><file name="_background.scss" hash="e7125e6d00deae7955c61ef9ce5b7557"/><file name="_functions.scss" hash="33d52f0bb6a333da77ac8c4482a1d862"/><file name="_grid.scss" hash="687c942dcaba8b87dac49db2d734e594"/><file name="_isolation.scss" hash="8e097d991625106869a96101bdc2bde4"/><file name="_margin.scss" hash="cb03e121a2800a47d569b456f247a0e4"/><file name="_media.scss" hash="89c7da945f0159b5e97ce705e8d06ae6"/><file name="_padding.scss" hash="b775d9b8f5465ae985da128e31818342"/><file name="_settings.scss" hash="e9942cc79f66826c45c525705aca4c5b"/><file name="_support.scss" hash="7c51df6bd18e85e6954b46e37b47db48"/><file name="_units.scss" hash="fea6309f28d01dc5cbf3fa8503f6bfae"/></dir></dir></dir><file name="example.php" hash="909400c241ad5d58484d600b7d0c4c92"/><file name="example.scss" hash="1c36b8695ac3d22afa9caa72a5e0a96f"/><file name="theme.scss" hash="7210d729d56c93a23b91d4d280570e17"/></dir><file name="README.md" hash="f680aedff15c35475551bf0e0652be57"/><file name="SassException.php" hash="1b481a8b5ddaa54b372ada4eb8598bb5"/><file name="SassFile.php" hash="76ba06279ded72bb92388ec51c32b560"/><file name="SassParser.php" hash="538f2a5a5795d7dfd065d9b80b9aaf1d"/><file name="VERSION" hash="fc3abbf04899a7be14a6aef73d83c120"/><file name="compile-apache.php" hash="7a95ffbe3baf88cd27260645e51d326d"/><file name="composer.json" hash="fb5dad84d70d71d3ad3ea36e06238c21"/><dir name="renderers"><file name="SassCompactRenderer.php" hash="efa3e80cb179be28b933c674cd06d70b"/><file name="SassCompressedRenderer.php" hash="a76e47ecc939efb39ad3bd091d90cc52"/><file name="SassExpandedRenderer.php" hash="938e703678e01367f8bfbfc0af2c9aca"/><file name="SassNestedRenderer.php" hash="963cade34043342728476d4b80a8f66d"/><file name="SassRenderer.php" hash="cba7988395cfc8ceba91dd1ae5777abd"/></dir><dir name="script"><file name="SassScriptFunction.php" hash="1682579a7b1fe57ba5ae30d52e7effc2"/><file name="SassScriptFunctions.php" hash="d423c2837d5c72443ed37926b1e0b4e4"/><file name="SassScriptLexer.php" hash="888286d5b2542bcf57f292966953f3ad"/><file name="SassScriptOperation.php" hash="b4f2eabeedd761157c378d4b36272b65"/><file name="SassScriptParser.php" hash="122201f80fb07cb78b5a1d32f4ec2a78"/><file name="SassScriptParserExceptions.php" hash="b24e0948e0e07f38bcfded7ddd0220ce"/><file name="SassScriptVariable.php" hash="b7450d09a86722cb89755fdc259820dd"/><dir name="literals"><file name="SassBoolean.php" hash="09644008ffd1b31bd13d4191fbcbdfa1"/><file name="SassColour.php" hash="05e81b7dfc201eeebecec47a96269055"/><file name="SassList.php" hash="9c1a851b068515b08d7c0bdb0c01d355"/><file name="SassLiteral.php" hash="77cf2a7af40aeaea5f27a2f055949aad"/><file name="SassLiteralExceptions.php" hash="dee1ed83e9fbbb173c2d1ae8a3cd5ba8"/><file name="SassNumber.php" hash="953e230977d422496526cc6cbc64e829"/><file name="SassString.php" hash="3a6350304d07995a93c68824628bcd3a"/></dir></dir><file name="test.css" hash="1655ffa4e91349bbe84d9e9f87b5ae39"/><file name="test.php" hash="811210b59e0b2b0e243a53c7328f9d26"/><dir name="tests"><file name="_imported_charset_ibm866.sass" hash="92b1d97a137e4219bb7796d7751aa847"/><file name="_imported_charset_utf8.sass" hash="51489125c07d0e8f2b055295d40d2549"/><file name="_imported_content.sass" hash="aafd4b9ba2de82e4f977e04934f204d7"/><file name="_partial.sass" hash="529fb954d7e0f6b42c484c869e60fbcf"/><file name="alt.css" hash="d48efc67765cb14b1c532b36b036a064"/><file name="alt.sass" hash="66be58fb872cd96be90fb95425a0aadf"/><file name="alt.scss" hash="ec1074aaba9b4a1ef3933d091c547c63"/><file name="basic.css" hash="22c341ec6e41dba84606032a40ea21c3"/><file name="basic.sass" hash="450faf5ca8e4bacefd01a74509ae135c"/><file name="bork1.sass" hash="0608533ebc4c4a16ddff507f818a709e"/><file name="bork2.sass" hash="036c6e0bcebc36908f9093d1b536ceb1"/><file name="bork3.sass" hash="ad06e4551ead8422ac443ae0cad7994b"/><file name="bork4.sass" hash="0bd4b0aed58208f5abf4418eb9672ef9"/><file name="bork5.sass" hash="e467427a1e928d1d72ef8db10482e262"/><file name="colour-nth.css" hash="8e457058415890dd4aac86f75a6e39e4"/><file name="colour-nth.scss" hash="3de860789a01fa9b5cf2d9a74a85dba7"/><file name="comments.css" hash="0ca95a61ccc49717e465173fb0c2e6c6"/><file name="comments.sass" hash="41bb5d2d2e14e3dd16c8b0296608a00e"/><file name="compact.css" hash="96105d0147b6881651b723eabe303f65"/><file name="compact.sass" hash="d51cfe7db78fe0d81793c7e24cb32e46"/><file name="complex.css" hash="3ffea6ccf80b24cc136bb102b3b41a67"/><file name="complex.sass" hash="b1426382fb915456b5efc0877ae7072d"/><file name="compressed.css" hash="1975f89cc758e39302d317578fdfdedb"/><file name="compressed.sass" hash="d51cfe7db78fe0d81793c7e24cb32e46"/><file name="content.css" hash="0c0892c48d74761fee54e09ccba6e662"/><file name="content.scss" hash="e624a12355435c147c0772f9fd1fe065"/><file name="css3.css" hash="8b2a0df29de7f2158baa3e97e76d91f2"/><file name="css3.scss" hash="819f570dae1e0c8c77007a03a2642158"/><file name="default.css" hash="8296f416c47ae4b66fa6bdf3259b1015"/><file name="default.sass" hash="90e19da7fd8144eeab4d93e5d3adb3bd"/><file name="default_imported.sass" hash="dbea23754dce7bc6c0f7ff69863c05c5"/><file name="each.css" hash="3f84fdb19433d6c2fb0e63c60c06d072"/><file name="each.scss" hash="9661d8222338cfdd6ba8ff771f1c881c"/><file name="expanded.css" hash="88ee2a16c4d88965bcbcf573a2d7c0fa"/><file name="expanded.sass" hash="66dbccbf13e56c23c9b12401ef4edb2d"/><file name="extend.css" hash="c4e9ba7d8748202d2c1351d5b69e3353"/><file name="extend.sass" hash="f34bd79d09364600631ea4889232ad64"/><file name="extend_included.scss" hash="be61d8166e45b16c08e49087985ed1fb"/><file name="extend_placeholders.css" hash="369b772056769bece364221f3c069a8e"/><file name="extend_placeholders.scss" hash="4af5f1ee5888e7cd6cf6c6de45dbfc17"/><file name="filters.css" hash="f37ab5406ea00310513ce2e114cf6f07"/><file name="filters.scss" hash="ea989dd11a1d2a147b72d748b3a9c8c9"/><file name="functions.css" hash="0a039fdec50d756df0ca5430fdc25a0a"/><file name="functions.scss" hash="c9669b01b11b3abe4d82f701180ac2b0"/><file name="holmes.css" hash="07772c914ace61121cba53beb6ad8ca6"/><file name="holmes.sass" hash="e2199b90032b5f14a4dfc5233a915223"/><file name="hsl-functions.css" hash="b90a44e5919a286a8a62040f211b3580"/><file name="hsl-functions.scss" hash="fa055c7d603b5436613ecac898351cae"/><file name="if.css" hash="82391ad41348b41fc209cca5412ed740"/><file name="if.sass" hash="c3a27a421eb7e3d463918e189195b573"/><file name="if_parentheses.css" hash="7f5bc7f906a7cd678c9598c2e5650833"/><file name="if_parentheses.scss" hash="5140ac11b185061d3c5f7dc238e8ee86"/><file name="import.css" hash="3c8abb5481ee0c0002916b49681af2a5"/><file name="import.sass" hash="4d43389aa785393a47d57734724dad2f"/><file name="import_content.css" hash="4b78a566882b2768336f603d54f73fa4"/><file name="import_content.sass" hash="2db9b7a5b9a581e9f44256b6c8dbedd1"/><file name="importee.sass" hash="606678a5d48f7653f6d8e2e327109310"/><file name="interpolation.css" hash="ef048c83424f05a9c0882007ba0f4958"/><file name="interpolation.scss" hash="ce66433664f7f37277a8d4726a39556c"/><file name="introspection.css" hash="0d9f0e64e263388ec0e87eadef41193e"/><file name="introspection.scss" hash="9d57f03789f7a947ce62d6ab0320f886"/><file name="line_numbers.css" hash="802e2285df194c362503f849647a1380"/><file name="line_numbers.sass" hash="4770a812ab401d2bd35b352408623a17"/><file name="list.css" hash="4dd913d85cf2a28cb12d8af0f622ce03"/><file name="list.scss" hash="24f96a097c84d0da64cb3e753e2439ee"/><file name="list_empty.css" hash="c2fae66e0a28506f1733ac469a1c95ec"/><file name="list_empty.scss" hash="25d245b57859102ba6b36c12e89f3e7e"/><file name="list_variable.css" hash="d10df2dc91b4221bbfe4c3464bd34d5b"/><file name="list_variable.scss" hash="17a541748f730b9da21275a75852cf4e"/><file name="media.css" hash="409f2c0c468598dc19067376a796828f"/><file name="media.scss" hash="1fadbcd19113ff5855d1137be0693799"/><file name="media_in_for.css" hash="fd8292f715cc999ba7b64f8224c40a8a"/><file name="media_in_for.scss" hash="ad7702a6b95e121da52b93d69d782683"/><file name="media_in_mixin.css" hash="8c2bd3f961ab4336c55a5249f78e6bf4"/><file name="media_in_mixin.scss" hash="084e6f0edd3da537020a43d7ce8dbac4"/><file name="media_in_mixin_in_mixin.css" hash="8adc138ca27531ac5693c7e2274fdf9f"/><file name="media_in_mixin_in_mixin.scss" hash="049301e720820f076ceec6cc08037ede"/><file name="misc-functions.css" hash="7da15f26cab9b6df784ce1e37e9a30f1"/><file name="misc-functions.scss" hash="b133df9bb8cf346a3e6d3b3612c1de64"/><file name="misc.css" hash="a05a0a6b49ddbfdd803e92c5abe97594"/><file name="misc.scss" hash="36b58121127544b6a8179ae8a0c90a35"/><file name="mixin-content.css" hash="1b2490ce75d60d2b0c495a5db87a9f49"/><file name="mixin-content.sass" hash="41fa6bbd93b8d0b4ea8826fdd5585381"/><file name="mixin-content.scss" hash="f3252f583aac7dd5bbb7017fbd5654df"/><file name="mixin-ja1.css" hash="c551c8ffd0723e1c9e5795708d5dbda5"/><file name="mixin-ja1.sass" hash="90d3f2653ccbccbc00a9009bd31f8071"/><file name="mixin-list-params.css" hash="47064a4d242dfec9debba53326e529f3"/><file name="mixin-list-params.scss" hash="34478559346aec44c56c867a6b898af3"/><file name="mixin-params.css" hash="1a1f609e66c1dbe24383fe6855e95526"/><file name="mixin-params.scss" hash="a874ab4cacc02475acc827c956275cfe"/><file name="mixin-rgba-param.css" hash="bc5dc6caac3c74b37b82b1ed3cc2e553"/><file name="mixin-rgba-param.scss" hash="961219de858ecf7c17f2f7df24cf68cb"/><file name="mixin_bork.sass" hash="259fd0cca5a94583c0d406646b3217eb"/><file name="mixin_in_mixin.css" hash="46690de92ec525f39d5568bc2e46ee54"/><file name="mixin_in_mixin.scss" hash="0a6bef40d3215b63bb9f972896784a89"/><file name="mixin_setvar.css" hash="757520a01eca279c109d494d7fb4cd02"/><file name="mixin_setvar.scss" hash="12cd65c514056b3c0df1e4e92640a808"/><file name="mixins.css" hash="76ea6005844a4339745b1afe66274c74"/><file name="mixins.sass" hash="55fb1a104a59d6e5411987447af96b55"/><file name="multiline.css" hash="4a3d9bfe75a3b98c52ed95f3d785b079"/><file name="multiline.sass" hash="2f4ff6cfefa20eece2830170e29ea25e"/><file name="nested-media.css" hash="4fc2c8503b918fe9add9fcb230215fe2"/><file name="nested-media.scss" hash="2ee9901f1413f1f0839cfdc9b2ea00af"/><file name="nested.css" hash="26bd112a486652342cbfd55060552576"/><file name="nested.sass" hash="0bdc5d64efc02766544553f968bb82fd"/><file name="nested_bork1.sass" hash="56fa9072b6cc553909bfbd18f571a11d"/><file name="nested_bork2.sass" hash="999ae47bdbc6190972f0f52958870130"/><file name="nested_bork3.sass" hash="ccb998041d90cfe54a39f01afc4c4cc0"/><file name="nested_bork4.sass" hash="eed6453ea8564978c35d60f26a9bbb25"/><file name="nested_bork5.sass" hash="d6de98aee6d80aaecc1aa97311136003"/><file name="nested_import.css" hash="de8bc2a3cd89496c22ff564e65c2b046"/><file name="nested_import.sass" hash="b4493203dae52b5757ca91e17dd42e42"/><file name="nested_media.css" hash="d910a2026928133ce7235e8e1143a425"/><file name="nested_media.scss" hash="6e2dceddb572a0caa6f3959e00d332f4"/><file name="nested_mixin_bork.sass" hash="d9f57da9545e6c9a54d89bebe2f750b9"/><file name="nested_pseudo.css" hash="435b969153bc5030ceb8c251d241d358"/><file name="nested_pseudo.scss" hash="145d425a42541236d8952ea9f5e68ae7"/><file name="number.css" hash="000ca28603c30a49647d53bc5aabed94"/><file name="number.scss" hash="c585efaf419263809a1c91b76d8a0799"/><file name="opacity.css" hash="f54a7fbecddad66df7a6dae52bea4c21"/><file name="opacity.scss" hash="3a20a779e1becfcfaba90758d907c05e"/><file name="other-color.css" hash="45d9e1061d0e71b1c55362c2974b7bdf"/><file name="other-color.scss" hash="e2b8b86016461cbcdae6365ee14b0a5d"/><file name="parent_ref.css" hash="cbecced10861e9c060fa05187f94ee5f"/><file name="parent_ref.sass" hash="b5a3fe6fd3384b0853211e3515427796"/><file name="phpSassTest.php" hash="85b1d8fa19f923311ad45c00672a3a26"/><file name="phpunit.xml.dist" hash="3f11a2a97eb3d9b8bb48f60915daefda"/><file name="proprietary-selector.css" hash="6da7ab22184ed10ec679065835fc0f5f"/><file name="proprietary-selector.scss" hash="a7fa95fad2ae9aa0b93d8b49101eaf5f"/><file name="rgb-functions.css" hash="24177c2bc7b35526bf06334ea4174e27"/><file name="rgb-functions.scss" hash="7ad824885f782f15738ef67bbf00ae2a"/><file name="scss_import.css" hash="9eeec339e1ce59cbf3f2d29efab1382b"/><file name="scss_import.scss" hash="7ae409e52a06ad89582fe89063cf6bdd"/><file name="scss_importee.css" hash="7cad5194c7f7bb18e50f1ca093597033"/><file name="scss_importee.scss" hash="20c55fb516c7b137eadc6462f74cfa94"/><file name="splats.css" hash="3d11bc1d58858e4967ed498a3d75d008"/><file name="splats.scss" hash="4fab47d7391ff72a2e8d6de13c5e1b80"/><file name="string.css" hash="9f1482fe5b4964e96d24c00765c2503d"/><file name="string.scss" hash="f89f2aad48738bb1fa33a67f733e2e90"/><dir name="subdir"><dir name="nested_subdir"><file name="_nested_partial.sass" hash="24985866e9414ee4ef69621b738833ee"/><file name="nested_subdir.css" hash="759df6872a88c4174a39c32fe7d95a04"/><file name="nested_subdir.sass" hash="9e5e623f6765e28d5bec3bb2d3944eac"/></dir><file name="subdir.css" hash="ddd9dd41c2b72164a7ba634e359c2872"/><file name="subdir.sass" hash="acde24bd965d15ae3f19bf74b1f1c2a8"/></dir><file name="units.css" hash="ebc7390d227439bf2694a3ce29c54a6d"/><file name="units.sass" hash="040de247b027e6368c7edbc57d6e331f"/><file name="warn.css" hash="31c098880201803dc33c8785ecf3de26"/><file name="warn.sass" hash="47c7543a6a374523514669e108249f41"/><file name="warn_imported.sass" hash="2b7455acd686bf2511fce0b710874b01"/></dir><dir name="tree"><file name="SassCommentNode.php" hash="807249e546eb578d6087ed95e2f4e305"/><file name="SassContentNode.php" hash="2a20a58b2e1e43b82cac4cff908aa241"/><file name="SassContext.php" hash="4b7dc36ef0866a3678a0c53c5bb5a4b6"/><file name="SassDebugNode.php" hash="07c197af56822312088191a73e3225ff"/><file name="SassDirectiveNode.php" hash="813e62abcd27a49bbb2062e5a3e54acf"/><file name="SassEachNode.php" hash="c514b6b558faf12a5c56b233a9f4b01a"/><file name="SassElseNode.php" hash="1b5e603ccf2de0edfda2f7075e642dd2"/><file name="SassExtendNode.php" hash="d415ada9c7974775cc00de239ad8d8a2"/><file name="SassForNode.php" hash="9fc5364ce7a8c9557e26d62bd0aaeb59"/><file name="SassFunctionDefinitionNode.php" hash="67a5bf31c0e8f0225161f9ecdd61084e"/><file name="SassIfNode.php" hash="586e0ac2339af4e0836ee15168398801"/><file name="SassImportNode.php" hash="ea27128d9923cd0af8b7dae8b49edd69"/><file name="SassMediaNode.php" hash="8f88befb058bdb6f02c9f66bbca54b7a"/><file name="SassMixinDefinitionNode.php" hash="27fb3a6e0b141b8413ea657986950dcb"/><file name="SassMixinNode.php" hash="0112bd92ca1ddb3a180b28797bc8395b"/><file name="SassNode.php" hash="218a90269cb7f32ff47f94dee2af8b59"/><file name="SassNodeExceptions.php" hash="be582689b346f1ff54eba30d3e6550f5"/><file name="SassPropertyNode.php" hash="33312fdc1b87e96454363b3197f5ca9d"/><file name="SassReturnNode.php" hash="8218ceb0ed55b37c901d31952330d9c5"/><file name="SassRootNode.php" hash="5330f46536b9a7c8212b51516b35490a"/><file name="SassRuleNode.php" hash="3f3d01641155acdddd1322f3043b20dd"/><file name="SassVariableNode.php" hash="d15e503dd71000ae9100b473d1436f43"/><file name="SassWarnNode.php" hash="70875fe1e5d4e806def3d9b4984bb855"/><file name="SassWhileNode.php" hash="809afdba4213c5549dc7923125dbe10a"/></dir><file name=".travis.yml" hash="d0ac6ce1cf8465183941fa3ac326a54e"/></dir></target></contents>
21
  <compatible/>
22
+ <dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php></required></dependencies>
23
  </package>