mirror of
https://github.com/kovetskiy/mark.git
synced 2025-01-23 09:13:49 +08:00
Feat: Use custom heading anchors
Confluence Anchors are case-sensitive.
This commit is contained in:
parent
e7a3877ded
commit
876626098b
@ -91,8 +91,10 @@ func CompileMarkdown(markdown []byte, stdlib *stdlib.Lib, path string, mermaidPr
|
||||
html.WithXHTML(),
|
||||
))
|
||||
|
||||
ctx := parser.NewContext(parser.WithIDs(&cparser.ConfluenceIDs{Values: map[string]bool{}}))
|
||||
|
||||
var buf bytes.Buffer
|
||||
err := converter.Convert(markdown, &buf)
|
||||
err := converter.Convert(markdown, &buf, parser.WithContext(ctx))
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
56
parser/confluenceids.go
Normal file
56
parser/confluenceids.go
Normal file
@ -0,0 +1,56 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/yuin/goldmark/ast"
|
||||
"github.com/yuin/goldmark/util"
|
||||
)
|
||||
|
||||
type ConfluenceIDs struct {
|
||||
Values map[string]bool
|
||||
}
|
||||
|
||||
|
||||
// https://github.com/yuin/goldmark/blob/d9c03f07f08c2d36f23afe52dda865f05320ac86/parser/parser.go#L75
|
||||
func (s *ConfluenceIDs) Generate(value []byte, kind ast.NodeKind) []byte {
|
||||
value = util.TrimLeftSpace(value)
|
||||
value = util.TrimRightSpace(value)
|
||||
result := []byte{}
|
||||
for i := 0; i < len(value); {
|
||||
v := value[i]
|
||||
l := util.UTF8Len(v)
|
||||
i += int(l)
|
||||
if l != 1 {
|
||||
continue
|
||||
}
|
||||
if util.IsAlphaNumeric(v) || v == '/' || v == '_' || v == '.' {
|
||||
result = append(result, v)
|
||||
} else if util.IsSpace(v) || v == '-' {
|
||||
result = append(result, '-')
|
||||
}
|
||||
}
|
||||
if len(result) == 0 {
|
||||
if kind == ast.KindHeading {
|
||||
result = []byte("heading")
|
||||
} else {
|
||||
result = []byte("id")
|
||||
}
|
||||
}
|
||||
if _, ok := s.Values[util.BytesToReadOnlyString(result)]; !ok {
|
||||
s.Values[util.BytesToReadOnlyString(result)] = true
|
||||
return result
|
||||
}
|
||||
for i := 1; ; i++ {
|
||||
newResult := fmt.Sprintf("%s-%d", result, i)
|
||||
if _, ok := s.Values[newResult]; !ok {
|
||||
s.Values[newResult] = true
|
||||
return []byte(newResult)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ConfluenceIDs) Put(value []byte) {
|
||||
s.Values[util.BytesToReadOnlyString(value)] = true
|
||||
}
|
1
testdata/header-droph1.html
vendored
1
testdata/header-droph1.html
vendored
@ -4,3 +4,4 @@
|
||||
<h5 id="e">e</h5>
|
||||
<h1 id="f">f</h1>
|
||||
<h2 id="g">g</h2>
|
||||
<h1 id="This/is-some_Heading.yml">This/is some_Heading.yml</h1>
|
||||
|
1
testdata/header.html
vendored
1
testdata/header.html
vendored
@ -5,3 +5,4 @@
|
||||
<h5 id="e">e</h5>
|
||||
<h1 id="f">f</h1>
|
||||
<h2 id="g">g</h2>
|
||||
<h1 id="This/is-some_Heading.yml">This/is some_Heading.yml</h1>
|
||||
|
2
testdata/header.md
vendored
2
testdata/header.md
vendored
@ -8,3 +8,5 @@ f
|
||||
=
|
||||
g
|
||||
-
|
||||
|
||||
# This/is some_Heading.yml
|
||||
|
22
testdata/quotes-droph1.html
vendored
22
testdata/quotes-droph1.html
vendored
@ -1,4 +1,4 @@
|
||||
<h2 id="first-heading">First Heading</h2>
|
||||
<h2 id="First-Heading">First Heading</h2>
|
||||
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p><strong>NOTES:</strong></p>
|
||||
<ol>
|
||||
@ -11,7 +11,7 @@ b</p>
|
||||
</blockquote>
|
||||
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h2 id="second-heading">Second Heading</h2>
|
||||
<h2 id="Second-Heading">Second Heading</h2>
|
||||
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p><strong>Warn</strong></p>
|
||||
<ul>
|
||||
@ -23,12 +23,12 @@ b</p>
|
||||
<li>Regular list
|
||||
that runs long</li>
|
||||
</ul>
|
||||
<h2 id="third-heading">Third Heading</h2>
|
||||
<h2 id="Third-Heading">Third Heading</h2>
|
||||
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<!-- Info -->
|
||||
<p>Test</p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h2 id="fourth-heading---warn-should-not-get-picked-as-block-quote">Fourth Heading - Warn should not get picked as block quote</h2>
|
||||
<h2 id="Fourth-Heading---Warn-should-not-get-picked-as-block-quote">Fourth Heading - Warn should not get picked as block quote</h2>
|
||||
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p><strong>TIP:</strong></p>
|
||||
<ol>
|
||||
@ -41,12 +41,12 @@ b</p>
|
||||
</blockquote>
|
||||
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h2 id="simple-blockquote">Simple Blockquote</h2>
|
||||
<h2 id="Simple-Blockquote">Simple Blockquote</h2>
|
||||
<blockquote>
|
||||
<p>This paragraph is a simple blockquote</p>
|
||||
</blockquote>
|
||||
<h2 id="gh-alerts-heading">GH Alerts Heading</h2>
|
||||
<h3 id="note-type-alert-heading">Note Type Alert Heading</h3>
|
||||
<h2 id="GH-Alerts-Heading">GH Alerts Heading</h2>
|
||||
<h3 id="Note-Type-Alert-Heading">Note Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!NOTE]</p>
|
||||
<ul>
|
||||
@ -54,7 +54,7 @@ b</p>
|
||||
<li>Note bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="tip-type-alert-heading">Tip Type Alert Heading</h3>
|
||||
<h3 id="Tip-Type-Alert-Heading">Tip Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!TIP]</p>
|
||||
<ul>
|
||||
@ -62,7 +62,7 @@ b</p>
|
||||
<li>Tip bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="warning-type-alert-heading">Warning Type Alert Heading</h3>
|
||||
<h3 id="Warning-Type-Alert-Heading">Warning Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!WARNING]</p>
|
||||
<ul>
|
||||
@ -70,7 +70,7 @@ b</p>
|
||||
<li>Warning bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="importantcaution-type-alert-heading">Important/Caution Type Alert Heading</h3>
|
||||
<h3 id="Important/Caution-Type-Alert-Heading">Important/Caution Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!IMPORTANT]</p>
|
||||
<ul>
|
||||
@ -85,7 +85,7 @@ b</p>
|
||||
<li>Important bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="should-not-be-picked-up-and-converted-into-blockquote-macro">Should not be picked up and converted into blockquote macro</h3>
|
||||
<h3 id="Should-not-be-picked-up-and-converted-into-blockquote-macro">Should not be picked up and converted into blockquote macro</h3>
|
||||
<blockquote>
|
||||
<p>[[!NOTE]</p>
|
||||
</blockquote>
|
||||
|
24
testdata/quotes-stripnewlines.html
vendored
24
testdata/quotes-stripnewlines.html
vendored
@ -1,5 +1,5 @@
|
||||
<h1 id="main-heading">Main Heading</h1>
|
||||
<h2 id="first-heading">First Heading</h2>
|
||||
<h1 id="Main-Heading">Main Heading</h1>
|
||||
<h2 id="First-Heading">First Heading</h2>
|
||||
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p><strong>NOTES:</strong></p>
|
||||
<ol>
|
||||
@ -11,7 +11,7 @@
|
||||
</blockquote>
|
||||
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h2 id="second-heading">Second Heading</h2>
|
||||
<h2 id="Second-Heading">Second Heading</h2>
|
||||
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p><strong>Warn</strong></p>
|
||||
<ul>
|
||||
@ -22,12 +22,12 @@
|
||||
<ul>
|
||||
<li>Regular list that runs long</li>
|
||||
</ul>
|
||||
<h2 id="third-heading">Third Heading</h2>
|
||||
<h2 id="Third-Heading">Third Heading</h2>
|
||||
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<!-- Info -->
|
||||
<p>Test</p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h2 id="fourth-heading---warn-should-not-get-picked-as-block-quote">Fourth Heading - Warn should not get picked as block quote</h2>
|
||||
<h2 id="Fourth-Heading---Warn-should-not-get-picked-as-block-quote">Fourth Heading - Warn should not get picked as block quote</h2>
|
||||
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p><strong>TIP:</strong></p>
|
||||
<ol>
|
||||
@ -39,12 +39,12 @@
|
||||
</blockquote>
|
||||
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h2 id="simple-blockquote">Simple Blockquote</h2>
|
||||
<h2 id="Simple-Blockquote">Simple Blockquote</h2>
|
||||
<blockquote>
|
||||
<p>This paragraph is a simple blockquote</p>
|
||||
</blockquote>
|
||||
<h2 id="gh-alerts-heading">GH Alerts Heading</h2>
|
||||
<h3 id="note-type-alert-heading">Note Type Alert Heading</h3>
|
||||
<h2 id="GH-Alerts-Heading">GH Alerts Heading</h2>
|
||||
<h3 id="Note-Type-Alert-Heading">Note Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!NOTE]</p>
|
||||
<ul>
|
||||
@ -52,7 +52,7 @@
|
||||
<li>Note bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="tip-type-alert-heading">Tip Type Alert Heading</h3>
|
||||
<h3 id="Tip-Type-Alert-Heading">Tip Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!TIP]</p>
|
||||
<ul>
|
||||
@ -60,7 +60,7 @@
|
||||
<li>Tip bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="warning-type-alert-heading">Warning Type Alert Heading</h3>
|
||||
<h3 id="Warning-Type-Alert-Heading">Warning Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!WARNING]</p>
|
||||
<ul>
|
||||
@ -68,7 +68,7 @@
|
||||
<li>Warning bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="importantcaution-type-alert-heading">Important/Caution Type Alert Heading</h3>
|
||||
<h3 id="Important/Caution-Type-Alert-Heading">Important/Caution Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!IMPORTANT]</p>
|
||||
<ul>
|
||||
@ -83,7 +83,7 @@
|
||||
<li>Important bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="should-not-be-picked-up-and-converted-into-blockquote-macro">Should not be picked up and converted into blockquote macro</h3>
|
||||
<h3 id="Should-not-be-picked-up-and-converted-into-blockquote-macro">Should not be picked up and converted into blockquote macro</h3>
|
||||
<blockquote>
|
||||
<p>[[!NOTE]</p>
|
||||
</blockquote>
|
||||
|
24
testdata/quotes.html
vendored
24
testdata/quotes.html
vendored
@ -1,5 +1,5 @@
|
||||
<h1 id="main-heading">Main Heading</h1>
|
||||
<h2 id="first-heading">First Heading</h2>
|
||||
<h1 id="Main-Heading">Main Heading</h1>
|
||||
<h2 id="First-Heading">First Heading</h2>
|
||||
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p><strong>NOTES:</strong></p>
|
||||
<ol>
|
||||
@ -12,7 +12,7 @@ b</p>
|
||||
</blockquote>
|
||||
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h2 id="second-heading">Second Heading</h2>
|
||||
<h2 id="Second-Heading">Second Heading</h2>
|
||||
<ac:structured-macro ac:name="warning"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p><strong>Warn</strong></p>
|
||||
<ul>
|
||||
@ -24,12 +24,12 @@ b</p>
|
||||
<li>Regular list
|
||||
that runs long</li>
|
||||
</ul>
|
||||
<h2 id="third-heading">Third Heading</h2>
|
||||
<h2 id="Third-Heading">Third Heading</h2>
|
||||
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<!-- Info -->
|
||||
<p>Test</p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h2 id="fourth-heading---warn-should-not-get-picked-as-block-quote">Fourth Heading - Warn should not get picked as block quote</h2>
|
||||
<h2 id="Fourth-Heading---Warn-should-not-get-picked-as-block-quote">Fourth Heading - Warn should not get picked as block quote</h2>
|
||||
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p><strong>TIP:</strong></p>
|
||||
<ol>
|
||||
@ -42,12 +42,12 @@ b</p>
|
||||
</blockquote>
|
||||
<p><strong>Warn (Should not be picked as blockquote type)</strong></p>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h2 id="simple-blockquote">Simple Blockquote</h2>
|
||||
<h2 id="Simple-Blockquote">Simple Blockquote</h2>
|
||||
<blockquote>
|
||||
<p>This paragraph is a simple blockquote</p>
|
||||
</blockquote>
|
||||
<h2 id="gh-alerts-heading">GH Alerts Heading</h2>
|
||||
<h3 id="note-type-alert-heading">Note Type Alert Heading</h3>
|
||||
<h2 id="GH-Alerts-Heading">GH Alerts Heading</h2>
|
||||
<h3 id="Note-Type-Alert-Heading">Note Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!NOTE]</p>
|
||||
<ul>
|
||||
@ -55,7 +55,7 @@ b</p>
|
||||
<li>Note bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="tip-type-alert-heading">Tip Type Alert Heading</h3>
|
||||
<h3 id="Tip-Type-Alert-Heading">Tip Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="tip"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!TIP]</p>
|
||||
<ul>
|
||||
@ -63,7 +63,7 @@ b</p>
|
||||
<li>Tip bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="warning-type-alert-heading">Warning Type Alert Heading</h3>
|
||||
<h3 id="Warning-Type-Alert-Heading">Warning Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="note"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!WARNING]</p>
|
||||
<ul>
|
||||
@ -71,7 +71,7 @@ b</p>
|
||||
<li>Warning bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="importantcaution-type-alert-heading">Important/Caution Type Alert Heading</h3>
|
||||
<h3 id="Important/Caution-Type-Alert-Heading">Important/Caution Type Alert Heading</h3>
|
||||
<ac:structured-macro ac:name="info"><ac:parameter ac:name="icon">true</ac:parameter><ac:rich-text-body>
|
||||
<p>[!IMPORTANT]</p>
|
||||
<ul>
|
||||
@ -86,7 +86,7 @@ b</p>
|
||||
<li>Important bullet 2</li>
|
||||
</ul>
|
||||
</ac:rich-text-body></ac:structured-macro>
|
||||
<h3 id="should-not-be-picked-up-and-converted-into-blockquote-macro">Should not be picked up and converted into blockquote macro</h3>
|
||||
<h3 id="Should-not-be-picked-up-and-converted-into-blockquote-macro">Should not be picked up and converted into blockquote macro</h3>
|
||||
<blockquote>
|
||||
<p>[[!NOTE]</p>
|
||||
</blockquote>
|
||||
|
Loading…
Reference in New Issue
Block a user