Skip to content

Commit 5e6026f

Browse files
authored
Merge pull request #64 from Kozea/css-color5
Add support for Color 5
2 parents 520b09c + 725d2b5 commit 5e6026f

File tree

4 files changed

+321
-12
lines changed

4 files changed

+321
-12
lines changed

tests/css-parsing-tests

tests/test_tinycss2.py

Lines changed: 201 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from tinycss2.color3 import parse_color as parse_color3 # isort:skip
2121
from tinycss2.color4 import Color # isort:skip
2222
from tinycss2.color4 import parse_color as parse_color4 # isort:skip
23+
from tinycss2.color5 import parse_color as parse_color5 # isort:skip
2324
from tinycss2.nth import parse_nth # isort:skip
2425

2526

@@ -159,6 +160,19 @@ def _number(value):
159160
return str(int(value) if value.is_integer() else value)
160161

161162

163+
def _build_color(color):
164+
if color is None:
165+
return
166+
(*coordinates, alpha) = color
167+
result = f'color({color.space}'
168+
for coordinate in coordinates:
169+
result += f' {_number(coordinate)}'
170+
if alpha != 1:
171+
result += f' / {_number(alpha)}'
172+
result += ')'
173+
return result
174+
175+
162176
def test_color_currentcolor_3():
163177
for value in ('currentcolor', 'currentColor', 'CURRENTCOLOR'):
164178
assert parse_color3(value) == 'currentColor'
@@ -169,23 +183,48 @@ def test_color_currentcolor_4():
169183
assert parse_color4(value) == 'currentcolor'
170184

171185

186+
def test_color_currentcolor_5():
187+
for value in ('currentcolor', 'currentColor', 'CURRENTCOLOR'):
188+
assert parse_color5(value) == 'currentcolor'
189+
190+
172191
@json_test()
173192
def test_color_function_4(input):
174-
if not (color := parse_color4(input)):
193+
return _build_color(parse_color4(input))
194+
195+
196+
@json_test(filename='color_function_4.json')
197+
def test_color_function_4_with_5(input):
198+
return _build_color(parse_color5(input))
199+
200+
201+
@json_test()
202+
def test_color_functions_5(input):
203+
if input.startswith('light-dark'):
204+
result = []
205+
result.append(_build_color(parse_color5(input, ('light',))))
206+
result.append(_build_color(parse_color5(input, ('dark',))))
207+
else:
208+
result = _build_color(parse_color5(input))
209+
return result
210+
211+
212+
@json_test()
213+
def test_color_hexadecimal_3(input):
214+
if not (color := parse_color3(input)):
175215
return None
176216
(*coordinates, alpha) = color
177-
result = f'color({color.space}'
178-
for coordinate in coordinates:
179-
result += f' {_number(coordinate)}'
217+
result = f'rgb{"a" if alpha != 1 else ""}('
218+
result += f'{", ".join(_number(coordinate * 255) for coordinate in coordinates)}'
180219
if alpha != 1:
181-
result += f' / {_number(alpha)}'
220+
result += f', {_number(alpha)}'
182221
result += ')'
183222
return result
184223

185224

186-
@json_test()
187-
def test_color_hexadecimal_3(input):
188-
if not (color := parse_color3(input)):
225+
@json_test(filename='color_hexadecimal_3.json')
226+
def test_color_hexadecimal_3_with_4(input):
227+
if not (color := parse_color4(input)):
189228
return None
190229
(*coordinates, alpha) = color
191230
result = f'rgb{"a" if alpha != 1 else ""}('
@@ -210,9 +249,23 @@ def test_color_hexadecimal_4(input):
210249
return result
211250

212251

