From 26fb0b56e6c4f97b3245323a0553f5aff0b8d1b7 Mon Sep 17 00:00:00 2001
From: yuin
Date: Wed, 18 Dec 2019 15:46:54 +0900
Subject: [PATCH] Fixes gohugoio/hugo#6626
---
README.md | 77 +++++++++++++++++++++++++++++++++++----------
_test/extra.txt | 8 +++++
parser/delimiter.go | 21 +++++++------
3 files changed, 81 insertions(+), 25 deletions(-)
diff --git a/README.md b/README.md
index d98ba47..9e61344 100644
--- a/README.md
+++ b/README.md
@@ -91,7 +91,15 @@ if err := goldmark.Convert(source, &buf, parser.WithContext(ctx)); err != nil {
| Functional option | Type | Description |
| ----------------- | ---- | ----------- |
-| `parser.WithContext` | A parser.Context | Context for the parsing phase. |
+| `parser.WithContext` | A `parser.Context` | Context for the parsing phase. |
+
+Context options
+----------------------
+
+| Functional option | Type | Description |
+| ----------------- | ---- | ----------- |
+| `parser.WithIDs` | A `parser.IDs` | `IDs` allows you to change logics that are related to element id(ex: Auto heading id generation). |
+
Custom parser and renderer
--------------------------
@@ -130,6 +138,7 @@ Parser and Renderer options
| `parser.WithBlockParsers` | A `util.PrioritizedSlice` whose elements are `parser.BlockParser` | Parsers for parsing block level elements. |
| `parser.WithInlineParsers` | A `util.PrioritizedSlice` whose elements are `parser.InlineParser` | Parsers for parsing inline level elements. |
| `parser.WithParagraphTransformers` | A `util.PrioritizedSlice` whose elements are `parser.ParagraphTransformer` | Transformers for transforming paragraph nodes. |
+| `parser.WithASTTransformers` | A `util.PrioritizedSlice` whose elements are `parser.ASTTransformer` | Transformers for transforming an AST. |
| `parser.WithAutoHeadingID` | `-` | Enables auto heading ids. |
| `parser.WithAttribute` | `-` | Enables custom attributes. Currently only headings supports attributes. |
@@ -217,21 +226,6 @@ markdown := goldmark.New(
)
```
-
-
-Create extensions
---------------------
-**TODO**
-
-See `extension` directory for examples of extensions.
-
-Summary:
-
-1. Define AST Node as a struct in which `ast.BaseBlock` or `ast.BaseInline` is embedded.
-2. Write a parser that implements `parser.BlockParser` or `parser.InlineParser`.
-3. Write a renderer that implements `renderer.NodeRenderer`.
-4. Define your goldmark extension that implements `goldmark.Extender`.
-
Security
--------------------
By default, goldmark does not render raw HTML and potentially dangerous URLs.
@@ -285,6 +279,57 @@ Extensions
for the goldmark markdown parser.
- [goldmark-mathjax](https://github.com/litao91/goldmark-mathjax): Mathjax support for goldmark markdown parser
+goldmark internal(for extension developers)
+----------------------------------------------
+### Overview
+goldmark's Markdown processing is outlined as a bellow diagram.
+
+```
+
+ |
+ V
+ +-------- parser.Parser ---------------------------
+ | 1. Parse block elements into AST
+ | 1. If a parsed block is a paragraph, apply
+ | ast.ParagraphTransformer
+ | 2. Traverse AST and parse blocks.
+ | 1. Process delimiters(emphasis) at the end of
+ | block parsing
+ | 3. Apply parser.ASTTransformers to AST
+ |
+ V
+
+ |
+ V
+ +------- renderer.Renderer ------------------------
+ | 1. Traverse AST and apply renderer.NodeRenderer
+ | corespond to the node type
+
+ |
+ V
+
test
atest
//= = = = = = = = = = = = = = = = = = = = = = = =//
+
+
+5
+//- - - - - - - - -//
+_**TL/DR** - [Go see summary.](#my-summary-area)_
+//- - - - - - - - -//
+TL/DR - Go see summary.
+//= = = = = = = = = = = = = = = = = = = = = = = =//
diff --git a/parser/delimiter.go b/parser/delimiter.go
index 0cdaab3..50aa7bd 100644
--- a/parser/delimiter.go
+++ b/parser/delimiter.go
@@ -156,20 +156,23 @@ func ScanDelimiter(line []byte, before rune, min int, processor DelimiterProcess
// If you implement an inline parser that can have other inline nodes as
// children, you should call this function when nesting span has closed.
func ProcessDelimiters(bottom ast.Node, pc Context) {
- if pc.LastDelimiter() == nil {
+ lastDelimiter := pc.LastDelimiter()
+ if lastDelimiter == nil {
return
}
var closer *Delimiter
if bottom != nil {
- for c := pc.LastDelimiter().PreviousSibling(); c != nil; {
- if d, ok := c.(*Delimiter); ok {
- closer = d
- }
- prev := c.PreviousSibling()
- if prev == bottom {
- break
+ if bottom != lastDelimiter {
+ for c := lastDelimiter.PreviousSibling(); c != nil; {
+ if d, ok := c.(*Delimiter); ok {
+ closer = d
+ }
+ prev := c.PreviousSibling()
+ if prev == bottom {
+ break
+ }
+ c = prev
}
- c = prev
}
} else {
closer = pc.FirstDelimiter()