summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEevee (Alex Munroe) <eevee.git@veekun.com>2013-08-23 16:21:43 -0700
committerEevee (Alex Munroe) <eevee.git@veekun.com>2013-08-23 16:21:43 -0700
commit930e7382d41f450f8aa4bb29649204683a07353a (patch)
treed33c4980bd21373868a812029d0092b47e7521f5
parent444ac8f8b4e5d167050b3d0eb0869bce5335aa33 (diff)
downloadpyscss-parsley.tar.gz
Map literals in Parsley, and a few other minor fixes.parsley
- Labels for some of the rules. - Faux goal_argspec rule to play nicely with parse_expression. - Wrap ParseErrors in SassParseError. - Ruby's interp-and-slash test now passes exactly. - Don't render nulls in an interpolation.
-rw-r--r--scss/expression.parsley24
-rw-r--r--scss/expression.py8
-rw-r--r--scss/tests/test_expression.py3
3 files changed, 28 insertions, 7 deletions
diff --git a/scss/expression.parsley b/scss/expression.parsley
index 77b41fa..8fc35bf 100644
--- a/scss/expression.parsley
+++ b/scss/expression.parsley
@@ -38,7 +38,7 @@ spaced_list = single_expression:head (
)*:tails -> ListLiteral([head] + tails, comma=False) if tails else head
-single_expression = or_test
+single_expression = or_test ^(single expression)
or_test = and_test:head (
'o' 'r'
@@ -97,6 +97,9 @@ atom = (
# TODO kill this off
| '[' comma_list:node ']' -> Parentheses(node)
+ # Map literal
+ | map
+
# URL literal
| 'u' 'r' 'l' '(' inside_url:s ')' -> FunctionLiteral('url', s)
@@ -135,6 +138,21 @@ atom = (
# Variable
| variable:name -> Variable(name)
)
+ ^(single value)
+
+
+### Map literals
+map = '(' ows
+ ( map_pair:pair ows ',' ows -> pair )*:pairs
+ ( map_pair:pair ows !(pairs.append(pair)) )?
+ ')'
+ -> MapLiteral(pairs)
+
+map_pair =
+ single_expression:key
+ ows ':' ows
+ spaced_list:value
+ -> (key, value)
### Strings, literals, and interpolation
@@ -174,6 +192,8 @@ string_part :end = <(
### Function definitions and arguments
+goal_argspec = argspec
+
argspec = (
argspec_item:node
ows ',' ows
@@ -186,7 +206,7 @@ argspec = (
argspec_item =
ows
(
- ( variable:name ows ':' ows -> name )?:name
+ ( variable:name ows ':' ows -> Variable(name) )?:name
spaced_list:value
-> (name, value)
)
diff --git a/scss/expression.py b/scss/expression.py
index ebec7e2..bd19031 100644
--- a/scss/expression.py
+++ b/scss/expression.py
@@ -29,7 +29,7 @@ log = logging.getLogger(__name__)
FATAL_UNDEFINED = True
-from ometa.runtime import EOFError, OMetaBase, expected
+from ometa.runtime import EOFError, OMetaBase, ParseError, expected
import string
HEXDIGITS = frozenset(string.hexdigits)
WHITESPACE = frozenset(' \n\r\t\f')
@@ -224,7 +224,7 @@ class Calculator(object):
ast = getattr(parser, target)()
print(repr(ast))
- except SyntaxError as e:
+ except (SyntaxError, ParseError) as e:
raise SassParseError(e, expression=expr, expression_pos=parser._char_pos)
self.ast_cache[key] = ast
@@ -551,7 +551,9 @@ class Interpolation(Expression):
ret = []
for part in self.parts:
expr = part.evaluate(calculator)
- if isinstance(expr, String):
+ if expr.is_null:
+ pass
+ elif isinstance(expr, String):
ret.append(expr.value)
else:
ret.append(expr.render())
diff --git a/scss/tests/test_expression.py b/scss/tests/test_expression.py
index a16950e..848d9ce 100644
--- a/scss/tests/test_expression.py
+++ b/scss/tests/test_expression.py
@@ -43,8 +43,7 @@ def test_reference_operations():
assert calc('$width/2') == Number(500, "px") # uses a variable; does division
assert calc('(500px/2)') == Number(250, "px") # uses parens; does division
assert calc('5px + 8px/2px') == Number(9, "px") # uses +; does division
- # TODO: Ruby doesn't include these spaces
- assert calc('#{$font-size}/#{$line-height}') == String('12px / 30px')
+ assert calc('#{$font-size}/#{$line-height}') == String('12px/30px')
# uses #{}; does no division
# Color operations