From 0773b2c16c9d15f2dc76f7a4d49e98c1e5f59ea2 Mon Sep 17 00:00:00 2001 From: "Eevee (Alex Munroe)" Date: Tue, 27 Aug 2013 15:22:32 -0700 Subject: At long last, kill ParserValue and most of the Color constructor. --- scss/expression.py | 6 +++--- scss/src/grammar/grammar.g | 4 ++-- scss/tests/test_expression.py | 2 +- scss/types.py | 37 ++++++++++++------------------------- 4 files changed, 18 insertions(+), 31 deletions(-) diff --git a/scss/expression.py b/scss/expression.py index c2667f0..45c6bca 100644 --- a/scss/expression.py +++ b/scss/expression.py @@ -11,7 +11,7 @@ import scss.config as config from scss.cssdefs import COLOR_NAMES, is_builtin_css_function, _expr_glob_re, _interpolate_re, _variable_re from scss.errors import SassError, SassEvaluationError, SassParseError from scss.rule import Namespace -from scss.types import Boolean, Color, List, Map, Null, Number, ParserValue, String, Undefined, Value +from scss.types import Boolean, Color, List, Map, Null, Number, String, Undefined, Value from scss.util import dequote, normalize_var ################################################################################ @@ -802,7 +802,7 @@ class SassExpression(Parser): return Literal(String(QSTR[1:-1], quotes='"')) elif _token_ == 'COLOR': COLOR = self._scan('COLOR') - return Literal(Color(ParserValue(COLOR))) + return Literal(Color.from_hex(COLOR, literal=True)) else: # == 'VAR' VAR = self._scan('VAR') return Variable(VAR) @@ -828,7 +828,7 @@ class SassExpression(Parser): return Literal(String(KWQSTR[1:-1], quotes='"')) elif _token_ == 'KWCOLOR': KWCOLOR = self._scan('KWCOLOR') - return Literal(Color(ParserValue(KWCOLOR))) + return Literal(Color.from_hex(COLOR, literal=True)) else: # == 'KWVAR' KWVAR = self._scan('KWVAR') return Variable(KWVAR) diff --git a/scss/src/grammar/grammar.g b/scss/src/grammar/grammar.g index d6d663e..20a6cbf 100644 --- a/scss/src/grammar/grammar.g +++ b/scss/src/grammar/grammar.g @@ -141,7 +141,7 @@ parser SassExpression: [ UNITS ] {{ return Literal(Number(float(NUM), unit=UNITS)) }} | STR {{ return Literal(String(STR[1:-1], quotes="'")) }} | QSTR {{ return Literal(String(QSTR[1:-1], quotes='"')) }} - | COLOR {{ return Literal(Color(ParserValue(COLOR))) }} + | COLOR {{ return Literal(Color.from_hex(COLOR, literal=True)) }} | VAR {{ return Variable(VAR) }} rule kwatom: @@ -150,7 +150,7 @@ parser SassExpression: [ UNITS ] {{ return Literal(Number(float(KWNUM), unit=UNITS)) }} | KWSTR {{ return Literal(String(KWSTR[1:-1], quotes="'")) }} | KWQSTR {{ return Literal(String(KWQSTR[1:-1], quotes='"')) }} - | KWCOLOR {{ return Literal(Color(ParserValue(KWCOLOR))) }} + | KWCOLOR {{ return Literal(Color.from_hex(COLOR, literal=True)) }} | KWVAR {{ return Variable(KWVAR) }} %% ### Grammar ends. diff --git a/scss/tests/test_expression.py b/scss/tests/test_expression.py index a16950e..4798006 100644 --- a/scss/tests/test_expression.py +++ b/scss/tests/test_expression.py @@ -80,7 +80,7 @@ def test_functions(calc): ns = Namespace(functions=CORE_LIBRARY) calc = Calculator(ns).calculate - assert calc('grayscale(red)') == Color((127.5, 127.5, 127.5, 1)) + assert calc('grayscale(red)') == Color.from_rgb(0.5, 0.5, 0.5) assert calc('grayscale(1)') == String('grayscale(1)', quotes=None) # Misusing css built-in functions (with scss counterpart) assert calc('skew(1)') == String('skew(1)', quotes=None) # Missing css-only built-in functions with pytest.raises(TypeError): diff --git a/scss/types.py b/scss/types.py index 0a4c293..1040537 100644 --- a/scss/types.py +++ b/scss/types.py @@ -14,11 +14,6 @@ from scss.util import escape ################################################################################ # pyScss data types: -class ParserValue(object): - def __init__(self, value): - self.value = value - - class Value(object): is_null = False sass_type_name = u'unknown' @@ -636,14 +631,6 @@ def _constrain(value, lb=0, ub=1): class Color(Value): sass_type_name = u'color' - - HEX2RGBA = { - 9: lambda c: (int(c[1:3], 16), int(c[3:5], 16), int(c[5:7], 16), int(c[7:9], 16)), - 7: lambda c: (int(c[1:3], 16), int(c[3:5], 16), int(c[5:7], 16), 1.0), - 5: lambda c: (int(c[1] * 2, 16), int(c[2] * 2, 16), int(c[3] * 2, 16), int(c[4] * 2, 16)), - 4: lambda c: (int(c[1] * 2, 16), int(c[2] * 2, 16), int(c[3] * 2, 16), 1.0), - } - original_literal = None def __init__(self, tokens): @@ -651,24 +638,15 @@ class Color(Value): self.value = (0, 0, 0, 1) if tokens is None: self.value = (0, 0, 0, 1) - elif isinstance(tokens, ParserValue): - hex = tokens.value - self.original_literal = hex - self.value = self.HEX2RGBA[len(hex)](hex) elif isinstance(tokens, Color): self.value = tokens.value - elif isinstance(tokens, (list, tuple)): - c = tokens[:4] - r = 255.0, 255.0, 255.0, 1.0 - c = [0.0 if c[i] < 0 else r[i] if c[i] > r[i] else c[i] for i in range(4)] - self.value = tuple(c) else: raise TypeError("Can't make Color from %r" % (tokens,)) ### Alternate constructors @classmethod - def from_rgb(cls, red, green, blue, alpha=1.0): + def from_rgb(cls, red, green, blue, alpha=1.0, original_literal=None): red = _constrain(red) green = _constrain(green) blue = _constrain(blue) @@ -679,6 +657,10 @@ class Color(Value): # TODO really should store these things internally as 0-1, but can't # until stuff stops examining .value directly self.value = (red * 255.0, green * 255.0, blue * 255.0, alpha) + + if original_literal is not None: + self.original_literal = original_literal + return self @classmethod @@ -692,10 +674,15 @@ class Color(Value): return cls.from_rgb(r, g, b, alpha) @classmethod - def from_hex(cls, hex_string): + def from_hex(cls, hex_string, literal=False): if not hex_string.startswith('#'): raise ValueError("Expected #abcdef, got %r" % (hex_string,)) + if literal: + original_literal = hex_string + else: + original_literal = None + hex_string = hex_string[1:] # Always include the alpha channel @@ -714,7 +701,7 @@ class Color(Value): ] rgba = [int(ch, 16) / 255 for ch in chunks] - return cls.from_rgb(*rgba) + return cls.from_rgb(*rgba, original_literal=original_literal) @classmethod def from_name(cls, name): -- cgit v1.2.1