-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgfm_ids.go
84 lines (69 loc) · 1.46 KB
/
gfm_ids.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package md2html
import (
"bytes"
"fmt"
"unicode"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
"golang.org/x/text/unicode/norm"
)
type GfmIDs struct {
values map[string]bool
}
func init() {
AutoIdsMap["gfm"] = NewGfmIDs
}
func NewGfmIDs() parser.IDs {
return &GfmIDs{
values: map[string]bool{},
}
}
func (ids *GfmIDs) toText(value []byte) []byte {
var txt_buf bytes.Buffer
err := convertMdToText(value, &txt_buf)
if err != nil {
return []byte("auto")
}
return txt_buf.Bytes()
}
func (ids *GfmIDs) toValid(value []byte) []byte {
ancher := make([]byte, 0, len(value))
dash_mode := false
for _, r := range string(value) {
if unicode.IsLetter(r) || unicode.IsNumber(r) {
if dash_mode && len(ancher) > 0 {
ancher = append(ancher, '-')
}
dash_mode = false
ancher = append(ancher, string(unicode.ToLower(r))...)
} else {
dash_mode = true
}
}
return ancher
}
func (ids *GfmIDs) Generate(value []byte, kind ast.NodeKind) []byte {
value = ids.toText(value)
value = ids.toValid(value)
value = norm.NFC.Bytes(value)
if len(value) == 0 {
value = []byte("header")
}
if _, ok := ids.values[string(value)]; !ok {
ids.Put(value)
return value
}
rewrite:
for i := 1; ; i++ {
new_id := fmt.Sprintf("%s-%d", value, i)
if _, ok := ids.values[new_id]; !ok {
value = []byte(new_id)
break rewrite
}
}
ids.Put(value)
return value
}
func (ids *GfmIDs) Put(value []byte) {
ids.values[string(value)] = true
}