forked from pre-commit/pre-commit.com
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtemplate_lib.py
More file actions
114 lines (93 loc) · 2.87 KB
/
template_lib.py
File metadata and controls
114 lines (93 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import os
import re
import shlex
import subprocess
import sys
import markdown_code_blocks
import markupsafe
ID_RE = re.compile(r'\[\]\(#([a-z0-9-]+)\)')
SPECIAL_CHARS_RE = re.compile('[^a-z0-9 _-]')
ROW = '=r='
COL = ' =c= '
INDENT = ' ' * 8
def _render_table(code: str) -> str:
"""Renders our custom "table" type
```table
=r=
=c= col1
=c= col2
=r=
=c= col3
=c= col4
```
renders to
<table class="table table-bordered">
<tbody>
<tr><td>col1</td><td>col2</td></tr>
<tr><td>col3</td><td>col4</td></tr>
</tbody>
</table>
"""
output = ['<table class="table table-bordered"><tbody>']
in_row = False
col_buffer = None
def _maybe_end_col() -> None:
nonlocal col_buffer
if col_buffer is not None:
output.append(f'<td>{md(col_buffer)}</td>')
col_buffer = None
def _maybe_end_row() -> None:
nonlocal in_row
if in_row:
output.append('</tr>')
in_row = False
for line in code.splitlines(True):
if line.startswith(ROW):
_maybe_end_col()
_maybe_end_row()
in_row = True
output.append('<tr>')
elif line.startswith(COL):
_maybe_end_col()
col_buffer = line[len(COL):]
elif col_buffer is not None:
if line == '\n':
col_buffer += line
else:
assert line.startswith(INDENT), line
col_buffer += line[len(INDENT):]
else:
raise AssertionError(line)
_maybe_end_col()
_maybe_end_row()
output.append('</tbody></table>')
return ''.join(output)
def _render_cmd(code: str) -> str:
cmdstr = code.strip()
path = f'{os.path.dirname(sys.executable)}{os.pathsep}{os.environ["PATH"]}'
env = {**os.environ, 'PATH': path}
output = subprocess.check_output(shlex.split(cmdstr), env=env).decode()
return str(md(f'```pre-commit\n$ {cmdstr}\n{output}```'))
class Renderer(markdown_code_blocks.CodeRenderer):
def header(self, text: str, level: int, raw: str) -> str:
match = ID_RE.search(raw)
if match:
h_id = match.group(1)
else:
h_id = SPECIAL_CHARS_RE.sub('', raw.lower()).replace(' ', '-')
return (
f'<h{level} id="{h_id}">'
f' {text} <small><a href="#{h_id}">¶</a></small>'
f'</h{level}> '
)
def block_code(self, code: str, lang: str) -> str:
if lang == 'table':
return _render_table(code)
elif lang == 'cmd':
return _render_cmd(code)
else:
return super().block_code(code, lang)
def md(s: str) -> str:
html = markdown_code_blocks.highlight(s, Renderer=Renderer)
# manually bless the highlighted output.
return markupsafe.Markup(html)