Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

math2svg.lua filter #118

Merged
merged 51 commits into from
Jan 16, 2021
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
4e04b48
new file: README.md
Oct 11, 2020
4812569
modified: displaymath2svg README.md
Oct 11, 2020
d51a163
modified: README.md
Oct 11, 2020
2d30334
modified: README.md
Oct 11, 2020
ac2e714
Privacy code auditing
Oct 11, 2020
45b55e3
modified: displaymath2svg README.md
Oct 11, 2020
a160c06
modified: README.md
Oct 11, 2020
797a596
displaymath2svg.lua test added
Oct 11, 2020
f6d72c9
displaymath2svg
Oct 11, 2020
82fa204
modified: README.md
Oct 11, 2020
8db789e
MIT License
Oct 11, 2020
113413f
MathML comment
Oct 11, 2020
3102fb5
math2svg.lua
Oct 12, 2020
1f96b0d
README.md
Oct 12, 2020
6848665
refactoring of math2svg.lua
Oct 12, 2020
2121998
pandoc.Image when output format is not HTML.
Oct 12, 2020
277c007
License
Oct 12, 2020
74a4445
install instructions
Oct 12, 2020
afdfe46
MathML newcommands
Oct 12, 2020
1516ed5
improved inline SVG
Oct 12, 2020
fbdf9ce
argumentlist & reduced description
Oct 13, 2020
a38c802
macros removed in favour of header-includes
Oct 13, 2020
dd19ae1
sample.yaml
Oct 13, 2020
c8975ea
configuration over --metadata key values
Oct 14, 2020
0d9e3e3
README.md math2svg.lua
Oct 15, 2020
e40396e
Documentation completed (#1)
stroobandt Oct 15, 2020
6c1410d
README.md
Oct 15, 2020
b52cf39
README.md
Oct 16, 2020
15ff17c
README.md
Oct 16, 2020
a0a1d58
README.md
Oct 16, 2020
db42ee6
120 column lines & math2svg_tex2svg key value
Oct 16, 2020
0d3876c
README.md privacy statement
Oct 16, 2020
237ce0c
Makefile
Oct 16, 2020
0691b00
<span class="math display">
Oct 16, 2020
02354d0
description
Oct 17, 2020
473c360
.travis.yml
Oct 17, 2020
59fd787
README.md
Oct 26, 2020
6811a49
README.md 80 columns
Oct 26, 2020
0ccfcc1
README.md 80 columns
Oct 26, 2020
4dd39ad
math2svg.lua 80 columns
Oct 26, 2020
4719dfb
Typo in README.md
stroobandt Oct 26, 2020
bb6c273
.travis.yml
Oct 26, 2020
c94c9c0
.travis.yml
Oct 26, 2020
58935cb
.travis.yml
Oct 27, 2020
55cfd17
.travis.yml
stroobandt Oct 27, 2020
4601caa
Dockerfile
stroobandt Jan 14, 2021
267b99a
Dockerfile
stroobandt Jan 14, 2021
803c7a2
year 2021
stroobandt Jan 14, 2021
f70e9c5
README.md
stroobandt Jan 16, 2021
9f2f99d
README.md
stroobandt Jan 16, 2021
1b7efba
Merge branch 'master' into master
tarleb Jan 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions math2svg/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.swp
stroobandt marked this conversation as resolved.
Show resolved Hide resolved
10 changes: 10 additions & 0 deletions math2svg/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
DIFF ?= diff --strip-trailing-cr -u

test: sample.md math2svg.lua
@pandoc --mathml --lua-filter=math2svg.lua --to=html $< \
| $(DIFF) expected.html -

expected: sample.md math2svg.lua
pandoc --mathml --lua-filter=math2svg.lua --output=expected.html $<

.PHONY: test
77 changes: 77 additions & 0 deletions math2svg/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Description
stroobandt marked this conversation as resolved.
Show resolved Hide resolved

This [Lua filter](https://pandoc.org/lua-filters.html)
for [Pandoc](https://pandoc.org/)
converts [LaTeX math](https://en.wikibooks.org/wiki/LaTeX/Mathematics)
to [MathJax](https://www.mathjax.org/) generated
[scalable vector graphics (SVG)](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics)
in any of the [available MathJax fonts](https://docs.mathjax.org/en/latest/output/fonts.html).

This is useful when a CSS paged media engine cannot process complex JavaScript
stroobandt marked this conversation as resolved.
Show resolved Hide resolved
as required by MathJax.
See: <https://www.print-css.rocks> for information about CSS paged media,
a [W3C standard](https://www.w3.org/TR/css-page-3/).

The filter also allows to define additional LaTeX commands.


# Requires

```bash
$ sudo apt install pandoc nodejs npm
stroobandt marked this conversation as resolved.
Show resolved Hide resolved
$ sudo npm install --global mathjax-node-cli
```


# Usage

To be used as a [Pandoc Lua filter](https://pandoc.org/lua-filters.html).
[MathML](https://en.wikipedia.org/wiki/MathML) should be set as a fallback.

```bash
pandoc --mathml --filter='math2svg.lua'
```


# Privacy

No Internet connection is established when creating MathJax SVG code using
the `tex2svg` command of [`mathjax-node-cli`](https://github.com/mathjax/mathjax-node-cli).
Hence, formulas in SVG can be created offline and will remain private.
For code auditing, see also:

- <https://github.com/mathjax/MathJax-node>
- <https://github.com/pkra/mathjax-node-sre>


# Copyright
stroobandt marked this conversation as resolved.
Show resolved Hide resolved

Copyright (c) 2020 Serge Y. Stroobandt


## MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


# Contact

```bash
$ echo c2VyZ2VAc3Ryb29iYW5kdC5jb20K |base64 -d
```
94 changes: 94 additions & 0 deletions math2svg/expected.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<p>Only <strong>plane waves in the far field</strong> exhibit the <a href="https://en.wikipedia.org/wiki/Impedance_of_free_space">characteristic impedance of free space</a>, which is exactly:</p>
<p><div class="math display"><svg xmlns:xlink="http://www.w3.org/1999/xlink" width="38.427ex" height="9.509ex" style="vertical-align: -4.171ex;" viewBox="0 -2298.3 16545 4094.3" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg">
<defs>
<path stroke-width="1" id="E1-GYREPAGELLANORMAL-1D44D" d="M637 672l-504 -633h281c44 0 82 4 127 13c10 26 6 8 32 90l7 22h26c-13 -69 -21 -126 -23 -167l-322 3l-241 -3v22l502 633h-180c-86 0 -124 -3 -180 -13l-6 -20c-12 -39 -18 -64 -21 -86h-26c8 73 11 112 11 158l118 1l237 -3l162 3v-20Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-30" d="M465 366c0 -256 -76 -386 -227 -386c-62 0 -118 28 -153 77s-56 150 -56 267c0 242 79 365 234 365c137 0 202 -104 202 -323zM381 316c0 240 -39 338 -136 338c-95 0 -132 -83 -132 -294c0 -244 41 -345 138 -345c92 0 130 88 130 301Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-3D" d="M680 330h-600c2 10 3 20 3 30s-1 20 -3 30h600c-2 -10 -3 -20 -3 -30s1 -20 3 -30zM680 110h-600c2 10 3 20 3 30s-1 20 -3 30h600c-2 -10 -3 -20 -3 -30s1 -20 3 -30Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-7C" d="M128 -150c-8 2 -16 3 -24 3s-16 -1 -24 -3v800c8 -2 16 -3 24 -3s16 1 24 3v-800Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLANORMAL-1D438" d="M570 689c-11 -38 -18 -88 -21 -152h-24l-8 89c-1 15 -42 24 -107 24c-99 -2 -74 -2 -130 -4c-4 -8 -6 -16 -9 -32l-42 -238h37l219 6l4 -7l-19 -45c-31 1 -6 4 -132 4h-117l-43 -253c-2 -12 -2 -23 -2 -35c63 -6 90 -7 131 -7c60 0 131 5 150 10c21 5 30 17 39 52l16 60 h27c-8 -41 -16 -83 -21 -125l-4 -36c-39 -1 -19 -3 -105 -3l-225 3l-154 -3l5 26c44 7 57 14 60 32l87 504c6 32 9 62 9 77c0 17 -11 25 -35 26l-54 2l3 28l160 -3l236 3c23 0 47 -1 69 -3Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-20D7" d="M-57 664c-45 -36 -85 -76 -120 -120c-12 2 -23 3 -34 3c-12 0 -23 -1 -34 -3c28 34 58 67 91 96h-289c2 8 3 16 3 24s-1 16 -3 24h289c-33 29 -63 62 -91 96c11 -2 22 -3 34 -3c11 0 22 1 34 3c35 -44 75 -84 120 -120Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLASIZE4-7C" d="M138 -579c-10 2 -19 3 -29 3s-19 -1 -29 -3v1658c10 -2 19 -3 29 -3s19 1 29 3v-1658Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLANORMAL-1D43B" d="M800 692l-3 -28l-36 -3c-38 -3 -44 -9 -51 -48l-92 -520c-3 -17 -4 -26 -4 -35c0 -21 10 -29 36 -30l58 -3l-3 -28l-132 3l-141 -3l4 28l50 3c22 1 33 6 37 14c5 6 12 34 21 83l40 215l-184 3l-184 -3l-42 -247c-3 -19 -4 -26 -4 -35c0 -21 9 -28 36 -30l49 -3l-3 -28 l-123 3l-132 -3l4 28l41 3c40 3 42 5 58 97l74 434c5 31 9 62 9 76c0 18 -11 26 -35 27l-47 2l3 28l141 -3l114 3l-3 -28l-42 -3c-37 -3 -44 -9 -51 -48l-42 -228h370l30 174c5 30 9 62 9 76c0 18 -11 26 -35 27l-48 2l3 28l143 -3c36 0 71 1 107 3Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLANORMAL-1D707" d="M549 85c-99 -72 -137 -94 -163 -94c-19 0 -30 15 -28 40c-1 16 3 38 14 76l39 132c-32 -51 -55 -79 -97 -125c-68 -74 -134 -125 -164 -125c-3 0 -10 1 -22 4l-18 -225c-2 -13 -10 -23 -34 -32l-31 -12l-13 8l148 660c2 11 -5 20 -15 20c-9 0 -19 -5 -49 -23l-33 -21 l-7 20l30 20c76 54 113 74 134 74c14 0 22 -11 22 -32c-1 -12 -3 -26 -6 -42l-65 -271c-7 -26 -9 -37 -8 -52c-1 -17 3 -26 12 -26c41 0 123 74 184 166c31 46 56 113 74 189l11 51l68 17l8 -9l-94 -357c-6 -16 -7 -32 -8 -40c0 -10 5 -17 13 -17c12 0 36 11 62 27l26 17Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLANORMAL-1D716" d="M491 422l-41 -52l-20 -2c-7 15 -18 32 -25 39c-20 24 -53 31 -86 31c-35 0 -71 -13 -98 -37c-43 -37 -62 -90 -70 -139l108 -1l125 2l-14 -35l-6 -6l-140 1c-7 0 -55 0 -80 -3c-2 -12 -4 -25 -3 -37c1 -11 0 -22 3 -32c13 -64 77 -112 122 -112c36 0 85 17 137 55l24 17 l9 -19c-94 -74 -146 -103 -205 -103c-53 0 -107 12 -139 50c-26 32 -38 73 -38 116c0 17 0 35 4 53c18 86 54 150 117 203c55 46 118 71 183 71c53 0 102 -23 133 -60Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLASIZE5-221A" d="M787 1500h-164l-90 -2530c-14 2 -27 3 -40 3c-14 0 -27 -1 -41 -3l-266 1218h-66v60h154l210 -961l81 2273h222v-60Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-22C5" d="M200 250c0 -36 -24 -60 -60 -60s-60 24 -60 60s24 60 60 60s60 -24 60 -60Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLANORMAL-1D450" d="M389 458c-9 -26 -16 -63 -24 -128h-23v60c0 24 -36 43 -81 43c-32 0 -57 -8 -78 -26c-48 -39 -82 -142 -82 -248c0 -79 29 -119 85 -119c35 0 73 17 145 65l15 10l8 -20l-50 -41c-55 -45 -103 -65 -157 -65c-80 0 -122 51 -122 147c0 107 38 211 95 261s128 85 173 85 c38 0 71 -8 96 -24Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-2248" d="M678 434c-29 -89 -62 -139 -124 -156c-13 -4 -26 -5 -38 -5c-54 0 -107 30 -154 62c-36 25 -75 53 -117 53c-8 0 -16 -1 -24 -4c-47 -13 -81 -43 -103 -110c-5 4 -12 7 -18 9s-13 3 -20 3c29 89 62 139 124 156c13 4 26 5 38 5c54 0 107 -30 154 -62 c36 -25 75 -53 117 -53c8 0 16 1 24 4c47 13 81 43 103 110c6 -4 12 -7 18 -9c7 -2 13 -3 20 -3zM678 214c-29 -89 -62 -139 -124 -156c-13 -4 -26 -5 -38 -5c-54 0 -107 30 -154 62c-36 25 -75 53 -117 53c-8 0 -16 -1 -24 -4c-47 -13 -81 -43 -103 -110c-5 4 -12 7 -18 9 s-13 3 -20 3c29 89 62 139 124 156c13 4 26 5 38 5c54 0 107 -30 154 -62c36 -25 75 -53 117 -53c8 0 16 1 24 4c47 13 81 43 103 110c6 -4 12 -7 18 -9c7 -2 13 -3 20 -3Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-33" d="M462 224c0 -47 -17 -91 -51 -132c-55 -67 -147 -112 -227 -112c-37 0 -81 8 -134 26c-6 50 -14 86 -35 147l27 10c19 -54 32 -77 56 -99c30 -28 71 -43 117 -43c93 0 154 67 154 169c0 91 -48 144 -131 144c-27 0 -46 -5 -84 -22l-7 6l12 53s39 -3 47 -3 c71 0 130 63 130 138c0 63 -53 116 -118 116c-52 0 -115 -34 -126 -68l-18 -56h-31l29 124c48 48 93 67 161 67c111 0 185 -59 185 -148c0 -59 -30 -105 -110 -167c50 -9 73 -17 98 -35c36 -25 56 -67 56 -115Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-37" d="M497 659l-183 -329c-89 -159 -115 -224 -157 -333c0 0 -28 3 -46 3s-46 -3 -46 -3l-9 13l244 392c38 61 69 119 109 201h-267c-46 0 -53 -8 -61 -70l-7 -56h-30s3 62 3 102c0 41 -3 105 -3 105l10 5c97 -4 114 -5 219 -5c107 0 116 1 224 5v-30Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-36" d="M468 219c0 -136 -97 -239 -227 -239c-129 0 -209 102 -209 267c0 137 56 259 159 346c51 44 92 64 188 96l37 -17v-8c-180 -54 -264 -152 -285 -333c66 54 103 78 162 78c106 0 175 -75 175 -190zM382 184c0 99 -51 165 -127 165c-48 0 -95 -24 -117 -58 c-11 -17 -15 -36 -15 -71c0 -134 46 -207 131 -207c77 0 128 67 128 171Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-2E" d="M183 53c0 -31 -28 -58 -60 -58c-29 0 -56 28 -56 58s27 58 57 58c31 0 59 -28 59 -58Z"></path>
<path stroke-width="1" id="E1-GYREPAGELLAMAIN-3A9" d="M801 158c-6 -43 -7 -112 -7 -161c-21 0 -81 3 -119 3c-23 0 -98 0 -119 -3h-22v39c9 9 23 13 38 23c6 4 15 14 25 29c27 40 79 155 79 247c0 212 -79 332 -256 332s-257 -119 -257 -332c0 -92 52 -207 79 -247c10 -15 19 -25 25 -29c14 -10 29 -14 38 -23v-39h-22 c-21 3 -96 3 -119 3c-38 0 -98 -3 -119 -3c0 49 -1 118 -7 161h26l7 -52c4 -29 17 -37 36 -37h115c-63 53 -166 170 -166 302c0 207 139 338 364 338s363 -132 363 -338c0 -132 -103 -249 -166 -302h115c19 0 32 8 36 37l7 52h26Z"></path>
</defs>
<g stroke="currentColor" fill="currentColor" stroke-width="0" transform="matrix(1 0 0 -1 0 0)">
<use xlink:href="#E1-GYREPAGELLANORMAL-1D44D" x="0" y="0"></use>
<use transform="scale(0.707)" xlink:href="#E1-GYREPAGELLAMAIN-30" x="943" y="-213"></use>
<use xlink:href="#E1-GYREPAGELLAMAIN-3D" x="1399" y="0"></use>
<g transform="translate(2159,0)">
<g transform="translate(397,0)">
<rect stroke="none" width="1357" height="60" x="0" y="220"></rect>
<g transform="translate(154,1099)">
<use xlink:href="#E1-GYREPAGELLASIZE4-7C"></use>
<g transform="translate(218,0)">
<use xlink:href="#E1-GYREPAGELLANORMAL-1D438" x="0" y="0"></use>
<use xlink:href="#E1-GYREPAGELLAMAIN-20D7" x="526" y="257"></use>
</g>
<use xlink:href="#E1-GYREPAGELLASIZE4-7C" x="830" y="0"></use>
</g>
<g transform="translate(60,-1100)">
<use xlink:href="#E1-GYREPAGELLASIZE4-7C"></use>
<g transform="translate(218,0)">
<use xlink:href="#E1-GYREPAGELLANORMAL-1D43B" x="0" y="0"></use>
<use xlink:href="#E1-GYREPAGELLAMAIN-20D7" x="635" y="257"></use>
</g>
<use xlink:href="#E1-GYREPAGELLASIZE4-7C" x="1019" y="0"></use>
</g>
</g>
</g>
<use xlink:href="#E1-GYREPAGELLAMAIN-3D" x="4312" y="0"></use>
<g transform="translate(5351,0)">
<use xlink:href="#E1-GYREPAGELLASIZE5-221A" x="0" y="-75"></use>
<rect stroke="none" width="1410" height="60" x="757" y="1426"></rect>
<g transform="translate(757,0)">
<g transform="translate(120,0)">
<rect stroke="none" width="1170" height="60" x="0" y="220"></rect>
<g transform="translate(60,796)">
<use xlink:href="#E1-GYREPAGELLANORMAL-1D707" x="0" y="0"></use>
<use transform="scale(0.707)" xlink:href="#E1-GYREPAGELLAMAIN-30" x="843" y="-213"></use>
</g>
<g transform="translate(113,-686)">
<use xlink:href="#E1-GYREPAGELLANORMAL-1D716" x="0" y="0"></use>
<use transform="scale(0.707)" xlink:href="#E1-GYREPAGELLAMAIN-30" x="692" y="-213"></use>
</g>
</g>
</g>
</g>
<use xlink:href="#E1-GYREPAGELLAMAIN-3D" x="7796" y="0"></use>
<g transform="translate(8834,0)">
<use xlink:href="#E1-GYREPAGELLANORMAL-1D707" x="0" y="0"></use>
<use transform="scale(0.707)" xlink:href="#E1-GYREPAGELLAMAIN-30" x="843" y="-213"></use>
</g>
<use xlink:href="#E1-GYREPAGELLAMAIN-22C5" x="10107" y="0"></use>
<g transform="translate(10610,0)">
<use xlink:href="#E1-GYREPAGELLANORMAL-1D450" x="0" y="0"></use>
<use transform="scale(0.707)" xlink:href="#E1-GYREPAGELLAMAIN-30" x="576" y="-213"></use>
</g>
<use xlink:href="#E1-GYREPAGELLAMAIN-2248" x="11749" y="0"></use>
<g transform="translate(12785,0)">
<use xlink:href="#E1-GYREPAGELLAMAIN-33"></use>
<use xlink:href="#E1-GYREPAGELLAMAIN-37" x="500" y="0"></use>
<use xlink:href="#E1-GYREPAGELLAMAIN-36" x="1001" y="0"></use>
<use xlink:href="#E1-GYREPAGELLAMAIN-2E" x="1501" y="0"></use>
<use xlink:href="#E1-GYREPAGELLAMAIN-37" x="1752" y="0"></use>
<use xlink:href="#E1-GYREPAGELLAMAIN-33" x="2252" y="0"></use>
</g>
<use xlink:href="#E1-GYREPAGELLAMAIN-3A9" x="15705" y="0"></use>
</g>
</svg>
</div></p>
<div class="line-block">where:<br />
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>c</mi><mn>0</mn></msub><mo>=</mo><mn>299</mn><mspace width="0.167em"></mspace><mn>792</mn><mspace width="0.167em"></mspace><mn>458</mn><mspace width="0.167em"></mspace><mfrac><mtext mathvariant="normal">m</mtext><mtext mathvariant="normal">s</mtext></mfrac></mrow><annotation encoding="application/x-tex">c_0 = 299\,792\,458\,\frac{\text{m}}{\text{s}}</annotation></semantics></math>: the speed of light in free space<br />
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>μ</mi><mn>0</mn></msub><mo>=</mo><mn>4</mn><mi>π</mi><mo>⋅</mo><msup><mn>10</mn><mrow><mo>−</mo><mn>7</mn></mrow></msup><mfrac><mtext mathvariant="normal">H</mtext><mtext mathvariant="normal">m</mtext></mfrac></mrow><annotation encoding="application/x-tex">\mu_0 = 4\pi\cdot10^{-7}\frac{\text{H}}{\text{m}}</annotation></semantics></math>: the free space permeability<br />
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>ϵ</mi><mn>0</mn></msub><mo>=</mo><mfrac><mn>1</mn><mrow><msub><mi>μ</mi><mn>0</mn></msub><msubsup><mi>c</mi><mn>0</mn><mn>2</mn></msubsup></mrow></mfrac></mrow><annotation encoding="application/x-tex">\epsilon_0 = \frac{1}{\mu_0 c_0^2}</annotation></semantics></math>: the absolute permittivity of free space<br />
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>Z</mi><mn>0</mn></msub><annotation encoding="application/x-tex">Z_0</annotation></semantics></math>: the characteristic impedance of free space</div>
137 changes: 137 additions & 0 deletions math2svg/math2svg.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
-- DESCRIPTION
stroobandt marked this conversation as resolved.
Show resolved Hide resolved
--
-- This Lua filter for Pandoc converts LaTeX math to MathJax generated
-- scalable vector graphics (SVG) in any of the available MathJax fonts.
--
-- This is useful when a CSS paged media engine cannot process complex JavaScript
-- as required by MathJax.
--
-- See: https://www.print-css.rocks for information about CSS paged media, a W3C
-- standard.
--
-- The filter also allows to define additional LaTeX commands.


-- REQUIRES
--
-- $ sudo apt install pandoc nodejs npm
-- $ sudo npm install --global mathjax-node-cli


-- USAGE
--
-- To be used as a Pandoc Lua filter.
-- MathML should be set as a fallback.
--
-- pandoc --mathml --filter='math2svg.lua'
--
-- See also: https://pandoc.org/lua-filters.html


-- PRIVACY
--
-- No Internet connection is established when creating MathJax SVG code using
-- the tex2svg command of mathjax-node-cli.
-- Hence, formulas in SVG can be created offline and will remain private.
--
-- For code auditing, see also:
-- - https://github.com/mathjax/MathJax-node
-- - https://github.com/pkra/mathjax-node-sre
-- - https://github.com/mathjax/mathjax-node-cli


-- COPYRIGHT
--
-- Copyright (c) 2020 Serge Y. Stroobandt
--
-- MIT License
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in all
-- copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.


-- CONTACT
--
-- $ echo c2VyZ2VAc3Ryb29iYW5kdC5jb20K |base64 -d


-- Enter here the full path to the tex2svg binary of mathjax-node-cli.
-- The full path can be found with the following command:
-- $ which tex2svg
local tex2svg = '/usr/local/lib/node_modules/mathjax-node-cli/bin/tex2svg'
stroobandt marked this conversation as resolved.
Show resolved Hide resolved


-- Supported MathJax fonts are: https://docs.mathjax.org/en/latest/output/fonts.html
local font = 'Gyre-Pagella'


-- Indicate with true or false whether DisplayMath and InlineMath should be converted to SVG.
local display2svg = true
stroobandt marked this conversation as resolved.
Show resolved Hide resolved
local inline2svg = false
-- The fallback is MathML if pandoc is executed with the --mathml argument.
-- MathML output gets generated much faster than SVG output.
-- Moreover, MathML is better suited to InlineMath as line heights are kept small.


-- Any additional LaTeX math commands can be defined here.
-- For example:
-- local newcommands = '\\newcommand{\\j}{{\\text{j}}}\\newcommand{\\e}[1]{\\,{\\text{e}}^{#1}}'
local newcommands = ''
stroobandt marked this conversation as resolved.
Show resolved Hide resolved


-- The available options for tex2svg are:
--help Show help [boolean]
--version Show version number [boolean]
--inline process as in-line TeX [boolean]
--speech include speech text [boolean] [default: true]
--linebreaks perform automatic line-breaking [boolean]
--font web font to use [default: "TeX"]
--ex ex-size in pixels [default: 6]
--width width of container in ex [default: 100]
--extensions extra MathJax extensions e.g. 'Safe,TeX/noUndefined' [default: ""]


function Math(elem)

if elem.mathtype == 'DisplayMath' and display2svg then

local svg = pandoc.pipe(tex2svg, {'--speech=false', '--font', font, newcommands .. elem.text}, '')

if FORMAT:match '^html.?' then
svg = '<div class="math display">' .. svg .. '</div>'
return pandoc.RawInline(FORMAT, svg)
else
local filename = pandoc.sha1(svg) .. '.svg'
return pandoc.mediabag.insert(filename, 'image/svg+xml', svg)
end

elseif elem.mathtype == 'InlineMath' and inline2svg then

local svg = pandoc.pipe(tex2svg, {'--speech=false', '--font', font, newcommands .. elem.text}, '')
stroobandt marked this conversation as resolved.
Show resolved Hide resolved

if FORMAT:match '^html.?' then
svg = '<span class="math inline">' .. svg .. '</span>'
return pandoc.RawInline(FORMAT, svg)
else
local filename = pandoc.sha1(svg) .. '.svg'
return pandoc.mediabag.insert(filename, 'image/svg+xml', svg)
stroobandt marked this conversation as resolved.
Show resolved Hide resolved
end

end

end
Loading