Skip to content

Commit 172665f

Browse files
committed
Add list properties
1 parent abebfff commit 172665f

File tree

5 files changed

+144
-17
lines changed

5 files changed

+144
-17
lines changed

colosseum/constants.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from .validators import (ValidationError, is_border_spacing, is_color,
22
is_integer, is_length, is_number, is_percentage,
3-
is_quote, is_rect)
3+
is_quote, is_rect, is_uri)
44

55

66
class Choices:
@@ -305,8 +305,60 @@ def value(self, context):
305305
# 12.5 Lists
306306
######################################################################
307307
# list_style_type
308+
DISC = 'disc'
309+
CIRCLE = 'circle'
310+
SQUARE = 'square'
311+
DECIMAL = 'decimal'
312+
DECIMAL_LEADING_ZERO = 'decimal-leading-zero'
313+
LOWER_ROMAN = 'lower-roman'
314+
UPPER_ROMAN = 'upper-roman'
315+
LOWER_GREEK = 'lower-greek'
316+
LOWER_LATIN = 'lower-latin'
317+
UPPER_LATIN = 'upper-latin'
318+
ARMENIAN = 'armenian'
319+
GEORGIAN = 'georgian'
320+
LOWER_ALPHA = 'lower-alpha'
321+
UPPER_ALPHA = 'upper-alpha'
322+
323+
324+
LIST_TYPE_CHOICES = Choices(
325+
DISC,
326+
CIRCLE,
327+
SQUARE,
328+
DECIMAL,
329+
DECIMAL_LEADING_ZERO,
330+
LOWER_ROMAN,
331+
UPPER_ROMAN,
332+
LOWER_GREEK,
333+
LOWER_LATIN,
334+
UPPER_LATIN,
335+
ARMENIAN,
336+
GEORGIAN,
337+
LOWER_ALPHA,
338+
UPPER_ALPHA,
339+
None,
340+
explicit_defaulting_constants=[INHERIT],
341+
)
342+
308343
# list_style_image
344+
LIST_IMAGE_CHOICES = Choices(
345+
None,
346+
validators=[is_uri],
347+
explicit_defaulting_constants=[INHERIT],
348+
)
349+
350+
309351
# list_style_position
352+
INSIDE = 'inside'
353+
OUTSIDE = 'outside'
354+
355+
LIST_POSITION_CHOICES = Choices(
356+
INSIDE,
357+
OUTSIDE,
358+
explicit_defaulting_constants=[INHERIT],
359+
)
360+
361+
310362
# list_style
311363

312364
# 13. Paged media ####################################################

colosseum/declaration.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,33 @@
1-
from . import engine as css_engine
2-
from . import parser
1+
from . import engine as css_engine, parser
32
from .constants import ( # noqa
43
ALIGN_CONTENT_CHOICES, ALIGN_ITEMS_CHOICES, ALIGN_SELF_CHOICES, AUTO,
54
BACKGROUND_COLOR_CHOICES, BORDER_COLLAPSE_CHOICES, BORDER_COLOR_CHOICES,
65
BORDER_SPACING_CHOICES, BORDER_STYLE_CHOICES, BORDER_WIDTH_CHOICES,
76
BOX_OFFSET_CHOICES, CAPTION_SIDE_CHOICES, CLEAR_CHOICES, CLIP_CHOICES,
8-
COLOR_CHOICES, DIRECTION_CHOICES, DISPLAY_CHOICES, EMPTY_CELLS_CHOICES,
9-
FLEX_BASIS_CHOICES, FLEX_DIRECTION_CHOICES, FLEX_GROW_CHOICES,
10-
FLEX_SHRINK_CHOICES, FLEX_START, FLEX_WRAP_CHOICES, FLOAT_CHOICES,
11-
GRID_AUTO_CHOICES, GRID_AUTO_FLOW_CHOICES, GRID_GAP_CHOICES,
7+
COLOR_CHOICES, DIRECTION_CHOICES, DISC, DISPLAY_CHOICES,
8+
EMPTY_CELLS_CHOICES, FLEX_BASIS_CHOICES, FLEX_DIRECTION_CHOICES,
9+
FLEX_GROW_CHOICES, FLEX_SHRINK_CHOICES, FLEX_START, FLEX_WRAP_CHOICES,
10+
FLOAT_CHOICES, GRID_AUTO_CHOICES, GRID_AUTO_FLOW_CHOICES, GRID_GAP_CHOICES,
1211
GRID_PLACEMENT_CHOICES, GRID_TEMPLATE_AREA_CHOICES, GRID_TEMPLATE_CHOICES,
1312
INITIAL, INLINE, INVERT, JUSTIFY_CONTENT_CHOICES, LETTER_SPACING_CHOICES,
14-
LTR, MARGIN_CHOICES, MAX_SIZE_CHOICES, MEDIUM, MIN_SIZE_CHOICES, NORMAL,
15-
NOWRAP, ORDER_CHOICES, ORPHANS_CHOICES, OUTLINE_COLOR_CHOICES,
16-
OUTLINE_STYLE_CHOICES, OUTLINE_WIDTH_CHOICES, OVERFLOW_CHOICES,
13+
LIST_IMAGE_CHOICES, LIST_POSITION_CHOICES, LIST_TYPE_CHOICES, LTR,
14+
MARGIN_CHOICES, MAX_SIZE_CHOICES, MEDIUM, MIN_SIZE_CHOICES, NORMAL, NOWRAP,
15+
ORDER_CHOICES, ORPHANS_CHOICES, OUTLINE_COLOR_CHOICES,
16+
OUTLINE_STYLE_CHOICES, OUTLINE_WIDTH_CHOICES, OUTSIDE, OVERFLOW_CHOICES,
1717
PADDING_CHOICES, PAGE_BREAK_AFTER_CHOICES, PAGE_BREAK_BEFORE_CHOICES,
18-
PAGE_BREAK_INSIDE_CHOICES, POSITION_CHOICES, QUOTES_CHOICES, ROW,
19-
SEPARATE, SHOW, SIZE_CHOICES, STATIC, STRETCH, TABLE_LAYOUT_CHOICES,
18+
PAGE_BREAK_INSIDE_CHOICES, POSITION_CHOICES, QUOTES_CHOICES, ROW, SEPARATE,
19+
SHOW, SIZE_CHOICES, STATIC, STRETCH, TABLE_LAYOUT_CHOICES,
2020
TEXT_ALIGN_CHOICES, TEXT_DECORATION_CHOICES, TEXT_INDENT_CHOICES,
2121
TEXT_TRANSFORM_CHOICES, TOP, TRANSPARENT, UNICODE_BIDI_CHOICES,
2222
VISIBILITY_CHOICES, VISIBLE, WHITE_SPACE_CHOICES, WIDOWS_CHOICES,
2323
WORD_SPACING_CHOICES, Z_INDEX_CHOICES, OtherProperty,
2424
TextAlignInitialValue, default,
2525
)
2626
from .exceptions import ValidationError
27-
from .wrappers import Border, BorderBottom, BorderLeft, BorderRight, BorderTop, Outline
27+
from .wrappers import (
28+
Border, BorderBottom, BorderLeft, BorderRight, BorderTop, ListStyle,
29+
Outline,
30+
)
2831

