Skip to content

Commit 0a496e6

Browse files
Build markdown documents to HTML in the CI workflow (w3c#13432)
Add a build step that converts .md files in spec directories (explainers, transition documents, proposals, etc.) to HTML so they're served from GitHub Pages. The legacy draft server that previously handled this conversion is struggling with ~60% uptime. Relates to w3c#12054
1 parent 6827f30 commit 0a496e6

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

.github/workflows/build-specs.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
python-version: "3.14"
3434
cache: 'pip'
3535

36-
- run: pip install bikeshed
36+
- run: pip install bikeshed markdown
3737
- run: bikeshed update
3838

3939
# The following chunk of code all stolen from andeubotella
@@ -63,6 +63,8 @@ jobs:
6363
echo " $file"
6464
bikeshed issues-list "$file" || true
6565
done
66+
- name: Build markdown
67+
run: python ./bin/build-markdown.py
6668
- name: Build index & symlinks
6769
run: python ./bin/build-index.py
6870
- run: rm -rf ./.git{,attributes,ignore}

bin/build-markdown.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env python3
2+
"""Convert markdown files in spec directories to HTML."""
3+
4+
import glob
5+
import os
6+
import re
7+
8+
import markdown
9+
10+
TEMPLATE = """\
11+
<!doctype html>
12+
<meta charset="utf-8">
13+
<title>{title}</title>
14+
<style>
15+
body {{ max-width: 50em; margin: 2em auto; padding: 0 1em; font-family: sans-serif; line-height: 1.6; }}
16+
code {{ background: #f4f4f4; padding: .1em .3em; border-radius: 3px; }}
17+
pre {{ background: #f4f4f4; padding: 1em; overflow: auto; border-radius: 3px; }}
18+
pre code {{ background: none; padding: 0; }}
19+
img {{ max-width: 100%; }}
20+
</style>
21+
{body}
22+
"""
23+
24+
25+
def extract_title(text):
26+
m = re.search(r"^#\s+(.+)", text, re.MULTILINE)
27+
return m.group(1).strip() if m else "Untitled"
28+
29+
30+
def main():
31+
md = markdown.Markdown(extensions=["fenced_code", "tables"])
32+
33+
for md_file in sorted(glob.glob("*/*.md")):
34+
if md_file.startswith("."):
35+
continue
36+
37+
html_file = os.path.splitext(md_file)[0] + ".html"
38+
if os.path.exists(html_file):
39+
continue
40+
41+
with open(md_file, encoding="utf-8") as f:
42+
text = f.read()
43+
44+
title = extract_title(text)
45+
body = md.convert(text)
46+
md.reset()
47+
48+
with open(html_file, "w", encoding="utf-8") as f:
49+
f.write(TEMPLATE.format(title=title, body=body))
50+
51+
print(f" {html_file}")
52+
53+
54+
if __name__ == "__main__":
55+
main()

0 commit comments

Comments
 (0)