-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathhighlighting.py
57 lines (40 loc) · 1.61 KB
/
highlighting.py
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
"""Highlights code blocks using Pygments."""
import html
import re
import pygments.formatters
import pygments.lexers
# Make code fences with `python` as the language default to highlighting as
# Python 3.
_LANG_ALIASES = {
'python': 'python3',
}
def highlight(content: str) -> str:
"""Syntax-highlights HTML-rendered Markdown.
Plucks sections to highlight that conform the the GitHub fenced code info
string as defined at https://github.github.com/gfm/#info-string.
"""
formatter = pygments.formatters.HtmlFormatter(nowrap=True)
code_expr = re.compile(
r'<pre><code class="language-(?P<lang>.+?)">(?P<code>.+?)'
r'</code></pre>', re.DOTALL)
def replacer(match):
try:
lang = match.group('lang')
lang = _LANG_ALIASES.get(lang, lang)
lexer = pygments.lexers.get_lexer_by_name(lang)
except ValueError:
lexer = pygments.lexers.TextLexer()
code = match.group('code')
# Decode html entities in the code. cmark tries to be helpful and
# translate '"' to '"', but it confuses pygments. Pygments will
# escape any html entities when re-writing the code.
code = html.unescape(code)
highlighted = pygments.highlight(code, lexer, formatter)
return '<pre class="lang-{}">{}</pre>'.format(lang, highlighted)
result = code_expr.sub(replacer, content)
return result
def get_style_css(style):
"""Returns the CSS for the given Pygments style."""
formatter = pygments.formatters.HtmlFormatter(
style=style)
return formatter.get_style_defs('pre')