mirror of
https://github.com/gohugoio/hugo.git
synced 2025-12-13 20:36:04 +01:00
markup/asciidocext: Improve Asciidoctor integration
Fixes an issue where improper attribute derivation from the page's relative permalink caused failures with `outdir`, `imagesoutdir`, and `imagesdir` when `markup.asciidocext.workingFolderCurrent` is enabled. The updated logic now correctly handles: - Multi-byte characters - Multilingual multi-host sites - Site builds from a subdirectory - Pages using ugly URLs Supports diagram caching as implemented in v3.1.0 of the asciidoctor-diagram extension: - Enables caching by default - Sets default cache location to the compiled value of caches.misc.dir Reduces duration of integration tests by: - Generating GoAT diagrams instead of Ditaa diagrams - Taking advantage of asciidoctor-diagram caching Closes #9202 Closes #10183 Closes #10473 Closes #14160
This commit is contained in:
committed by
Bjørn Erik Pedersen
parent
34b0c15a54
commit
3d21b0687b
9
.github/workflows/test.yml
vendored
9
.github/workflows/test.yml
vendored
@@ -46,19 +46,12 @@ jobs:
|
||||
uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0
|
||||
with:
|
||||
ruby-version: "3.4.5"
|
||||
- name: Install gems
|
||||
- name: Install Ruby gems
|
||||
run: |
|
||||
gem install asciidoctor -v "2.0.26"
|
||||
gem install asciidoctor-diagram -v "3.1.0"
|
||||
gem install asciidoctor-diagram-ditaamini -v "1.0.3"
|
||||
- name: Install GoAT
|
||||
run: go install github.com/blampe/goat/cmd/goat@177de93b192b8ffae608e5d9ec421cc99bf68402
|
||||
- name: Install Java # required by asciidoctor-diagram-ditaamini
|
||||
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: "25"
|
||||
java-package: jre
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
|
||||
with:
|
||||
|
||||
7
cache/filecache/filecache_config.go
vendored
7
cache/filecache/filecache_config.go
vendored
@@ -51,11 +51,18 @@ const (
|
||||
|
||||
type Configs map[string]FileCacheConfig
|
||||
|
||||
// CacheDirModules returns the compiled path to the modules cache.
|
||||
// For internal use.
|
||||
func (c Configs) CacheDirModules() string {
|
||||
return c[CacheKeyModules].DirCompiled
|
||||
}
|
||||
|
||||
// CacheDirMisc returns the compiled path to the misc cache.
|
||||
// For internal use.
|
||||
func (c Configs) CacheDirMisc() string {
|
||||
return c[CacheKeyMisc].DirCompiled
|
||||
}
|
||||
|
||||
var defaultCacheConfigs = Configs{
|
||||
CacheKeyModules: {
|
||||
MaxAge: -1,
|
||||
|
||||
@@ -135,6 +135,10 @@ func (c ConfigLanguage) WorkingDir() string {
|
||||
return c.m.Base.WorkingDir
|
||||
}
|
||||
|
||||
func (c ConfigLanguage) CacheDirMisc() string {
|
||||
return c.config.Caches.CacheDirMisc()
|
||||
}
|
||||
|
||||
func (c ConfigLanguage) Quiet() bool {
|
||||
return c.m.Base.Internal.Quiet
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ type AllProvider interface {
|
||||
WorkingDir() string
|
||||
EnableEmoji() bool
|
||||
ConfiguredDimensions() *sitesmatrix.ConfiguredDimensions
|
||||
CacheDirMisc() string
|
||||
}
|
||||
|
||||
// We cannot import the media package as that would create a circular dependency.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -121,7 +121,7 @@ func IsGitHubAction() bool {
|
||||
}
|
||||
|
||||
// SupportsAll reports whether the running system supports all Hugo features,
|
||||
// e.g. Asciidoc, Pandoc etc.
|
||||
// e.g. AsciiDoc, Pandoc etc.
|
||||
func SupportsAll() bool {
|
||||
return IsGitHubAction() || os.Getenv("CI_LOCAL") != ""
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ func testAllMarkdownEnginesForPages(t *testing.T,
|
||||
shouldExecute func() bool
|
||||
}{
|
||||
{"md", func() bool { return true }},
|
||||
{"ad", func() bool { return asciidocext.Supports() }},
|
||||
{"ad", func() bool { ok, _ := asciidocext.Supports(); return ok }},
|
||||
{"rst", func() bool { return !htesting.IsRealCI() && rst.Supports() }},
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ func TestPageSummary(t *testing.T) {
|
||||
assertFunc := func(t *testing.T, ext string, pages page.Pages) {
|
||||
p := pages[0]
|
||||
checkPageTitle(t, p, "SimpleWithoutSummaryDelimiter")
|
||||
// Source is not Asciidoctor- or RST-compatible so don't test them
|
||||
// Source is not AsciiDoc- or RST-compatible so don't test them
|
||||
if ext != "ad" && ext != "rst" {
|
||||
checkPageContent(t, p, normalizeExpected(ext, "<p><a href=\"https://lipsum.com/\">Lorem ipsum</a> dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n\n<p>Additional text.</p>\n\n<p>Further text.</p>\n"), ext)
|
||||
checkPageSummary(t, p, normalizeExpected(ext, "<p><a href=\"https://lipsum.com/\">Lorem ipsum</a> dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><p>Additional text.</p>"), ext)
|
||||
@@ -604,7 +604,7 @@ func TestPageWithSummaryParameter(t *testing.T) {
|
||||
p := pages[0]
|
||||
checkPageTitle(t, p, "SimpleWithSummaryParameter")
|
||||
checkPageContent(t, p, normalizeExpected(ext, "<p>Some text.</p>\n\n<p>Some more text.</p>\n"), ext)
|
||||
// Summary is not Asciidoctor- or RST-compatible so don't test them
|
||||
// Summary is not AsciiDoc- or RST-compatible so don't test them
|
||||
if ext != "ad" && ext != "rst" {
|
||||
checkPageSummary(t, p, normalizeExpected(ext, "Page with summary parameter and <a href=\"http://www.example.com/\">a link</a>"), ext)
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ docs/p1/sub/mymixcasetext2.txt
|
||||
b.AssertFileContent("public/docs/p3/index.html", "<strong>Hello World Default</strong>")
|
||||
}
|
||||
|
||||
func TestPagesFromGoTmplAsciidocAndSimilar(t *testing.T) {
|
||||
func TestPagesFromGoTmplAsciiDocAndSimilar(t *testing.T) {
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
disableKinds = ["taxonomy", "term", "rss", "sitemap"]
|
||||
@@ -153,7 +153,7 @@ allow = ['asciidoctor', 'pandoc','rst2html', 'python']
|
||||
|
||||
b := hugolib.Test(t, files)
|
||||
|
||||
if asciidocext.Supports() {
|
||||
if ok, _ := asciidocext.Supports(); ok {
|
||||
b.AssertFileContent("public/docs/asciidoc/index.html",
|
||||
"Mark my words, <mark>automation is essential</mark>",
|
||||
"Path: /docs/asciidoc|",
|
||||
@@ -503,7 +503,7 @@ baseURL = "https://example.com"
|
||||
func TestPagesFromGoTmplCascade(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
files := `
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
disableKinds = ["taxonomy", "term", "rss", "sitemap"]
|
||||
baseURL = "https://example.com"
|
||||
@@ -523,7 +523,7 @@ baseURL = "https://example.com"
|
||||
func TestPagesFromGoBuildOptions(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
files := `
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
disableKinds = ["taxonomy", "term", "rss", "sitemap"]
|
||||
baseURL = "https://example.com"
|
||||
@@ -644,11 +644,11 @@ func TestPagesFromGoTmplMenusMap(t *testing.T) {
|
||||
-- hugo.toml --
|
||||
disableKinds = ['rss','section','sitemap','taxonomy','term']
|
||||
-- content/_content.gotmpl --
|
||||
{{ $menu1 := dict
|
||||
{{ $menu1 := dict
|
||||
"parent" "main-page"
|
||||
"identifier" "id1"
|
||||
}}
|
||||
{{ $menu2 := dict
|
||||
{{ $menu2 := dict
|
||||
"parent" "main-page"
|
||||
"identifier" "id2"
|
||||
}}
|
||||
@@ -859,7 +859,7 @@ Title: {{ .Title }}|Content: {{ .Content }}|
|
||||
func TestPagesFromGoTmplHome(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
files := `
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
disableKinds = ["taxonomy", "term", "rss", "sitemap"]
|
||||
baseURL = "https://example.com"
|
||||
|
||||
@@ -1927,9 +1927,9 @@ Myotherpartial Inline.|{{ .Title }}|
|
||||
b.AssertFileContent("public/index.html", "My inline partial in all Edited.")
|
||||
}
|
||||
|
||||
func TestRebuildEditAsciidocContentFile(t *testing.T) {
|
||||
if !asciidocext.Supports() {
|
||||
t.Skip("skip asciidoc")
|
||||
func TestRebuildEditAsciiDocContentFile(t *testing.T) {
|
||||
if ok, err := asciidocext.Supports(); !ok {
|
||||
t.Skip(err)
|
||||
}
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
|
||||
@@ -54,10 +54,10 @@ baseURL = "https://example.org"
|
||||
Test(c, files)
|
||||
})
|
||||
|
||||
c.Run("Asciidoc, denied", func(c *qt.C) {
|
||||
c.Run("AsciiDoc, denied", func(c *qt.C) {
|
||||
c.Parallel()
|
||||
if !asciidocext.Supports() {
|
||||
c.Skip()
|
||||
if ok, err := asciidocext.Supports(); !ok {
|
||||
c.Skip(err)
|
||||
}
|
||||
|
||||
files := `
|
||||
|
||||
1155
markup/asciidocext/asciidoc_integration_test.go
Normal file
1155
markup/asciidocext/asciidoc_integration_test.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -29,21 +29,38 @@ 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 &internal.AsciidocConverter{
|
||||
return &internal.AsciiDocConverter{
|
||||
Ctx: ctx,
|
||||
Cfg: cfg,
|
||||
}, nil
|
||||
}), nil
|
||||
}
|
||||
|
||||
// Supports returns whether Asciidoctor is installed on this computer.
|
||||
func Supports() bool {
|
||||
hasBin := internal.HasAsciiDoc()
|
||||
// Supports reports whether the AsciiDoc converter is installed. Only used in
|
||||
// tests.
|
||||
func Supports() (bool, error) {
|
||||
hasAsciiDoc, err := internal.HasAsciiDoc()
|
||||
if htesting.SupportsAll() {
|
||||
if !hasBin {
|
||||
panic("asciidoctor not installed")
|
||||
if !hasAsciiDoc {
|
||||
panic(err)
|
||||
}
|
||||
return true
|
||||
return true, nil
|
||||
|
||||
}
|
||||
return hasBin
|
||||
|
||||
return hasAsciiDoc, err
|
||||
}
|
||||
|
||||
// SupportsGoATDiagrams reports whether the AsciiDoc converter can render GoAT
|
||||
// diagrams. Only used in tests.
|
||||
func SupportsGoATDiagrams() (bool, error) {
|
||||
supportsGoATDiagrams, err := internal.CanRenderGoATDiagrams()
|
||||
if htesting.SupportsAll() {
|
||||
if !supportsGoATDiagrams {
|
||||
panic(err)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return supportsGoATDiagrams, err
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package asciidocext converts AsciiDoc to HTML using Asciidoctor
|
||||
// Package asciidocext converts AsciiDoc to HTML using the Asciidoctor
|
||||
// external binary. The `asciidoc` module is reserved for a future golang
|
||||
// implementation.
|
||||
|
||||
package asciidocext_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/gohugoio/hugo/common/collections"
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/gohugoio/hugo/config/security"
|
||||
"github.com/gohugoio/hugo/config/testconfig"
|
||||
"github.com/gohugoio/hugo/markup/asciidocext"
|
||||
"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/markup_config"
|
||||
@@ -36,6 +37,24 @@ import (
|
||||
qt "github.com/frankban/quicktest"
|
||||
)
|
||||
|
||||
var defaultAsciiDocExtConfigAsJSON []byte
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
defaultAsciiDocExtConfigAsJSON, err = json.Marshal(markup_config.Default.AsciiDocExt)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func resetDefaultAsciiDocExtConfig() {
|
||||
markup_config.Default.AsciiDocExt = asciidocext_config.Config{}
|
||||
err := json.Unmarshal(defaultAsciiDocExtConfigAsJSON, &markup_config.Default.AsciiDocExt)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAsciidoctorDefaultArgs(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
cfg := config.New()
|
||||
@@ -52,24 +71,30 @@ func TestAsciidoctorDefaultArgs(t *testing.T) {
|
||||
conv, err := p.New(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
ac := conv.(*internal.AsciidocConverter)
|
||||
ac := conv.(*internal.AsciiDocConverter)
|
||||
c.Assert(ac, qt.Not(qt.IsNil))
|
||||
|
||||
args := ac.ParseArgs(converter.DocumentContext{})
|
||||
args, err := ac.ParseArgs(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
expected := []string{"--no-header-footer"}
|
||||
c.Assert(args, qt.DeepEquals, expected)
|
||||
}
|
||||
|
||||
func TestAsciidoctorNonDefaultArgs(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
t.Cleanup(func() {
|
||||
resetDefaultAsciiDocExtConfig()
|
||||
})
|
||||
|
||||
mconf := markup_config.Default
|
||||
mconf.AsciidocExt.Backend = "manpage"
|
||||
mconf.AsciidocExt.NoHeaderOrFooter = false
|
||||
mconf.AsciidocExt.SafeMode = "safe"
|
||||
mconf.AsciidocExt.SectionNumbers = true
|
||||
mconf.AsciidocExt.Verbose = true
|
||||
mconf.AsciidocExt.Trace = false
|
||||
mconf.AsciidocExt.FailureLevel = "warn"
|
||||
mconf.AsciiDocExt.Backend = "manpage"
|
||||
mconf.AsciiDocExt.NoHeaderOrFooter = false
|
||||
mconf.AsciiDocExt.SafeMode = "safe"
|
||||
mconf.AsciiDocExt.SectionNumbers = true
|
||||
mconf.AsciiDocExt.Verbose = true
|
||||
mconf.AsciiDocExt.Trace = false
|
||||
mconf.AsciiDocExt.FailureLevel = "warn"
|
||||
|
||||
conf := testconfig.GetTestConfigSectionFromStruct("markup", mconf)
|
||||
|
||||
@@ -84,22 +109,28 @@ func TestAsciidoctorNonDefaultArgs(t *testing.T) {
|
||||
conv, err := p.New(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
ac := conv.(*internal.AsciidocConverter)
|
||||
ac := conv.(*internal.AsciiDocConverter)
|
||||
c.Assert(ac, qt.Not(qt.IsNil))
|
||||
|
||||
args := ac.ParseArgs(converter.DocumentContext{})
|
||||
args, err := ac.ParseArgs(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
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)
|
||||
|
||||
t.Cleanup(func() {
|
||||
resetDefaultAsciiDocExtConfig()
|
||||
})
|
||||
|
||||
mconf := markup_config.Default
|
||||
mconf.AsciidocExt.Backend = "disallowed-backend"
|
||||
mconf.AsciidocExt.Extensions = []string{"./disallowed-extension"}
|
||||
mconf.AsciidocExt.Attributes = map[string]any{"outdir": "disallowed-attribute"}
|
||||
mconf.AsciidocExt.SafeMode = "disallowed-safemode"
|
||||
mconf.AsciidocExt.FailureLevel = "disallowed-failurelevel"
|
||||
mconf.AsciiDocExt.Backend = "disallowed-backend"
|
||||
mconf.AsciiDocExt.Extensions = []string{"./disallowed-extension"}
|
||||
mconf.AsciiDocExt.Attributes = map[string]any{"outdir": "disallowed-attribute"}
|
||||
mconf.AsciiDocExt.SafeMode = "disallowed-safemode"
|
||||
mconf.AsciiDocExt.FailureLevel = "disallowed-failurelevel"
|
||||
|
||||
conf := testconfig.GetTestConfigSectionFromStruct("markup", mconf)
|
||||
|
||||
@@ -114,18 +145,24 @@ func TestAsciidoctorDisallowedArgs(t *testing.T) {
|
||||
conv, err := p.New(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
ac := conv.(*internal.AsciidocConverter)
|
||||
ac := conv.(*internal.AsciiDocConverter)
|
||||
c.Assert(ac, qt.Not(qt.IsNil))
|
||||
|
||||
args := ac.ParseArgs(converter.DocumentContext{})
|
||||
args, err := ac.ParseArgs(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
expected := []string{"--no-header-footer"}
|
||||
c.Assert(args, qt.DeepEquals, expected)
|
||||
}
|
||||
|
||||
func TestAsciidoctorArbitraryExtension(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
t.Cleanup(func() {
|
||||
resetDefaultAsciiDocExtConfig()
|
||||
})
|
||||
|
||||
mconf := markup_config.Default
|
||||
mconf.AsciidocExt.Extensions = []string{"arbitrary-extension"}
|
||||
mconf.AsciiDocExt.Extensions = []string{"arbitrary-extension"}
|
||||
conf := testconfig.GetTestConfigSectionFromStruct("markup", mconf)
|
||||
p, err := asciidocext.Provider.New(
|
||||
converter.ProviderConfig{
|
||||
@@ -138,10 +175,11 @@ func TestAsciidoctorArbitraryExtension(t *testing.T) {
|
||||
conv, err := p.New(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
ac := conv.(*internal.AsciidocConverter)
|
||||
ac := conv.(*internal.AsciiDocConverter)
|
||||
c.Assert(ac, qt.Not(qt.IsNil))
|
||||
|
||||
args := ac.ParseArgs(converter.DocumentContext{})
|
||||
args, err := ac.ParseArgs(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
expected := []string{"-r", "arbitrary-extension", "--no-header-footer"}
|
||||
c.Assert(args, qt.DeepEquals, expected)
|
||||
}
|
||||
@@ -149,6 +187,10 @@ func TestAsciidoctorArbitraryExtension(t *testing.T) {
|
||||
func TestAsciidoctorDisallowedExtension(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
t.Cleanup(func() {
|
||||
resetDefaultAsciiDocExtConfig()
|
||||
})
|
||||
|
||||
for _, disallowedExtension := range []string{
|
||||
`foo-bar//`,
|
||||
`foo-bar\\ `,
|
||||
@@ -159,7 +201,7 @@ func TestAsciidoctorDisallowedExtension(t *testing.T) {
|
||||
`foo.bar`,
|
||||
} {
|
||||
mconf := markup_config.Default
|
||||
mconf.AsciidocExt.Extensions = []string{disallowedExtension}
|
||||
mconf.AsciiDocExt.Extensions = []string{disallowedExtension}
|
||||
conf := testconfig.GetTestConfigSectionFromStruct("markup", mconf)
|
||||
p, err := asciidocext.Provider.New(
|
||||
converter.ProviderConfig{
|
||||
@@ -172,94 +214,23 @@ func TestAsciidoctorDisallowedExtension(t *testing.T) {
|
||||
conv, err := p.New(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
ac := conv.(*internal.AsciidocConverter)
|
||||
ac := conv.(*internal.AsciiDocConverter)
|
||||
c.Assert(ac, qt.Not(qt.IsNil))
|
||||
|
||||
args := ac.ParseArgs(converter.DocumentContext{})
|
||||
args, err := ac.ParseArgs(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
expected := []string{"--no-header-footer"}
|
||||
c.Assert(args, qt.DeepEquals, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAsciidoctorWorkingFolderCurrent(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
cfg := config.FromTOMLConfigString(`
|
||||
[markup]
|
||||
[markup.asciidocext]
|
||||
workingFolderCurrent = true
|
||||
trace = false
|
||||
`)
|
||||
|
||||
conf := testconfig.GetTestConfig(afero.NewMemMapFs(), cfg)
|
||||
|
||||
p, err := asciidocext.Provider.New(
|
||||
converter.ProviderConfig{
|
||||
Conf: conf,
|
||||
Logger: loggers.NewDefault(),
|
||||
},
|
||||
)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
ctx := converter.DocumentContext{Filename: "/tmp/hugo_asciidoc_ddd/docs/chapter2/index.adoc", DocumentName: "chapter2/index.adoc"}
|
||||
conv, err := p.New(ctx)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
ac := conv.(*internal.AsciidocConverter)
|
||||
c.Assert(ac, qt.Not(qt.IsNil))
|
||||
|
||||
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=.*chapter2`)
|
||||
c.Assert(args[4], qt.Equals, "--no-header-footer")
|
||||
}
|
||||
|
||||
func TestAsciidoctorWorkingFolderCurrentAndExtensions(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
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{
|
||||
Conf: conf,
|
||||
Logger: loggers.NewDefault(),
|
||||
},
|
||||
)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
conv, err := p.New(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
ac := conv.(*internal.AsciidocConverter)
|
||||
c.Assert(ac, qt.Not(qt.IsNil))
|
||||
|
||||
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")
|
||||
c.Assert(args[2], qt.Equals, "-r")
|
||||
c.Assert(args[3], qt.Equals, "asciidoctor-html5s")
|
||||
c.Assert(args[4], qt.Equals, "-r")
|
||||
c.Assert(args[5], qt.Equals, "asciidoctor-diagram")
|
||||
c.Assert(args[6], qt.Equals, "--base-dir")
|
||||
c.Assert(args[7], qt.Equals, ".")
|
||||
c.Assert(args[8], qt.Equals, "-a")
|
||||
c.Assert(args[9], qt.Contains, "outdir=")
|
||||
c.Assert(args[10], qt.Equals, "--no-header-footer")
|
||||
}
|
||||
|
||||
func TestAsciidoctorAttributes(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
t.Cleanup(func() {
|
||||
resetDefaultAsciiDocExtConfig()
|
||||
})
|
||||
|
||||
cfg := config.FromTOMLConfigString(`
|
||||
[markup]
|
||||
[markup.asciidocext]
|
||||
@@ -282,7 +253,7 @@ my-attribute-false = false
|
||||
conv, err := p.New(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
ac := conv.(*internal.AsciidocConverter)
|
||||
ac := conv.(*internal.AsciiDocConverter)
|
||||
c.Assert(ac, qt.Not(qt.IsNil))
|
||||
|
||||
expectedValues := map[string]bool{
|
||||
@@ -292,7 +263,8 @@ my-attribute-false = false
|
||||
"'!my-attribute-false'": true,
|
||||
}
|
||||
|
||||
args := ac.ParseArgs(converter.DocumentContext{})
|
||||
args, err := ac.ParseArgs(converter.DocumentContext{})
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(len(args), qt.Equals, 9)
|
||||
c.Assert(args[0], qt.Equals, "-a")
|
||||
c.Assert(expectedValues[args[1]], qt.Equals, true)
|
||||
@@ -329,8 +301,8 @@ allow = ['asciidoctor']
|
||||
}
|
||||
|
||||
func TestConvert(t *testing.T) {
|
||||
if !asciidocext.Supports() {
|
||||
t.Skip("asciidoctor not installed")
|
||||
if ok, err := asciidocext.Supports(); !ok {
|
||||
t.Skip(err)
|
||||
}
|
||||
c := qt.New(t)
|
||||
|
||||
@@ -345,8 +317,8 @@ func TestConvert(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTableOfContents(t *testing.T) {
|
||||
if !asciidocext.Supports() {
|
||||
t.Skip("asciidoctor not installed")
|
||||
if ok, err := asciidocext.Supports(); !ok {
|
||||
t.Skip(err)
|
||||
}
|
||||
c := qt.New(t)
|
||||
p := getProvider(c, "")
|
||||
@@ -387,8 +359,8 @@ testContent
|
||||
}
|
||||
|
||||
func TestTableOfContentsWithCode(t *testing.T) {
|
||||
if !asciidocext.Supports() {
|
||||
t.Skip("asciidoctor not installed")
|
||||
if ok, err := asciidocext.Supports(); !ok {
|
||||
t.Skip(err)
|
||||
}
|
||||
c := qt.New(t)
|
||||
p := getProvider(c, "")
|
||||
@@ -406,8 +378,8 @@ func TestTableOfContentsWithCode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTableOfContentsPreserveTOC(t *testing.T) {
|
||||
if !asciidocext.Supports() {
|
||||
t.Skip("asciidoctor not installed")
|
||||
if ok, err := asciidocext.Supports(); !ok {
|
||||
t.Skip(err)
|
||||
}
|
||||
c := qt.New(t)
|
||||
confStr := `
|
||||
|
||||
@@ -2,11 +2,17 @@ package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gohugoio/hugo/common/hexec"
|
||||
"github.com/gohugoio/hugo/common/loggers"
|
||||
"github.com/gohugoio/hugo/config/security"
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
"github.com/gohugoio/hugo/langs"
|
||||
"github.com/gohugoio/hugo/markup/asciidocext/asciidocext_config"
|
||||
"github.com/gohugoio/hugo/markup/converter"
|
||||
"github.com/gohugoio/hugo/markup/internal"
|
||||
@@ -15,27 +21,52 @@ import (
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
type AsciidocConverter struct {
|
||||
type AsciiDocConverter struct {
|
||||
Ctx converter.DocumentContext
|
||||
Cfg converter.ProviderConfig
|
||||
}
|
||||
|
||||
type AsciidocResult struct {
|
||||
type asciiDocResult struct {
|
||||
converter.ResultRender
|
||||
toc *tableofcontents.Fragments
|
||||
}
|
||||
|
||||
/* ToDo: RelPermalink patch for svg posts not working*/
|
||||
type pageSubset interface {
|
||||
IsPage() bool
|
||||
RelPermalink() string
|
||||
Section() string
|
||||
}
|
||||
|
||||
func (r AsciidocResult) TableOfContents() *tableofcontents.Fragments {
|
||||
const (
|
||||
// asciiDocBinaryName is name of the AsciiDoc converter CLI.
|
||||
asciiDocBinaryName = "asciidoctor"
|
||||
|
||||
// asciiDocDiagramExtension is the name of the AsciiDoc converter diagram
|
||||
// extension.
|
||||
asciiDocDiagramExtension = "asciidoctor-diagram"
|
||||
|
||||
// asciiDocDiagramCacheDirKey is the AsciiDoc converter attribute key for
|
||||
// setting the path to the diagram cache directory.
|
||||
asciiDocDiagramCacheDirKey = "diagram-cachedir"
|
||||
|
||||
// asciiDocDiagramCacheImagesOptionKey is the AsciiDoc converter attribute
|
||||
// key for determining whether to cache image files in addition to
|
||||
// metadata files.
|
||||
asciiDocDiagramCacheImagesOptionKey = "diagram-cache-images-option"
|
||||
|
||||
// gemBinaryName is the name of the RubyGems CLI.
|
||||
gemBinaryName = "gem"
|
||||
|
||||
// goatBinaryName is the name of the GoAT CLI.
|
||||
goatBinaryName = "goat"
|
||||
)
|
||||
|
||||
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)
|
||||
func (a *AsciiDocConverter) Convert(ctx converter.RenderContext) (converter.ResultRender, error) {
|
||||
b, err := a.GetAsciiDocContent(ctx.Src, a.Ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -43,50 +74,81 @@ func (a *AsciidocConverter) Convert(ctx converter.RenderContext) (converter.Resu
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return AsciidocResult{
|
||||
return asciiDocResult{
|
||||
ResultRender: converter.Bytes(content),
|
||||
toc: toc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *AsciidocConverter) Supports(_ identity.Identity) bool {
|
||||
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.")
|
||||
// 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
|
||||
}
|
||||
|
||||
args := a.ParseArgs(ctx)
|
||||
args = append(args, "-")
|
||||
args, err := a.ParseArgs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
args = append(args, "-") // read from stdin
|
||||
|
||||
a.Cfg.Logger.Infoln("Rendering", ctx.DocumentName, " using asciidoctor args", args, "...")
|
||||
a.Cfg.Logger.Infof("Rendering %s using Asciidoctor args %s ...", ctx.DocumentName, args)
|
||||
|
||||
return internal.ExternallyRenderContent(a.Cfg, ctx, src, asciiDocBinaryName, args)
|
||||
}
|
||||
|
||||
func (a *AsciidocConverter) ParseArgs(ctx converter.DocumentContext) []string {
|
||||
cfg := a.Cfg.MarkupConfig().AsciidocExt
|
||||
func (a *AsciiDocConverter) ParseArgs(ctx converter.DocumentContext) ([]string, error) {
|
||||
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.")
|
||||
a.Cfg.Logger.Errorf(
|
||||
"The %q Asciidoctor extension is unsupported and ignored. Only installed Asciidoctor extensions are allowed.",
|
||||
extension,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
args = append(args, "-r", extension)
|
||||
|
||||
if extension == asciiDocDiagramExtension {
|
||||
cacheDir := filepath.Clean(filepath.Join(a.Cfg.Conf.CacheDirMisc(), asciiDocDiagramExtension))
|
||||
args = append(args, "-a", asciiDocDiagramCacheDirKey+"="+cacheDir)
|
||||
args = append(args, "-a", asciiDocDiagramCacheImagesOptionKey)
|
||||
}
|
||||
}
|
||||
|
||||
for attributeKey, attributeValue := range cfg.Attributes {
|
||||
if asciidocext_config.DisallowedAttributes[attributeKey] {
|
||||
a.Cfg.Logger.Errorln("Unsupported asciidoctor attribute was passed in. Attribute `" + attributeKey + "` ignored.")
|
||||
a.Cfg.Logger.Errorf(
|
||||
"The %q Asciidoctor attribute is unsupported and ignored.",
|
||||
attributeKey,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
if attributeKey == asciiDocDiagramCacheImagesOptionKey {
|
||||
a.Cfg.Logger.Warnf(
|
||||
"The %q Asciidoctor attribute is fixed and cannot be modified. To disable caching of both image and metadata files, set markup.asciidocext.attributes.diagram-nocache-option to true in your site configuration.",
|
||||
attributeKey,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
if attributeKey == asciiDocDiagramCacheDirKey {
|
||||
a.Cfg.Logger.Warnf(
|
||||
"The %q Asciidoctor attribute is fixed and cannot be modified. To change the cache location, modify caches.misc.dir in your site configuration.",
|
||||
attributeKey,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -105,42 +167,63 @@ func (a *AsciidocConverter) ParseArgs(ctx converter.DocumentContext) []string {
|
||||
}
|
||||
|
||||
if cfg.WorkingFolderCurrent {
|
||||
contentDir := filepath.Dir(ctx.Filename)
|
||||
destinationDir := a.Cfg.Conf.BaseConfig().PublishDir
|
||||
|
||||
if destinationDir == "" {
|
||||
a.Cfg.Logger.Errorln("markup.asciidocext.workingFolderCurrent requires hugo command option --destination to be set")
|
||||
page, ok := ctx.Document.(pageSubset)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected pageSubset, got %T", ctx.Document)
|
||||
}
|
||||
|
||||
var outDir string
|
||||
var err error
|
||||
// Derive the outdir document attribute from the relative permalink.
|
||||
relPath := strings.TrimPrefix(page.RelPermalink(), a.Cfg.Conf.BaseURL().BasePathNoTrailingSlash)
|
||||
relPath, err := url.PathUnescape(relPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
file := filepath.Base(ctx.Filename)
|
||||
if a.Cfg.Conf.IsUglyURLs("") || 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())
|
||||
if a.Cfg.Conf.IsMultihost() {
|
||||
// In a multi-host configuration, neither absolute nor relative
|
||||
// permalinks include the language key; prepend it.
|
||||
language, ok := a.Cfg.Conf.Language().(*langs.Language)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected *langs.Language, got %T", a.Cfg.Conf.Language())
|
||||
}
|
||||
relPath = path.Join(language.Lang, relPath)
|
||||
}
|
||||
|
||||
if a.Cfg.Conf.IsUglyURLs(page.Section()) {
|
||||
if page.IsPage() {
|
||||
// Remove the extension.
|
||||
relPath = strings.TrimSuffix(relPath, path.Ext(relPath))
|
||||
} else {
|
||||
a.Cfg.Logger.Errorln("unable to cast interface to pageSubset")
|
||||
// Remove the file name.
|
||||
relPath = path.Dir(relPath)
|
||||
}
|
||||
|
||||
outDir, err = filepath.Abs(filepath.Join(destinationDir, filepath.Dir(ctx.DocumentName), postDir))
|
||||
}
|
||||
// Set imagesoutdir and imagesdir attributes.
|
||||
imagesoutdir, err := filepath.Abs(filepath.Join(a.Cfg.Conf.BaseConfig().PublishDir, relPath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
imagesdir := filepath.Base(imagesoutdir)
|
||||
|
||||
if page.IsPage() {
|
||||
args = append(args, "-a", "imagesoutdir="+imagesoutdir, "-a", "imagesdir="+imagesdir)
|
||||
} else {
|
||||
args = append(args, "-a", "imagesoutdir="+imagesoutdir)
|
||||
}
|
||||
}
|
||||
// Prepend the publishDir.
|
||||
outDir, err := filepath.Abs(filepath.Join(a.Cfg.Conf.BaseConfig().PublishDir, relPath))
|
||||
if err != nil {
|
||||
a.Cfg.Logger.Errorln("asciidoctor outDir: ", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args = append(args, "--base-dir", contentDir, "-a", "outdir="+outDir)
|
||||
args = append(args, "--base-dir", filepath.Dir(ctx.Filename), "-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")
|
||||
a.Cfg.Logger.Warnln("Asciidoctor parameter NoHeaderOrFooter is required for correct HTML rendering")
|
||||
}
|
||||
|
||||
if cfg.SectionNumbers {
|
||||
@@ -159,29 +242,71 @@ func (a *AsciidocConverter) ParseArgs(ctx converter.DocumentContext) []string {
|
||||
|
||||
args = a.AppendArg(args, "--safe-mode", cfg.SafeMode, asciidocext_config.CliDefault.SafeMode, asciidocext_config.AllowedSafeMode)
|
||||
|
||||
return args
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (a *AsciidocConverter) AppendArg(args []string, option, value, defaultValue string, allowedValues map[string]bool) []string {
|
||||
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.")
|
||||
a.Cfg.Logger.Errorf(
|
||||
"Unsupported Asciidoctor value %q for option %q was passed in and will be ignored.",
|
||||
value,
|
||||
option,
|
||||
)
|
||||
}
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
const asciiDocBinaryName = "asciidoctor"
|
||||
// HasAsciiDoc reports whether the AsciiDoc converter is installed.
|
||||
func HasAsciiDoc() (bool, error) {
|
||||
if !hexec.InPath(asciiDocBinaryName) {
|
||||
return false, fmt.Errorf("the AsciiDoc converter (%s) is not installed", asciiDocBinaryName)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func HasAsciiDoc() bool {
|
||||
return hexec.InPath(asciiDocBinaryName)
|
||||
// CanRenderGoATDiagrams reports whether the AsciiDoc converter can render
|
||||
// GoAT diagrams. Only used in tests.
|
||||
func CanRenderGoATDiagrams() (bool, error) {
|
||||
// Verify that the AsciiDoc converter is installed.
|
||||
if ok, err := HasAsciiDoc(); !ok {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Verify that the RubyGems CLI is installed.
|
||||
if !hexec.InPath(gemBinaryName) {
|
||||
return false, fmt.Errorf("the RubyGems CLI (%s) is not installed", gemBinaryName)
|
||||
}
|
||||
|
||||
// Verify that the required AsciiDoc converter extension is installed.
|
||||
sc := security.DefaultConfig
|
||||
sc.Exec.Allow = security.MustNewWhitelist(gemBinaryName)
|
||||
ex := hexec.New(sc, "", loggers.NewDefault())
|
||||
|
||||
args := []any{"list", asciiDocDiagramExtension, "--installed"}
|
||||
cmd, err := ex.New(gemBinaryName, args...)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("the %s gem is not installed", asciiDocDiagramExtension)
|
||||
}
|
||||
|
||||
// Verify that the GoAT CLI is installed.
|
||||
if !hexec.InPath(goatBinaryName) {
|
||||
return false, fmt.Errorf("the GoAT CLI (%s) is not installed", goatBinaryName)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
func (a *AsciiDocConverter) extractTOC(src []byte) ([]byte, *tableofcontents.Fragments, error) {
|
||||
var buf bytes.Buffer
|
||||
buf.Write(src)
|
||||
node, err := html.Parse(&buf)
|
||||
@@ -196,7 +321,7 @@ func (a *AsciidocConverter) extractTOC(src []byte) ([]byte, *tableofcontents.Fra
|
||||
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 {
|
||||
if !a.Cfg.MarkupConfig().AsciiDocExt.PreserveTOC {
|
||||
n.Parent.RemoveChild(n)
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -37,8 +37,8 @@ type Config struct {
|
||||
// Configuration for the Goldmark markdown engine.
|
||||
Goldmark goldmark_config.Config
|
||||
|
||||
// Configuration for the Asciidoc external markdown engine.
|
||||
AsciidocExt asciidocext_config.Config
|
||||
// Configuration for the AsciiDoc external markdown engine.
|
||||
AsciiDocExt asciidocext_config.Config
|
||||
}
|
||||
|
||||
func (c *Config) Init() error {
|
||||
@@ -118,5 +118,5 @@ var Default = Config{
|
||||
Highlight: highlight.DefaultConfig,
|
||||
|
||||
Goldmark: goldmark_config.Default,
|
||||
AsciidocExt: asciidocext_config.Default,
|
||||
AsciiDocExt: asciidocext_config.Default,
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ func TestConfig(t *testing.T) {
|
||||
c.Assert(conf.Goldmark.Parser.Attribute.Title, qt.Equals, true)
|
||||
c.Assert(conf.Goldmark.Parser.Attribute.Block, qt.Equals, false)
|
||||
|
||||
c.Assert(conf.AsciidocExt.WorkingFolderCurrent, qt.Equals, true)
|
||||
c.Assert(conf.AsciidocExt.Extensions[0], qt.Equals, "asciidoctor-html5s")
|
||||
c.Assert(conf.AsciiDocExt.WorkingFolderCurrent, qt.Equals, true)
|
||||
c.Assert(conf.AsciiDocExt.Extensions[0], qt.Equals, "asciidoctor-html5s")
|
||||
})
|
||||
|
||||
// We changed the typographer extension config from a bool to a struct in 0.112.0.
|
||||
|
||||
@@ -297,10 +297,10 @@ Summary Truncated: {{ .Truncated }}|
|
||||
)
|
||||
}
|
||||
|
||||
func TestPageMarkupWithoutSummaryAsciidoc(t *testing.T) {
|
||||
func TestPageMarkupWithoutSummaryAsciiDoc(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !asciidocext.Supports() {
|
||||
t.Skip("Skip asiidoc test as not supported")
|
||||
if ok, err := asciidocext.Supports(); !ok {
|
||||
t.Skip(err)
|
||||
}
|
||||
|
||||
files := `
|
||||
|
||||
Reference in New Issue
Block a user