2019-08-16 09:55:03 -04:00
|
|
|
// 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 mmark converts Markdown to HTML using MMark v1.
|
|
|
|
package mmark
|
|
|
|
|
|
|
|
import (
|
2019-11-27 07:42:36 -05:00
|
|
|
"github.com/gohugoio/hugo/identity"
|
2019-11-06 14:10:47 -05:00
|
|
|
"github.com/gohugoio/hugo/markup/blackfriday/blackfriday_config"
|
2019-08-16 09:55:03 -04:00
|
|
|
"github.com/gohugoio/hugo/markup/converter"
|
|
|
|
"github.com/miekg/mmark"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Provider is the package entry point.
|
2019-11-06 14:10:47 -05:00
|
|
|
var Provider converter.ProviderProvider = provider{}
|
2019-08-16 09:55:03 -04:00
|
|
|
|
|
|
|
type provider struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p provider) New(cfg converter.ProviderConfig) (converter.Provider, error) {
|
2019-11-06 14:10:47 -05:00
|
|
|
defaultBlackFriday := cfg.MarkupConfig.BlackFriday
|
2019-08-16 09:55:03 -04:00
|
|
|
defaultExtensions := getMmarkExtensions(defaultBlackFriday)
|
|
|
|
|
2019-11-06 14:10:47 -05:00
|
|
|
return converter.NewProvider("mmark", func(ctx converter.DocumentContext) (converter.Converter, error) {
|
2019-08-16 09:55:03 -04:00
|
|
|
b := defaultBlackFriday
|
|
|
|
extensions := defaultExtensions
|
|
|
|
|
|
|
|
if ctx.ConfigOverrides != nil {
|
|
|
|
var err error
|
2019-11-06 14:10:47 -05:00
|
|
|
b, err = blackfriday_config.UpdateConfig(b, ctx.ConfigOverrides)
|
2019-08-16 09:55:03 -04:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
extensions = getMmarkExtensions(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &mmarkConverter{
|
|
|
|
ctx: ctx,
|
|
|
|
b: b,
|
|
|
|
extensions: extensions,
|
|
|
|
cfg: cfg,
|
|
|
|
}, nil
|
2019-11-06 14:10:47 -05:00
|
|
|
}), nil
|
2019-08-16 09:55:03 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
type mmarkConverter struct {
|
|
|
|
ctx converter.DocumentContext
|
|
|
|
extensions int
|
2019-11-06 14:10:47 -05:00
|
|
|
b blackfriday_config.Config
|
2019-08-16 09:55:03 -04:00
|
|
|
cfg converter.ProviderConfig
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *mmarkConverter) Convert(ctx converter.RenderContext) (converter.Result, error) {
|
|
|
|
r := getHTMLRenderer(c.ctx, c.b, c.cfg)
|
|
|
|
return mmark.Parse(ctx.Src, r, c.extensions), nil
|
|
|
|
}
|
|
|
|
|
2019-11-27 07:42:36 -05:00
|
|
|
func (c *mmarkConverter) Supports(feature identity.Identity) bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2019-08-16 09:55:03 -04:00
|
|
|
func getHTMLRenderer(
|
|
|
|
ctx converter.DocumentContext,
|
2019-11-06 14:10:47 -05:00
|
|
|
cfg blackfriday_config.Config,
|
2019-08-16 09:55:03 -04:00
|
|
|
pcfg converter.ProviderConfig) mmark.Renderer {
|
|
|
|
|
|
|
|
var (
|
|
|
|
flags int
|
|
|
|
documentID string
|
|
|
|
)
|
|
|
|
|
|
|
|
documentID = ctx.DocumentID
|
|
|
|
|
|
|
|
renderParameters := mmark.HtmlRendererParameters{
|
|
|
|
FootnoteAnchorPrefix: cfg.FootnoteAnchorPrefix,
|
|
|
|
FootnoteReturnLinkContents: cfg.FootnoteReturnLinkContents,
|
|
|
|
}
|
|
|
|
|
|
|
|
if documentID != "" && !cfg.PlainIDAnchors {
|
|
|
|
renderParameters.FootnoteAnchorPrefix = documentID + ":" + renderParameters.FootnoteAnchorPrefix
|
|
|
|
}
|
|
|
|
|
|
|
|
htmlFlags := flags
|
|
|
|
htmlFlags |= mmark.HTML_FOOTNOTE_RETURN_LINKS
|
|
|
|
|
|
|
|
return &mmarkRenderer{
|
2019-11-06 14:10:47 -05:00
|
|
|
BlackfridayConfig: cfg,
|
|
|
|
Config: pcfg,
|
|
|
|
Renderer: mmark.HtmlRendererWithParameters(htmlFlags, "", "", renderParameters),
|
2019-08-16 09:55:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-11-06 14:10:47 -05:00
|
|
|
func getMmarkExtensions(cfg blackfriday_config.Config) int {
|
2019-08-16 09:55:03 -04:00
|
|
|
flags := 0
|
|
|
|
flags |= mmark.EXTENSION_TABLES
|
|
|
|
flags |= mmark.EXTENSION_FENCED_CODE
|
|
|
|
flags |= mmark.EXTENSION_AUTOLINK
|
|
|
|
flags |= mmark.EXTENSION_SPACE_HEADERS
|
|
|
|
flags |= mmark.EXTENSION_CITATION
|
|
|
|
flags |= mmark.EXTENSION_TITLEBLOCK_TOML
|
|
|
|
flags |= mmark.EXTENSION_HEADER_IDS
|
|
|
|
flags |= mmark.EXTENSION_AUTO_HEADER_IDS
|
|
|
|
flags |= mmark.EXTENSION_UNIQUE_HEADER_IDS
|
|
|
|
flags |= mmark.EXTENSION_FOOTNOTES
|
|
|
|
flags |= mmark.EXTENSION_SHORT_REF
|
|
|
|
flags |= mmark.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK
|
|
|
|
flags |= mmark.EXTENSION_INCLUDE
|
|
|
|
|
|
|
|
for _, extension := range cfg.Extensions {
|
|
|
|
if flag, ok := mmarkExtensionMap[extension]; ok {
|
|
|
|
flags |= flag
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return flags
|
|
|
|
}
|
|
|
|
|
|
|
|
var mmarkExtensionMap = map[string]int{
|
|
|
|
"tables": mmark.EXTENSION_TABLES,
|
|
|
|
"fencedCode": mmark.EXTENSION_FENCED_CODE,
|
|
|
|
"autolink": mmark.EXTENSION_AUTOLINK,
|
|
|
|
"laxHtmlBlocks": mmark.EXTENSION_LAX_HTML_BLOCKS,
|
|
|
|
"spaceHeaders": mmark.EXTENSION_SPACE_HEADERS,
|
|
|
|
"hardLineBreak": mmark.EXTENSION_HARD_LINE_BREAK,
|
|
|
|
"footnotes": mmark.EXTENSION_FOOTNOTES,
|
|
|
|
"noEmptyLineBeforeBlock": mmark.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK,
|
|
|
|
"headerIds": mmark.EXTENSION_HEADER_IDS,
|
|
|
|
"autoHeaderIds": mmark.EXTENSION_AUTO_HEADER_IDS,
|
|
|
|
}
|