Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/mistune/plugins/table.py: 97%

91 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-03 06:10 +0000

1import re 

2 

3__all__ = ['plugin_table'] 

4 

5TABLE_PATTERN = re.compile( 

6 r' {0,3}\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*' 

7) 

8NP_TABLE_PATTERN = re.compile( 

9 r' {0,3}(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*' 

10) 

11HEADER_SUB = re.compile(r'\| *$') 

12HEADER_SPLIT = re.compile(r' *\| *') 

13ALIGN_SPLIT = re.compile(r' *\| *') 

14 

15 

16def parse_table(self, m, state): 

17 header = HEADER_SUB.sub('', m.group(1)).strip() 

18 align = HEADER_SUB.sub('', m.group(2)) 

19 thead, aligns = _process_table(header, align) 

20 

21 text = re.sub(r'(?: *\| *)?\n$', '', m.group(3)) 

22 rows = [] 

23 for i, v in enumerate(text.split('\n')): 

24 v = re.sub(r'^ *\| *| *\| *$', '', v) 

25 rows.append(_process_row(v, aligns)) 

26 

27 children = [thead, {'type': 'table_body', 'children': rows}] 

28 return {'type': 'table', 'children': children} 

29 

30 

31def parse_nptable(self, m, state): 

32 thead, aligns = _process_table(m.group(1), m.group(2)) 

33 

34 text = re.sub(r'\n$', '', m.group(3)) 

35 rows = [] 

36 for i, v in enumerate(text.split('\n')): 

37 rows.append(_process_row(v, aligns)) 

38 

39 children = [thead, {'type': 'table_body', 'children': rows}] 

40 return {'type': 'table', 'children': children} 

41 

42 

43def _process_table(header, align): 

44 headers = HEADER_SPLIT.split(header) 

45 aligns = ALIGN_SPLIT.split(align) 

46 

47 if header.endswith('|'): 

48 headers.append('') 

49 

50 cells = [] 

51 for i, v in enumerate(aligns): 

52 if re.search(r'^ *-+: *$', v): 

53 aligns[i] = 'right' 

54 elif re.search(r'^ *:-+: *$', v): 

55 aligns[i] = 'center' 

56 elif re.search(r'^ *:-+ *$', v): 

57 aligns[i] = 'left' 

58 else: 

59 aligns[i] = None 

60 

61 if len(headers) > i: 

62 cells.append({ 

63 'type': 'table_cell', 

64 'text': headers[i], 

65 'params': (aligns[i], True) 

66 }) 

67 

68 i += 1 

69 while i + 1 < len(headers): 

70 cells.append({ 

71 'type': 'table_cell', 

72 'text': headers[i], 

73 'params': (None, True) 

74 }) 

75 aligns.append(None) 

76 i += 1 

77 

78 thead = {'type': 'table_head', 'children': cells} 

79 return thead, aligns 

80 

81 

82def _process_row(row, aligns): 

83 cells = [] 

84 for i, s in enumerate(re.split(r' *(?<!\\)\| *', row)): 

85 text = re.sub(r'\\\|', '|', s.strip()) 

86 if len(aligns) < i + 1: 

87 cells.append({ 

88 'type': 'table_cell', 

89 'text': text, 

90 'params': (None, False) 

91 }) 

92 else: 

93 cells.append({ 

94 'type': 'table_cell', 

95 'text': text, 

96 'params': (aligns[i], False) 

97 }) 

98 

99 if len(cells) < len(aligns): 

100 for align in aligns[len(cells):]: 

101 cells.append({ 

102 'type': 'table_cell', 

103 'text': '', 

104 'params': (align, False), 

105 }) 

106 

107 return {'type': 'table_row', 'children': cells} 

108 

109 

110def render_html_table(text): 

111 return '<table>\n' + text + '</table>\n' 

112 

113 

114def render_html_table_head(text): 

115 return '<thead>\n<tr>\n' + text + '</tr>\n</thead>\n' 

116 

117 

118def render_html_table_body(text): 

119 return '<tbody>\n' + text + '</tbody>\n' 

120 

121 

122def render_html_table_row(text): 

123 return '<tr>\n' + text + '</tr>\n' 

124 

125 

126def render_html_table_cell(text, align=None, is_head=False): 

127 if is_head: 

128 tag = 'th' 

129 else: 

130 tag = 'td' 

131 

132 html = ' <' + tag 

133 if align: 

134 html += ' style="text-align:' + align + '"' 

135 

136 return html + '>' + text + '</' + tag + '>\n' 

137 

138 

139def render_ast_table_cell(children, align=None, is_head=False): 

140 return { 

141 'type': 'table_cell', 

142 'children': children, 

143 'align': align, 

144 'is_head': is_head 

145 } 

146 

147 

148def plugin_table(md): 

149 md.block.register_rule('table', TABLE_PATTERN, parse_table) 

150 md.block.register_rule('nptable', NP_TABLE_PATTERN, parse_nptable) 

151 md.block.rules.append('table') 

152 md.block.rules.append('nptable') 

153 

154 if md.renderer.NAME == 'html': 

155 md.renderer.register('table', render_html_table) 

156 md.renderer.register('table_head', render_html_table_head) 

157 md.renderer.register('table_body', render_html_table_body) 

158 md.renderer.register('table_row', render_html_table_row) 

159 md.renderer.register('table_cell', render_html_table_cell) 

160 

161 elif md.renderer.NAME == 'ast': 

162 md.renderer.register('table_cell', render_ast_table_cell)