markup: Standardize behavior when external converters are missing

Closes #14222
This commit is contained in:
Joe Mooring
2026-06-08 07:34:21 -07:00
committed by Bjørn Erik Pedersen
parent 1f35beb918
commit 147f605f7d
4 changed files with 35 additions and 23 deletions
@@ -136,40 +136,55 @@ docs/p1/sub/mymixcasetext2.txt
}
func TestPagesFromGoTmplAsciiDocAndSimilar(t *testing.T) {
files := `
supportsAsciiDoc, _ := asciidocext.Supports()
supportsPandoc := pandoc.Supports()
supportsRst := rst.Supports()
var contentGotmpl strings.Builder
var securityAllow []string
if supportsAsciiDoc {
contentGotmpl.WriteString("{{ $.AddPage (dict \"path\" \"asciidoc\" \"content\" (dict \"value\" \"Mark my words, #automation is essential#.\" \"mediaType\" \"text/asciidoc\" )) }}\n")
securityAllow = append(securityAllow, "'asciidoctor'")
}
if supportsPandoc {
contentGotmpl.WriteString("{{ $.AddPage (dict \"path\" \"pandoc\" \"content\" (dict \"value\" \"This ~~is deleted text.~~\" \"mediaType\" \"text/pandoc\" )) }}\n")
securityAllow = append(securityAllow, "'pandoc'")
}
if supportsRst {
contentGotmpl.WriteString("{{ $.AddPage (dict \"path\" \"rst\" \"content\" (dict \"value\" \"This is *bold*.\" \"mediaType\" \"text/rst\" )) }}\n")
securityAllow = append(securityAllow, "'rst2html'", "'python'")
}
contentGotmpl.WriteString("{{ $.AddPage (dict \"path\" \"org\" \"content\" (dict \"value\" \"the ability to use +strikethrough+ is a plus\" \"mediaType\" \"text/org\" )) }}\n")
contentGotmpl.WriteString("{{ $.AddPage (dict \"path\" \"nocontent\" \"title\" \"No Content\" ) }}\n")
files := fmt.Sprintf(`
-- hugo.toml --
disableKinds = ["taxonomy", "term", "rss", "sitemap"]
baseURL = "https://example.com"
[security]
[security.exec]
allow = ['asciidoctor', 'pandoc','rst2html', 'python']
allow = [%s]
-- layouts/single.html --
|Content: {{ .Content }}|Title: {{ .Title }}|Path: {{ .Path }}|
-- content/docs/_content.gotmpl --
{{ $.AddPage (dict "path" "asciidoc" "content" (dict "value" "Mark my words, #automation is essential#." "mediaType" "text/asciidoc" )) }}
{{ $.AddPage (dict "path" "pandoc" "content" (dict "value" "This ~~is deleted text.~~" "mediaType" "text/pandoc" )) }}
{{ $.AddPage (dict "path" "rst" "content" (dict "value" "This is *bold*." "mediaType" "text/rst" )) }}
{{ $.AddPage (dict "path" "org" "content" (dict "value" "the ability to use +strikethrough+ is a plus" "mediaType" "text/org" )) }}
{{ $.AddPage (dict "path" "nocontent" "title" "No Content" ) }}
`
%s
`, strings.Join(securityAllow, ", "), contentGotmpl.String())
b := hugolib.Test(t, files)
if ok, _ := asciidocext.Supports(); ok {
if supportsAsciiDoc {
b.AssertFileContent("public/docs/asciidoc/index.html",
"Mark my words, <mark>automation is essential</mark>",
"Path: /docs/asciidoc|",
)
}
if pandoc.Supports() {
if supportsPandoc {
b.AssertFileContent("public/docs/pandoc/index.html",
"This <del>is deleted text.</del>",
"Path: /docs/pandoc|",
)
}
if rst.Supports() {
if supportsRst {
b.AssertFileContent("public/docs/rst/index.html",
"This is <em>bold</em>",
"Path: /docs/rst|",
+2 -3
View File
@@ -87,9 +87,8 @@ func (a *AsciiDocConverter) Supports(_ identity.Identity) bool {
// GetAsciiDocContent calls asciidoctor as an external helper to convert
// AsciiDoc content to HTML.
func (a *AsciiDocConverter) GetAsciiDocContent(src []byte, ctx converter.DocumentContext) ([]byte, error) {
if ok, err := HasAsciiDoc(); !ok {
a.Cfg.Logger.Errorf("leaving AsciiDoc content unrendered: %s", err.Error())
return src, nil
if !hexec.InPath(asciiDocBinaryName) {
return nil, fmt.Errorf("asciidoctor not found in $PATH, cannot render %q", ctx.DocumentName)
}
args, err := a.ParseArgs(ctx)
+3 -4
View File
@@ -15,6 +15,8 @@
package pandoc
import (
"fmt"
"github.com/gohugoio/hugo/common/hexec"
"github.com/gohugoio/hugo/htesting"
"github.com/gohugoio/hugo/identity"
@@ -56,12 +58,9 @@ func (c *pandocConverter) Supports(feature identity.Identity) bool {
// getPandocContent calls pandoc as an external helper to convert pandoc markdown to HTML.
func (c *pandocConverter) getPandocContent(src []byte, ctx converter.DocumentContext) ([]byte, error) {
logger := c.cfg.Logger
binaryName := getPandocBinaryName()
if binaryName == "" {
logger.Println("pandoc not found in $PATH: Please install.\n",
" Leaving pandoc content unrendered.")
return src, nil
return nil, fmt.Errorf("pandoc not found in $PATH, cannot render %q", ctx.DocumentName)
}
args := []string{"--mathjax"}
return internal.ExternallyRenderContent(c.cfg, ctx, src, binaryName, args)
+2 -3
View File
@@ -16,6 +16,7 @@ package rst
import (
"bytes"
"fmt"
"runtime"
"github.com/gohugoio/hugo/common/hexec"
@@ -65,9 +66,7 @@ func (c *rstConverter) getRstContent(src []byte, ctx converter.DocumentContext)
binaryName, binaryPath := getRstBinaryNameAndPath()
if binaryName == "" {
logger.Println("rst2html / rst2html.py not found in $PATH: Please install.\n",
" Leaving reStructuredText content unrendered.")
return src, nil
return nil, fmt.Errorf("rst2html / rst2html.py not found in $PATH, cannot render %q", ctx.DocumentName)
}
logger.Infoln("Rendering", ctx.DocumentName, "with", binaryName, "...")