252+
@json_test(filename='color_hexadecimal_4.json')
253+
def test_color_hexadecimal_4_with_5(input):
254+
if not (color := parse_color5(input)):
255+
return None
256+
assert color.space == 'srgb'
257+
(*coordinates, alpha) = color
258+
result = f'rgb{"a" if alpha != 1 else ""}('
259+
result += f'{", ".join(_number(coordinate * 255) for coordinate in coordinates)}'
260+
if alpha != 1:
261+
result += f', {_number(alpha)}'
262+
result += ')'
263+
return result
264+
265+
213266
@json_test(filename='color_hexadecimal_3.json')
214-
def test_color_hexadecimal_3_with_4(input):
215-
if not (color := parse_color4(input)):
267+
def test_color_hexadecimal_3_with_5(input):
268+
if not (color := parse_color5(input)):
216269
return None
217270
assert color.space == 'srgb'
218271
(*coordinates, alpha) = color
@@ -251,6 +304,20 @@ def test_color_hsl_3_with_4(input):
251304
return result
252305

253306

307+
@json_test(filename='color_hsl_3.json')
308+
def test_color_hsl_3_with_5(input):
309+
if not (color := parse_color5(input)):
310+
return None
311+
assert color.space == 'hsl'
312+
(*coordinates, alpha) = color.to('srgb')
313+
result = f'rgb{"a" if alpha != 1 else ""}('
314+
result += f'{", ".join(_number(coordinate * 255) for coordinate in coordinates)}'
315+
if alpha != 1:
316+
result += f', {_number(alpha)}'
317+
result += ')'
318+
return result
319+
320+
254321
@json_test()
255322
def test_color_hsl_4(input):
256323
if not (color := parse_color4(input)):
@@ -265,6 +332,20 @@ def test_color_hsl_4(input):
265332
return result
266333

267334

335+
@json_test(filename='color_hsl_4.json')
336+
def test_color_hsl_4_with_5(input):
337+
if not (color := parse_color5(input)):
338+
return None
339+
assert color.space == 'hsl'
340+
(*coordinates, alpha) = color.to('srgb')
341+
result = f'rgb{"a" if alpha != 1 else ""}('
342+
result += f'{", ".join(_number(coordinate * 255) for coordinate in coordinates)}'
343+
if alpha != 1:
344+
result += f', {_number(alpha)}'
345+
result += ')'
346+
return result
347+
348+
268349
@json_test()
269350
def test_color_hwb_4(input):
270351
if not (color := parse_color4(input)):
@@ -279,6 +360,20 @@ def test_color_hwb_4(input):
279360
return result
280361

281362

363+
@json_test(filename='color_hwb_4.json')
364+
def test_color_hwb_4_with_5(input):
365+
if not (color := parse_color5(input)):
366+
return None
367+
assert color.space == 'hwb'
368+
(*coordinates, alpha) = color.to('srgb')
369+
result = f'rgb{"a" if alpha != 1 else ""}('
370+
result += f'{", ".join(_number(coordinate * 255) for coordinate in coordinates)}'
371+
if alpha != 1:
372+
result += f', {_number(alpha)}'
373+
result += ')'
374+
return result
375+
376+
282377
@json_test()
283378
def test_color_keywords_3(input):
284379
if not (color := parse_color3(input)):
@@ -310,6 +405,22 @@ def test_color_keywords_3_with_4(input):
310405
return result
311406

312407

408+
@json_test(filename='color_keywords_3.json')
409+
def test_color_keywords_3_with_5(input):
410+
if not (color := parse_color5(input)):
411+
return None
412+
elif isinstance(color, str):
413+
return color
414+
assert color.space == 'srgb'
415+
(*coordinates, alpha) = color
416+
result = f'rgb{"a" if alpha != 1 else ""}('
417+
result += f'{", ".join(_number(coordinate * 255) for coordinate in coordinates)}'
418+
if alpha != 1:
419+
result += f', {_number(alpha)}'
420+
result += ')'
421+
return result
422+
423+
313424
@json_test()
314425
def test_color_keywords_4(input):
315426
if not (color := parse_color4(input)):
@@ -326,6 +437,22 @@ def test_color_keywords_4(input):
326437
return result
327438

328439

