Mercurial > libervia-backend
comparison frontends/src/tools/css_color.py @ 2077:95ad70ad815c
frontends (tools): added a module to parse CSS colors
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 25 Sep 2016 15:41:43 +0200 |
parents | |
children | 8b37a62336c3 |
comparison
equal
deleted
inserted
replaced
2076:529a6d7f7f6a | 2077:95ad70ad815c |
---|---|
1 #!/usr/bin/env python2 | |
2 # -*- coding: utf-8 -*- | |
3 | |
4 # CSS color parsing | |
5 # Copyright (C) 2009-2016 Jérome-Poisson | |
6 | |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 from sat.core.log import getLogger | |
21 log = getLogger(__name__) | |
22 | |
23 | |
24 CSS_COLORS = { | |
25 u"black": u"000000", | |
26 u"silver": u"c0c0c0", | |
27 u"gray": u"808080", | |
28 u"white": u"ffffff", | |
29 u"maroon": u"800000", | |
30 u"red": u"ff0000", | |
31 u"purple": u"800080", | |
32 u"fuchsia": u"ff00ff", | |
33 u"green": u"008000", | |
34 u"lime": u"00ff00", | |
35 u"olive": u"808000", | |
36 u"yellow": u"ffff00", | |
37 u"navy": u"000080", | |
38 u"blue": u"0000ff", | |
39 u"teal": u"008080", | |
40 u"aqua": u"00ffff", | |
41 u"orange": u"ffa500", | |
42 u"aliceblue": u"f0f8ff", | |
43 u"antiquewhite": u"faebd7", | |
44 u"aquamarine": u"7fffd4", | |
45 u"azure": u"f0ffff", | |
46 u"beige": u"f5f5dc", | |
47 u"bisque": u"ffe4c4", | |
48 u"blanchedalmond": u"ffebcd", | |
49 u"blueviolet": u"8a2be2", | |
50 u"brown": u"a52a2a", | |
51 u"burlywood": u"deb887", | |
52 u"cadetblue": u"5f9ea0", | |
53 u"chartreuse": u"7fff00", | |
54 u"chocolate": u"d2691e", | |
55 u"coral": u"ff7f50", | |
56 u"cornflowerblue": u"6495ed", | |
57 u"cornsilk": u"fff8dc", | |
58 u"crimson": u"dc143c", | |
59 u"darkblue": u"00008b", | |
60 u"darkcyan": u"008b8b", | |
61 u"darkgoldenrod": u"b8860b", | |
62 u"darkgray": u"a9a9a9", | |
63 u"darkgreen": u"006400", | |
64 u"darkgrey": u"a9a9a9", | |
65 u"darkkhaki": u"bdb76b", | |
66 u"darkmagenta": u"8b008b", | |
67 u"darkolivegreen": u"556b2f", | |
68 u"darkorange": u"ff8c00", | |
69 u"darkorchid": u"9932cc", | |
70 u"darkred": u"8b0000", | |
71 u"darksalmon": u"e9967a", | |
72 u"darkseagreen": u"8fbc8f", | |
73 u"darkslateblue": u"483d8b", | |
74 u"darkslategray": u"2f4f4f", | |
75 u"darkslategrey": u"2f4f4f", | |
76 u"darkturquoise": u"00ced1", | |
77 u"darkviolet": u"9400d3", | |
78 u"deeppink": u"ff1493", | |
79 u"deepskyblue": u"00bfff", | |
80 u"dimgray": u"696969", | |
81 u"dimgrey": u"696969", | |
82 u"dodgerblue": u"1e90ff", | |
83 u"firebrick": u"b22222", | |
84 u"floralwhite": u"fffaf0", | |
85 u"forestgreen": u"228b22", | |
86 u"gainsboro": u"dcdcdc", | |
87 u"ghostwhite": u"f8f8ff", | |
88 u"gold": u"ffd700", | |
89 u"goldenrod": u"daa520", | |
90 u"greenyellow": u"adff2f", | |
91 u"grey": u"808080", | |
92 u"honeydew": u"f0fff0", | |
93 u"hotpink": u"ff69b4", | |
94 u"indianred": u"cd5c5c", | |
95 u"indigo": u"4b0082", | |
96 u"ivory": u"fffff0", | |
97 u"khaki": u"f0e68c", | |
98 u"lavender": u"e6e6fa", | |
99 u"lavenderblush": u"fff0f5", | |
100 u"lawngreen": u"7cfc00", | |
101 u"lemonchiffon": u"fffacd", | |
102 u"lightblue": u"add8e6", | |
103 u"lightcoral": u"f08080", | |
104 u"lightcyan": u"e0ffff", | |
105 u"lightgoldenrodyellow": u"fafad2", | |
106 u"lightgray": u"d3d3d3", | |
107 u"lightgreen": u"90ee90", | |
108 u"lightgrey": u"d3d3d3", | |
109 u"lightpink": u"ffb6c1", | |
110 u"lightsalmon": u"ffa07a", | |
111 u"lightseagreen": u"20b2aa", | |
112 u"lightskyblue": u"87cefa", | |
113 u"lightslategray": u"778899", | |
114 u"lightslategrey": u"778899", | |
115 u"lightsteelblue": u"b0c4de", | |
116 u"lightyellow": u"ffffe0", | |
117 u"limegreen": u"32cd32", | |
118 u"linen": u"faf0e6", | |
119 u"mediumaquamarine": u"66cdaa", | |
120 u"mediumblue": u"0000cd", | |
121 u"mediumorchid": u"ba55d3", | |
122 u"mediumpurple": u"9370db", | |
123 u"mediumseagreen": u"3cb371", | |
124 u"mediumslateblue": u"7b68ee", | |
125 u"mediumspringgreen": u"00fa9a", | |
126 u"mediumturquoise": u"48d1cc", | |
127 u"mediumvioletred": u"c71585", | |
128 u"midnightblue": u"191970", | |
129 u"mintcream": u"f5fffa", | |
130 u"mistyrose": u"ffe4e1", | |
131 u"moccasin": u"ffe4b5", | |
132 u"navajowhite": u"ffdead", | |
133 u"oldlace": u"fdf5e6", | |
134 u"olivedrab": u"6b8e23", | |
135 u"orangered": u"ff4500", | |
136 u"orchid": u"da70d6", | |
137 u"palegoldenrod": u"eee8aa", | |
138 u"palegreen": u"98fb98", | |
139 u"paleturquoise": u"afeeee", | |
140 u"palevioletred": u"db7093", | |
141 u"papayawhip": u"ffefd5", | |
142 u"peachpuff": u"ffdab9", | |
143 u"peru": u"cd853f", | |
144 u"pink": u"ffc0cb", | |
145 u"plum": u"dda0dd", | |
146 u"powderblue": u"b0e0e6", | |
147 u"rosybrown": u"bc8f8f", | |
148 u"royalblue": u"4169e1", | |
149 u"saddlebrown": u"8b4513", | |
150 u"salmon": u"fa8072", | |
151 u"sandybrown": u"f4a460", | |
152 u"seagreen": u"2e8b57", | |
153 u"seashell": u"fff5ee", | |
154 u"sienna": u"a0522d", | |
155 u"skyblue": u"87ceeb", | |
156 u"slateblue": u"6a5acd", | |
157 u"slategray": u"708090", | |
158 u"slategrey": u"708090", | |
159 u"snow": u"fffafa", | |
160 u"springgreen": u"00ff7f", | |
161 u"steelblue": u"4682b4", | |
162 u"tan": u"d2b48c", | |
163 u"thistle": u"d8bfd8", | |
164 u"tomato": u"ff6347", | |
165 u"turquoise": u"40e0d0", | |
166 u"violet": u"ee82ee", | |
167 u"wheat": u"f5deb3", | |
168 u"whitesmoke": u"f5f5f5", | |
169 u"yellowgreen": u"9acd32", | |
170 u"rebeccapurple": u"663399" | |
171 } | |
172 DEFAULT = u"000000" | |
173 | |
174 | |
175 def parse(raw_value, as_string=True): | |
176 """parse CSS color value and return normalised value | |
177 | |
178 @param raw_value(unicode): CSS value | |
179 @param as_string(bool): if True return a string, | |
180 else return a tuple of int | |
181 @return (unicode, tuple): normalised value | |
182 if as_string is True, value is 3 or 4 hex words (e.g. u"ff00aabb") | |
183 else value is a 3 or 4 tuple of int (e.g.: (255, 0, 170, 187)). | |
184 If present, the 4th value is the alpha channel | |
185 If value can't be parsed, a warning message is logged, and DEFAULT is returned | |
186 """ | |
187 raw_value = raw_value.strip().lower() | |
188 if raw_value.startswith(u'#'): | |
189 # we have a hexadecimal value | |
190 str_value = raw_value[1:] | |
191 if len(raw_value) in (3,4): | |
192 str_value = u''.join([2*v for v in str_value]) | |
193 elif raw_value.startswith(u'rgb'): | |
194 left_p = raw_value.find(u'(') | |
195 right_p = raw_value.find(u')') | |
196 rgb_values = [v.strip() for v in raw_value[left_p+1:right_p].split(',')] | |
197 expected_len = 4 if raw_value.startswith(u'rgba') else 3 | |
198 if len(rgb_values) != expected_len: | |
199 log.warning(u"incorrect value: {}".format(raw_value)) | |
200 str_value = DEFAULT | |
201 else: | |
202 int_values = [] | |
203 for rgb_v in rgb_values: | |
204 p_idx = rgb_v.find(u'%') | |
205 if p_idx == -1: | |
206 # base 10 value | |
207 try: | |
208 int_v = int(rgb_v) | |
209 if int_v > 255: | |
210 raise ValueError(u"value exceed 255") | |
211 int_values.append(int_v) | |
212 except ValueError: | |
213 log.warning(u"invalid int: {}".format(rgb_v)) | |
214 int_values.append(0) | |
215 else: | |
216 # percentage | |
217 try: | |
218 int_v = int(int(rgb_v[:p_idx]) / 100.0 * 255) | |
219 if int_v > 255: | |
220 raise ValueError(u"value exceed 255") | |
221 int_values.append(int_v) | |
222 except ValueError: | |
223 log.warning(u"invalid percent value: {}".format(rgb_v)) | |
224 int_values.append(0) | |
225 str_value = u''.join([u"{:02x}".format(v) for v in int_values]) | |
226 elif raw_value.startswith(u'hsl'): | |
227 log.warning(u"hue-saturation-lightness not handled yet") # TODO | |
228 str_value = DEFAULT | |
229 else: | |
230 try: | |
231 str_value = CSS_COLORS[raw_value] | |
232 except KeyError: | |
233 log.warning(u"unrecognised format: {}".format(raw_value)) | |
234 str_value = DEFAULT | |
235 | |
236 if as_string: | |
237 return str_value | |
238 else: | |
239 return tuple([int(str_value[i]+str_value[i+1], 16) for i in xrange(0, len(str_value), 2)]) |