Skip to content

Commit

Permalink
Add list properties
Browse files Browse the repository at this point in the history
  • Loading branch information
goanpeca committed Apr 27, 2020
1 parent abebfff commit 9660e19
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 7 deletions.
54 changes: 53 additions & 1 deletion colosseum/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .validators import (ValidationError, is_border_spacing, is_color,
is_integer, is_length, is_number, is_percentage,
is_quote, is_rect)
is_quote, is_rect, is_uri)


class Choices:
Expand Down Expand Up @@ -305,8 +305,60 @@ def value(self, context):
# 12.5 Lists
######################################################################
# list_style_type
DISC = 'disc'
CIRCLE = 'circle'
SQUARE = 'square'
DECIMAL = 'decimal'
DECIMAL_LEADING_ZERO = 'decimal-leading-zero'
LOWER_ROMAN = 'lower-roman'
UPPER_ROMAN = 'upper-roman'
LOWER_GREEK = 'lower-greek'
LOWER_LATIN = 'lower-latin'
UPPER_LATIN = 'upper-latin'
ARMENIAN = 'armenian'
GEORGIAN = 'georgian'
LOWER_ALPHA = 'lower-alpha'
UPPER_ALPHA = 'upper-alpha'


LIST_TYPE_CHOICES = Choices(
DISC,
CIRCLE,
SQUARE,
DECIMAL,
DECIMAL_LEADING_ZERO,
LOWER_ROMAN,
UPPER_ROMAN,
LOWER_GREEK,
LOWER_LATIN,
UPPER_LATIN,
ARMENIAN,
GEORGIAN,
LOWER_ALPHA,
UPPER_ALPHA,
None,
explicit_defaulting_constants=[INHERIT],
)

# list_style_image
LIST_IMAGE_CHOICES = Choices(
None,
validators=[is_uri],
explicit_defaulting_constants=[INHERIT],
)


# list_style_position
INSIDE = 'inside'
OUTSIDE = 'outside'

LIST_POSITION_CHOICES = Choices(
INSIDE,
OUTSIDE,
explicit_defaulting_constants=[INHERIT],
)


# list_style

# 13. Paged media ####################################################
Expand Down
14 changes: 8 additions & 6 deletions colosseum/declaration.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
TEXT_TRANSFORM_CHOICES, TOP, TRANSPARENT, UNICODE_BIDI_CHOICES,
VISIBILITY_CHOICES, VISIBLE, WHITE_SPACE_CHOICES, WIDOWS_CHOICES,
WORD_SPACING_CHOICES, Z_INDEX_CHOICES, OtherProperty,
TextAlignInitialValue, default,
TextAlignInitialValue, default, LIST_TYPE_CHOICES, LIST_IMAGE_CHOICES,
LIST_POSITION_CHOICES, DISC, OUTSIDE
)

from .exceptions import ValidationError
from .wrappers import Border, BorderBottom, BorderLeft, BorderRight, BorderTop, Outline
from .wrappers import Border, BorderBottom, BorderLeft, BorderRight, BorderTop, Outline, ListStyle

_CSS_PROPERTIES = set()

Expand Down Expand Up @@ -329,10 +331,10 @@ def __init__(self, **style):
# counter-increment

# 12.5 Lists
# list_style_type
# list_style_image
# list_style_position
# list_style
list_style_type = validated_property('list_style_type', choices=LIST_TYPE_CHOICES, initial=DISC)
list_style_image = validated_property('list_style_type', choices=LIST_IMAGE_CHOICES, initial=None)
list_style_position = validated_property('list_style_position', choices=LIST_POSITION_CHOICES, initial=OUTSIDE)
list_style = validated_shorthand_property('list_style', parser=parser.list_style, wrapper=ListStyle)

# 13. Paged media ####################################################
# 13.3.1 Page break properties
Expand Down
61 changes: 61 additions & 0 deletions colosseum/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,64 @@ def border_bottom(value):
def border_top(value):
"""Parse border string into a dictionary of outline properties."""
return border(value, direction='top')


##############################################################################
# List shorthands
##############################################################################
def _parse_list_style_property_part(value, list_style_dict):
"""Parse list style shorthand property part for known properties."""
from .constants import ( # noqa
LIST_TYPE_CHOICES, LIST_IMAGE_CHOICES, LIST_POSITION_CHOICES
)

for property_name, choices in {'list_style_type': LIST_TYPE_CHOICES,
'list_style_image': LIST_IMAGE_CHOICES,
'list_style_position': LIST_POSITION_CHOICES}.items():
try:
value = choices.validate(value)
except (ValueError, ValidationError):
continue

if property_name in list_style_dict:
raise ValueError('Invalid duplicated property!')

list_style_dict[property_name] = value
return list_style_dict

raise ValueError('List style value "{value}" not valid!'.format(value=value))


def list_style(value):
"""
Parse list style string into a dictionary of list style properties.
The font CSS property is a shorthand for list-style-type, list-style-image, and list-style-position.
Reference:
- https://www.w3.org/TR/2011/REC-CSS2-20110607/generate.html#lists
"""
if value:
if isinstance(value, str):
values = [val.strip() for val in value.split()]
elif isinstance(value, Sequence):
values = value
else:
raise ValueError('Unknown list style %s ' % value)
else:
raise ValueError('Unknown list style %s ' % value)

# We iteratively split by the first left hand space found and try to validate if that part
# is a valid <list-style-type> or <list-style-image> or <list-style-position> (which can come in any order)

# We use this dictionary to store parsed values and check that values properties are not
# duplicated
list_style_dict = {}
for idx, part in enumerate(values):
if idx > 2:
# Outline can have a maximum of 3 parts
raise ValueError('List style property shorthand contains too many parts!')

list_style_dict = _parse_list_style_property_part(part, list_style_dict)

return list_style_dict
7 changes: 7 additions & 0 deletions colosseum/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,10 @@ def is_quote(value):


is_quote.description = '[<string> <string>]+'


def is_uri(value):
return value


is_uri.description = 'TODO'
4 changes: 4 additions & 0 deletions colosseum/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,7 @@ class BorderLeft(Shorthand):

class Border(Shorthand):
VALID_KEYS = ['border_width', 'border_style', 'border_color']


class ListStyle(Shorthand):
VALID_KEYS = ['list_style_type', 'list_style_image', 'list_style_position']

0 comments on commit 9660e19

Please sign in to comment.