File removemathstuff.patch of Package hugo
diff --git a/deps/deps.go b/deps/deps.go
index d0d6d95fc..b6009a397 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 247e1cff9..578b12081 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,16 +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,
- Warnf: logger.WarnCommand("wasm").Logf,
- },
- ),
}
if err := firstSiteDeps.Init(); err != nil {
diff --git a/tpl/transform/transform.go b/tpl/transform/transform.go
index b5a2d3b4c..b5f80e89b 100644
--- a/tpl/transform/transform.go
+++ b/tpl/transform/transform.go
@@ -17,13 +17,10 @@ package transform
import (
"bytes"
"context"
- "encoding/json"
"encoding/xml"
"errors"
- "fmt"
"html"
"html/template"
- "io"
"strings"
"sync/atomic"
@@ -37,15 +34,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"
@@ -223,108 +216,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,
- Strict: "error",
- },
- }
-
- if len(args) > 1 {
- if err := mapstructure.WeakDecode(args[1], &katexInput.Options); err != nil {
- return "", err
- }
- }
-
- switch katexInput.Options.Strict {
- case "error", "ignore", "warn":
- // Valid strict mode, continue
- default:
- return "", fmt.Errorf("invalid strict mode; expected one of error, ignore, or warn; received %s", katexInput.Options.Strict)
- }
-
- type fileCacheEntry struct {
- Version string `json:"version"`
- Output string `json:"output"`
- Warnings []string `json:"warnings,omitempty"`
- }
-
- const fileCacheEntryVersion = "v1" // Increment on incompatible changes.
-
- s := hashing.HashString(args...)
- key := "tomath/" + fileCacheEntryVersion + "/" + 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
- }
-
- e := fileCacheEntry{
- Version: fileCacheEntryVersion,
- Output: result.Data.Output,
- Warnings: result.Header.Warnings,
- }
-
- buf := &bytes.Buffer{}
- enc := json.NewEncoder(buf)
- enc.SetEscapeHTML(false)
- if err := enc.Encode(e); err != nil {
- return nil, fmt.Errorf("failed to encode file cache entry: %w", err)
- }
- return hugio.NewReadSeekerNoOpCloserFromBytes(buf.Bytes()), nil
- })
- if err != nil {
- return "", err
- }
-
- var e fileCacheEntry
- if err := json.NewDecoder(r).Decode(&e); err != nil {
- return "", fmt.Errorf("failed to decode file cache entry: %w", err)
- }
-
- for _, warning := range e.Warnings {
- ns.deps.Log.Warnf("transform.ToMath: %s", warning)
- }
-
- return template.HTML(e.Output), 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 51c2f5fb1..29fa5f194 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", `
-<span class="katex"><math
- `)
-}
-
-func TestToMathError(t *testing.T) {
- t.Run("Default", func(t *testing.T) {
- files := `
--- hugo.toml --
-disableKinds = ['page','rss','section','sitemap','taxonomy','term']
--- layouts/index.html --
-{{ transform.ToMath "c = \\foo{a^2 + b^2}" }}
- `
- b, err := hugolib.TestE(t, files, hugolib.TestOptWarn())
-
- b.Assert(err, qt.IsNotNil)
- b.Assert(err.Error(), qt.Contains, "KaTeX parse error: Undefined control sequence: \\foo")
- })
-
- t.Run("Disable ThrowOnError", func(t *testing.T) {
- files := `
--- hugo.toml --
-disableKinds = ['page','rss','section','sitemap','taxonomy','term']
--- layouts/index.html --
-{{ $opts := dict "throwOnError" false }}
-{{ transform.ToMath "c = \\foo{a^2 + b^2}" $opts }}
- `
- b, err := hugolib.TestE(t, files, hugolib.TestOptWarn())
-
- b.Assert(err, qt.IsNil)
- b.AssertFileContent("public/index.html", `#cc0000`) // Error color
- })
-
- t.Run("Handle in template", func(t *testing.T) {
- files := `
--- hugo.toml --
-disableKinds = ['page','rss','section','sitemap','taxonomy','term']
--- layouts/index.html --
-{{ with try (transform.ToMath "c = \\foo{a^2 + b^2}") }}
- {{ with .Err }}
- {{ warnf "error: %s" . }}
- {{ else }}
- {{ .Value }}
- {{ end }}
-{{ end }}
- `
- b, err := hugolib.TestE(t, files, hugolib.TestOptWarn())
-
- b.Assert(err, qt.IsNil)
- b.AssertLogContains("WARN error: template: index.html:1:22: executing \"index.html\" at <transform.ToMath>: 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", `
- <span class="katex"><math
- `)
- })
-
- t.Run("Large and complex expression", func(t *testing.T) {
- // This is pulled from the file above, which times out for some reason.
- largeAndComplexeExpressions := `\begin{align*} \frac{\pi^2}{6}&=\frac{4}{3}\frac{(\arcsin 1)^2}{2}\\ &=\frac{4}{3}\int_0^1\frac{\arcsin x}{\sqrt{1-x^2}}\,dx\\ &=\frac{4}{3}\int_0^1\frac{x+\sum_{n=1}^{\infty}\frac{(2n-1)!!}{(2n)!!}\frac{x^{2n+1}}{2n+1}}{\sqrt{1-x^2}}\,dx\\ &=\frac{4}{3}\int_0^1\frac{x}{\sqrt{1-x^2}}\,dx +\frac{4}{3}\sum_{n=1}^{\infty}\frac{(2n-1)!!}{(2n)!!(2n+1)}\int_0^1x^{2n}\frac{x}{\sqrt{1-x^2}}\,dx\\ &=\frac{4}{3}+\frac{4}{3}\sum_{n=1}^{\infty}\frac{(2n-1)!!}{(2n)!!(2n+1)}\left[\frac{(2n)!!}{(2n+1)!!}\right]\\ &=\frac{4}{3}\sum_{n=0}^{\infty}\frac{1}{(2n+1)^2}\\ &=\frac{4}{3}\left(\sum_{n=1}^{\infty}\frac{1}{n^2}-\frac{1}{4}\sum_{n=1}^{\infty}\frac{1}{n^2}\right)\\ &=\sum_{n=1}^{\infty}\frac{1}{n^2} \end{align*}`
- files := strings.ReplaceAll(filesTemplate, "P1_CONTENT", fmt.Sprintf(`---
-title: p1
----
-
-$$%s$$
- `, largeAndComplexeExpressions))
-
- b := hugolib.Test(t, files)
- b.AssertFileContent("public/p1/index.html", `
- <span class="katex"><math
- `)
- })
-}
-
-// Issue #13406.
-func TestToMathRenderHookPosition(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 --
----
-title: p1
----
-
-Block:
-
-$$1+2$$
-
-Some inline $1+3$ math.
-
--- layouts/index.html --
-Home.
--- layouts/_default/single.html --
-Content: {{ .Content }}|
--- layouts/_default/_markup/render-passthrough.html --
-{{ $opts := dict "throwOnError" true "displayMode" true }}
-{{- with try (transform.ToMath .Inner $opts ) }}
- {{- with .Err }}
- {{ errorf "KaTeX: %s: see %s." . $.Position }}
- {{- else }}
- {{- .Value }}
- {{- end }}
-{{- end -}}
-
-`
-
- // Block math.
- files := strings.Replace(filesTemplate, "$$1+2$$", "$$\\foo1+2$$", 1)
- b, err := hugolib.TestE(t, files)
- b.Assert(err, qt.IsNotNil)
- b.AssertLogContains("p1.md:6:1")
-
- // Inline math.
- files = strings.Replace(filesTemplate, "$1+3$", "$\\foo1+3$", 1)
- b, err = hugolib.TestE(t, files)
- b.Assert(err, qt.IsNotNil)
- b.AssertLogContains("p1.md:8:13")
-}
-
-func TestToMathMacros(t *testing.T) {
- files := `
--- hugo.toml --
-disableKinds = ['page','rss','section','sitemap','taxonomy','term']
--- layouts/index.html --
-{{ $macros := dict
- "\\addBar" "\\bar{#1}"
- "\\bold" "\\mathbf{#1}"
-}}
-{{ $opts := dict "macros" $macros }}
-{{ transform.ToMath "\\addBar{y} + \\bold{H}" $opts }}
- `
- b := hugolib.Test(t, files)
-
- b.AssertFileContent("public/index.html", `
-<mi>y</mi>
- `)
-}
-
// Issue #12977
func TestUnmarshalWithIndentedYAML(t *testing.T) {
t.Parallel()