package d2latex
import (
_ "embed"
"fmt"
"math"
"regexp"
"strconv"
"strings"
"oss.terrastruct.com/d2/lib/jsrunner"
"oss.terrastruct.com/util-go/xdefer"
)
var pxPerEx = 8
var polyfillsJS string
var setupJS string
var mathjaxJS string
var svgRe = regexp .MustCompile (`<svg[^>]+width="([0-9\.]+)ex" height="([0-9\.]+)ex"[^>]+>` )
func Render (s string ) (_ string , err error ) {
defer xdefer .Errorf (&err , "latex failed to parse" )
s = doubleBackslashes (s )
runner := jsrunner .NewJSRunner ()
if _ , err := runner .RunString (polyfillsJS ); err != nil {
return "" , err
}
if _ , err := runner .RunString (mathjaxJS ); err != nil {
if runner .Engine () == jsrunner .Goja {
return "" , err
}
}
if _ , err := runner .RunString (setupJS ); err != nil {
return "" , err
}
val , err := runner .RunString (fmt .Sprintf (`adaptor.innerHTML(html.convert(` +"`" +"%s`" +`, {
em: %d,
ex: %d,
}))` , s , pxPerEx *2 , pxPerEx ))
if err != nil {
return "" , err
}
return val .String (), nil
}
func Measure (s string ) (width , height int , err error ) {
defer xdefer .Errorf (&err , "latex failed to parse" )
svg , err := Render (s )
if err != nil {
return 0 , 0 , err
}
dims := svgRe .FindAllStringSubmatch (svg , -1 )
if len (dims ) != 1 || len (dims [0 ]) != 3 {
return 0 , 0 , fmt .Errorf ("svg parsing failed for latex: %v" , svg )
}
wEx := dims [0 ][1 ]
hEx := dims [0 ][2 ]
wf , err := strconv .ParseFloat (wEx , 64 )
if err != nil {
return 0 , 0 , fmt .Errorf ("svg parsing failed for latex: %v" , svg )
}
hf , err := strconv .ParseFloat (hEx , 64 )
if err != nil {
return 0 , 0 , fmt .Errorf ("svg parsing failed for latex: %v" , svg )
}
return int (math .Ceil (wf * float64 (pxPerEx ))), int (math .Ceil (hf * float64 (pxPerEx ))), nil
}
func doubleBackslashes(s string ) string {
var result strings .Builder
for i := 0 ; i < len (s ); i ++ {
if s [i ] == '\\' {
result .WriteString ("\\\\" )
} else {
result .WriteByte (s [i ])
}
}
return result .String ()
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .