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
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 06:10 +0000
1import re
3__all__ = ['plugin_table']
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' *\| *')
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)
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))
27 children = [thead, {'type': 'table_body', 'children': rows}]
28 return {'type': 'table', 'children': children}
31def parse_nptable(self, m, state):
32 thead, aligns = _process_table(m.group(1), m.group(2))
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))
39 children = [thead, {'type': 'table_body', 'children': rows}]
40 return {'type': 'table', 'children': children}
43def _process_table(header, align):
44 headers = HEADER_SPLIT.split(header)
45 aligns = ALIGN_SPLIT.split(align)
47 if header.endswith('|'):
48 headers.append('')
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
61 if len(headers) > i:
62 cells.append({
63 'type': 'table_cell',
64 'text': headers[i],
65 'params': (aligns[i], True)
66 })
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
78 thead = {'type': 'table_head', 'children': cells}
79 return thead, aligns
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 })
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 })
107 return {'type': 'table_row', 'children': cells}
110def render_html_table(text):
111 return '<table>\n' + text + '</table>\n'
114def render_html_table_head(text):
115 return '<thead>\n<tr>\n' + text + '</tr>\n</thead>\n'
118def render_html_table_body(text):
119 return '<tbody>\n' + text + '</tbody>\n'
122def render_html_table_row(text):
123 return '<tr>\n' + text + '</tr>\n'
126def render_html_table_cell(text, align=None, is_head=False):
127 if is_head:
128 tag = 'th'
129 else:
130 tag = 'td'
132 html = ' <' + tag
133 if align:
134 html += ' style="text-align:' + align + '"'
136 return html + '>' + text + '</' + tag + '>\n'
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 }
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')
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)
161 elif md.renderer.NAME == 'ast':
162 md.renderer.register('table_cell', render_ast_table_cell)