Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tinycss2/serializer.py: 19%
37 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-01 06:54 +0000
1def serialize(nodes):
2 """Serialize nodes to CSS syntax.
4 This should be used for :term:`component values`
5 instead of just :meth:`tinycss2.ast.Node.serialize` on each node
6 as it takes care of corner cases such as ``;`` between declarations,
7 and consecutive identifiers
8 that would otherwise parse back as the same token.
10 :type nodes: :term:`iterable`
11 :param nodes: An iterable of :class:`tinycss2.ast.Node` objects.
12 :returns: A :obj:`string <str>` representing the nodes.
14 """
15 chunks = []
16 _serialize_to(nodes, chunks.append)
17 return ''.join(chunks)
20def serialize_identifier(value):
21 """Serialize any string as a CSS identifier
23 :type value: :obj:`str`
24 :param value: A string representing a CSS value.
25 :returns:
26 A :obj:`string <str>` that would parse as an
27 :class:`tinycss2.ast.IdentToken` whose
28 :attr:`tinycss2.ast.IdentToken.value` attribute equals the passed
29 ``value`` argument.
31 """
32 if value == '-':
33 return r'\-'
35 if value[:2] == '--':
36 return '--' + serialize_name(value[2:])
38 if value[0] == '-':
39 result = '-'
40 value = value[1:]
41 else:
42 result = ''
43 c = value[0]
44 result += (
45 c if c in ('abcdefghijklmnopqrstuvwxyz_'
46 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') or ord(c) > 0x7F else
47 r'\A ' if c == '\n' else
48 r'\D ' if c == '\r' else
49 r'\C ' if c == '\f' else
50 '\\%X ' % ord(c) if c in '0123456789' else
51 '\\' + c
52 )
53 result += serialize_name(value[1:])
54 return result
57def serialize_name(value):
58 return ''.join(
59 c if c in ('abcdefghijklmnopqrstuvwxyz-_0123456789'
60 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') or ord(c) > 0x7F else
61 r'\A ' if c == '\n' else
62 r'\D ' if c == '\r' else
63 r'\C ' if c == '\f' else
64 '\\' + c
65 for c in value
66 )
69def serialize_string_value(value):
70 return ''.join(
71 r'\"' if c == '"' else
72 r'\\' if c == '\\' else
73 r'\A ' if c == '\n' else
74 r'\D ' if c == '\r' else
75 r'\C ' if c == '\f' else
76 c
77 for c in value
78 )
81def serialize_url(value):
82 return ''.join(
83 r"\'" if c == "'" else
84 r'\"' if c == '"' else
85 r'\\' if c == '\\' else
86 r'\ ' if c == ' ' else
87 r'\9 ' if c == '\t' else
88 r'\A ' if c == '\n' else
89 r'\D ' if c == '\r' else
90 r'\C ' if c == '\f' else
91 r'\(' if c == '(' else
92 r'\)' if c == ')' else
93 c
94 for c in value
95 )
98# https://drafts.csswg.org/css-syntax/#serialization-tables
99def _serialize_to(nodes, write):
100 """Serialize an iterable of nodes to CSS syntax.
102 White chunks as a string by calling the provided :obj:`write` callback.
104 """
105 bad_pairs = BAD_PAIRS
106 previous_type = None
107 for node in nodes:
108 serialization_type = (node.type if node.type != 'literal'
109 else node.value)
110 if (previous_type, serialization_type) in bad_pairs:
111 write('/**/')
112 elif previous_type == '\\' and not (
113 serialization_type == 'whitespace' and
114 node.value.startswith('\n')):
115 write('\n')
116 node._serialize_to(write)
117 if serialization_type == 'declaration':
118 write(';')
119 previous_type = serialization_type
122BAD_PAIRS = set(
123 [(a, b)
124 for a in ('ident', 'at-keyword', 'hash', 'dimension', '#', '-',
125 'number')
126 for b in ('ident', 'function', 'url', 'number', 'percentage',
127 'dimension', 'unicode-range')] +
128 [(a, b)
129 for a in ('ident', 'at-keyword', 'hash', 'dimension')
130 for b in ('-', '-->')] +
131 [(a, b)
132 for a in ('#', '-', 'number', '@')
133 for b in ('ident', 'function', 'url')] +
134 [(a, b)
135 for a in ('unicode-range', '.', '+')
136 for b in ('number', 'percentage', 'dimension')] +
137 [('@', b) for b in ('ident', 'function', 'url', 'unicode-range', '-')] +
138 [('unicode-range', b) for b in ('ident', 'function', '?')] +
139 [(a, '=') for a in '$*^~|'] +
140 [('ident', '() block'), ('|', '|'), ('/', '*')]
141)