440+
@json_test(filename='color_keywords_4.json')
441+
def test_color_keywords_4_with_5(input):
442+
if not (color := parse_color5(input)):
443+
return None
444+
elif isinstance(color, str):
445+
return color
446+
assert color.space == 'srgb'
447+
(*coordinates, alpha) = color
448+
result = f'rgb{"a" if alpha != 1 else ""}('
449+
result += f'{", ".join(_number(coordinate * 255) for coordinate in coordinates)}'
450+
if alpha != 1:
451+
result += f', {_number(alpha)}'
452+
result += ')'
453+
return result
454+
455+
329456
@json_test()
330457
def test_color_lab_4(input):
331458
if not (color := parse_color4(input)):
@@ -342,6 +469,22 @@ def test_color_lab_4(input):
342469
return result
343470

344471

472+
@json_test(filename='color_lab_4.json')
473+
def test_color_lab_4_with_5(input):
474+
if not (color := parse_color5(input)):
475+
return None
476+
elif isinstance(color, str):
477+
return color
478+
assert color.space == 'lab'
479+
(*coordinates, alpha) = color
480+
result = f'{color.space}('
481+
result += f'{" ".join(_number(coordinate) for coordinate in coordinates)}'
482+
if alpha != 1:
483+
result += f' / {_number(alpha)}'
484+
result += ')'
485+
return result
486+
487+
345488
@json_test()
346489
def test_color_oklab_4(input):
347490
if not (color := parse_color4(input)):
@@ -358,6 +501,22 @@ def test_color_oklab_4(input):
358501
return result
359502

360503

504+
@json_test(filename='color_oklab_4.json')
505+
def test_color_oklab_4_with_5(input):
506+
if not (color := parse_color5(input)):
507+
return None
508+
elif isinstance(color, str):
509+
return color
510+
assert color.space == 'oklab'
511+
(*coordinates, alpha) = color
512+
result = f'{color.space}('
513+
result += f'{" ".join(_number(coordinate) for coordinate in coordinates)}'
514+
if alpha != 1:
515+
result += f' / {_number(alpha)}'
516+
result += ')'
517+
return result
518+
519+
361520
@json_test()
362521
def test_color_lch_4(input):
363522
if not (color := parse_color4(input)):
@@ -374,6 +533,22 @@ def test_color_lch_4(input):
374533
return result
375534

376535

536+
@json_test(filename='color_lch_4.json')
537+
def test_color_lch_4_with_5(input):
538+
if not (color := parse_color5(input)):
539+
return None
540+
elif isinstance(color, str):
541+
return color
542+
assert color.space == 'lch'
543+
(*coordinates, alpha) = color
544+
result = f'{color.space}('
545+
result += f'{" ".join(_number(coordinate) for coordinate in coordinates)}'
546+
if alpha != 1:
547+
result += f' / {_number(alpha)}'
548+
result += ')'
549+
return result
550+
551+
377552
@json_test()
378553
def test_color_oklch_4(input):
379554
if not (color := parse_color4(input)):
@@ -390,6 +565,22 @@ def test_color_oklch_4(input):
390565
return result
391566

392567

568+
@json_test(filename='color_oklch_4.json')
569+
def test_color_oklch_4_with_5(input):
570+
if not (color := parse_color5(input)):
571+
return None
572+
elif isinstance(color, str):
573+
return color
574+
assert color.space == 'oklch'
575+
(*coordinates, alpha) = color
576+
result = f'{color.space}('
577+
result += f'{" ".join(_number(coordinate) for coordinate in coordinates)}'
578+
if alpha != 1:
579+
result += f' / {_number(alpha)}'
580+
result += ')'
581+
return result
582+
583+
393584
@json_test()
394585
def test_stylesheet_bytes(kwargs):
395586
kwargs['css_bytes'] = kwargs['css_bytes'].encode('latin1')

tinycss2/color4.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ class Color:
2323
to [0, 1]. Coordinates can also be set to ``None`` when undefined.
2424
2525
"""
26+
COLOR_SPACES = COLOR_SPACES
27+
2628
def __init__(self, space, coordinates, alpha):
27-
assert space in COLOR_SPACES, f"{space} is not a supported color space"
29+
if self.COLOR_SPACES:
30+
assert space in self.COLOR_SPACES, f"{space} is not a supported color space"
2831
self.space = space
2932
self.coordinates = tuple(
3033
None if coordinate is None else float(coordinate)

0 commit comments

Comments
 (0)