| 
									
										
										
										
											2019-11-06 20:10:47 +01: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 goldmark converts Markdown to HTML using Goldmark.
 | 
					
						
							|  |  |  | package goldmark
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import (
 | 
					
						
							|  |  |  | 	"bytes"
 | 
					
						
							|  |  |  | 	"fmt"
 | 
					
						
							| 
									
										
										
										
											2019-12-18 17:23:09 +01:00
										 |  |  | 	"math/bits"
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 	"path/filepath"
 | 
					
						
							| 
									
										
										
										
											2019-11-25 18:41:46 +01:00
										 |  |  | 	"runtime/debug"
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 18:08:46 +01:00
										 |  |  | 	"github.com/gohugoio/hugo/markup/goldmark/internal/extensions/attributes"
 | 
					
						
							| 
									
										
										
										
											2021-02-23 18:04:05 +01:00
										 |  |  | 	"github.com/yuin/goldmark/ast"
 | 
					
						
							| 
									
										
										
										
											2021-02-07 18:08:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | 	"github.com/gohugoio/hugo/identity"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 	"github.com/pkg/errors"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/spf13/afero"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/gohugoio/hugo/hugofs"
 | 
					
						
							|  |  |  | 	"github.com/gohugoio/hugo/markup/converter"
 | 
					
						
							|  |  |  | 	"github.com/gohugoio/hugo/markup/highlight"
 | 
					
						
							|  |  |  | 	"github.com/gohugoio/hugo/markup/tableofcontents"
 | 
					
						
							|  |  |  | 	"github.com/yuin/goldmark"
 | 
					
						
							| 
									
										
										
										
											2019-11-24 13:56:37 +01:00
										 |  |  | 	hl "github.com/yuin/goldmark-highlighting"
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 	"github.com/yuin/goldmark/extension"
 | 
					
						
							|  |  |  | 	"github.com/yuin/goldmark/parser"
 | 
					
						
							|  |  |  | 	"github.com/yuin/goldmark/renderer"
 | 
					
						
							|  |  |  | 	"github.com/yuin/goldmark/renderer/html"
 | 
					
						
							|  |  |  | 	"github.com/yuin/goldmark/text"
 | 
					
						
							|  |  |  | 	"github.com/yuin/goldmark/util"
 | 
					
						
							|  |  |  | )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Provider is the package entry point.
 | 
					
						
							|  |  |  | var Provider converter.ProviderProvider = provide{}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type provide struct {
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (p provide) New(cfg converter.ProviderConfig) (converter.Provider, error) {
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | 	md := newMarkdown(cfg)
 | 
					
						
							| 
									
										
										
										
											2020-01-04 11:28:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 	return converter.NewProvider("goldmark", func(ctx converter.DocumentContext) (converter.Converter, error) {
 | 
					
						
							|  |  |  | 		return &goldmarkConverter{
 | 
					
						
							|  |  |  | 			ctx: ctx,
 | 
					
						
							|  |  |  | 			cfg: cfg,
 | 
					
						
							|  |  |  | 			md:  md,
 | 
					
						
							| 
									
										
										
										
											2020-01-04 11:28:19 +01:00
										 |  |  | 			sanitizeAnchorName: func(s string) string {
 | 
					
						
							| 
									
										
										
										
											2020-01-05 11:52:00 +01:00
										 |  |  | 				return sanitizeAnchorNameString(s, cfg.MarkupConfig.Goldmark.Parser.AutoHeadingIDType)
 | 
					
						
							| 
									
										
										
										
											2020-01-04 11:28:19 +01:00
										 |  |  | 			},
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 		}, nil
 | 
					
						
							|  |  |  | 	}), nil
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-02 13:23:25 +01:00
										 |  |  | var _ converter.AnchorNameSanitizer = (*goldmarkConverter)(nil)
 | 
					
						
							| 
									
										
										
										
											2020-01-04 11:28:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | type goldmarkConverter struct {
 | 
					
						
							|  |  |  | 	md  goldmark.Markdown
 | 
					
						
							|  |  |  | 	ctx converter.DocumentContext
 | 
					
						
							|  |  |  | 	cfg converter.ProviderConfig
 | 
					
						
							| 
									
										
										
										
											2020-01-04 11:28:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	sanitizeAnchorName func(s string) string
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *goldmarkConverter) SanitizeAnchorName(s string) string {
 | 
					
						
							|  |  |  | 	return c.sanitizeAnchorName(s)
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | func newMarkdown(pcfg converter.ProviderConfig) goldmark.Markdown {
 | 
					
						
							|  |  |  | 	mcfg := pcfg.MarkupConfig
 | 
					
						
							|  |  |  | 	cfg := pcfg.MarkupConfig.Goldmark
 | 
					
						
							| 
									
										
										
										
											2020-02-23 02:06:30 +09:00
										 |  |  | 	var rendererOptions []renderer.Option
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Renderer.HardWraps {
 | 
					
						
							|  |  |  | 		rendererOptions = append(rendererOptions, html.WithHardWraps())
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Renderer.XHTML {
 | 
					
						
							|  |  |  | 		rendererOptions = append(rendererOptions, html.WithXHTML())
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Renderer.Unsafe {
 | 
					
						
							|  |  |  | 		rendererOptions = append(rendererOptions, html.WithUnsafe())
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-23 02:06:30 +09:00
										 |  |  | 	var (
 | 
					
						
							|  |  |  | 		extensions = []goldmark.Extender{
 | 
					
						
							|  |  |  | 			newLinks(),
 | 
					
						
							|  |  |  | 			newTocExtension(rendererOptions),
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 		parserOptions []parser.Option
 | 
					
						
							|  |  |  | 	)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 	if mcfg.Highlight.CodeFences {
 | 
					
						
							|  |  |  | 		extensions = append(extensions, newHighlighting(mcfg.Highlight))
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Extensions.Table {
 | 
					
						
							|  |  |  | 		extensions = append(extensions, extension.Table)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Extensions.Strikethrough {
 | 
					
						
							|  |  |  | 		extensions = append(extensions, extension.Strikethrough)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Extensions.Linkify {
 | 
					
						
							|  |  |  | 		extensions = append(extensions, extension.Linkify)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Extensions.TaskList {
 | 
					
						
							|  |  |  | 		extensions = append(extensions, extension.TaskList)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Extensions.Typographer {
 | 
					
						
							|  |  |  | 		extensions = append(extensions, extension.Typographer)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Extensions.DefinitionList {
 | 
					
						
							|  |  |  | 		extensions = append(extensions, extension.DefinitionList)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Extensions.Footnote {
 | 
					
						
							|  |  |  | 		extensions = append(extensions, extension.Footnote)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if cfg.Parser.AutoHeadingID {
 | 
					
						
							|  |  |  | 		parserOptions = append(parserOptions, parser.WithAutoHeadingID())
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 18:08:46 +01:00
										 |  |  | 	if cfg.Parser.Attribute.Title {
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 		parserOptions = append(parserOptions, parser.WithAttribute())
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-07 18:08:46 +01:00
										 |  |  | 	if cfg.Parser.Attribute.Block {
 | 
					
						
							|  |  |  | 		extensions = append(extensions, attributes.New())
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 	md := goldmark.New(
 | 
					
						
							|  |  |  | 		goldmark.WithExtensions(
 | 
					
						
							|  |  |  | 			extensions...,
 | 
					
						
							|  |  |  | 		),
 | 
					
						
							|  |  |  | 		goldmark.WithParserOptions(
 | 
					
						
							|  |  |  | 			parserOptions...,
 | 
					
						
							|  |  |  | 		),
 | 
					
						
							|  |  |  | 		goldmark.WithRendererOptions(
 | 
					
						
							|  |  |  | 			rendererOptions...,
 | 
					
						
							|  |  |  | 		),
 | 
					
						
							|  |  |  | 	)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return md
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | var _ identity.IdentitiesProvider = (*converterResult)(nil)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | type converterResult struct {
 | 
					
						
							|  |  |  | 	converter.Result
 | 
					
						
							|  |  |  | 	toc tableofcontents.Root
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | 	ids identity.Identities
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c converterResult) TableOfContents() tableofcontents.Root {
 | 
					
						
							|  |  |  | 	return c.toc
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | func (c converterResult) GetIdentities() identity.Identities {
 | 
					
						
							|  |  |  | 	return c.ids
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 17:23:09 +01:00
										 |  |  | type bufWriter struct {
 | 
					
						
							|  |  |  | 	*bytes.Buffer
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const maxInt = 1<<(bits.UintSize-1) - 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (b *bufWriter) Available() int {
 | 
					
						
							|  |  |  | 	return maxInt
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (b *bufWriter) Buffered() int {
 | 
					
						
							|  |  |  | 	return b.Len()
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (b *bufWriter) Flush() error {
 | 
					
						
							|  |  |  | 	return nil
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | type renderContext struct {
 | 
					
						
							| 
									
										
										
										
											2019-12-18 17:23:09 +01:00
										 |  |  | 	*bufWriter
 | 
					
						
							|  |  |  | 	pos int
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | 	renderContextData
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type renderContextData interface {
 | 
					
						
							|  |  |  | 	RenderContext() converter.RenderContext
 | 
					
						
							|  |  |  | 	DocumentContext() converter.DocumentContext
 | 
					
						
							| 
									
										
										
										
											2020-11-26 08:32:49 +01:00
										 |  |  | 	AddIdentity(id identity.Provider)
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-26 08:32:49 +01:00
										 |  |  | func (ctx *renderContextDataHolder) AddIdentity(id identity.Provider) {
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | 	ctx.ids.Add(id)
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var converterIdentity = identity.KeyValueIdentity{Key: "goldmark", Value: "converter"}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | func (c *goldmarkConverter) Convert(ctx converter.RenderContext) (result converter.Result, err error) {
 | 
					
						
							|  |  |  | 	defer func() {
 | 
					
						
							|  |  |  | 		if r := recover(); r != nil {
 | 
					
						
							|  |  |  | 			dir := afero.GetTempDir(hugofs.Os, "hugo_bugs")
 | 
					
						
							|  |  |  | 			name := fmt.Sprintf("goldmark_%s.txt", c.ctx.DocumentID)
 | 
					
						
							|  |  |  | 			filename := filepath.Join(dir, name)
 | 
					
						
							|  |  |  | 			afero.WriteFile(hugofs.Os, filename, ctx.Src, 07555)
 | 
					
						
							| 
									
										
										
										
											2019-11-25 18:41:46 +01:00
										 |  |  | 			fmt.Print(string(debug.Stack()))
 | 
					
						
							| 
									
										
										
										
											2019-11-25 12:49:04 +01:00
										 |  |  | 			err = errors.Errorf("[BUG] goldmark: %s: create an issue on GitHub attaching the file in: %s", r, filename)
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 		}
 | 
					
						
							|  |  |  | 	}()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 17:23:09 +01:00
										 |  |  | 	buf := &bufWriter{Buffer: &bytes.Buffer{}}
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 	result = buf
 | 
					
						
							| 
									
										
										
										
											2020-01-04 11:28:19 +01:00
										 |  |  | 	pctx := c.newParserContext(ctx)
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 	reader := text.NewReader(ctx.Src)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	doc := c.md.Parser().Parse(
 | 
					
						
							|  |  |  | 		reader,
 | 
					
						
							|  |  |  | 		parser.WithContext(pctx),
 | 
					
						
							|  |  |  | 	)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | 	rcx := &renderContextDataHolder{
 | 
					
						
							|  |  |  | 		rctx: ctx,
 | 
					
						
							|  |  |  | 		dctx: c.ctx,
 | 
					
						
							|  |  |  | 		ids:  identity.NewManager(converterIdentity),
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 17:23:09 +01:00
										 |  |  | 	w := &renderContext{
 | 
					
						
							|  |  |  | 		bufWriter:         buf,
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | 		renderContextData: rcx,
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := c.md.Renderer().Render(w, ctx.Src, doc); err != nil {
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 		return nil, err
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | 	return converterResult{
 | 
					
						
							|  |  |  | 		Result: buf,
 | 
					
						
							|  |  |  | 		ids:    rcx.ids.GetIdentities(),
 | 
					
						
							|  |  |  | 		toc:    pctx.TableOfContents(),
 | 
					
						
							|  |  |  | 	}, nil
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var featureSet = map[identity.Identity]bool{
 | 
					
						
							|  |  |  | 	converter.FeatureRenderHooks: true,
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *goldmarkConverter) Supports(feature identity.Identity) bool {
 | 
					
						
							|  |  |  | 	return featureSet[feature.GetIdentity()]
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-04 11:28:19 +01:00
										 |  |  | func (c *goldmarkConverter) newParserContext(rctx converter.RenderContext) *parserContext {
 | 
					
						
							| 
									
										
										
										
											2020-01-05 11:29:22 +01:00
										 |  |  | 	ctx := parser.NewContext(parser.WithIDs(newIDFactory(c.cfg.MarkupConfig.Goldmark.Parser.AutoHeadingIDType)))
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | 	ctx.Set(tocEnableKey, rctx.RenderTOC)
 | 
					
						
							|  |  |  | 	return &parserContext{
 | 
					
						
							|  |  |  | 		Context: ctx,
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | }
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | type parserContext struct {
 | 
					
						
							|  |  |  | 	parser.Context
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | func (p *parserContext) TableOfContents() tableofcontents.Root {
 | 
					
						
							|  |  |  | 	if v := p.Get(tocResultKey); v != nil {
 | 
					
						
							|  |  |  | 		return v.(tableofcontents.Root)
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 	}
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | 	return tableofcontents.Root{}
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-27 13:42:36 +01:00
										 |  |  | func newHighlighting(cfg highlight.Config) goldmark.Extender {
 | 
					
						
							|  |  |  | 	return hl.NewHighlighting(
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 		hl.WithStyle(cfg.Style),
 | 
					
						
							| 
									
										
										
										
											2019-12-02 08:31:23 +01:00
										 |  |  | 		hl.WithGuessLanguage(cfg.GuessSyntax),
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 		hl.WithCodeBlockOptions(highlight.GetCodeBlockOptions()),
 | 
					
						
							|  |  |  | 		hl.WithFormatOptions(
 | 
					
						
							|  |  |  | 			cfg.ToHTMLOptions()...,
 | 
					
						
							|  |  |  | 		),
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		hl.WithWrapperRenderer(func(w util.BufWriter, ctx hl.CodeBlockContext, entering bool) {
 | 
					
						
							|  |  |  | 			l, hasLang := ctx.Language()
 | 
					
						
							|  |  |  | 			var language string
 | 
					
						
							|  |  |  | 			if hasLang {
 | 
					
						
							|  |  |  | 				language = string(l)
 | 
					
						
							|  |  |  | 			}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if entering {
 | 
					
						
							|  |  |  | 				if !ctx.Highlighted() {
 | 
					
						
							|  |  |  | 					w.WriteString(`<pre>`)
 | 
					
						
							|  |  |  | 					highlight.WriteCodeTag(w, language)
 | 
					
						
							|  |  |  | 					return
 | 
					
						
							|  |  |  | 				}
 | 
					
						
							| 
									
										
										
										
											2021-02-23 18:04:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				w.WriteString(`<div class="highlight`)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				var attributes []ast.Attribute
 | 
					
						
							|  |  |  | 				if ctx.Attributes() != nil {
 | 
					
						
							|  |  |  | 					attributes = ctx.Attributes().All()
 | 
					
						
							|  |  |  | 				}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if attributes != nil {
 | 
					
						
							|  |  |  | 					class, found := ctx.Attributes().GetString("class")
 | 
					
						
							|  |  |  | 					if found {
 | 
					
						
							|  |  |  | 						w.WriteString(" ")
 | 
					
						
							|  |  |  | 						w.Write(util.EscapeHTML(class.([]byte)))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					}
 | 
					
						
							|  |  |  | 					_, _ = w.WriteString("\"")
 | 
					
						
							|  |  |  | 					renderAttributes(w, true, attributes...)
 | 
					
						
							|  |  |  | 				} else {
 | 
					
						
							|  |  |  | 					_, _ = w.WriteString("\"")
 | 
					
						
							|  |  |  | 				}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				w.WriteString(">")
 | 
					
						
							| 
									
										
										
										
											2019-11-06 20:10:47 +01:00
										 |  |  | 				return
 | 
					
						
							|  |  |  | 			}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if !ctx.Highlighted() {
 | 
					
						
							|  |  |  | 				w.WriteString(`</code></pre>`)
 | 
					
						
							|  |  |  | 				return
 | 
					
						
							|  |  |  | 			}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			w.WriteString("</div>")
 | 
					
						
							|  |  |  | 		}),
 | 
					
						
							|  |  |  | 	)
 | 
					
						
							|  |  |  | }
 |