2932
_CSS_PROPERTIES = set()
3033

@@ -329,10 +332,10 @@ def __init__(self, **style):
329332
# counter-increment
330333

331334
# 12.5 Lists
332-
# list_style_type
333-
# list_style_image
334-
# list_style_position
335-
# list_style
335+
list_style_type = validated_property('list_style_type', choices=LIST_TYPE_CHOICES, initial=DISC)
336+
list_style_image = validated_property('list_style_type', choices=LIST_IMAGE_CHOICES, initial=None)
337+
list_style_position = validated_property('list_style_position', choices=LIST_POSITION_CHOICES, initial=OUTSIDE)
338+
list_style = validated_shorthand_property('list_style', parser=parser.list_style, wrapper=ListStyle)
336339

337340
# 13. Paged media ####################################################
338341
# 13.3.1 Page break properties

colosseum/parser.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,64 @@ def border_bottom(value):
369369
def border_top(value):
370370
"""Parse border string into a dictionary of outline properties."""
371371
return border(value, direction='top')
372+
373+
374+
##############################################################################
375+
# List shorthands
376+
##############################################################################
377+
def _parse_list_style_property_part(value, list_style_dict):
378+
"""Parse list style shorthand property part for known properties."""
379+
from .constants import ( # noqa
380+
LIST_TYPE_CHOICES, LIST_IMAGE_CHOICES, LIST_POSITION_CHOICES
381+
)
382+
383+
for property_name, choices in {'list_style_type': LIST_TYPE_CHOICES,
384+
'list_style_image': LIST_IMAGE_CHOICES,
385+
'list_style_position': LIST_POSITION_CHOICES}.items():
386+
try:
387+
value = choices.validate(value)
388+
except (ValueError, ValidationError):
389+
continue
390+
391+
if property_name in list_style_dict:
392+
raise ValueError('Invalid duplicated property!')
393+
394+
list_style_dict[property_name] = value
395+
return list_style_dict
396+
397+
raise ValueError('List style value "{value}" not valid!'.format(value=value))
398+
399+
400+
def list_style(value):
401+
"""
402+
Parse list style string into a dictionary of list style properties.
403+
404+
The font CSS property is a shorthand for list-style-type, list-style-image, and list-style-position.
405+
406+
Reference:
407+
- https://www.w3.org/TR/2011/REC-CSS2-20110607/generate.html#lists
408+
"""
409+
if value:
410+
if isinstance(value, str):
411+
values = [val.strip() for val in value.split()]
412+
elif isinstance(value, Sequence):
413+
values = value
414+
else:
415+
raise ValueError('Unknown list style %s ' % value)
416+
else:
417+
raise ValueError('Unknown list style %s ' % value)
418+
419+
# We iteratively split by the first left hand space found and try to validate if that part
420+
# is a valid <list-style-type> or <list-style-image> or <list-style-position> (which can come in any order)
421+
422+
# We use this dictionary to store parsed values and check that values properties are not
423+
# duplicated
424+
list_style_dict = {}
425+
for idx, part in enumerate(values):
426+
if idx > 2:
427+
# Outline can have a maximum of 3 parts
428+
raise ValueError('List style property shorthand contains too many parts!')
429+
430+
list_style_dict = _parse_list_style_property_part(part, list_style_dict)
431+
432+
return list_style_dict

colosseum/validators.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,10 @@ def is_quote(value):
147147

148148

149149
is_quote.description = '[<string> <string>]+'
150+
151+
152+
def is_uri(value):
153+
return value
154+
155+
156+
is_uri.description = 'TODO'

colosseum/wrappers.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,7 @@ class BorderLeft(Shorthand):
151151

152152
class Border(Shorthand):
153153
VALID_KEYS = ['border_width', 'border_style', 'border_color']
154+
155+
156+
class ListStyle(Shorthand):
157+
VALID_KEYS = ['list_style_type', 'list_style_image', 'list_style_position']

0 commit comments

Comments
 (0)