Skip to content

Commit

Permalink
Use pipes to communicate with mathjax; add asciimath support (#2)
Browse files Browse the repository at this point in the history
* change svg I/O from shell args to pipe;
add asciimath support

* update README
  • Loading branch information
zmx0142857 authored Feb 20, 2022
1 parent 6a4786d commit 8906a7b
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 26 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ $ manimgl-mathjax install
⚠ Currently you must use the latest version of ManimGL (i.e. clone from GitHub and install)

## Usage
Just use `JTex` instead of [`MTex`](https://github.com/3b1b/manim/pull/1725#issue-1121866424)
Just use `JTex` instead of [`MTex`](https://github.com/3b1b/manim/pull/1725#issue-1121866424)

Use `AM` to write math in [asciimath](http://asciimath.org/) notation, [see also](https://zmx0142857.gitee.io/note/#math).
2 changes: 1 addition & 1 deletion manimgl_mathjax/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

__version__ = pkg_resources.get_distribution("manimgl_mathjax").version

from .mathjax import JTex
from .mathjax import JTex, AM
41 changes: 38 additions & 3 deletions manimgl_mathjax/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
const fs = require('fs')
/**
* This file reads asciimath string from stdin and output svg formula to
* stdout. On linux you can end the input with ctrl-d; unfortunately on
* windows this is not possible, so you may use ctrl-c to interrupt the
* input.
*
* Another option is to redirect from file:
* $ node index.js < input.txt
* On windows, quote is needed:
* $ "node" index.js < input.txt
*/

const { am2tex } = require('asciimath-js')
const tex2svg = require('./tex2svg.js')
const { stdin, stdout } = process
const buf = []

stdin.setEncoding('utf8')

stdin.on('readable', () => {
let data
while ((data = stdin.read()) !== null) {
buf.push(data.trim())
}
})

const convert = process.argv[2] === '--am'
? (input) => tex2svg(am2tex(input))
: tex2svg

function onEnd () {
const input = buf.join('\n')
convert(input).then(svg => {
console.log(svg)
process.exit()
})
}

let { argv } = process
tex2svg(argv[3]).then(svg => fs.writeFileSync(argv[2], svg))
stdin.on('end', onEnd)
process.on('SIGINT', onEnd)
49 changes: 28 additions & 21 deletions manimgl_mathjax/mathjax.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import sys
import inspect
import importlib
import subprocess
from manimlib.logger import log
from manimlib.utils.directories import get_tex_dir
from manimlib.mobject.svg.mtex_mobject import MTex
Expand All @@ -15,33 +16,31 @@ def get_mathjax_dir():
return os.path.abspath(os.path.join(directory, "index.js"))


def tex_content_to_svg_file_using_mathjax(tex_content):
def tex_content_to_svg_file_using_mathjax(tex_content, *args):
svg_file = os.path.join(
get_tex_dir(), tex_hash(tex_content) + ".svg"
)
if not os.path.exists(svg_file):
tex_content_to_svg_using_mathjax(tex_content, svg_file)
return svg_file

# create pipe
process = subprocess.Popen(
["node", get_mathjax_dir(), *args],
stdout=subprocess.PIPE,
stdin=subprocess.PIPE
)
process.stdin.write(bytes(tex_content, "utf-8"))
stdout, stderr = process.communicate()

def tex_content_to_svg_using_mathjax(tex_file_content, svg_file):
commands = [
"node",
f"\"{get_mathjax_dir()}\"",
f"\"{svg_file}\"",
f"\"{tex_file_content}\"",
">",
os.devnull
]
exit_code = os.system(" ".join(commands))
with open(svg_file, "r", encoding="utf-8") as file:
error_match_obj = re.search(r"(?<=data\-mjx\-error\=\")(.*?)(?=\")", file.read())
if exit_code != 0 or error_match_obj is not None:
log.error("LaTeX Error! Not a worry, it happens to the best of us.")
# capture LaTeX error
svg_str = str(stdout, "utf-8")
error_match_obj = re.search(r"(?<=data\-mjx\-error\=\")(.*?)(?=\")", svg_str)
if error_match_obj is not None:
log.error("LaTeX Error! Not a worry, it happens to the best of us.")
log.debug(f"The error could be: `{error_match_obj.group()}`")
os.remove(svg_file)
sys.exit(2)
sys.exit(2)

# save svg file
with open(svg_file, "wb") as out:
out.write(stdout)
return svg_file


Expand Down Expand Up @@ -73,9 +72,17 @@ def hash_seed(self):
def get_tex_file_body(self, tex_string):
if not self.use_mathjax:
return super().get_tex_file_body(tex_string)
return tex_string.replace("\"", "\\\"").replace("\n", " ")
return tex_string

def tex_to_svg_file_path(self, tex_file_content):
if not self.use_mathjax:
return super().tex_to_svg_file_path(tex_file_content)
return tex_content_to_svg_file_using_mathjax(tex_file_content)


class AM(JTex):
def get_tex_file_body(self, am_string):
return am_string

def get_file_path(self):
return tex_content_to_svg_file_using_mathjax(self.tex_string, "--am")
1 change: 1 addition & 0 deletions manimgl_mathjax/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"dependencies": {
"asciimath-js": "^1.0.1",
"mathjax-full": "^3.2.0"
},
"name": "manim-mathjax",
Expand Down

0 comments on commit 8906a7b

Please sign in to comment.