summaryrefslogtreecommitdiffstats
path: root/markup
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2023-01-04 18:24:36 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2023-05-16 18:01:29 +0200
commit241b21b0fd34d91fccb2ce69874110dceae6f926 (patch)
treed4e0118eac7e9c42f065815447a70805f8d6ad3e /markup
parent6aededf6b42011c3039f5f66487a89a8dd65e0e7 (diff)
Create a struct with all of Hugo's config options
Primary motivation is documentation, but it will also hopefully simplify the code. Also, * Lower case the default output format names; this is in line with the custom ones (map keys) and how it's treated all the places. This avoids doing `stringds.EqualFold` everywhere. Closes #10896 Closes #10620
Diffstat (limited to 'markup')
-rw-r--r--markup/asciidocext/convert.go283
-rw-r--r--markup/asciidocext/convert_test.go202
-rw-r--r--markup/asciidocext/internal/converter.go274
-rw-r--r--markup/converter/converter.go8
-rw-r--r--markup/converter/hooks/hooks.go2
-rw-r--r--markup/goldmark/convert.go8
-rw-r--r--markup/goldmark/convert_test.go213
-rw-r--r--markup/goldmark/toc_test.go34
-rw-r--r--markup/highlight/config.go2
-rw-r--r--markup/highlight/highlight.go4
-rw-r--r--markup/markup.go12
-rw-r--r--markup/markup_config/config.go14
-rw-r--r--markup/markup_test.go11
-rw-r--r--markup/org/convert_test.go13
-rw-r--r--markup/pandoc/convert.go2
-rw-r--r--markup/rst/convert.go2
-rw-r--r--markup/tableofcontents/tableofcontents.go1
17 files changed, 602 insertions, 483 deletions
diff --git a/markup/asciidocext/convert.go b/markup/asciidocext/convert.go
index c3bd90edd..ecf3eb9ac 100644
--- a/markup/asciidocext/convert.go
+++ b/markup/asciidocext/convert.go
@@ -17,26 +17,11 @@
package asciidocext
import (
- "bytes"
- "path/filepath"
- "strings"
-
- "github.com/gohugoio/hugo/common/hexec"
"github.com/gohugoio/hugo/htesting"
-
- "github.com/gohugoio/hugo/identity"
- "github.com/gohugoio/hugo/markup/asciidocext/asciidocext_config"
+ "github.com/gohugoio/hugo/markup/asciidocext/internal"
"github.com/gohugoio/hugo/markup/converter"
- "github.com/gohugoio/hugo/markup/internal"
- "github.com/gohugoio/hugo/markup/tableofcontents"
- "golang.org/x/net/html"
)
-/* ToDo: RelPermalink patch for svg posts not working*/
-type pageSubset interface {
- RelPermalink() string
-}
-
// Provider is the package entry point.
var Provider converter.ProviderProvider = provider{}
@@ -44,274 +29,16 @@ type provider struct{}
func (p provider) New(cfg converter.ProviderConfig) (converter.Provider, error) {
return converter.NewProvider("asciidocext", func(ctx converter.DocumentContext) (converter.Converter, error) {
- return &asciidocConverter{
- ctx: ctx,
- cfg: cfg,
+ return &internal.AsciidocConverter{
+ Ctx: ctx,
+ Cfg: cfg,
}, nil
}), nil
}
-type asciidocResult struct {
- converter.ResultRender
- toc *tableofcontents.Fragments
-}
-
-func (r asciidocResult) TableOfContents() *tableofcontents.Fragments {
- return r.toc
-}
-
-type asciidocConverter struct {
- ctx converter.DocumentContext
- cfg converter.ProviderConfig
-}
-
-func (a *asciidocConverter) Convert(ctx converter.RenderContext) (converter.ResultRender, error) {
- b, err := a.getAsciidocContent(ctx.Src, a.ctx)
- if err != nil {
- return nil, err
- }
- content, toc, err := a.extractTOC(b)
- if err != nil {
- return nil, err
- }
- return asciidocResult{
- ResultRender: converter.Bytes(content),
- toc: toc,
- }, nil
-}
-
-func (a *asciidocConverter) Supports(_ identity.Identity) bool {
- return false
-}
-
-// 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 !hasAsciiDoc() {
- a.cfg.Logger.Errorln("asciidoctor not found in $PATH: Please install.\n",
- " Leaving AsciiDoc content unrendered.")
- return src, nil
- }
-
- args := a.parseArgs(ctx)
- args = append(args, "-")
-
- a.cfg.Logger.Infoln("Rendering", ctx.DocumentName, " using asciidoctor args", args, "...")
-
- return internal.ExternallyRenderContent(a.cfg, ctx, src, asciiDocBinaryName, args)
-}
-
-func (a *asciidocConverter) parseArgs(ctx converter.DocumentContext) []string {
- cfg := a.cfg.MarkupConfig.AsciidocExt
- args := []string{}
-
- args = a.appendArg(args, "-b", cfg.Backend, asciidocext_config.CliDefault.Backend, asciidocext_config.AllowedBackend)
-
- for _, extension := range cfg.Extensions {
- if strings.LastIndexAny(extension, `\/.`) > -1 {
- a.cfg.Logger.Errorln("Unsupported asciidoctor extension was passed in. Extension `" + extension + "` ignored. Only installed asciidoctor extensions are allowed.")
- continue
- }
- args = append(args, "-r", extension)
- }
-
- for attributeKey, attributeValue := range cfg.Attributes {
- if asciidocext_config.DisallowedAttributes[attributeKey] {
- a.cfg.Logger.Errorln("Unsupported asciidoctor attribute was passed in. Attribute `" + attributeKey + "` ignored.")
- continue
- }
-
- args = append(args, "-a", attributeKey+"="+attributeValue)
- }
-
- if cfg.WorkingFolderCurrent {
- contentDir := filepath.Dir(ctx.Filename)
- sourceDir := a.cfg.Cfg.GetString("source")
- destinationDir := a.cfg.Cfg.GetString("destination")
-
- if destinationDir == "" {
- a.cfg.Logger.Errorln("markup.asciidocext.workingFolderCurrent requires hugo command option --destination to be set")
- }
- if !filepath.IsAbs(destinationDir) && sourceDir != "" {
- destinationDir = filepath.Join(sourceDir, destinationDir)
- }
-
- var outDir string
- var err error
-
- file := filepath.Base(ctx.Filename)
- if a.cfg.Cfg.GetBool("uglyUrls") || file == "_index.adoc" || file == "index.adoc" {
- outDir, err = filepath.Abs(filepath.Dir(filepath.Join(destinationDir, ctx.DocumentName)))
- } else {
- postDir := ""
- page, ok := ctx.Document.(pageSubset)
- if ok {
- postDir = filepath.Base(page.RelPermalink())
- } else {
- a.cfg.Logger.Errorln("unable to cast interface to pageSubset")
- }
-
- outDir, err = filepath.Abs(filepath.Join(destinationDir, filepath.Dir(ctx.DocumentName), postDir))
- }
-
- if err != nil {
- a.cfg.Logger.Errorln("asciidoctor outDir: ", err)
- }
-
- args = append(args, "--base-dir", contentDir, "-a", "outdir="+outDir)
- }
-
- if cfg.NoHeaderOrFooter {
- args = append(args, "--no-header-footer")
- } else {
- a.cfg.Logger.Warnln("asciidoctor parameter NoHeaderOrFooter is expected for correct html rendering")
- }
-
- if cfg.SectionNumbers {
- args = append(args, "--section-numbers")
- }
-
- if cfg.Verbose {
- args = append(args, "--verbose")
- }
-
- if cfg.Trace {
- args = append(args, "--trace")
- }
-
- args = a.appendArg(args, "--failure-level", cfg.FailureLevel, asciidocext_config.CliDefault.FailureLevel, asciidocext_config.AllowedFailureLevel)
-
- args = a.appendArg(args, "--safe-mode", cfg.SafeMode, asciidocext_config.CliDefault.SafeMode, asciidocext_config.AllowedSafeMode)
-
- return args
-}
-
-func (a *asciidocConverter) appendArg(args []string, option, value, defaultValue string, allowedValues map[string]bool) []string {
- if value != defaultValue {
- if allowedValues[value] {
- args = append(args, option, value)
- } else {
- a.cfg.Logger.Errorln("Unsupported asciidoctor value `" + value + "` for option " + option + " was passed in and will be ignored.")
- }
- }
- return args
-}
-
-const asciiDocBinaryName = "asciidoctor"
-
-func hasAsciiDoc() bool {
- return hexec.InPath(asciiDocBinaryName)
-}
-
-// extractTOC extracts the toc from the given src html.
-// It returns the html without the TOC, and the TOC data
-func (a *asciidocConverter) extractTOC(src []byte) ([]byte, *tableofcontents.Fragments, error) {
- var buf bytes.Buffer
- buf.Write(src)
- node, err := html.Parse(&buf)
- if err != nil {
- return nil, nil, err
- }
- var (
- f func(*html.Node) bool
- toc *tableofcontents.Fragments
- toVisit []*html.Node
- )
- f = func(n *html.Node) bool {
- if n.Type == html.ElementNode && n.Data == "div" && attr(n, "id") == "toc" {
- toc = parseTOC(n)
- if !a.cfg.MarkupConfig.AsciidocExt.PreserveTOC {
- n.Parent.RemoveChild(n)
- }
- return true
- }
- if n.FirstChild != nil {
- toVisit = append(toVisit, n.FirstChild)
- }
- if n.NextSibling != nil && f(n.NextSibling) {
- return true
- }
- for len(toVisit) > 0 {
- nv := toVisit[0]
- toVisit = toVisit[1:]
- if f(nv) {
- return true
- }
- }
- return false
- }
- f(node)
- if err != nil {
- return nil, nil, err
- }
- buf.Reset()
- err = html.Render(&buf, node)
- if err != nil {
- return nil, nil, err
- }
- // ltrim <html><head></head><body> and rtrim </body></html> which are added by html.Render
- res := buf.Bytes()[25:]
- res = res[:len(res)-14]
- return res, toc, nil
-}
-
-// parseTOC returns a TOC root from the given toc Node
-func parseTOC(doc *html.Node) *tableofcontents.Fragments {
- var (
- toc tableofcontents.Builder
- f func(*html.Node, int, int)
- )
- f = func(n *html.Node, row, level int) {
- if n.Type == html.ElementNode {
- switch n.Data {
- case "ul":
- if level == 0 {
- row++
- }
- level++
- f(n.FirstChild, row, level)
- case "li":
- for c := n.FirstChild; c != nil; c = c.NextSibling {
- if c.Type != html.ElementNode || c.Data != "a" {
- continue
- }
- href := attr(c, "href")[1:]
- toc.AddAt(&tableofcontents.Heading{
- Title: nodeContent(c),
- ID: href,
- }, row, level)
- }
- f(n.FirstChild, row, level)
- }
- }
- if n.NextSibling != nil {
- f(n.NextSibling, row, level)
- }
- }
- f(doc.FirstChild, -1, 0)
- return toc.Build()
-}
-
-func attr(node *html.Node, key string) string {
- for _, a := range node.Attr {
- if a.Key == key {
- return a.Val
- }
- }
- return ""
-}
-
-func nodeContent(node *html.Node) string {
- var buf bytes.Buffer
- for c := node.FirstChild; c != nil; c = c.NextSibling {
- html.Render(&buf, c)
- }
- return buf.String()
-}
-
// Supports returns whether Asciidoctor is installed on this computer.
func Supports() bool {
- hasBin := hasAsciiDoc()
+ hasBin := internal.HasAsciiDoc()
if htesting.SupportsAll() {
if !hasBin {
panic("asciidoctor not installed")
diff --git a/markup/asciidocext/convert_test.go b/markup/asciidocext/convert_test.go
index 47208c066..cdc981263 100644
--- a/markup/asciidocext/convert_test.go
+++ b/markup/asciidocext/convert_test.go
@@ -1,4 +1,4 @@
-// Copyright 2020 The Hugo Authors. All rights reserved.
+// Copyright 2023 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.
@@ -15,7 +15,7 @@
// external binary. The `asciidoc` module is reserved for a future golang
// implementation.
-package asciidocext
+package asciidocext_test
import (
"path/filepath"
@@ -26,8 +26,12 @@ import (
"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/config/security"
+ "github.com/gohugoio/hugo/config/testconfig"
+ "github.com/gohugoio/hugo/markup/asciidocext"
+ "github.com/gohugoio/hugo/markup/asciidocext/internal"
"github.com/gohugoio/hugo/markup/converter"
"github.com/gohugoio/hugo/markup/markup_config"
+ "github.com/spf13/afero"
qt "github.com/frankban/quicktest"
)
@@ -35,13 +39,12 @@ import (
func TestAsciidoctorDefaultArgs(t *testing.T) {
c := qt.New(t)
cfg := config.New()
- mconf := markup_config.Default
+ conf := testconfig.GetTestConfig(afero.NewMemMapFs(), cfg)
- p, err := Provider.New(
+ p, err := asciidocext.Provider.New(
converter.ProviderConfig{
- Cfg: cfg,
- MarkupConfig: mconf,
- Logger: loggers.NewErrorLogger(),
+ Conf: conf,
+ Logger: loggers.NewErrorLogger(),
},
)
c.Assert(err, qt.IsNil)
@@ -49,17 +52,16 @@ func TestAsciidoctorDefaultArgs(t *testing.T) {
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
- ac := conv.(*asciidocConverter)
+ ac := conv.(*internal.AsciidocConverter)
c.Assert(ac, qt.Not(qt.IsNil))
- args := ac.parseArgs(converter.DocumentContext{})
+ args := ac.ParseArgs(converter.DocumentContext{})
expected := []string{"--no-header-footer"}
c.Assert(args, qt.DeepEquals, expected)
}
func TestAsciidoctorNonDefaultArgs(t *testing.T) {
c := qt.New(t)
- cfg := config.New()
mconf := markup_config.Default
mconf.AsciidocExt.Backend = "manpage"
mconf.AsciidocExt.NoHeaderOrFooter = false
@@ -68,11 +70,13 @@ func TestAsciidoctorNonDefaultArgs(t *testing.T) {
mconf.AsciidocExt.Verbose = true
mconf.AsciidocExt.Trace = false
mconf.AsciidocExt.FailureLevel = "warn"
- p, err := Provider.New(
+
+ conf := testconfig.GetTestConfigSectionFromStruct("markup", mconf)
+
+ p, err := asciidocext.Provider.New(
converter.ProviderConfig{
- Cfg: cfg,
- MarkupConfig: mconf,
- Logger: loggers.NewErrorLogger(),
+ Conf: conf,
+ Logger: loggers.NewErrorLogger(),
},
)
c.Assert(err, qt.IsNil)
@@ -80,28 +84,29 @@ func TestAsciidoctorNonDefaultArgs(t *testing.T) {
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
- ac := conv.(*asciidocConverter)
+ ac := conv.(*internal.AsciidocConverter)
c.Assert(ac, qt.Not(qt.IsNil))
- args := ac.parseArgs(converter.DocumentContext{})
+ args := ac.ParseArgs(converter.DocumentContext{})
expected := []string{"-b", "manpage", "--section-numbers", "--verbose", "--failure-level", "warn", "--safe-mode", "safe"}
c.Assert(args, qt.DeepEquals, expected)
}
func TestAsciidoctorDisallowedArgs(t *testing.T) {
c := qt.New(t)
- cfg := config.New()
mconf := markup_config.Default
mconf.AsciidocExt.Backend = "disallowed-backend"
mconf.AsciidocExt.Extensions = []string{"./disallowed-extension"}
mconf.AsciidocExt.Attributes = map[string]string{"outdir": "disallowed-attribute"}
mconf.AsciidocExt.SafeMode = "disallowed-safemode"
mconf.AsciidocExt.FailureLevel = "disallowed-failurelevel"
- p, err := Provider.New(
+
+ conf := testconfig.GetTestConfigSectionFromStruct("markup", mconf)
+
+ p, err := asciidocext.Provider.New(
converter.ProviderConfig{
- Cfg: cfg,
- MarkupConfig: mconf,
- Logger: loggers.NewErrorLogger(),
+ Conf: conf,
+ Logger: loggers.NewErrorLogger(),
},
)
c.Assert(err, qt.IsNil)
@@ -109,24 +114,23 @@ func TestAsciidoctorDisallowedArgs(t *testing.T) {
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
- ac := conv.(*asciidocConverter)
+ ac := conv.(*internal.AsciidocConverter)
c.Assert(ac, qt.Not(qt.IsNil))
- args := ac.parseArgs(converter.DocumentContext{})
+ args := ac.ParseArgs(converter.DocumentContext{})
expected := []string{"--no-header-footer"}
c.Assert(args, qt.DeepEquals, expected)
}
func TestAsciidoctorArbitraryExtension(t *testing.T) {
c := qt.New(t)
- cfg := config.New()
mconf := markup_config.Default
mconf.AsciidocExt.Extensions = []string{"arbitrary-extension"}
- p, err := Provider.New(
+ conf := testconfig.GetTestConfigSectionFromStruct("markup", mconf)
+ p, err := asciidocext.Provider.New(
converter.ProviderConfig{
- Cfg: cfg,
- MarkupConfig: mconf,
- Logger: loggers.NewErrorLogger(),
+ Conf: conf,
+ Logger: loggers.NewErrorLogger(),
},
)
c.Assert(err, qt.IsNil)
@@ -134,17 +138,17 @@ func TestAsciidoctorArbitraryExtension(t *testing.T) {
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
- ac := conv.(*asciidocConverter)
+ ac := conv.(*internal.AsciidocConverter)
c.Assert(ac, qt.Not(qt.IsNil))
- args := ac.parseArgs(converter.DocumentContext{})
+ args := ac.ParseArgs(converter.DocumentContext{})
expected := []string{"-r", "arbitrary-extension", "--no-header-footer"}
c.Assert(args, qt.DeepEquals, expected)
}
func TestAsciidoctorDisallowedExtension(t *testing.T) {
c := qt.New(t)
- cfg := config.New()
+
for _, disallowedExtension := range []string{
`foo-bar//`,
`foo-bar\\ `,
@@ -156,11 +160,11 @@ func TestAsciidoctorDisallowedExtension(t *testing.T) {
} {
mconf := markup_config.Default
mconf.AsciidocExt.Extensions = []string{disallowedExtension}
- p, err := Provider.New(
+ conf := testconfig.GetTestConfigSectionFromStruct("markup", mconf)
+ p, err := asciidocext.Provider.New(
converter.ProviderConfig{
- Cfg: cfg,
- MarkupConfig: mconf,
- Logger: loggers.NewErrorLogger(),
+ Conf: conf,
+ Logger: loggers.NewErrorLogger(),
},
)
c.Assert(err, qt.IsNil)
@@ -168,10 +172,10 @@ func TestAsciidoctorDisallowedExtension(t *testing.T) {
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
- ac := conv.(*asciidocConverter)
+ ac := conv.(*internal.AsciidocConverter)
c.Assert(ac, qt.Not(qt.IsNil))
- args := ac.parseArgs(converter.DocumentContext{})
+ args := ac.ParseArgs(converter.DocumentContext{})
expected := []string{"--no-header-footer"}
c.Assert(args, qt.DeepEquals, expected)
}
@@ -179,15 +183,19 @@ func TestAsciidoctorDisallowedExtension(t *testing.T) {
func TestAsciidoctorWorkingFolderCurrent(t *testing.T) {
c := qt.New(t)
- cfg := config.New()
- mconf := markup_config.Default
- mconf.AsciidocExt.WorkingFolderCurrent = true
- mconf.AsciidocExt.Trace = false
- p, err := Provider.New(
+ cfg := config.FromTOMLConfigString(`
+[markup]
+[markup.asciidocext]
+workingFolderCurrent = true
+trace = false
+`)
+
+ conf := testconfig.GetTestConfig(afero.NewMemMapFs(), cfg)
+
+ p, err := asciidocext.Provider.New(
converter.ProviderConfig{
- Cfg: cfg,
- MarkupConfig: mconf,
- Logger: loggers.NewErrorLogger(),
+ Conf: conf,
+ Logger: loggers.NewErrorLogger(),
},
)
c.Assert(err, qt.IsNil)
@@ -196,32 +204,35 @@ func TestAsciidoctorWorkingFolderCurrent(t *testing.T) {
conv, err := p.New(ctx)
c.Assert(err, qt.IsNil)
- ac := conv.(*asciidocConverter)
+ ac := conv.(*internal.AsciidocConverter)
c.Assert(ac, qt.Not(qt.IsNil))
- args := ac.parseArgs(ctx)
+ args := ac.ParseArgs(ctx)
c.Assert(len(args), qt.Equals, 5)
c.Assert(args[0], qt.Equals, "--base-dir")
c.Assert(filepath.ToSlash(args[1]), qt.Matches, "/tmp/hugo_asciidoc_ddd/docs/chapter2")
c.Assert(args[2], qt.Equals, "-a")
- c.Assert(args[3], qt.Matches, `outdir=.*[/\\]{1,2}asciidocext[/\\]{1,2}chapter2`)
+ c.Assert(args[3], qt.Matches, `outdir=.*chapter2`)
c.Assert(args[4], qt.Equals, "--no-header-footer")
}
func TestAsciidoctorWorkingFolderCurrentAndExtensions(t *testing.T) {
c := qt.New(t)
- cfg := config.New()
- mconf := markup_config.Default
- mconf.AsciidocExt.NoHeaderOrFooter = true
- mconf.AsciidocExt.Extensions = []string{"asciidoctor-html5s", "asciidoctor-diagram"}
- mconf.AsciidocExt.Backend = "html5s"
- mconf.AsciidocExt.WorkingFolderCurrent = true
- mconf.AsciidocExt.Trace = false
- p, err := Provider.New(
+ cfg := config.FromTOMLConfigString(`
+[markup]
+[markup.asciidocext]
+backend = "html5s"
+workingFolderCurrent = true
+trace = false
+noHeaderOrFooter = true
+extensions = ["asciidoctor-html5s", "asciidoctor-diagram"]
+`)
+ conf := testconfig.GetTestConfig(afero.NewMemMapFs(), cfg)
+
+ p, err := asciidocext.Provider.New(
converter.ProviderConfig{
- Cfg: cfg,
- MarkupConfig: mconf,
- Logger: loggers.NewErrorLogger(),
+ Conf: conf,
+ Logger: loggers.NewErrorLogger(),
},
)
c.Assert(err, qt.IsNil)
@@ -229,10 +240,10 @@ func TestAsciidoctorWorkingFolderCurrentAndExtensions(t *testing.T) {
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
- ac := conv.(*asciidocConverter)
+ ac := conv.(*internal.AsciidocConverter)
c.Assert(ac, qt.Not(qt.IsNil))
- args := ac.parseArgs(converter.DocumentContext{})
+ args := ac.ParseArgs(converter.DocumentContext{})
c.Assert(len(args), qt.Equals, 11)
c.Assert(args[0], qt.Equals, "-b")
c.Assert(args[1], qt.Equals, "html5s")
@@ -249,15 +260,19 @@ func TestAsciidoctorWorkingFolderCurrentAndExtensions(t *testing.T) {
func TestAsciidoctorAttributes(t *testing.T) {
c := qt.New(t)
- cfg := config.New()
- mconf := markup_config.Default
- mconf.AsciidocExt.Attributes = map[string]string{"my-base-url": "https://gohugo.io/", "my-attribute-name": "my value"}
- mconf.AsciidocExt.Trace = false
- p, err := Provider.New(
+ cfg := config.FromTOMLConfigString(`
+[markup]
+[markup.asciidocext]
+trace = false
+[markup.asciidocext.attributes]
+my-base-url = "https://gohugo.io/"
+my-attribute-name = "my value"
+`)
+ conf := testconfig.GetTestConfig(nil, cfg)
+ p, err := asciidocext.Provider.New(
converter.ProviderConfig{
- Cfg: cfg,
- MarkupConfig: mconf,
- Logger: loggers.NewErrorLogger(),
+ Conf: conf,
+ Logger: loggers.NewErrorLogger(),
},
)
c.Assert(err, qt.IsNil)
@@ -265,7 +280,7 @@ func TestAsciidoctorAttributes(t *testing.T) {
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
- ac := conv.(*asciidocConverter)
+ ac := conv.(*internal.AsciidocConverter)
c.Assert(ac, qt.Not(qt.IsNil))
expectedValues := map[string]bool{
@@ -273,7 +288,7 @@ func TestAsciidoctorAttributes(t *testing.T) {
"my-attribute-name=my value": true,
}
- args := ac.parseArgs(converter.DocumentContext{})
+ args := ac.ParseArgs(converter.DocumentContext{})
c.Assert(len(args), qt.Equals, 5)
c.Assert(args[0], qt.Equals, "-a")
c.Assert(expectedValues[args[1]], qt.Equals, true)
@@ -282,15 +297,23 @@ func TestAsciidoctorAttributes(t *testing.T) {
c.Assert(args[4], qt.Equals, "--no-header-footer")
}
-func getProvider(c *qt.C, mconf markup_config.Config) converter.Provider {
- sc := security.DefaultConfig
- sc.Exec.Allow = security.NewWhitelist("asciidoctor")
+func getProvider(c *qt.C, mConfStr string) converter.Provider {
+ confStr := `
+[security]
+[security.exec]
+allow = ['asciidoctor']
+`
+ confStr += mConfStr
- p, err := Provider.New(
+ cfg := config.FromTOMLConfigString(confStr)
+ conf := testconfig.GetTestConfig(nil, cfg)
+ securityConfig := conf.GetConfigSection("security").(security.Config)
+
+ p, err := asciidocext.Provider.New(
converter.ProviderConfig{
- MarkupConfig: mconf,
- Logger: loggers.NewErrorLogger(),
- Exec: hexec.New(sc),
+ Logger: loggers.NewErrorLogger(),
+ Conf: conf,
+ Exec: hexec.New(securityConfig),
},
)
c.Assert(err, qt.IsNil)
@@ -298,12 +321,12 @@ func getProvider(c *qt.C, mconf markup_config.Config) converter.Provider {
}
func TestConvert(t *testing.T) {
- if !Supports() {
+ if !asciidocext.Supports() {
t.Skip("asciidoctor not installed")
}
c := qt.New(t)
- p := getProvider(c, markup_config.Default)
+ p := getProvider(c, "")
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
@@ -314,11 +337,11 @@ func TestConvert(t *testing.T) {
}
func TestTableOfContents(t *testing.T) {
- if !Supports() {
+ if !asciidocext.Supports() {
t.Skip("asciidoctor not installed")
}
c := qt.New(t)
- p := getProvider(c, markup_config.Default)
+ p := getProvider(c, "")
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
@@ -349,11 +372,11 @@ testContent
}
func TestTableOfContentsWithCode(t *testing.T) {
- if !Supports() {
+ if !asciidocext.Supports() {
t.Skip("asciidoctor not installed")
}
c := qt.New(t)
- p := getProvider(c, markup_config.Default)
+ p := getProvider(c, "")
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
r, err := conv.Convert(converter.RenderContext{Src: []byte(`:toc: auto
@@ -368,13 +391,16 @@ func TestTableOfContentsWithCode(t *testing.T) {
}
func TestTableOfContentsPreserveTOC(t *testing.T) {
- if !Supports() {
+ if !asciidocext.Supports() {
t.Skip("asciidoctor not installed")
}
c := qt.New(t)
- mconf := markup_config.Default
- mconf.AsciidocExt.PreserveTOC = true
- p := getProvider(c, mconf)
+ confStr := `
+[markup]
+[markup.asciidocExt]
+preserveTOC = true
+ `
+ p := getProvider(c, confStr)
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
diff --git a/markup/asciidocext/internal/converter.go b/markup/asciidocext/internal/converter.go
new file mode 100644
index 000000000..5108bdd0a
--- /dev/null
+++ b/markup/asciidocext/internal/converter.go
@@ -0,0 +1,274 @@
+package internal
+
+import (
+ "bytes"
+ "path/filepath"
+ "strings"
+
+ "github.com/gohugoio/hugo/common/hexec"
+ "github.com/gohugoio/hugo/identity"
+ "github.com/gohugoio/hugo/markup/asciidocext/asciidocext_config"
+ "github.com/gohugoio/hugo/markup/converter"
+ "github.com/gohugoio/hugo/markup/internal"
+ "github.com/gohugoio/hugo/markup/tableofcontents"
+ "golang.org/x/net/html"
+)
+
+type AsciidocConverter struct {
+ Ctx converter.DocumentContext
+ Cfg converter.ProviderConfig
+}
+
+type AsciidocResult struct {
+ converter.ResultRender
+ toc *tableofcontents.Fragments
+}
+
+/* ToDo: RelPermalink patch for svg posts not working*/
+type pageSubset interface {
+ RelPermalink() string
+}
+
+func (r AsciidocResult) TableOfContents() *tableofcontents.Fragments {
+ return r.toc
+}
+
+func (a *AsciidocConverter) Convert(ctx converter.RenderContext) (converter.ResultRender, error) {
+ b, err := a.GetAsciidocContent(ctx.Src, a.Ctx)
+ if err != nil {
+ return nil, err
+ }
+ content, toc, err := a.extractTOC(b)
+ if err != nil {
+ return nil, err
+ }
+ return AsciidocResult{
+ ResultRender: converter.Bytes(content),
+ toc: toc,
+ }, nil
+}
+
+func (a *AsciidocConverter) Supports(_ identity.Identity) bool {
+ return false
+}
+
+// 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 !HasAsciiDoc() {
+ a.Cf