mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-18 21:11:19 +02:00
Add render template hooks for links and images
This commit also * revises the change detection for templates used by content files in server mode. * Adds a Page.RenderString method Fixes #6545 Fixes #4663 Closes #6043
This commit is contained in:
@@ -18,6 +18,7 @@ package asciidoc
|
||||
import (
|
||||
"os/exec"
|
||||
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
"github.com/gohugoio/hugo/markup/internal"
|
||||
|
||||
"github.com/gohugoio/hugo/markup/converter"
|
||||
@@ -47,6 +48,10 @@ func (a *asciidocConverter) Convert(ctx converter.RenderContext) (converter.Resu
|
||||
return converter.Bytes(a.getAsciidocContent(ctx.Src, a.ctx)), nil
|
||||
}
|
||||
|
||||
func (c *asciidocConverter) Supports(feature identity.Identity) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// getAsciidocContent calls asciidoctor or asciidoc as an external helper
|
||||
// to convert AsciiDoc content to HTML.
|
||||
func (a *asciidocConverter) getAsciidocContent(src []byte, ctx converter.DocumentContext) []byte {
|
||||
|
@@ -15,6 +15,7 @@
|
||||
package blackfriday
|
||||
|
||||
import (
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
"github.com/gohugoio/hugo/markup/blackfriday/blackfriday_config"
|
||||
"github.com/gohugoio/hugo/markup/converter"
|
||||
"github.com/russross/blackfriday"
|
||||
@@ -72,6 +73,10 @@ func (c *blackfridayConverter) Convert(ctx converter.RenderContext) (converter.R
|
||||
return converter.Bytes(blackfriday.Markdown(ctx.Src, r, c.extensions)), nil
|
||||
}
|
||||
|
||||
func (c *blackfridayConverter) Supports(feature identity.Identity) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *blackfridayConverter) getHTMLRenderer(renderTOC bool) blackfriday.Renderer {
|
||||
flags := getFlags(renderTOC, c.bf)
|
||||
|
||||
|
@@ -16,6 +16,8 @@ package converter
|
||||
import (
|
||||
"github.com/gohugoio/hugo/common/loggers"
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
"github.com/gohugoio/hugo/markup/converter/hooks"
|
||||
"github.com/gohugoio/hugo/markup/markup_config"
|
||||
"github.com/gohugoio/hugo/markup/tableofcontents"
|
||||
"github.com/spf13/afero"
|
||||
@@ -67,6 +69,7 @@ func (n newConverter) Name() string {
|
||||
// another format, e.g. Markdown to HTML.
|
||||
type Converter interface {
|
||||
Convert(ctx RenderContext) (Result, error)
|
||||
Supports(feature identity.Identity) bool
|
||||
}
|
||||
|
||||
// Result represents the minimum returned from Convert.
|
||||
@@ -94,6 +97,7 @@ func (b Bytes) Bytes() []byte {
|
||||
|
||||
// DocumentContext holds contextual information about the document to convert.
|
||||
type DocumentContext struct {
|
||||
Document interface{} // May be nil. Usually a page.Page
|
||||
DocumentID string
|
||||
DocumentName string
|
||||
ConfigOverrides map[string]interface{}
|
||||
@@ -101,6 +105,11 @@ type DocumentContext struct {
|
||||
|
||||
// RenderContext holds contextual information about the content to render.
|
||||
type RenderContext struct {
|
||||
Src []byte
|
||||
RenderTOC bool
|
||||
Src []byte
|
||||
RenderTOC bool
|
||||
RenderHooks *hooks.Render
|
||||
}
|
||||
|
||||
var (
|
||||
FeatureRenderHooks = identity.NewPathIdentity("markup", "renderingHooks")
|
||||
)
|
||||
|
57
markup/converter/hooks/hooks.go
Normal file
57
markup/converter/hooks/hooks.go
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2019 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 hooks
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
)
|
||||
|
||||
type LinkContext interface {
|
||||
Page() interface{}
|
||||
Destination() string
|
||||
Title() string
|
||||
Text() string
|
||||
}
|
||||
|
||||
type Render struct {
|
||||
LinkRenderer LinkRenderer
|
||||
ImageRenderer LinkRenderer
|
||||
}
|
||||
|
||||
func (r *Render) Eq(other interface{}) bool {
|
||||
ro, ok := other.(*Render)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if r == nil || ro == nil {
|
||||
return r == nil
|
||||
}
|
||||
|
||||
if r.ImageRenderer.GetIdentity() != ro.ImageRenderer.GetIdentity() {
|
||||
return false
|
||||
}
|
||||
|
||||
if r.LinkRenderer.GetIdentity() != ro.LinkRenderer.GetIdentity() {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
type LinkRenderer interface {
|
||||
Render(w io.Writer, ctx LinkContext) error
|
||||
identity.Provider
|
||||
}
|
@@ -15,21 +15,22 @@
|
||||
package goldmark
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime/debug"
|
||||
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
|
||||
"github.com/gohugoio/hugo/hugofs"
|
||||
|
||||
"github.com/alecthomas/chroma/styles"
|
||||
"github.com/gohugoio/hugo/markup/converter"
|
||||
"github.com/gohugoio/hugo/markup/highlight"
|
||||
"github.com/gohugoio/hugo/markup/markup_config"
|
||||
"github.com/gohugoio/hugo/markup/tableofcontents"
|
||||
"github.com/yuin/goldmark"
|
||||
hl "github.com/yuin/goldmark-highlighting"
|
||||
@@ -48,7 +49,7 @@ type provide struct {
|
||||
}
|
||||
|
||||
func (p provide) New(cfg converter.ProviderConfig) (converter.Provider, error) {
|
||||
md := newMarkdown(cfg.MarkupConfig)
|
||||
md := newMarkdown(cfg)
|
||||
return converter.NewProvider("goldmark", func(ctx converter.DocumentContext) (converter.Converter, error) {
|
||||
return &goldmarkConverter{
|
||||
ctx: ctx,
|
||||
@@ -64,11 +65,13 @@ type goldmarkConverter struct {
|
||||
cfg converter.ProviderConfig
|
||||
}
|
||||
|
||||
func newMarkdown(mcfg markup_config.Config) goldmark.Markdown {
|
||||
cfg := mcfg.Goldmark
|
||||
func newMarkdown(pcfg converter.ProviderConfig) goldmark.Markdown {
|
||||
mcfg := pcfg.MarkupConfig
|
||||
cfg := pcfg.MarkupConfig.Goldmark
|
||||
|
||||
var (
|
||||
extensions = []goldmark.Extender{
|
||||
newLinks(),
|
||||
newTocExtension(),
|
||||
}
|
||||
rendererOptions []renderer.Option
|
||||
@@ -143,15 +146,53 @@ func newMarkdown(mcfg markup_config.Config) goldmark.Markdown {
|
||||
|
||||
}
|
||||
|
||||
var _ identity.IdentitiesProvider = (*converterResult)(nil)
|
||||
|
||||
type converterResult struct {
|
||||
converter.Result
|
||||
toc tableofcontents.Root
|
||||
ids identity.Identities
|
||||
}
|
||||
|
||||
func (c converterResult) TableOfContents() tableofcontents.Root {
|
||||
return c.toc
|
||||
}
|
||||
|
||||
func (c converterResult) GetIdentities() identity.Identities {
|
||||
return c.ids
|
||||
}
|
||||
|
||||
type renderContext struct {
|
||||
util.BufWriter
|
||||
renderContextData
|
||||
}
|
||||
|
||||
type renderContextData interface {
|
||||
RenderContext() converter.RenderContext
|
||||
DocumentContext() converter.DocumentContext
|
||||
AddIdentity(id identity.Identity)
|
||||
}
|
||||
|
||||
type renderContextDataHolder struct {
|
||||
rctx converter.RenderContext
|
||||
dctx converter.DocumentContext
|
||||
ids identity.Manager
|
||||
}
|
||||
|
||||
func (ctx *renderContextDataHolder) RenderContext() converter.RenderContext {
|
||||
return ctx.rctx
|
||||
}
|
||||
|
||||
func (ctx *renderContextDataHolder) DocumentContext() converter.DocumentContext {
|
||||
return ctx.dctx
|
||||
}
|
||||
|
||||
func (ctx *renderContextDataHolder) AddIdentity(id identity.Identity) {
|
||||
ctx.ids.Add(id)
|
||||
}
|
||||
|
||||
var converterIdentity = identity.KeyValueIdentity{Key: "goldmark", Value: "converter"}
|
||||
|
||||
func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result converter.Result, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@@ -166,9 +207,7 @@ func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result convert
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
result = buf
|
||||
pctx := parser.NewContext()
|
||||
pctx.Set(tocEnableKey, ctx.RenderTOC)
|
||||
|
||||
pctx := newParserContext(ctx)
|
||||
reader := text.NewReader(ctx.Src)
|
||||
|
||||
doc := c.md.Parser().Parse(
|
||||
@@ -176,27 +215,58 @@ func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result convert
|
||||
parser.WithContext(pctx),
|
||||
)
|
||||
|
||||
if err := c.md.Renderer().Render(buf, ctx.Src, doc); err != nil {
|
||||
rcx := &renderContextDataHolder{
|
||||
rctx: ctx,
|
||||
dctx: c.ctx,
|
||||
ids: identity.NewManager(converterIdentity),
|
||||
}
|
||||
|
||||
w := renderContext{
|
||||
BufWriter: bufio.NewWriter(buf),
|
||||
renderContextData: rcx,
|
||||
}
|
||||
|
||||
if err := c.md.Renderer().Render(w, ctx.Src, doc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if toc, ok := pctx.Get(tocResultKey).(tableofcontents.Root); ok {
|
||||
return converterResult{
|
||||
Result: buf,
|
||||
toc: toc,
|
||||
}, nil
|
||||
}
|
||||
return converterResult{
|
||||
Result: buf,
|
||||
ids: rcx.ids.GetIdentities(),
|
||||
toc: pctx.TableOfContents(),
|
||||
}, nil
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
var featureSet = map[identity.Identity]bool{
|
||||
converter.FeatureRenderHooks: true,
|
||||
}
|
||||
|
||||
func (c *goldmarkConverter) Supports(feature identity.Identity) bool {
|
||||
return featureSet[feature.GetIdentity()]
|
||||
}
|
||||
|
||||
func newParserContext(rctx converter.RenderContext) *parserContext {
|
||||
ctx := parser.NewContext()
|
||||
ctx.Set(tocEnableKey, rctx.RenderTOC)
|
||||
return &parserContext{
|
||||
Context: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
type parserContext struct {
|
||||
parser.Context
|
||||
}
|
||||
|
||||
func (p *parserContext) TableOfContents() tableofcontents.Root {
|
||||
if v := p.Get(tocResultKey); v != nil {
|
||||
return v.(tableofcontents.Root)
|
||||
}
|
||||
return tableofcontents.Root{}
|
||||
}
|
||||
|
||||
func newHighlighting(cfg highlight.Config) goldmark.Extender {
|
||||
style := styles.Get(cfg.Style)
|
||||
if style == nil {
|
||||
style = styles.Fallback
|
||||
}
|
||||
|
||||
e := hl.NewHighlighting(
|
||||
return hl.NewHighlighting(
|
||||
hl.WithStyle(cfg.Style),
|
||||
hl.WithGuessLanguage(cfg.GuessSyntax),
|
||||
hl.WithCodeBlockOptions(highlight.GetCodeBlockOptions()),
|
||||
@@ -230,6 +300,4 @@ func newHighlighting(cfg highlight.Config) goldmark.Extender {
|
||||
|
||||
}),
|
||||
)
|
||||
|
||||
return e
|
||||
}
|
||||
|
@@ -38,6 +38,9 @@ func TestConvert(t *testing.T) {
|
||||
https://github.com/gohugoio/hugo/issues/6528
|
||||
[Live Demo here!](https://docuapi.netlify.com/)
|
||||
|
||||
[I'm an inline-style link with title](https://www.google.com "Google's Homepage")
|
||||
|
||||
|
||||
## Code Fences
|
||||
|
||||
§§§bash
|
||||
@@ -98,6 +101,7 @@ description
|
||||
|
||||
mconf := markup_config.Default
|
||||
mconf.Highlight.NoClasses = false
|
||||
mconf.Goldmark.Renderer.Unsafe = true
|
||||
|
||||
p, err := Provider.New(
|
||||
converter.ProviderConfig{
|
||||
@@ -106,15 +110,15 @@ description
|
||||
},
|
||||
)
|
||||
c.Assert(err, qt.IsNil)
|
||||
conv, err := p.New(converter.DocumentContext{})
|
||||
conv, err := p.New(converter.DocumentContext{DocumentID: "thedoc"})
|
||||
c.Assert(err, qt.IsNil)
|
||||
b, err := conv.Convert(converter.RenderContext{Src: []byte(content)})
|
||||
b, err := conv.Convert(converter.RenderContext{RenderTOC: true, Src: []byte(content)})
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
got := string(b.Bytes())
|
||||
|
||||
// Links
|
||||
c.Assert(got, qt.Contains, `<a href="https://docuapi.netlify.com/">Live Demo here!</a>`)
|
||||
// c.Assert(got, qt.Contains, `<a href="https://docuapi.netlify.com/">Live Demo here!</a>`)
|
||||
|
||||
// Header IDs
|
||||
c.Assert(got, qt.Contains, `<h2 id="custom">Custom ID</h2>`, qt.Commentf(got))
|
||||
@@ -137,6 +141,11 @@ description
|
||||
c.Assert(got, qt.Contains, `<section class="footnotes" role="doc-endnotes">`)
|
||||
c.Assert(got, qt.Contains, `<dt>date</dt>`)
|
||||
|
||||
toc, ok := b.(converter.TableOfContentsProvider)
|
||||
c.Assert(ok, qt.Equals, true)
|
||||
tocHTML := toc.TableOfContents().ToHTML(1, 2, false)
|
||||
c.Assert(tocHTML, qt.Contains, "TableOfContents")
|
||||
|
||||
}
|
||||
|
||||
func TestCodeFence(t *testing.T) {
|
||||
|
208
markup/goldmark/render_link.go
Normal file
208
markup/goldmark/render_link.go
Normal file
@@ -0,0 +1,208 @@
|
||||
// Copyright 2019 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 goldmark
|
||||
|
||||
import (
|
||||
"github.com/gohugoio/hugo/markup/converter/hooks"
|
||||
|
||||
"github.com/yuin/goldmark"
|
||||
"github.com/yuin/goldmark/ast"
|
||||
"github.com/yuin/goldmark/renderer"
|
||||
"github.com/yuin/goldmark/renderer/html"
|
||||
"github.com/yuin/goldmark/util"
|
||||
)
|
||||
|
||||
var _ renderer.SetOptioner = (*linkRenderer)(nil)
|
||||
|
||||
func newLinkRenderer() renderer.NodeRenderer {
|
||||
r := &linkRenderer{
|
||||
Config: html.Config{
|
||||
Writer: html.DefaultWriter,
|
||||
},
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func newLinks() goldmark.Extender {
|
||||
return &links{}
|
||||
}
|
||||
|
||||
type linkContext struct {
|
||||
page interface{}
|
||||
destination string
|
||||
title string
|
||||
text string
|
||||
}
|
||||
|
||||
func (ctx linkContext) Destination() string {
|
||||
return ctx.destination
|
||||
}
|
||||
|
||||
func (ctx linkContext) Resolved() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (ctx linkContext) Page() interface{} {
|
||||
return ctx.page
|
||||
}
|
||||
|
||||
func (ctx linkContext) Text() string {
|
||||
return ctx.text
|
||||
}
|
||||
|
||||
func (ctx linkContext) Title() string {
|
||||
return ctx.title
|
||||
}
|
||||
|
||||
type linkRenderer struct {
|
||||
html.Config
|
||||
}
|
||||
|
||||
func (r *linkRenderer) SetOption(name renderer.OptionName, value interface{}) {
|
||||
r.Config.SetOption(name, value)
|
||||
}
|
||||
|
||||
// RegisterFuncs implements NodeRenderer.RegisterFuncs.
|
||||
func (r *linkRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
|
||||
reg.Register(ast.KindLink, r.renderLink)
|
||||
reg.Register(ast.KindImage, r.renderImage)
|
||||
}
|
||||
|
||||
// Fall back to the default Goldmark render funcs. Method below borrowed from:
|
||||
// https://github.com/yuin/goldmark/blob/b611cd333a492416b56aa8d94b04a67bf0096ab2/renderer/html/html.go#L404
|
||||
func (r *linkRenderer) renderDefaultImage(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
if !entering {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
n := node.(*ast.Image)
|
||||
_, _ = w.WriteString("<img src=\"")
|
||||
if r.Unsafe || !html.IsDangerousURL(n.Destination) {
|
||||
_, _ = w.Write(util.EscapeHTML(util.URLEscape(n.Destination, true)))
|
||||
}
|
||||
_, _ = w.WriteString(`" alt="`)
|
||||
_, _ = w.Write(n.Text(source))
|
||||
_ = w.WriteByte('"')
|
||||
if n.Title != nil {
|
||||
_, _ = w.WriteString(` title="`)
|
||||
r.Writer.Write(w, n.Title)
|
||||
_ = w.WriteByte('"')
|
||||
}
|
||||
if r.XHTML {
|
||||
_, _ = w.WriteString(" />")
|
||||
} else {
|
||||
_, _ = w.WriteString(">")
|
||||
}
|
||||
return ast.WalkSkipChildren, nil
|
||||
}
|
||||
|
||||
// Fall back to the default Goldmark render funcs. Method below borrowed from:
|
||||
// https://github.com/yuin/goldmark/blob/b611cd333a492416b56aa8d94b04a67bf0096ab2/renderer/html/html.go#L404
|
||||
func (r *linkRenderer) renderDefaultLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
n := node.(*ast.Link)
|
||||
if entering {
|
||||
_, _ = w.WriteString("<a href=\"")
|
||||
if r.Unsafe || !html.IsDangerousURL(n.Destination) {
|
||||
_, _ = w.Write(util.EscapeHTML(util.URLEscape(n.Destination, true)))
|
||||
}
|
||||
_ = w.WriteByte('"')
|
||||
if n.Title != nil {
|
||||
_, _ = w.WriteString(` title="`)
|
||||
r.Writer.Write(w, n.Title)
|
||||
_ = w.WriteByte('"')
|
||||
}
|
||||
_ = w.WriteByte('>')
|
||||
} else {
|
||||
_, _ = w.WriteString("</a>")
|
||||
}
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
func (r *linkRenderer) renderImage(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
n := node.(*ast.Image)
|
||||
var h *hooks.Render
|
||||
|
||||
ctx, ok := w.(renderContextData)
|
||||
if ok {
|
||||
h = ctx.RenderContext().RenderHooks
|
||||
ok = h != nil && h.ImageRenderer != nil
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return r.renderDefaultImage(w, source, node, entering)
|
||||
}
|
||||
|
||||
if !entering {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
err := h.ImageRenderer.Render(
|
||||
w,
|
||||
linkContext{
|
||||
page: ctx.DocumentContext().Document,
|
||||
destination: string(n.Destination),
|
||||
title: string(n.Title),
|
||||
text: string(n.Text(source)),
|
||||
},
|
||||
)
|
||||
|
||||
ctx.AddIdentity(h.ImageRenderer.GetIdentity())
|
||||
|
||||
return ast.WalkSkipChildren, err
|
||||
|
||||
}
|
||||
|
||||
func (r *linkRenderer) renderLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
n := node.(*ast.Link)
|
||||
var h *hooks.Render
|
||||
|
||||
ctx, ok := w.(renderContextData)
|
||||
if ok {
|
||||
h = ctx.RenderContext().RenderHooks
|
||||
ok = h != nil && h.LinkRenderer != nil
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return r.renderDefaultLink(w, source, node, entering)
|
||||
}
|
||||
|
||||
if !entering {
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
||||
err := h.LinkRenderer.Render(
|
||||
w,
|
||||
linkContext{
|
||||
page: ctx.DocumentContext().Document,
|
||||
destination: string(n.Destination),
|
||||
title: string(n.Title),
|
||||
text: string(n.Text(source)),
|
||||
},
|
||||
)
|
||||
|
||||
ctx.AddIdentity(h.LinkRenderer.GetIdentity())
|
||||
|
||||
// Do not render the inner text.
|
||||
return ast.WalkSkipChildren, err
|
||||
|
||||
}
|
||||
|
||||
type links struct {
|
||||
}
|
||||
|
||||
// Extend implements goldmark.Extender.
|
||||
func (e *links) Extend(m goldmark.Markdown) {
|
||||
m.Renderer().AddOptions(renderer.WithNodeRenderers(
|
||||
util.Prioritized(newLinkRenderer(), 100),
|
||||
))
|
||||
}
|
@@ -15,6 +15,7 @@
|
||||
package mmark
|
||||
|
||||
import (
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
"github.com/gohugoio/hugo/markup/blackfriday/blackfriday_config"
|
||||
"github.com/gohugoio/hugo/markup/converter"
|
||||
"github.com/miekg/mmark"
|
||||
@@ -65,6 +66,10 @@ func (c *mmarkConverter) Convert(ctx converter.RenderContext) (converter.Result,
|
||||
return mmark.Parse(ctx.Src, r, c.extensions), nil
|
||||
}
|
||||
|
||||
func (c *mmarkConverter) Supports(feature identity.Identity) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func getHTMLRenderer(
|
||||
ctx converter.DocumentContext,
|
||||
cfg blackfriday_config.Config,
|
||||
|
@@ -17,6 +17,8 @@ package org
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
|
||||
"github.com/gohugoio/hugo/markup/converter"
|
||||
"github.com/niklasfasching/go-org/org"
|
||||
"github.com/spf13/afero"
|
||||
@@ -66,3 +68,7 @@ func (c *orgConverter) Convert(ctx converter.RenderContext) (converter.Result, e
|
||||
}
|
||||
return converter.Bytes([]byte(html)), nil
|
||||
}
|
||||
|
||||
func (c *orgConverter) Supports(feature identity.Identity) bool {
|
||||
return false
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ package pandoc
|
||||
import (
|
||||
"os/exec"
|
||||
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
"github.com/gohugoio/hugo/markup/internal"
|
||||
|
||||
"github.com/gohugoio/hugo/markup/converter"
|
||||
@@ -47,6 +48,10 @@ func (c *pandocConverter) Convert(ctx converter.RenderContext) (converter.Result
|
||||
return converter.Bytes(c.getPandocContent(ctx.Src, c.ctx)), nil
|
||||
}
|
||||
|
||||
func (c *pandocConverter) Supports(feature identity.Identity) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// getPandocContent calls pandoc as an external helper to convert pandoc markdown to HTML.
|
||||
func (c *pandocConverter) getPandocContent(src []byte, ctx converter.DocumentContext) []byte {
|
||||
logger := c.cfg.Logger
|
||||
|
@@ -19,6 +19,7 @@ import (
|
||||
"os/exec"
|
||||
"runtime"
|
||||
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
"github.com/gohugoio/hugo/markup/internal"
|
||||
|
||||
"github.com/gohugoio/hugo/markup/converter"
|
||||
@@ -48,6 +49,10 @@ func (c *rstConverter) Convert(ctx converter.RenderContext) (converter.Result, e
|
||||
return converter.Bytes(c.getRstContent(ctx.Src, c.ctx)), nil
|
||||
}
|
||||
|
||||
func (c *rstConverter) Supports(feature identity.Identity) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// getRstContent calls the Python script rst2html as an external helper
|
||||
// to convert reStructuredText content to HTML.
|
||||
func (c *rstConverter) getRstContent(src []byte, ctx converter.DocumentContext) []byte {
|
||||
|
Reference in New Issue
Block a user