summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--README.rst1
-rw-r--r--scss/__init__.py46
-rw-r--r--scss/src/grammar/grammar.g32
-rw-r--r--scss/src/grammar/grammar.py32
5 files changed, 57 insertions, 55 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 1770888..2333b77 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@ Changelog
1.1.4 ???
+ Added ``--debug-info`` command line option (for *FireSass* output).
+ Added compass helper function ``reject()``.
+ + Added ``undefined`` keyword for undefined variables.
1.1.3 Jan 9, 2012
+ Support for the new Sass 3.2.0 features (``@content`` and placeholder selectors)
diff --git a/README.rst b/README.rst
index 5e6b4bb..068710e 100644
--- a/README.rst
+++ b/README.rst
@@ -275,6 +275,7 @@ Changelog
1.1.4 ???
+ Added ``--debug-info`` command line option (for *FireSass* output).
+ Added compass helper function ``reject()``.
+ + Added ``undefined`` keyword for undefined variables.
1.1.3 Jan 9, 2012
+ Support for the new Sass 3.2.0 features (``@content`` and placeholder selectors)
diff --git a/scss/__init__.py b/scss/__init__.py
index 030fc03..aaf6f94 100644
--- a/scss/__init__.py
+++ b/scss/__init__.py
@@ -950,7 +950,7 @@ class Scss(object):
name = name.strip()
if name.lower() in ('1', 'true', 't', 'yes', 'y', 'on'):
name = 1
- elif name.lower() in ('0', 'false', 'f', 'no', 'n', 'off'):
+ elif name.lower() in ('0', 'false', 'f', 'no', 'n', 'off', 'undefined'):
name = 0
DEBUG = name
log.info("Debug mode is %s", 'On' if DEBUG else 'Off')
@@ -1013,7 +1013,7 @@ class Scss(object):
if option:
if value.lower() in ('1', 'true', 't', 'yes', 'y', 'on'):
value = 1
- elif value.lower() in ('0', 'false', 'f', 'no', 'n', 'off'):
+ elif value.lower() in ('0', 'false', 'f', 'no', 'n', 'off', 'undefined'):
value = 0
rule[OPTIONS][option] = value
@@ -1293,7 +1293,7 @@ class Scss(object):
val = True
if val:
val = self.calculate(name, rule[CONTEXT], rule[OPTIONS], rule)
- val = bool(False if not val or val in('0', 'false',) or (isinstance(val, basestring) and _variable_re.match(val)) else val)
+ val = bool(False if not val or isinstance(val, basestring) and (val in ('0', 'false', 'undefined') or _variable_re.match(val)) else val)
if val:
rule[CODESTR] = c_codestr
self.manage_children(rule, p_selectors, p_parents, p_children, scope, media)
@@ -1370,7 +1370,7 @@ class Scss(object):
# first_val = None
# while True:
# val = self.calculate(name, rule[CONTEXT], rule[OPTIONS], rule)
- # val = bool(False if not val or val in('0', 'false',) or (isinstance(val, basestring) and _variable_re.match(val)) else val)
+ # val = bool(False if not val or isinstance(val, basestring) and (val in ('0', 'false', 'undefined') or _variable_re.match(val)) else val)
# if first_val is None:
# first_val = val
# if not val:
@@ -3578,7 +3578,7 @@ def _type_of(obj): # -> bool, number, string, color, list
def _if(condition, if_true, if_false=''):
- condition = bool(False if not condition or condition in('0', 'false',) or (isinstance(condition, basestring) and _variable_re.match(condition)) else condition)
+ condition = bool(False if not condition or isinstance(condition, basestring) and (condition in ('0', 'false', 'undefined') or _variable_re.match(condition)) else condition)
return if_true.__class__(if_true) if condition else if_true.__class__(if_false)
@@ -3902,11 +3902,11 @@ class BooleanValue(Value):
second = second.value if isinstance(second, Value) else second
if first in ('true', '1', 'on', 'yes', 't', 'y'):
first = True
- elif first in ('false', '0', 'off', 'no', 'f', 'n'):
+ elif first in ('false', '0', 'off', 'no', 'f', 'n', 'undefined'):
first = False
if second in ('true', '1', 'on', 'yes', 't', 'y'):
second = True
- elif second in ('false', '0', 'off', 'no', 'f', 'n'):
+ elif second in ('false', '0', 'off', 'no', 'f', 'n', 'undefined'):
second = False
return op(first, second)
@@ -4937,7 +4937,7 @@ class Calculator(Parser):
while self._peek(self.expr_rsts) == 'OR':
OR = self._scan('OR')
and_test = self.and_test(R)
- v = v or and_test
+ v = and_test if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v or and_test)
return v
def and_test(self, R):
@@ -4946,7 +4946,7 @@ class Calculator(Parser):
while self._peek(self.and_test_rsts) == 'AND':
AND = self._scan('AND')
not_test = self.not_test(R)
- v = v and not_test
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v and not_test)
return v
def not_test(self, R):
@@ -4960,11 +4960,11 @@ class Calculator(Parser):
if _token_ == 'NOT':
NOT = self._scan('NOT')
not_test = self.not_test(R)
- v = not not_test
+ v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else (not not_test)
else: # == 'INV'
INV = self._scan('INV')
not_test = self.not_test(R)
- v = _inv('!', not_test)
+ v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else _inv('!', not_test)
if self._peek(self.not_test_rsts_) not in self.not_test_chks:
break
return v
@@ -4977,27 +4977,27 @@ class Calculator(Parser):
if _token_ == 'LT':
LT = self._scan('LT')
a_expr = self.a_expr(R)
- v = v < a_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v < a_expr)
elif _token_ == 'GT':
GT = self._scan('GT')
a_expr = self.a_expr(R)
- v = v > a_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v > a_expr)
elif _token_ == 'LE':
LE = self._scan('LE')
a_expr = self.a_expr(R)
- v = v <= a_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v <= a_expr)
elif _token_ == 'GE':
GE = self._scan('GE')
a_expr = self.a_expr(R)
- v = v >= a_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v >= a_expr)
elif _token_ == 'EQ':
EQ = self._scan('EQ')
a_expr = self.a_expr(R)
- v = v == a_expr
+ v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) == (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr)
else: # == 'NE'
NE = self._scan('NE')
a_expr = self.a_expr(R)
- v = v != a_expr
+ v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) != (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr)
return v
def a_expr(self, R):
@@ -5008,11 +5008,11 @@ class Calculator(Parser):
if _token_ == 'ADD':
ADD = self._scan('ADD')
m_expr = self.m_expr(R)
- v = v + m_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v + m_expr)
else: # == 'SUB'
SUB = self._scan('SUB')
m_expr = self.m_expr(R)
- v = v - m_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v - m_expr)
return v
def m_expr(self, R):
@@ -5023,11 +5023,11 @@ class Calculator(Parser):
if _token_ == 'MUL':
MUL = self._scan('MUL')
u_expr = self.u_expr(R)
- v = v * u_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v * u_expr)
else: # == 'DIV'
DIV = self._scan('DIV')
u_expr = self.u_expr(R)
- v = v / u_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v / u_expr)
return v
def u_expr(self, R):
@@ -5035,11 +5035,11 @@ class Calculator(Parser):
if _token_ == 'SIGN':
SIGN = self._scan('SIGN')
u_expr = self.u_expr(R)
- return _inv('-', u_expr)
+ return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else _inv('-', u_expr)
elif _token_ == 'ADD':
ADD = self._scan('ADD')
u_expr = self.u_expr(R)
- return u_expr
+ return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else u_expr
else: # in self.u_expr_chks
atom = self.atom(R)
v = atom
diff --git a/scss/src/grammar/grammar.g b/scss/src/grammar/grammar.g
index 913a632..a7966d3 100644
--- a/scss/src/grammar/grammar.g
+++ b/scss/src/grammar/grammar.g
@@ -72,48 +72,48 @@ parser Calculator:
END {{ return v }}
rule expr<<R>>: and_test<<R>> {{ v = and_test }}
(
- OR and_test<<R>> {{ v = v or and_test }}
+ OR and_test<<R>> {{ v = and_test if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v or and_test) }}
)* {{ return v }}
rule and_test<<R>>: not_test<<R>> {{ v = not_test }}
(
- AND not_test<<R>> {{ v = v and not_test }}
+ AND not_test<<R>> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v and not_test) }}
)* {{ return v }}
rule not_test<<R>>: comparison<<R>> {{ return comparison }}
|
(
- NOT not_test<<R>> {{ v = not not_test }}
+ NOT not_test<<R>> {{ v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else (not not_test) }}
|
- INV not_test<<R>> {{ v = _inv('!', not_test) }}
+ INV not_test<<R>> {{ v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else _inv('!', not_test) }}
)+ {{ return v }}
rule comparison<<R>>: a_expr<<R>> {{ v = a_expr }}
(
- LT a_expr<<R>> {{ v = v < a_expr }}
+ LT a_expr<<R>> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v < a_expr) }}
|
- GT a_expr<<R>> {{ v = v > a_expr }}
+ GT a_expr<<R>> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v > a_expr) }}
|
- LE a_expr<<R>> {{ v = v <= a_expr }}
+ LE a_expr<<R>> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v <= a_expr) }}
|
- GE a_expr<<R>> {{ v = v >= a_expr }}
+ GE a_expr<<R>> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v >= a_expr) }}
|
- EQ a_expr<<R>> {{ v = v == a_expr }}
+ EQ a_expr<<R>> {{ v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) == (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr) }}
|
- NE a_expr<<R>> {{ v = v != a_expr }}
+ NE a_expr<<R>> {{ v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) != (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr) }}
)* {{ return v }}
rule a_expr<<R>>: m_expr<<R>> {{ v = m_expr }}
(
- ADD m_expr<<R>> {{ v = v + m_expr }}
+ ADD m_expr<<R>> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v + m_expr) }}
|
- SUB m_expr<<R>> {{ v = v - m_expr }}
+ SUB m_expr<<R>> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v - m_expr) }}
)* {{ return v }}
rule m_expr<<R>>: u_expr<<R>> {{ v = u_expr }}
(
- MUL u_expr<<R>> {{ v = v * u_expr }}
+ MUL u_expr<<R>> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v * u_expr) }}
|
- DIV u_expr<<R>> {{ v = v / u_expr }}
+ DIV u_expr<<R>> {{ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v / u_expr) }}
)* {{ return v }}
- rule u_expr<<R>>: SIGN u_expr<<R>> {{ return _inv('-', u_expr) }}
+ rule u_expr<<R>>: SIGN u_expr<<R>> {{ return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else _inv('-', u_expr) }}
|
- ADD u_expr<<R>> {{ return u_expr }}
+ ADD u_expr<<R>> {{ return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else u_expr }}
|
atom<<R>> {{ v = atom }}
[
diff --git a/scss/src/grammar/grammar.py b/scss/src/grammar/grammar.py
index cce032f..88f374a 100644
--- a/scss/src/grammar/grammar.py
+++ b/scss/src/grammar/grammar.py
@@ -101,7 +101,7 @@ class Calculator(Parser):
while self._peek(self.expr_rsts) == 'OR':
OR = self._scan('OR')
and_test = self.and_test(R)
- v = v or and_test
+ v = and_test if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v or and_test)
return v
def and_test(self, R):
@@ -110,7 +110,7 @@ class Calculator(Parser):
while self._peek(self.and_test_rsts) == 'AND':
AND = self._scan('AND')
not_test = self.not_test(R)
- v = v and not_test
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else (v and not_test)
return v
def not_test(self, R):
@@ -124,11 +124,11 @@ class Calculator(Parser):
if _token_ == 'NOT':
NOT = self._scan('NOT')
not_test = self.not_test(R)
- v = not not_test
+ v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else (not not_test)
else: # == 'INV'
INV = self._scan('INV')
not_test = self.not_test(R)
- v = _inv('!', not_test)
+ v = 'undefined' if isinstance(not_test, basestring) and (not_test == 'undefined' or not_test.startswith('$')) else _inv('!', not_test)
if self._peek(self.not_test_rsts_) not in self.not_test_chks:
break
return v
@@ -141,27 +141,27 @@ class Calculator(Parser):
if _token_ == 'LT':
LT = self._scan('LT')
a_expr = self.a_expr(R)
- v = v < a_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v < a_expr)
elif _token_ == 'GT':
GT = self._scan('GT')
a_expr = self.a_expr(R)
- v = v > a_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v > a_expr)
elif _token_ == 'LE':
LE = self._scan('LE')
a_expr = self.a_expr(R)
- v = v <= a_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v <= a_expr)
elif _token_ == 'GE':
GE = self._scan('GE')
a_expr = self.a_expr(R)
- v = v >= a_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else (v >= a_expr)
elif _token_ == 'EQ':
EQ = self._scan('EQ')
a_expr = self.a_expr(R)
- v = v == a_expr
+ v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) == (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr)
else: # == 'NE'
NE = self._scan('NE')
a_expr = self.a_expr(R)
- v = v != a_expr
+ v = (None if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) else v) != (None if isinstance(a_expr, basestring) and (a_expr == 'undefined' or a_expr.startswith('$')) else a_expr)
return v
def a_expr(self, R):
@@ -172,11 +172,11 @@ class Calculator(Parser):
if _token_ == 'ADD':
ADD = self._scan('ADD')
m_expr = self.m_expr(R)
- v = v + m_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v + m_expr)
else: # == 'SUB'
SUB = self._scan('SUB')
m_expr = self.m_expr(R)
- v = v - m_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(m_expr, basestring) and (m_expr == 'undefined' or m_expr.startswith('$')) else (v - m_expr)
return v
def m_expr(self, R):
@@ -187,11 +187,11 @@ class Calculator(Parser):
if _token_ == 'MUL':
MUL = self._scan('MUL')
u_expr = self.u_expr(R)
- v = v * u_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v * u_expr)
else: # == 'DIV'
DIV = self._scan('DIV')
u_expr = self.u_expr(R)
- v = v / u_expr
+ v = 'undefined' if isinstance(v, basestring) and (v == 'undefined' or v.startswith('$')) or isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else (v / u_expr)
return v
def u_expr(self, R):
@@ -199,11 +199,11 @@ class Calculator(Parser):
if _token_ == 'SIGN':
SIGN = self._scan('SIGN')
u_expr = self.u_expr(R)
- return _inv('-', u_expr)
+ return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else _inv('-', u_expr)
elif _token_ == 'ADD':
ADD = self._scan('ADD')
u_expr = self.u_expr(R)
- return u_expr
+ return 'undefined' if isinstance(u_expr, basestring) and (u_expr == 'undefined' or u_expr.startswith('$')) else u_expr
else: # in self.u_expr_chks
atom = self.atom(R)
v = atom