summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEevee (Alex Munroe) <eevee.git@veekun.com>2013-08-09 17:27:54 -0700
committerEevee (Alex Munroe) <eevee.git@veekun.com>2013-08-09 17:27:54 -0700
commitfb3f1b12a80c54b4e50b263405efb792b1d0bc6e (patch)
treece27c8d19bb00c05adbf624529213c26ae0af2d8
parent6f9547f7ffcbdec7a29e5f7976e1e7b81c092b9e (diff)
downloadpyscss-fb3f1b12a80c54b4e50b263405efb792b1d0bc6e.tar.gz
Simplified ColorValue considerably.
- Rendering now follows Ruby's rules: shortest representation when compressing, otherwise use the original literal, the name, and hex notation in that order. - The old __str__ fallback is gone. - The `types` attribute is no longer needed. - The strange `merge` method is no longer needed. - Got rid of a couple uses of `to_str`, and made it aware of how to render types.
-rw-r--r--scss/expression.py5
-rw-r--r--scss/functions/core.py5
-rw-r--r--scss/tests/files/original-doctests/001-variables.css4
-rw-r--r--scss/tests/files/original-doctests/005-extends.css2
-rw-r--r--scss/tests/files/original-doctests/006-extends-2.css2
-rw-r--r--scss/tests/files/original-doctests/007-extends-3.css2
-rw-r--r--scss/tests/files/original-doctests/008-extends-4.css2
-rw-r--r--scss/tests/files/original-doctests/009-extends-5.css2
-rw-r--r--scss/tests/files/original-doctests/010-math.css2
-rw-r--r--scss/tests/files/original-doctests/021-extend.css2
-rw-r--r--scss/tests/files/original-doctests/022-extend-multiple.css2
-rw-r--r--scss/tests/files/original-doctests/023-extend-multiple-2.scss4
-rw-r--r--scss/tests/files/original-doctests/026-forum-2.scss10
-rw-r--r--scss/tests/files/original-doctests/027-forum-3.css2
-rw-r--r--scss/tests/test_expression.py2
-rw-r--r--scss/tests/test_misc.py2
-rw-r--r--scss/types.py103
-rw-r--r--scss/util.py7
18 files changed, 53 insertions, 107 deletions
diff --git a/scss/expression.py b/scss/expression.py
index b3224e5..55a1bdd 100644
--- a/scss/expression.py
+++ b/scss/expression.py
@@ -39,7 +39,7 @@ class Calculator(object):
if better_expr_str is None:
better_expr_str = self.apply_vars(_base_str)
else:
- better_expr_str = dequote(str(to_str(better_expr_str)))
+ better_expr_str = dequote(better_expr_str.render())
return better_expr_str
@@ -65,7 +65,8 @@ class Calculator(object):
def _av(m):
v = self.namespace.variable(m.group(2))
if v:
- v = to_str(v)
+ if not isinstance(v, six.string_types):
+ v = v.render()
# TODO this used to test for _dequote
if m.group(1):
v = dequote(v)
diff --git a/scss/functions/core.py b/scss/functions/core.py
index 2d49a0d..5f36be3 100644
--- a/scss/functions/core.py
+++ b/scss/functions/core.py
@@ -175,10 +175,7 @@ def mix(color1, color2, weight=None):
q = [w1, w1, w1, p]
r = [w2, w2, w2, 1 - p]
- color = ColorValue(None).merge(c1).merge(c2)
- color.value = [c1[i] * q[i] + c2[i] * r[i] for i in range(4)]
-
- return color
+ return ColorValue([c1[i] * q[i] + c2[i] * r[i] for i in range(4)])
# ------------------------------------------------------------------------------
diff --git a/scss/tests/files/original-doctests/001-variables.css b/scss/tests/files/original-doctests/001-variables.css
index f47ad65..e2f060c 100644
--- a/scss/tests/files/original-doctests/001-variables.css
+++ b/scss/tests/files/original-doctests/001-variables.css
@@ -1,5 +1,5 @@
.selector {
background-image: url(../img/tmpl1/png/head_bg.png);
- background-color: #f0f;
- border-top: 1px solid #f0f;
+ background-color: #FF00FF;
+ border-top: 1px solid #FF00FF;
}
diff --git a/scss/tests/files/original-doctests/005-extends.css b/scss/tests/files/original-doctests/005-extends.css
index a72e6cc..73bc78d 100644
--- a/scss/tests/files/original-doctests/005-extends.css
+++ b/scss/tests/files/original-doctests/005-extends.css
@@ -1,4 +1,4 @@
.basicClass, .specialClass {
padding: 20px;
- background-color: red;
+ background-color: #FF0000;
}
diff --git a/scss/tests/files/original-doctests/006-extends-2.css b/scss/tests/files/original-doctests/006-extends-2.css
index 5218394..707315e 100644
--- a/scss/tests/files/original-doctests/006-extends-2.css
+++ b/scss/tests/files/original-doctests/006-extends-2.css
@@ -1,6 +1,6 @@
.basicClass, .specialClass {
padding: 20px;
- background-color: red;
+ background-color: #FF0000;
}
.specialClass {
padding: 10px;
diff --git a/scss/tests/files/original-doctests/007-extends-3.css b/scss/tests/files/original-doctests/007-extends-3.css
index 93e30fa..1b17778 100644
--- a/scss/tests/files/original-doctests/007-extends-3.css
+++ b/scss/tests/files/original-doctests/007-extends-3.css
@@ -1,6 +1,6 @@
.basicClass, .specialClass {
padding: 20px;
- background-color: red;
+ background-color: #FF0000;
}
.basicClass a, .specialClass a, .specialLink {
text-decoration: none;
diff --git a/scss/tests/files/original-doctests/008-extends-4.css b/scss/tests/files/original-doctests/008-extends-4.css
index 76b7e02..7286429 100644
--- a/scss/tests/files/original-doctests/008-extends-4.css
+++ b/scss/tests/files/original-doctests/008-extends-4.css
@@ -1,6 +1,6 @@
.basicList li, .specialClass li {
padding: 5px 10px;
- border-bottom: 1px solid #000;
+ border-bottom: 1px solid #000000;
}
.basicList dd, .specialClass dd {
margin: 4px;
diff --git a/scss/tests/files/original-doctests/009-extends-5.css b/scss/tests/files/original-doctests/009-extends-5.css
index ee1ca33..a46e22d 100644
--- a/scss/tests/files/original-doctests/009-extends-5.css
+++ b/scss/tests/files/original-doctests/009-extends-5.css
@@ -1,6 +1,6 @@
.basicList li, .specialClass dt {
padding: 5px 10px;
- border-bottom: 1px solid #000;
+ border-bottom: 1px solid #000000;
}
.basicList dd {
margin: 4px;
diff --git a/scss/tests/files/original-doctests/010-math.css b/scss/tests/files/original-doctests/010-math.css
index bf7d182..fb430df 100644
--- a/scss/tests/files/original-doctests/010-math.css
+++ b/scss/tests/files/original-doctests/010-math.css
@@ -1,5 +1,5 @@
.selector {
padding: 10px;
- color: #fff;
+ color: white;
background-color: #ede343;
}
diff --git a/scss/tests/files/original-doctests/021-extend.css b/scss/tests/files/original-doctests/021-extend.css
index 9221c6b..86beaaa 100644
--- a/scss/tests/files/original-doctests/021-extend.css
+++ b/scss/tests/files/original-doctests/021-extend.css
@@ -1,5 +1,5 @@
.error, .seriousError {
- border: 1px red;
+ border: 1px #f00;
background-color: #fdd;
}
.error.intrusion, .seriousError.intrusion {
diff --git a/scss/tests/files/original-doctests/022-extend-multiple.css b/scss/tests/files/original-doctests/022-extend-multiple.css
index 34dd6db..c8546d8 100644
--- a/scss/tests/files/original-doctests/022-extend-multiple.css
+++ b/scss/tests/files/original-doctests/022-extend-multiple.css
@@ -1,5 +1,5 @@
.error, .seriousError {
- border: 1px red;
+ border: 1px #f00;
background-color: #fdd;
}
.attention, .seriousError {
diff --git a/scss/tests/files/original-doctests/023-extend-multiple-2.scss b/scss/tests/files/original-doctests/023-extend-multiple-2.scss
index 9875925..c1c5929 100644
--- a/scss/tests/files/original-doctests/023-extend-multiple-2.scss
+++ b/scss/tests/files/original-doctests/023-extend-multiple-2.scss
@@ -3,7 +3,7 @@
color: red !important;
}
.error {
- border: 1px #f00;
+ border: 1px red;
background-color: #fdd;
}
.attention {
@@ -14,4 +14,4 @@
@extend .error, .attention;
@extend .bad;
border-width: 3px;
-} \ No newline at end of file
+}
diff --git a/scss/tests/files/original-doctests/026-forum-2.scss b/scss/tests/files/original-doctests/026-forum-2.scss
index 0184280..b243093 100644
--- a/scss/tests/files/original-doctests/026-forum-2.scss
+++ b/scss/tests/files/original-doctests/026-forum-2.scss
@@ -4,10 +4,10 @@
$ie7 = *:first-child+html;
}
$ie6 {
- .a { color:white; }
- .b { color:black; }
+ .a { color:#fff; }
+ .b { color:#000; }
}
$ie7 {
- .a { color:white; }
- .b { color:black; }
-} \ No newline at end of file
+ .a { color:#fff; }
+ .b { color:#000; }
+}
diff --git a/scss/tests/files/original-doctests/027-forum-3.css b/scss/tests/files/original-doctests/027-forum-3.css
index 5218394..707315e 100644
--- a/scss/tests/files/original-doctests/027-forum-3.css
+++ b/scss/tests/files/original-doctests/027-forum-3.css
@@ -1,6 +1,6 @@
.basicClass, .specialClass {
padding: 20px;
- background-color: red;
+ background-color: #FF0000;
}
.specialClass {
padding: 10px;
diff --git a/scss/tests/test_expression.py b/scss/tests/test_expression.py
index 7135042..1784180 100644
--- a/scss/tests/test_expression.py
+++ b/scss/tests/test_expression.py
@@ -71,7 +71,7 @@ def test_addition():
assert calc('"abc" + "def"') == '"abcdef"'
assert calc('#010305 + #050301') == '#060606'
- assert calc('#ffffff + #ffffff') == '#ffffff'
+ assert calc('#ffffff + #ffffff') == 'white'
def test_subtraction():
calc = lambda expr: to_str(Calculator(Namespace()).calculate(expr))
diff --git a/scss/tests/test_misc.py b/scss/tests/test_misc.py
index 5eebdd3..dada062 100644
--- a/scss/tests/test_misc.py
+++ b/scss/tests/test_misc.py
@@ -26,7 +26,7 @@ def test_extend_across_files():
expected = """\
.basicClass, .specialClass {
padding: 20px;
- background-color: red;
+ background-color: #FF0000;
}
.specialClass {
padding: 10px;
diff --git a/scss/types.py b/scss/types.py
index f9da805..1dabdf2 100644
--- a/scss/types.py
+++ b/scss/types.py
@@ -87,13 +87,6 @@ class Value(object):
def __neg__(self):
return String("-" + self.render())
- def merge(self, obj):
- if isinstance(obj, Value):
- self.value = obj.value
- else:
- self.value = obj
- return self
-
def render(self, compress=False, short_colors=False):
return self.__str__()
@@ -502,19 +495,19 @@ class ColorValue(Value):
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):
self.tokens = tokens
self.value = (0, 0, 0, 1)
- self.types = {}
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)
- self.types = {'rgba': 1}
elif isinstance(tokens, ColorValue):
self.value = tokens.value
- self.types = tokens.types.copy()
elif isinstance(tokens, NumberValue):
val = tokens.value
self.value = (val, val, val, 1)
@@ -523,9 +516,6 @@ class ColorValue(Value):
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)
- type = tokens[-1]
- if type in ('rgb', 'rgba', 'hsl', 'hsla'):
- self.types = {type: 1}
elif isinstance(tokens, (int, float)):
val = float(tokens)
self.value = (val, val, val, 1)
@@ -551,7 +541,6 @@ class ColorValue(Value):
col = [0.0 if c[i] < 0 else 255.0 if c[i] > 255 else c[i] for i in range(3)]
col += [0.0 if c[3] < 0 else 1.0 if c[3] > 1 else c[3]]
self.value = tuple(col)
- self.types = {type: 1}
except:
raise ValueError("Value is not a Color! (%s)" % tokens)
elif type in ('hsl', 'hsla'):
@@ -561,7 +550,6 @@ class ColorValue(Value):
col = [c[0] % 360.0] / 360.0
col += [0.0 if c[i] < 0 else 1.0 if c[i] > 1 else c[i] for i in range(1, 4)]
self.value = tuple([c * 255.0 for c in colorsys.hls_to_rgb(col[0], 0.999999 if col[2] == 1 else col[2], 0.999999 if col[1] == 1 else col[1])] + [col[3]])
- self.types = {type: 1}
except:
raise ValueError("Value is not a Color! (%s)" % tokens)
else:
@@ -575,64 +563,25 @@ class ColorValue(Value):
self.tokens = None
# TODO really should store these things internally as 0-1
self.value = (red * 255.0, green * 255.0, blue * 255.0, alpha)
- if alpha == 1.0:
- self.types = {'rgb': 1}
- else:
- self.types = {'rgba': 1}
-
return self
@classmethod
def from_name(cls, name):
"""Build a Color from a CSS color name."""
self = cls.__new__(cls) # TODO
- self.tokens = ParserValue(name)
+ self.original_literal = name
r, g, b, a = COLOR_NAMES[name]
self.value = r, g, b, a
- if a == 1.0:
- self.types = {'rgb': 1}
- else:
- self.types = {'rgba': 1}
-
return self
def __repr__(self):
- return '<%s: %s, %s>' % (self.__class__.__name__, repr(self.value), repr(self.types))
+ return '<%s: %s>' % (self.__class__.__name__, repr(self.value))
def __hash__(self):
return hash(self.value)
- def __str__(self):
- # TODO bit of a hack?
- if self.tokens is not None and isinstance(self.tokens, ParserValue):
- return self.tokens.value
-
- type = self.type
- c = self.value
- if type == 'hsl' or type == 'hsla' and c[3] == 1:
- h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0)
- return 'hsl(%s, %s%%, %s%%)' % (to_str(h * 360.0), to_str(s * 100.0), to_str(l * 100.0))
- if type == 'hsla':
- h, l, s = colorsys.rgb_to_hls(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0)
- return 'hsla(%s, %s%%, %s%%, %s)' % (to_str(h * 360.0), to_str(s * 100.0), to_str(l * 100.0), to_str(c[3]))
- r, g, b = to_str(c[0]), to_str(c[1]), to_str(c[2])
- are_integral = True
- for n in c[:3]:
- # replicating old logic; perhaps needs rethinking
- n2 = round(n * 100, 1)
- if n2 != int(n2):
- are_integral = False
- break
- if c[3] == 1:
- if not are_integral:
- return 'rgb(%s%%, %s%%, %s%%)' % (to_str(c[0] * 100.0 / 255.0), to_str(c[1] * 100.0 / 255.0), to_str(c[2] * 100.0 / 255.0))
- return '#%02x%02x%02x' % (round(c[0]), round(c[1]), round(c[2]))
- if not are_integral:
- return 'rgba(%s%%, %s%%, %s%%, %s)' % (to_str(c[0] * 100.0 / 255.0), to_str(c[1] * 100.0 / 255.0), to_str(c[2] * 100.0 / 255.0), to_str(c[3]))
- return 'rgba(%d, %d, %d, %s)' % (round(c[0]), round(c[1]), round(c[2]), to_str(c[3]))
-
def __eq__(self, other):
if not isinstance(other, ColorValue):
return BooleanValue(False)
@@ -663,32 +612,17 @@ class ColorValue(Value):
c = val
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)]
- ret = ColorValue(None).merge(first).merge(second)
- ret.value = tuple(c)
- return ret
-
- def merge(self, obj):
- obj = ColorValue(obj)
- self.value = obj.value
- for type, val in obj.types.items():
- self.types.setdefault(type, 0)
- self.types[type] += val
- return self
-
- @property
- def type(self):
- type = ''
- if self.types:
- types = sorted(self.types, key=self.types.get)
- while len(types):
- type = types.pop()
- if type:
- break
- return type
+ return ColorValue(c)
def render(self, compress=False, short_colors=False):
- if not compress and not short_colors:
- return self.__str__()
+ """Return a rendered representation of the color. If `compress` is
+ true, the shortest possible representation is used; otherwise, named
+ colors are rendered as names and all others are rendered as hex (or
+ with the rgba function).
+ """
+
+ if not compress and self.original_literal:
+ return self.original_literal
candidates = []
@@ -697,6 +631,10 @@ class ColorValue(Value):
r, g, b, a = self.value
r, g, b = int(round(r)), int(round(g)), int(round(b))
+ # Build a candidate list in order of preference. If `compress` is
+ # True, the shortest candidate is used; otherwise, the first candidate
+ # is used.
+
# Try color name
key = r, g, b, a
if key in COLOR_LOOKUP:
@@ -716,7 +654,10 @@ class ColorValue(Value):
sp = ' '
candidates.append("rgba(%d,%s%d,%s%d,%s%.2g)" % (r, sp, g, sp, b, sp, a))
- return min(candidates, key=len)
+ if compress:
+ return min(candidates, key=len)
+ else:
+ return candidates[0]
class String(Value):
diff --git a/scss/util.py b/scss/util.py
index 57d568e..0bcb13e 100644
--- a/scss/util.py
+++ b/scss/util.py
@@ -44,6 +44,13 @@ def depar(s):
def to_str(num):
+ try:
+ render = num.render
+ except AttributeError:
+ pass
+ else:
+ return render()
+
if isinstance(num, dict):
s = sorted(num.items())
sp = num.get('_', '')