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 14package converter 15 16import ( 17 "bytes" 18 19 "github.com/gohugoio/hugo/common/hexec" 20 "github.com/gohugoio/hugo/common/loggers" 21 "github.com/gohugoio/hugo/config" 22 "github.com/gohugoio/hugo/identity" 23 "github.com/gohugoio/hugo/markup/converter/hooks" 24 "github.com/gohugoio/hugo/markup/markup_config" 25 "github.com/gohugoio/hugo/markup/tableofcontents" 26 "github.com/spf13/afero" 27) 28 29// ProviderConfig configures a new Provider. 30type ProviderConfig struct { 31 MarkupConfig markup_config.Config 32 33 Cfg config.Provider // Site config 34 ContentFs afero.Fs 35 Logger loggers.Logger 36 Exec *hexec.Exec 37 Highlight func(code, lang, optsStr string) (string, error) 38} 39 40// ProviderProvider creates converter providers. 41type ProviderProvider interface { 42 New(cfg ProviderConfig) (Provider, error) 43} 44 45// Provider creates converters. 46type Provider interface { 47 New(ctx DocumentContext) (Converter, error) 48 Name() string 49} 50 51// NewProvider creates a new Provider with the given name. 52func NewProvider(name string, create func(ctx DocumentContext) (Converter, error)) Provider { 53 return newConverter{ 54 name: name, 55 create: create, 56 } 57} 58 59type newConverter struct { 60 name string 61 create func(ctx DocumentContext) (Converter, error) 62} 63 64func (n newConverter) New(ctx DocumentContext) (Converter, error) { 65 return n.create(ctx) 66} 67 68func (n newConverter) Name() string { 69 return n.name 70} 71 72var NopConverter = new(nopConverter) 73 74type nopConverter int 75 76func (nopConverter) Convert(ctx RenderContext) (Result, error) { 77 return &bytes.Buffer{}, nil 78} 79 80func (nopConverter) Supports(feature identity.Identity) bool { 81 return false 82} 83 84// Converter wraps the Convert method that converts some markup into 85// another format, e.g. Markdown to HTML. 86type Converter interface { 87 Convert(ctx RenderContext) (Result, error) 88 Supports(feature identity.Identity) bool 89} 90 91// Result represents the minimum returned from Convert. 92type Result interface { 93 Bytes() []byte 94} 95 96// DocumentInfo holds additional information provided by some converters. 97type DocumentInfo interface { 98 AnchorSuffix() string 99} 100 101// TableOfContentsProvider provides the content as a ToC structure. 102type TableOfContentsProvider interface { 103 TableOfContents() tableofcontents.Root 104} 105 106// AnchorNameSanitizer tells how a converter sanitizes anchor names. 107type AnchorNameSanitizer interface { 108 SanitizeAnchorName(s string) string 109} 110 111// Bytes holds a byte slice and implements the Result interface. 112type Bytes []byte 113 114// Bytes returns itself 115func (b Bytes) Bytes() []byte { 116 return b 117} 118 119// DocumentContext holds contextual information about the document to convert. 120type DocumentContext struct { 121 Document interface{} // May be nil. Usually a page.Page 122 DocumentID string 123 DocumentName string 124 Filename string 125 ConfigOverrides map[string]interface{} 126} 127 128// RenderContext holds contextual information about the content to render. 129type RenderContext struct { 130 Src []byte 131 RenderTOC bool 132 RenderHooks hooks.Renderers 133} 134 135var FeatureRenderHooks = identity.NewPathIdentity("markup", "renderingHooks") 136