mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-26 00:08:53 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 43cf8a8468 |
@@ -63,7 +63,7 @@ jobs:
|
||||
run: go install github.com/gohugoio/gotmplfmt@latest
|
||||
- name: Install docutils
|
||||
run: |
|
||||
pip install docutils
|
||||
pip install docutils Pygments
|
||||
rst2html --version
|
||||
- if: matrix.os == 'ubuntu-latest'
|
||||
name: Install pandoc on Linux
|
||||
|
||||
@@ -14,11 +14,14 @@
|
||||
package markup_config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gohugoio/hugo/common/hmaps"
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/markup/asciidocext/asciidocext_config"
|
||||
"github.com/gohugoio/hugo/markup/goldmark/goldmark_config"
|
||||
"github.com/gohugoio/hugo/markup/highlight"
|
||||
"github.com/gohugoio/hugo/markup/rst/rst_config"
|
||||
"github.com/gohugoio/hugo/markup/tableofcontents"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
@@ -39,10 +42,19 @@ type Config struct {
|
||||
|
||||
// Configuration for the AsciiDoc external markdown engine.
|
||||
AsciiDocExt asciidocext_config.Config
|
||||
|
||||
// Configuration for the reStructuredText external markdown engine.
|
||||
RST rst_config.Config
|
||||
}
|
||||
|
||||
func (c *Config) Init() error {
|
||||
return c.Goldmark.Init()
|
||||
if err := c.Goldmark.Init(); err != nil {
|
||||
return fmt.Errorf("goldmark: %s", err)
|
||||
}
|
||||
if err := c.RST.Init(); err != nil {
|
||||
return fmt.Errorf("rst: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Decode(cfg config.Provider) (conf Config, err error) {
|
||||
@@ -119,4 +131,5 @@ var Default = Config{
|
||||
|
||||
Goldmark: goldmark_config.Default,
|
||||
AsciiDocExt: asciidocext_config.Default,
|
||||
RST: rst_config.Default,
|
||||
}
|
||||
|
||||
+20
-2
@@ -17,6 +17,7 @@ package rst
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
|
||||
"github.com/gohugoio/hugo/common/hexec"
|
||||
@@ -71,6 +72,11 @@ func (c *rstConverter) getRstContent(src []byte, ctx converter.DocumentContext)
|
||||
|
||||
logger.Infoln("Rendering", ctx.DocumentName, "with", binaryName, "...")
|
||||
|
||||
args := []string{"--leave-comments", "--initial-header-level=2"}
|
||||
if c.cfg.Conf != nil && c.cfg.MarkupConfig().RST.SyntaxHighlight != "long" {
|
||||
args = append(args, "--syntax-highlight="+c.cfg.MarkupConfig().RST.SyntaxHighlight)
|
||||
}
|
||||
|
||||
var result []byte
|
||||
var err error
|
||||
|
||||
@@ -80,10 +86,9 @@ func (c *rstConverter) getRstContent(src []byte, ctx converter.DocumentContext)
|
||||
// handle Windows manually because it doesn't do shebangs
|
||||
if runtime.GOOS == "windows" {
|
||||
pythonBinary, _ := internal.GetPythonBinaryAndExecPath()
|
||||
args := []string{binaryPath, "--leave-comments", "--initial-header-level=2"}
|
||||
args = append([]string{binaryPath}, args...)
|
||||
result, err = internal.ExternallyRenderContent(c.cfg, ctx, src, pythonBinary, args)
|
||||
} else {
|
||||
args := []string{"--leave-comments", "--initial-header-level=2"}
|
||||
result, err = internal.ExternallyRenderContent(c.cfg, ctx, src, binaryName, args)
|
||||
}
|
||||
|
||||
@@ -128,3 +133,16 @@ func Supports() bool {
|
||||
}
|
||||
return hasBin
|
||||
}
|
||||
|
||||
// SupportsPygments returns whether Pygments is (or should be) installed on this computer.
|
||||
func SupportsPygments() bool {
|
||||
for _, python := range []string{"python3", "python"} {
|
||||
if err := exec.Command(python, "-c", "import pygments").Run(); err == nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if htesting.SupportsAll() {
|
||||
panic("Pygments not installed")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2026 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package rst_config holds reStructuredText related configuration.
|
||||
package rst_config
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Default holds Hugo's default reStructuredText configuration.
|
||||
var Default = Config{
|
||||
SyntaxHighlight: "long",
|
||||
}
|
||||
|
||||
// Config configures reStructuredText.
|
||||
type Config struct {
|
||||
// Configures Pygments syntax highlighting. Valid values are "short", "long" (default) and "none".
|
||||
SyntaxHighlight string
|
||||
}
|
||||
|
||||
func (c *Config) Init() error {
|
||||
if c.SyntaxHighlight != "short" && c.SyntaxHighlight != "long" && c.SyntaxHighlight != "none" {
|
||||
return fmt.Errorf("invalid value for syntaxHighlight: %q", c.SyntaxHighlight)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright 2026 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package rst_test
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
|
||||
"github.com/gohugoio/hugo/hugolib"
|
||||
"github.com/gohugoio/hugo/markup/rst"
|
||||
)
|
||||
|
||||
// --syntax-highlight, default = long.
|
||||
func TestRSTSyntaxHighlight(t *testing.T) {
|
||||
if !rst.Supports() {
|
||||
t.Skip("rst not installed")
|
||||
}
|
||||
if !rst.SupportsPygments() {
|
||||
t.Skip("Pygments not installed")
|
||||
}
|
||||
|
||||
execAllow := `'^rst2html(\.py)?$'`
|
||||
if runtime.GOOS == "windows" {
|
||||
execAllow = `'^python(\.exe)?$'`
|
||||
}
|
||||
|
||||
filesTemplate := strings.ReplaceAll(`
|
||||
-- hugo.toml --
|
||||
baseURL = "https://example.org"
|
||||
disableKinds = ["home", "section", "taxonomy", "term", "rss", "sitemap"]
|
||||
|
||||
markup.rst.syntaxHighlight = 'SYNTAX_HIGHLIGHT'
|
||||
|
||||
[security.exec]
|
||||
allow = [RST_EXEC_ALLOW]
|
||||
|
||||
-- layouts/page.html --
|
||||
{{ .Content }}
|
||||
-- content/p.rst --
|
||||
---
|
||||
title: p
|
||||
---
|
||||
|
||||
.. code:: go
|
||||
|
||||
if true {}
|
||||
`, "RST_EXEC_ALLOW", execAllow)
|
||||
|
||||
files := strings.ReplaceAll(filesTemplate, "SYNTAX_HIGHLIGHT", "none")
|
||||
b := hugolib.Test(t, files)
|
||||
|
||||
b.AssertFileContent("public/p/index.html", `
|
||||
! Pygments
|
||||
`)
|
||||
|
||||
b.AssertFileContent("public/p/index.html", `
|
||||
if true {}
|
||||
! if</span>
|
||||
`)
|
||||
|
||||
files = strings.ReplaceAll(filesTemplate, "SYNTAX_HIGHLIGHT", "short")
|
||||
b = hugolib.Test(t, files)
|
||||
|
||||
b.AssertFileContent("public/p/index.html", `
|
||||
<span class="k">if</span>
|
||||
! <span class="keyword">if</span>
|
||||
`)
|
||||
|
||||
files = strings.ReplaceAll(filesTemplate, "SYNTAX_HIGHLIGHT", "long")
|
||||
b = hugolib.Test(t, files)
|
||||
|
||||
b.AssertFileContent("public/p/index.html", `
|
||||
! <span class="k">if</span>
|
||||
<span class="keyword">if</span>
|
||||
`)
|
||||
|
||||
// Default long.
|
||||
files = strings.ReplaceAll(filesTemplate, "markup.rst.syntaxHighlight = 'SYNTAX_HIGHLIGHT'", "")
|
||||
b = hugolib.Test(t, files)
|
||||
|
||||
b.AssertFileContent("public/p/index.html", `
|
||||
! <span class="k">if</span>
|
||||
<span class="keyword">if</span>
|
||||
`)
|
||||
|
||||
// Invalid.
|
||||
files = strings.ReplaceAll(filesTemplate, "SYNTAX_HIGHLIGHT", "foo")
|
||||
b, err := hugolib.TestE(t, files)
|
||||
b.Assert(err, qt.IsNotNil)
|
||||
b.Assert(err.Error(), qt.Contains, "rst: invalid value for syntaxHighlight: \"foo\"")
|
||||
}
|
||||
Reference in New Issue
Block a user