Newsletter
TechAnV Blog
Get updates on security engineering, Rust, eBPF, and DevSecOps. No spam, unsubscribe anytime.
Check your inbox and click the confirmation link to complete your subscription.
Rendering Markdown with the GitHub Markdown API#
I wanted to convert the Markdown used in my TILs to HTML, using the exact same configuration as GitHub does. GitHub has a whole load of custom extensions for things like tables and syntax highlighting (see issue 17).
It turns out they have an API for this!
1import httpx2
3body = """4# Example5
6This is example Markdown7"""8
9response = httpx.post(10 "https://api.github.com/markdown",11 json={12 # mode=gfm would expand #13 issue links, provided you pass13 # context=simonw/datasette too14 "mode": "markdown",15 "text": body,16 },17 headers=headers,18)19if response.status_code == 200:20 markdown_as_html = response.textresponse.headers will give you back information that includes rate-limiting details:
1{'server': 'GitHub.com',2 'date': 'Sat, 22 Aug 2020 19:20:29 GMT',3 'content-type': 'text/html;charset=utf-8',4 'content-length': '14',5 'status': '200 OK',6 'x-commonmarker-version': '0.21.0',7 'x-ratelimit-limit': '60',8 'x-ratelimit-remaining': '57',9 'x-ratelimit-reset': '1598125911',10 'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset',11 'access-control-allow-origin': '*',12 'strict-transport-security': 'max-age=31536000; includeSubdomains; preload',13 'x-frame-options': 'deny',14 'x-content-type-options': 'nosniff',15 'x-xss-protection': '1; mode=block',16 'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',17 'content-security-policy': "default-src 'none'",18 'vary': 'Accept-Encoding, Accept, X-Requested-With',19 'x-github-request-id': 'C9F0:12D7:32CDD4:8064E2:5F416FFD'}Calling it from JavaScript with fetch()#
I built a JavaScript tool that uses this API. Here’s the key function:
1async function render(markdown) {2 return (await fetch('https://api.github.com/markdown', {3 method: 'POST',4 headers: {5 'Content-Type': 'application/json'6 },7 body: JSON.stringify({'mode': 'markdown', 'text': markdown})8 })).text();9}Called like this:
1let rendered = await render(input.value);Syntax highlighting CSS#
Code examples you send to this API will come back something like this:
1<div class="highlight highlight-text-xml-svg"><pre><<span class="pl-ent">svg</span> <span class="pl-e">viewBox</span>=<span class="pl-s"><span class="pl-pds">"</span>0 0 500 100<span class="pl-pds">"</span></span>>2 <<span class="pl-ent">polyline</span>3 <span class="pl-e">fill</span>=<span class="pl-s"><span class="pl-pds">"</span>none<span class="pl-pds">"</span></span>4 <span class="pl-e">stroke</span>=<span class="pl-s"><span class="pl-pds">"</span>#0074d9<span class="pl-pds">"</span></span>5 <span class="pl-e">stroke-width</span>=<span class="pl-s"><span class="pl-pds">"</span>3<span class="pl-pds">"</span></span>6 <span class="pl-e">points</span>=<span class="pl-s"><span class="pl-pds">"</span></span>7<span class="pl-s"> 0,120</span>8<span class="pl-s"> 20,60</span>9<span class="pl-s"> 40,80</span>10<span class="pl-s"> 60,20<span class="pl-pds">"</span></span>/>https://github.com/primer/github-syntax-theme-generator has tools for theming these. I like this stylesheet (MIT licensed): https://github.com/primer/github-syntax-light/blob/master/lib/github-light.css - I figured this out in issue 20.