commit 9265a26eaddc6402751973cbdefbd779173b5a14 Author: Jeff Kowalczyk Date: Sun Apr 13 14:19:13 2025 -0700 Remove warpc and javy dep supporting ToMath() LaTex to MathML Upstream Hugo added a feature render LaTex to MathML server-side. Remove the functionality in Hugo related to this feature. Original patchset by darix. While useful, ToMath() brings along a dependency on the javy JS to WebAssembly toolchain implemented in Rust. Upstream ships precompiled .wasm binaries, but we cannot ship these in OBS built packages. These .wasm binaries are already being removed as a packaging step, see package changelog. There is currently no RPM package available for javy. If and when a javy package built in OBS is available, drop this patch. Upstream has declined suggestions to not ship precompiled .wasm in the source distribution. See deleted comments from darix on: hugo#12736 transform.ToMath, WASI/Wasm modules feedback thread https://github.com/gohugoio/hugo/issues/12736 diff --git a/deps/deps.go b/deps/deps.go index d0d6d95f..b6009a39 100644 --- a/deps/deps.go +++ b/deps/deps.go @@ -25,7 +25,6 @@ import ( "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/identity" "github.com/gohugoio/hugo/internal/js" - "github.com/gohugoio/hugo/internal/warpc" "github.com/gohugoio/hugo/media" "github.com/gohugoio/hugo/resources/page" "github.com/gohugoio/hugo/resources/postpub" @@ -101,10 +100,6 @@ type Deps struct { // Misc counters. Counters *Counters - // Holds RPC dispatchers for Katex etc. - // TODO(bep) rethink this re. a plugin setup, but this will have to do for now. - WasmDispatchers *warpc.Dispatchers - // The JS batcher client. JSBatcherClient js.BatcherClient @@ -380,9 +375,6 @@ func (d *Deps) Close() error { if d.MemCache != nil { d.MemCache.Stop() } - if d.WasmDispatchers != nil { - d.WasmDispatchers.Close() - } return d.BuildClosers.Close() } diff --git a/hugolib/site.go b/hugolib/site.go index 728b036d..6bce24db 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -43,7 +43,6 @@ import ( "github.com/gohugoio/hugo/hugolib/doctree" "github.com/gohugoio/hugo/hugolib/pagesfromdata" "github.com/gohugoio/hugo/internal/js/esbuild" - "github.com/gohugoio/hugo/internal/warpc" "github.com/gohugoio/hugo/langs/i18n" "github.com/gohugoio/hugo/modules" "github.com/gohugoio/hugo/resources" @@ -197,15 +196,6 @@ func NewHugoSites(cfg deps.DepsCfg) (*HugoSites, error) { Counters: &deps.Counters{}, MemCache: memCache, TranslationProvider: i18n.NewTranslationProvider(), - WasmDispatchers: warpc.AllDispatchers( - warpc.Options{ - CompilationCacheDir: filepath.Join(conf.Dirs().CacheDir, "_warpc"), - - // Katex is relatively slow. - PoolSize: 8, - Infof: logger.InfoCommand("wasm").Logf, - }, - ), } if err := firstSiteDeps.Init(); err != nil { diff --git a/tpl/transform/transform.go b/tpl/transform/transform.go index bc6d97cf..654bf0e1 100644 --- a/tpl/transform/transform.go +++ b/tpl/transform/transform.go @@ -18,10 +18,8 @@ import ( "bytes" "context" "encoding/xml" - "errors" "html" "html/template" - "io" "strings" "sync/atomic" @@ -30,15 +28,11 @@ import ( "github.com/bep/goportabletext" "github.com/gohugoio/hugo/cache/dynacache" - "github.com/gohugoio/hugo/common/hashing" - "github.com/gohugoio/hugo/common/hugio" - "github.com/gohugoio/hugo/internal/warpc" "github.com/gohugoio/hugo/markup/converter/hooks" "github.com/gohugoio/hugo/markup/highlight" "github.com/gohugoio/hugo/markup/highlight/chromalexers" "github.com/gohugoio/hugo/resources" "github.com/gohugoio/hugo/tpl" - "github.com/mitchellh/mapstructure" "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/helpers" @@ -216,72 +210,6 @@ func (ns *Namespace) PortableText(v any) (string, error) { return buf.String(), nil } -// ToMath converts a LaTeX string to math in the given format, default MathML. -// This uses KaTeX to render the math, see https://katex.org/. -func (ns *Namespace) ToMath(ctx context.Context, args ...any) (template.HTML, error) { - if len(args) < 1 { - return "", errors.New("must provide at least one argument") - } - expression, err := cast.ToStringE(args[0]) - if err != nil { - return "", err - } - - katexInput := warpc.KatexInput{ - Expression: expression, - Options: warpc.KatexOptions{ - Output: "mathml", - MinRuleThickness: 0.04, - ErrorColor: "#cc0000", - ThrowOnError: true, - }, - } - - if len(args) > 1 { - if err := mapstructure.WeakDecode(args[1], &katexInput.Options); err != nil { - return "", err - } - } - - s := hashing.HashString(args...) - key := "tomath/" + s[:2] + "/" + s[2:] - fileCache := ns.deps.ResourceSpec.FileCaches.MiscCache() - - v, err := ns.cacheMath.GetOrCreate(key, func(string) (template.HTML, error) { - _, r, err := fileCache.GetOrCreate(key, func() (io.ReadCloser, error) { - message := warpc.Message[warpc.KatexInput]{ - Header: warpc.Header{ - Version: 1, - ID: ns.id.Add(1), - }, - Data: katexInput, - } - - k, err := ns.deps.WasmDispatchers.Katex() - if err != nil { - return nil, err - } - result, err := k.Execute(ctx, message) - if err != nil { - return nil, err - } - return hugio.NewReadSeekerNoOpCloserFromString(result.Data.Output), nil - }) - if err != nil { - return "", err - } - - s, err := hugio.ReadString(r) - - return template.HTML(s), err - }) - if err != nil { - return "", err - } - - return v, nil -} - // For internal use. func (ns *Namespace) Reset() { ns.cacheUnmarshal.Clear() diff --git a/tpl/transform/transform_integration_test.go b/tpl/transform/transform_integration_test.go index ceb80309..6fe4aa0a 100644 --- a/tpl/transform/transform_integration_test.go +++ b/tpl/transform/transform_integration_test.go @@ -136,202 +136,6 @@ Scar,"a "dead cat",11 `) } -func TestToMath(t *testing.T) { - files := ` --- hugo.toml -- -disableKinds = ['page','rss','section','sitemap','taxonomy','term'] --- layouts/index.html -- -{{ transform.ToMath "c = \\pm\\sqrt{a^2 + b^2}" }} - ` - b := hugolib.Test(t, files) - - b.AssertFileContent("public/index.html", ` -: error calling ToMath: KaTeX parse error: Undefined control sequence: \\foo at position 5: c = \\̲f̲o̲o̲{a^2 + b^2}") - }) - - // See issue 13239. - t.Run("Handle in template, old Err construct", func(t *testing.T) { - files := ` --- hugo.toml -- -disableKinds = ['page','rss','section','sitemap','taxonomy','term'] --- layouts/index.html -- -{{ with transform.ToMath "c = \\pm\\sqrt{a^2 + b^2}" }} - {{ with .Err }} - {{ warnf "error: %s" . }} - {{ else }} - {{ . }} - {{ end }} -{{ end }} - ` - b, err := hugolib.TestE(t, files, hugolib.TestOptWarn()) - - b.Assert(err, qt.IsNotNil) - b.Assert(err.Error(), qt.Contains, "the return type of transform.ToMath was changed in Hugo v0.141.0 and the error handling replaced with a new try keyword, see https://gohugo.io/functions/go-template/try/") - }) -} - -func TestToMathBigAndManyExpressions(t *testing.T) { - filesTemplate := ` --- hugo.toml -- -disableKinds = ['rss','section','sitemap','taxonomy','term'] -[markup.goldmark.extensions.passthrough] -enable = true -[markup.goldmark.extensions.passthrough.delimiters] -block = [['\[', '\]'], ['$$', '$$']] -inline = [['\(', '\)'], ['$', '$']] --- content/p1.md -- -P1_CONTENT --- layouts/index.html -- -Home. --- layouts/_default/single.html -- -Content: {{ .Content }}| --- layouts/_default/_markup/render-passthrough.html -- -{{ $opts := dict "throwOnError" false "displayMode" true }} -{{ transform.ToMath .Inner $opts }} - ` - - t.Run("Very large file with many complex KaTeX expressions", func(t *testing.T) { - files := strings.ReplaceAll(filesTemplate, "P1_CONTENT", "sourcefilename: testdata/large-katex.md") - b := hugolib.Test(t, files) - b.AssertFileContent("public/p1/index.html", ` - y - `) -} - // Issue #12977 func TestUnmarshalWithIndentedYAML(t *testing.T) { t.Parallel()