Skip to content

Commit 1dd76cd

Browse files
committed
Going back to CodeCogs for math blocks
GitHub's LaTeX rendering is just not fit for purpose. When it works it's extremely convenient, but: 1. It's riddled with all sorts of bugs that are frustrating to try to work around. See https://github.com/nschloe/markdown-math-acid-test for some examples. This is after more than a year from release. The current pain in my backside is when you have both inline math and block math in the same list item? There's no real workaround for this so you either have to give up on math blocks or give up on lists. Both of these options make the readability of the document worse. See https://github.com/orgs/community/discussions/17325 for this specific bug. 2. The LaTeX rendering on GitHub is surprisingly ugly? It's quite jarring going from other markdown renderers like StackEdit to GitHub. Some research suggests this might be machine-font related, but I've tested on multiple machines, Firefox and Chrome (Chrome is slightly better), but the results have always be unsatisfying. So going back to CodeCogs. The ghmath2codecogs.py scripts helps with this. Note the original LaTeX is still accessible in the alt field of the img links.
1 parent a25dfe1 commit 1dd76cd

File tree

2 files changed

+80
-3
lines changed

2 files changed

+80
-3
lines changed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,12 @@ You can describe this mathematically in [GF(2)][gf2] (the extra
134134
$x^{\left|P\right|}$ represents shifting the message to make space for
135135
the CRC), but the above example is probably easier to understand:
136136

137-
``` math
138-
C(x) = M(x) x^{\left|P\right|} - (M(x) x^{\left|P\right|} \bmod P(x))
139-
```
137+
<p align="center">
138+
<img
139+
alt="C(x) = M(x) x^{\left|P\right|} - (M(x) x^{\left|P\right|} \bmod P(x))"
140+
src="https://latex.codecogs.com/svg.image?C%28x%29%20%3d%20M%28x%29%20x%5e%7b%5cleft%7cP%5cright%7c%7d%20%2d%20%28M%28x%29%20x%5e%7b%5cleft%7cP%5cright%7c%7d%20%5cbmod%20P%28x%29%29"
141+
>
142+
</p>
140143
141144
The neat thing is that this remainder operation does a real good job of
142145
mixing up all the bits. So if you choose a good CRC polynomial, it's very

ghmath2codecogs.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env python3
2+
3+
import re
4+
5+
URL = "https://latex.codecogs.com/svg.image?%s"
6+
7+
def main(input, output):
8+
lines = []
9+
with open(input) as f:
10+
for line in f:
11+
lines.append(line)
12+
13+
with open(output, 'w') as f:
14+
math = None
15+
ws = None
16+
for line in lines:
17+
if math is None:
18+
m = re.match('(\s*)```\s*math', line)
19+
if m:
20+
# start collecting math lines
21+
math = []
22+
ws = m.group(1)
23+
24+
else:
25+
f.write(line)
26+
27+
else:
28+
m = re.match('(\s*)```', line)
29+
if m:
30+
# merge all math, removing newlines
31+
math = ''.join(m[:-1]+' ' for m in math)
32+
# deduplicate a whitespace, but whitespace is
33+
# important so keep one space
34+
math = re.sub('\s+', ' ', math)
35+
# and strip
36+
math = math.strip()
37+
38+
# create the codecogs link
39+
f.write('%s<p align="center">\n' % ws)
40+
f.write('%s<img\n' % ws)
41+
f.write('%s alt="%s"\n' % (ws, math))
42+
f.write('%s src="%s"\n' % (ws, URL % ''.join(
43+
# for codecogs we need to url-encode our latex
44+
c if re.match('[a-zA-Z_]', c)
45+
else '%%%02x' % ord(c)
46+
for c in math)))
47+
f.write('%s>\n' % ws)
48+
f.write('%s</p>\n' % ws)
49+
50+
# reset
51+
math = None
52+
ws = None
53+
54+
else:
55+
math.append(line)
56+
57+
58+
if __name__ == "__main__":
59+
import sys
60+
import argparse
61+
parser = argparse.ArgumentParser(
62+
description="Rewrite a markdown file so GitHub math blocks "
63+
"are replaced with embedded images generated by codecogs.",
64+
allow_abbrev=False)
65+
parser.add_argument(
66+
'input',
67+
help="Input markdown file.")
68+
parser.add_argument(
69+
'-o', '--output',
70+
required=True,
71+
help="Output markdown file.")
72+
sys.exit(main(**{k: v
73+
for k, v in vars(parser.parse_args()).items()
74+
if v is not None}))

0 commit comments

Comments
 (0)