Skip to content

Commit 21156fd

Browse files
authored
[misc] use highlight.js for syntax highlighting in blog post (#18480)
Toe get highlighting to work, we just need to import the CSS and run the highlight.js that does the highlighting in JS client side. We can add the lines at the top of the blog post to do this. I've made it only support bash and python for now to help with detection. But if we have a reason to, we can remove that and let it try them all. In a previous PR I've added the necessary `<code>` tags. Since we're highlighting nicely now, I also removed the extra indendation. I've also noticed that we're pretty good at specifying the language in code blocks in the changelog. So we can take that language and use it in the code block as a class to tell highlight.js exactly what language that code block is in. If this is useful, we can remove the limitation of only python and bash support from the top configuration in the future. This is useful for smaller blocks of a few lines where maybe it doesn't detect the language properly. Used on mypy 1.14 blog post - https://mypy-lang.blogspot.com/2024/12/mypy-114-released.html
1 parent 8859d51 commit 21156fd

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

misc/gen_blog_post_html.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,23 @@ def format_code(h: str) -> str:
4444
while i < len(a):
4545
if a[i].startswith(" ") or a[i].startswith("```"):
4646
indent = a[i].startswith(" ")
47+
language: str = ""
4748
if not indent:
49+
language = a[i][3:]
4850
i += 1
49-
r.append("<pre><code>")
51+
if language:
52+
r.append(f'<pre><code class="language-{language}">')
53+
else:
54+
r.append("<pre><code>")
5055
while i < len(a) and (
5156
(indent and a[i].startswith(" ")) or (not indent and not a[i].startswith("```"))
5257
):
5358
# Undo &gt; and &lt;
5459
line = a[i].replace("&gt;", ">").replace("&lt;", "<")
55-
if not indent:
56-
line = " " + line
60+
if indent:
61+
# Undo this extra level of indentation so it looks nice with
62+
# syntax highlighting CSS.
63+
line = line[4:]
5764
r.append(html.escape(line))
5865
i += 1
5966
r.append("</code></pre>")
@@ -64,7 +71,7 @@ def format_code(h: str) -> str:
6471
i += 1
6572
formatted = "\n".join(r)
6673
# remove empty first line for code blocks
67-
return re.sub(r"<code>\n", r"<code>", formatted)
74+
return re.sub(r"<code([^\>]*)>\n", r"<code\1>", formatted)
6875

6976

7077
def convert(src: str) -> str:
@@ -131,8 +138,18 @@ def convert(src: str) -> str:
131138
h,
132139
)
133140

134-
# Add missing top-level HTML tags
135-
h = '<html>\n<meta charset="utf-8" />\n<body>\n' + h + "</body>\n</html>"
141+
# Add top-level HTML tags and headers for syntax highlighting css/js.
142+
# We're configuring hljs to highlight python and bash code. We can remove
143+
# this configure call to make it try all the languages it supports.
144+
h = f"""<html>
145+
<meta charset="utf-8" />
146+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/a11y-light.min.css">
147+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
148+
<script>hljs.configure({{languages:["python","bash"]}});hljs.highlightAll();</script>
149+
<body>
150+
{h}
151+
</body>
152+
</html>"""
136153

137154
return h
138155

0 commit comments

Comments
 (0)