diff options
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | README.rst | 1 | ||||
-rw-r--r-- | scss/__init__.py | 46 | ||||
-rw-r--r-- | scss/src/grammar/grammar.g | 32 | ||||
-rw-r--r-- | scss/src/grammar/grammar.py | 32 |
5 files changed, 57 insertions, 55 deletions
@@ -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) @@ -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 |