migrate latex

This commit is contained in:
Alexander Wang 2025-01-15 18:16:19 -07:00
parent 9c19637fff
commit 397f505a10
No known key found for this signature in database
GPG key ID: BE3937D0D52D8927
4 changed files with 32 additions and 11 deletions

View file

@ -35,6 +35,15 @@ describe("D2 Unit Tests", () => {
await d2.worker.terminate(); await d2.worker.terminate();
}, 20000); }, 20000);
test("latex works", async () => {
const d2 = new D2();
const result = await d2.compile("x: |latex \\frac{f(x+h)-f(x)}{h} |");
const svg = await d2.render(result.diagram);
expect(svg).toContain("<svg");
expect(svg).toContain("</svg>");
await d2.worker.terminate();
}, 20000);
test("handles syntax errors correctly", async () => { test("handles syntax errors correctly", async () => {
const d2 = new D2(); const d2 = new D2();
try { try {

View file

@ -7,8 +7,7 @@ import (
"regexp" "regexp"
"strconv" "strconv"
"github.com/dop251/goja" "oss.terrastruct.com/d2/lib/jsrunner"
"oss.terrastruct.com/util-go/xdefer" "oss.terrastruct.com/util-go/xdefer"
) )
@ -29,21 +28,24 @@ var svgRe = regexp.MustCompile(`<svg[^>]+width="([0-9\.]+)ex" height="([0-9\.]+)
func Render(s string) (_ string, err error) { func Render(s string) (_ string, err error) {
defer xdefer.Errorf(&err, "latex failed to parse") defer xdefer.Errorf(&err, "latex failed to parse")
vm := goja.New() runner := jsrunner.NewJSRunner()
if _, err := vm.RunString(polyfillsJS); err != nil { if _, err := runner.RunString(polyfillsJS); err != nil {
return "", err return "", err
} }
if _, err := vm.RunString(mathjaxJS); err != nil { if _, err := runner.RunString(mathjaxJS); err != nil {
// Known issue that a harmless error occurs in JS: https://github.com/mathjax/MathJax/issues/3289
if runner.Engine() == jsrunner.Goja {
return "", err
}
}
if _, err := runner.RunString(setupJS); err != nil {
return "", err return "", err
} }
if _, err := vm.RunString(setupJS); err != nil { val, err := runner.RunString(fmt.Sprintf(`adaptor.innerHTML(html.convert(`+"`"+"%s`"+`, {
return "", err
}
val, err := vm.RunString(fmt.Sprintf(`adaptor.innerHTML(html.convert(`+"`"+"%s`"+`, {
em: %d, em: %d,
ex: %d, ex: %d,
}))`, s, pxPerEx*2, pxPerEx)) }))`, s, pxPerEx*2, pxPerEx))

View file

@ -4,3 +4,8 @@ const html = MathJax._.mathjax.mathjax.document('', {
InputJax: new MathJax._.input.tex_ts.TeX({ packages: ['base', 'mathtools', 'ams', 'amscd', 'braket', 'cancel', 'cases', 'color', 'gensymb', 'mhchem', 'physics'] }), InputJax: new MathJax._.input.tex_ts.TeX({ packages: ['base', 'mathtools', 'ams', 'amscd', 'braket', 'cancel', 'cases', 'color', 'gensymb', 'mhchem', 'physics'] }),
OutputJax: new MathJax._.output.svg_ts.SVG(), OutputJax: new MathJax._.output.svg_ts.SVG(),
}); });
if (typeof globalThis !== 'undefined') {
globalThis.adaptor = adaptor;
globalThis.html = html;
}

View file

@ -42,7 +42,12 @@ func (j *jsRunner) MustGet(key string) (JSValue, error) {
return &jsValue{val: result}, nil return &jsValue{val: result}, nil
} }
func (j *jsRunner) RunString(code string) (JSValue, error) { func (j *jsRunner) RunString(code string) (_ JSValue, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
}()
result := j.global.Call("eval", code) result := j.global.Call("eval", code)
return &jsValue{val: result}, nil return &jsValue{val: result}, nil
} }