-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsafe_ids.go
76 lines (62 loc) · 1.28 KB
/
safe_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
package md2html
import (
"bytes"
"fmt"
"unicode"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
"golang.org/x/text/unicode/norm"
)
type SafeIDs struct {
values map[string]bool
}
func init() {
AutoIdsMap["safe"] = NewSafeIDs
}
func NewSafeIDs() parser.IDs {
return &SafeIDs{
values: map[string]bool{},
}
}
func (ids *SafeIDs) 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 *SafeIDs) toValid(value []byte) []byte {
anchor := make([]byte, 0, len(value))
for _, r := range string(value) {
if unicode.IsPrint(r) {
anchor = append(anchor, string(r)...)
}
}
return anchor
}
func (ids *SafeIDs) 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 *SafeIDs) Put(value []byte) {
ids.values[string(value)] = true
}