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

1def serialize(nodes): 

2 """Serialize nodes to CSS syntax. 

3 

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. 

9 

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. 

13 

14 """ 

15 chunks = [] 

16 _serialize_to(nodes, chunks.append) 

17 return ''.join(chunks) 

18 

19 

20def serialize_identifier(value): 

21 """Serialize any string as a CSS identifier 

22 

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. 

30 

31 """ 

32 if value == '-': 

33 return r'\-' 

34 

35 if value[:2] == '--': 

36 return '--' + serialize_name(value[2:]) 

37 

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 

55 

56 

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 ) 

67 

68 

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 ) 

79 

80 

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 ) 

96 

97 

98# https://drafts.csswg.org/css-syntax/#serialization-tables 

99def _serialize_to(nodes, write): 

100 """Serialize an iterable of nodes to CSS syntax. 

101 

102 White chunks as a string by calling the provided :obj:`write` callback. 

103 

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 

120 

121 

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)