github.com/linchen2chris/hugo@v0.0.0-20230307053224-cec209389705/markup/converter/converter.go (about) 1 // Copyright 2019 The Hugo Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package converter 15 16 import ( 17 "bytes" 18 "context" 19 20 "github.com/gohugoio/hugo/common/hexec" 21 "github.com/gohugoio/hugo/common/loggers" 22 "github.com/gohugoio/hugo/config" 23 "github.com/gohugoio/hugo/identity" 24 "github.com/gohugoio/hugo/markup/converter/hooks" 25 "github.com/gohugoio/hugo/markup/highlight" 26 "github.com/gohugoio/hugo/markup/markup_config" 27 "github.com/gohugoio/hugo/markup/tableofcontents" 28 "github.com/spf13/afero" 29 ) 30 31 // ProviderConfig configures a new Provider. 32 type ProviderConfig struct { 33 MarkupConfig markup_config.Config 34 35 Cfg config.Provider // Site config 36 ContentFs afero.Fs 37 Logger loggers.Logger 38 Exec *hexec.Exec 39 highlight.Highlighter 40 } 41 42 // ProviderProvider creates converter providers. 43 type ProviderProvider interface { 44 New(cfg ProviderConfig) (Provider, error) 45 } 46 47 // Provider creates converters. 48 type Provider interface { 49 New(ctx DocumentContext) (Converter, error) 50 Name() string 51 } 52 53 // NewProvider creates a new Provider with the given name. 54 func NewProvider(name string, create func(ctx DocumentContext) (Converter, error)) Provider { 55 return newConverter{ 56 name: name, 57 create: create, 58 } 59 } 60 61 type newConverter struct { 62 name string 63 create func(ctx DocumentContext) (Converter, error) 64 } 65 66 func (n newConverter) New(ctx DocumentContext) (Converter, error) { 67 return n.create(ctx) 68 } 69 70 func (n newConverter) Name() string { 71 return n.name 72 } 73 74 var NopConverter = new(nopConverter) 75 76 type nopConverter int 77 78 func (nopConverter) Convert(ctx RenderContext) (ResultRender, error) { 79 return &bytes.Buffer{}, nil 80 } 81 82 func (nopConverter) Supports(feature identity.Identity) bool { 83 return false 84 } 85 86 // Converter wraps the Convert method that converts some markup into 87 // another format, e.g. Markdown to HTML. 88 type Converter interface { 89 Convert(ctx RenderContext) (ResultRender, error) 90 Supports(feature identity.Identity) bool 91 } 92 93 // ParseRenderer is an optional interface. 94 // The Goldmark converter implements this, and this allows us 95 // to extract the ToC without having to render the content. 96 type ParseRenderer interface { 97 Parse(RenderContext) (ResultParse, error) 98 Render(RenderContext, any) (ResultRender, error) 99 } 100 101 // ResultRender represents the minimum returned from Convert and Render. 102 type ResultRender interface { 103 Bytes() []byte 104 } 105 106 // ResultParse represents the minimum returned from Parse. 107 type ResultParse interface { 108 Doc() any 109 TableOfContents() *tableofcontents.Fragments 110 } 111 112 // DocumentInfo holds additional information provided by some converters. 113 type DocumentInfo interface { 114 AnchorSuffix() string 115 } 116 117 // TableOfContentsProvider provides the content as a ToC structure. 118 type TableOfContentsProvider interface { 119 TableOfContents() *tableofcontents.Fragments 120 } 121 122 // AnchorNameSanitizer tells how a converter sanitizes anchor names. 123 type AnchorNameSanitizer interface { 124 SanitizeAnchorName(s string) string 125 } 126 127 // Bytes holds a byte slice and implements the Result interface. 128 type Bytes []byte 129 130 // Bytes returns itself 131 func (b Bytes) Bytes() []byte { 132 return b 133 } 134 135 // DocumentContext holds contextual information about the document to convert. 136 type DocumentContext struct { 137 Document any // May be nil. Usually a page.Page 138 DocumentID string 139 DocumentName string 140 Filename string 141 } 142 143 // RenderContext holds contextual information about the content to render. 144 type RenderContext struct { 145 // Ctx is the context.Context for the current Page render. 146 Ctx context.Context 147 148 // Src is the content to render. 149 Src []byte 150 151 // Whether to render TableOfContents. 152 RenderTOC bool 153 154 // GerRenderer provides hook renderers on demand. 155 GetRenderer hooks.GetRendererFunc 156 } 157 158 var FeatureRenderHooks = identity.NewPathIdentity("markup", "renderingHooks")