summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEevee (Alex Munroe) <eevee.git@veekun.com>2013-08-14 16:57:45 -0700
committerEevee (Alex Munroe) <eevee.git@veekun.com>2013-08-23 15:54:31 -0700
commit650fe58375f01bc960038a65ac1d33f39a0d9242 (patch)
treea6d9dca5e9a10ff13668c52364c8567ca8292a8d
parent73dd6b1d65fca0b0b200f49212f4d33175bb8992 (diff)
downloadpyscss-650fe58375f01bc960038a65ac1d33f39a0d9242.tar.gz
Make variables in url() work. Greatly simplify #{} parsing.
-rw-r--r--scss/expression.parsley48
-rw-r--r--scss/expression.py32
-rw-r--r--scss/tests/files/original-doctests/001-variables.scss2
3 files changed, 37 insertions, 45 deletions
diff --git a/scss/expression.parsley b/scss/expression.parsley
index 39255b9..aad3878 100644
--- a/scss/expression.parsley
+++ b/scss/expression.parsley
@@ -86,7 +86,7 @@ atom = (
| '[' comma_list:node ']' -> Parentheses(node)
# URL literal
- | 'u' 'r' 'l' '(' (string | uri):s ')' -> FunctionLiteral('url', s)
+ | 'u' 'r' 'l' '(' inside_url:s ')' -> FunctionLiteral('url', s)
# Function call
| identifier:name '(' argspec:args ')' -> CallOp(name, args)
@@ -118,36 +118,36 @@ atom = (
# TODO I'm not entirely sure any of these character classes are correct
# TODO ruby sass appears to preserve escapes
-uri = (
- escape
- | anything:ch ?(ord(ch) > 32 and ch not in ' !"$\'()') -> ch
- )*:s -> Literal(String(''.join(s), quotes=None))
+inside_url = (
+ interpolation:node -> node
+ | variable:name -> Variable(name)
+ | (
+ escape
+ | '#' ~'{'
+ | anything:ch ?(ord(ch) > 32 and ch not in ' !"#$\'()') -> ch
+ )+:s -> Literal(String(''.join(s), quotes=None))
+ | string_part(')'):s -> Literal(String(s, quotes=None))
+ )*:nodes
+ -> Interpolation(nodes, quotes=None)
string = (
- '"' string_contents('"'):node '"' -> node
- | '\'' string_contents('\''):node '\'' -> node
+ '"' string_contents('"' '"'):node '"' -> node
+ | '\'' string_contents('\'' '\''):node '\'' -> node
)
interpolation = '#' '{' expression:node '}' -> node
-string_contents :quote = (
- (
- string_part(quote):before
- -> Literal(String(before, quotes=quote))
- ):retval
- (
- (
- interpolation:node
- string_part(quote):after
- -> Interpolation(retval, node, Literal(String(after, quotes=quote)), quotes=quote)
- ):retval
- )*
- ) -> retval
-
-string_part :quote = <(
+string_contents :end :quotes =
+ (
+ interpolation:node -> node
+ | string_part(end):s -> Literal(String(s, quotes=quotes))
+ )*:nodes
+ -> Interpolation(nodes, quotes=quotes)
+
+string_part :end = <(
'#' ~'{'
- | anything:ch ?(ch not in ('#', quote))
- )*>
+ | anything:ch ?(ch not in ('#', end))
+ )+>
### Function definitions and arguments
diff --git a/scss/expression.py b/scss/expression.py
index 7a8a4af..ebec7e2 100644
--- a/scss/expression.py
+++ b/scss/expression.py
@@ -82,6 +82,8 @@ def get_grammar():
from parsley import wrapGrammar
from ometa.grammar import loadGrammar
grammar = loadGrammar(scss, 'expression', globals(), superclass=GrammarBase)
+ def tracer(rule, rule_offset, pos):
+ print("trace @", pos, ">", repr(rule))
_grammar = wrapGrammar(grammar)
return _grammar
@@ -541,30 +543,20 @@ class ArgspecLiteral(Expression):
class Interpolation(Expression):
- def __init__(self, left, expr, right, quotes):
- self.left = left
- self.expr = expr
- self.right = right
+ def __init__(self, parts, quotes=None):
+ self.parts = parts
self.quotes = quotes
def evaluate(self, calculator, divide=False):
- left_scss = self.left.evaluate(calculator)
- if not isinstance(left_scss, String):
- raise TypeError("Expected left side of interpolation to be String, got %r" % (left,))
- left = left_scss.value
-
- right_scss = self.right.evaluate(calculator)
- if not isinstance(right_scss, String):
- raise TypeError("Expected right side of interpolation to be String, got %r" % (left,))
- right = right_scss.value
-
- expr = self.expr.evaluate(calculator)
- if isinstance(expr, String):
- middle = expr.value
- else:
- middle = expr.render()
+ ret = []
+ for part in self.parts:
+ expr = part.evaluate(calculator)
+ if isinstance(expr, String):
+ ret.append(expr.value)
+ else:
+ ret.append(expr.render())
- return String(left + middle + right, quotes=self.quotes)
+ return String(''.join(ret), quotes=self.quotes)
def parse_bareword(word):
diff --git a/scss/tests/files/original-doctests/001-variables.scss b/scss/tests/files/original-doctests/001-variables.scss
index 7e2edc1..dc7e8ff 100644
--- a/scss/tests/files/original-doctests/001-variables.scss
+++ b/scss/tests/files/original-doctests/001-variables.scss
@@ -1,6 +1,6 @@
@option compress:no, short_colors:yes, reverse_colors:yes;
@variables {
- $path = ../img/tmpl1/png;
+ $path = '../img/tmpl1/png';
$color1 = #FF00FF;
$border = border-top: 1px solid $color1;
}