tpl/transform: Expose the KaTeX strict option

Closes #13729
This commit is contained in:
Joe Mooring
2025-05-23 08:22:25 -07:00
committed by Bjørn Erik Pedersen
parent e25db38467
commit 013c8cfb25
4 changed files with 68 additions and 2 deletions

View File

@@ -263,7 +263,7 @@ func (s *IntegrationTestBuilder) AssertLogContains(els ...string) {
}
}
// AssertLogNotContains asserts that the last build log does matches the given regular expressions.
// AssertLogMatches asserts that the last build log matches the given regular expressions.
// The regular expressions can be negated with a "! " prefix.
func (s *IntegrationTestBuilder) AssertLogMatches(expression string) {
s.Helper()

View File

@@ -53,6 +53,22 @@ type KatexOptions struct {
// If true, KaTeX will throw a ParseError when it encounters an unsupported command.
ThrowOnError bool `json:"throwOnError"`
// Controls how KaTeX handles LaTeX features that offer convenience but
// aren't officially supported, one of error (default), ignore, or warn.
//
// - error: Throws an error when convenient, unsupported LaTeX features
// are encountered.
// - ignore: Allows convenient, unsupported LaTeX features without any
// feedback.
// - warn: Emits a warning when convenient, unsupported LaTeX features are
// encountered.
//
// The "newLineInDisplayMode" error code, which flags the use of \\
// or \newline in display mode outside an array or tabular environment, is
// intentionally designed not to throw an error, despite this behavior
// being questionable.
Strict string `json:"strict"`
}
type KatexOutput struct {

View File

@@ -19,6 +19,7 @@ import (
"context"
"encoding/xml"
"errors"
"fmt"
"html"
"html/template"
"io"
@@ -234,6 +235,7 @@ func (ns *Namespace) ToMath(ctx context.Context, args ...any) (template.HTML, er
MinRuleThickness: 0.04,
ErrorColor: "#cc0000",
ThrowOnError: true,
Strict: "error",
},
}
@@ -243,6 +245,13 @@ func (ns *Namespace) ToMath(ctx context.Context, args ...any) (template.HTML, er
}
}
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)
}
s := hashing.HashString(args...)
key := "tomath/" + s[:2] + "/" + s[2:]
fileCache := ns.deps.ResourceSpec.FileCaches.MiscCache()

View File

@@ -495,3 +495,44 @@ DATA
}
}
}
// Issue 13729
func TestToMathStrictMode(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
-- layouts/all.html --
{{ transform.ToMath "a %" dict }}
-- foo --
`
// strict mode: default
f := strings.ReplaceAll(files, "dict", "")
b, err := hugolib.TestE(t, f)
b.Assert(err.Error(), qt.Contains, "[commentAtEnd]")
// strict mode: error
f = strings.ReplaceAll(files, "dict", `(dict "strict" "error")`)
b, err = hugolib.TestE(t, f)
b.Assert(err.Error(), qt.Contains, "[commentAtEnd]")
// strict mode: ignore
f = strings.ReplaceAll(files, "dict", `(dict "strict" "ignore")`)
b = hugolib.Test(t, f, hugolib.TestOptWarn())
b.AssertLogMatches("")
b.AssertFileContent("public/index.html", `<annotation encoding="application/x-tex">a %</annotation>`)
// strict: warn
// TODO: see https://github.com/gohugoio/hugo/issues/13735
// f = strings.ReplaceAll(files, "dict", `(dict "strict" "warn")`)
// b = hugolib.Test(t, f, hugolib.TestOptWarn())
// b.AssertLogMatches("[commentAtEnd]")
// b.AssertFileContent("public/index.html", `<annotation encoding="application/x-tex">a %</annotation>`)
// strict mode: invalid value
f = strings.ReplaceAll(files, "dict", `(dict "strict" "foo")`)
b, err = hugolib.TestE(t, f)
b.Assert(err.Error(), qt.Contains, "invalid strict mode")
}