github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/markup/mmark/convert.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 mmark converts Markdown to HTML using MMark v1. 15 package mmark 16 17 import ( 18 "github.com/gohugoio/hugo/identity" 19 "github.com/gohugoio/hugo/markup/blackfriday/blackfriday_config" 20 "github.com/gohugoio/hugo/markup/converter" 21 "github.com/miekg/mmark" 22 ) 23 24 // Provider is the package entry point. 25 var Provider converter.ProviderProvider = provider{} 26 27 type provider struct { 28 } 29 30 func (p provider) New(cfg converter.ProviderConfig) (converter.Provider, error) { 31 defaultBlackFriday := cfg.MarkupConfig.BlackFriday 32 defaultExtensions := getMmarkExtensions(defaultBlackFriday) 33 34 return converter.NewProvider("mmark", func(ctx converter.DocumentContext) (converter.Converter, error) { 35 b := defaultBlackFriday 36 extensions := defaultExtensions 37 38 if ctx.ConfigOverrides != nil { 39 var err error 40 b, err = blackfriday_config.UpdateConfig(b, ctx.ConfigOverrides) 41 if err != nil { 42 return nil, err 43 } 44 extensions = getMmarkExtensions(b) 45 } 46 47 return &mmarkConverter{ 48 ctx: ctx, 49 b: b, 50 extensions: extensions, 51 cfg: cfg, 52 }, nil 53 }), nil 54 } 55 56 type mmarkConverter struct { 57 ctx converter.DocumentContext 58 extensions int 59 b blackfriday_config.Config 60 cfg converter.ProviderConfig 61 } 62 63 func (c *mmarkConverter) Convert(ctx converter.RenderContext) (converter.Result, error) { 64 r := getHTMLRenderer(c.ctx, c.b, c.cfg) 65 return mmark.Parse(ctx.Src, r, c.extensions), nil 66 } 67 68 func (c *mmarkConverter) Supports(feature identity.Identity) bool { 69 return false 70 } 71 72 func getHTMLRenderer( 73 ctx converter.DocumentContext, 74 cfg blackfriday_config.Config, 75 pcfg converter.ProviderConfig) mmark.Renderer { 76 var ( 77 flags int 78 documentID string 79 ) 80 81 documentID = ctx.DocumentID 82 83 renderParameters := mmark.HtmlRendererParameters{ 84 FootnoteAnchorPrefix: cfg.FootnoteAnchorPrefix, 85 FootnoteReturnLinkContents: cfg.FootnoteReturnLinkContents, 86 } 87 88 if documentID != "" && !cfg.PlainIDAnchors { 89 renderParameters.FootnoteAnchorPrefix = documentID + ":" + renderParameters.FootnoteAnchorPrefix 90 } 91 92 htmlFlags := flags 93 htmlFlags |= mmark.HTML_FOOTNOTE_RETURN_LINKS 94 95 return &mmarkRenderer{ 96 BlackfridayConfig: cfg, 97 Config: pcfg, 98 Renderer: mmark.HtmlRendererWithParameters(htmlFlags, "", "", renderParameters), 99 } 100 } 101 102 func getMmarkExtensions(cfg blackfriday_config.Config) int { 103 flags := 0 104 flags |= mmark.EXTENSION_TABLES 105 flags |= mmark.EXTENSION_FENCED_CODE 106 flags |= mmark.EXTENSION_AUTOLINK 107 flags |= mmark.EXTENSION_SPACE_HEADERS 108 flags |= mmark.EXTENSION_CITATION 109 flags |= mmark.EXTENSION_TITLEBLOCK_TOML 110 flags |= mmark.EXTENSION_HEADER_IDS 111 flags |= mmark.EXTENSION_AUTO_HEADER_IDS 112 flags |= mmark.EXTENSION_UNIQUE_HEADER_IDS 113 flags |= mmark.EXTENSION_FOOTNOTES 114 flags |= mmark.EXTENSION_SHORT_REF 115 flags |= mmark.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK 116 flags |= mmark.EXTENSION_INCLUDE 117 118 for _, extension := range cfg.Extensions { 119 if flag, ok := mmarkExtensionMap[extension]; ok { 120 flags |= flag 121 } 122 } 123 return flags 124 } 125 126 var mmarkExtensionMap = map[string]int{ 127 "tables": mmark.EXTENSION_TABLES, 128 "fencedCode": mmark.EXTENSION_FENCED_CODE, 129 "autolink": mmark.EXTENSION_AUTOLINK, 130 "laxHtmlBlocks": mmark.EXTENSION_LAX_HTML_BLOCKS, 131 "spaceHeaders": mmark.EXTENSION_SPACE_HEADERS, 132 "hardLineBreak": mmark.EXTENSION_HARD_LINE_BREAK, 133 "footnotes": mmark.EXTENSION_FOOTNOTES, 134 "noEmptyLineBeforeBlock": mmark.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK, 135 "headerIds": mmark.EXTENSION_HEADER_IDS, 136 "autoHeaderIds": mmark.EXTENSION_AUTO_HEADER_IDS, 137 }