- commit
- ee83c2b
- parent
- 58da36f
- author
- Eric Bower
- date
- 2024-03-21 15:57:59 +0000 UTC
Merge branch 'tags'
3 files changed,
+53,
-1
M
go.mod
+2,
-0
1@@ -37,6 +37,7 @@ require (
2 github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594
3 github.com/yuin/goldmark-meta v1.1.0
4 go.abhg.dev/goldmark/anchor v0.1.1
5+ go.abhg.dev/goldmark/hashtag v0.3.1
6 golang.org/x/crypto v0.18.0
7 gopkg.in/yaml.v2 v2.4.0
8 )
9@@ -65,6 +66,7 @@ require (
10 github.com/dsoprea/go-png-image-structure v0.0.0-20210512210324-29b889a6093d // indirect
11 github.com/dsoprea/go-utility v0.0.0-20221003172846-a3e1774ef349 // indirect
12 github.com/dustin/go-humanize v1.0.1 // indirect
13+ github.com/forPelevin/gomoji v1.1.3 // indirect
14 github.com/go-errors/errors v1.5.1 // indirect
15 github.com/go-logfmt/logfmt v0.6.0 // indirect
16 github.com/go-ole/go-ole v1.3.0 // indirect
M
go.sum
+4,
-0
1@@ -76,6 +76,8 @@ github.com/dsoprea/go-utility v0.0.0-20221003172846-a3e1774ef349/go.mod h1:KVK+/
2 github.com/dsoprea/go-utility/v2 v2.0.0-20200717064901-2fccff4aa15e/go.mod h1:uAzdkPTub5Y9yQwXe8W4m2XuP0tK4a9Q/dantD0+uaU=
3 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
4 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
5+github.com/forPelevin/gomoji v1.1.3 h1:7c3dYzVmYhpOL3bS4riXqSWJBX3BhSvH68yoNNf3FH0=
6+github.com/forPelevin/gomoji v1.1.3/go.mod h1:ypB7Kz3Fsp+LVR7KoT7mEFOioYBuTuAtaAT4RGl+ASY=
7 github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
8 github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
9 github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
10@@ -263,6 +265,8 @@ github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFi
11 github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
12 go.abhg.dev/goldmark/anchor v0.1.1 h1:NUH3hAzhfeymRqZKOkSoFReZlEAmfXBZlbXEzpD2Qgc=
13 go.abhg.dev/goldmark/anchor v0.1.1/go.mod h1:zYKiaHXTdugwVJRZqInVdmNGQRM3ZRJ6AGBC7xP7its=
14+go.abhg.dev/goldmark/hashtag v0.3.1 h1:k0FQwEtVQ1SstIRR2fqDJ4VNYUS0AXLp869V0qHOZMg=
15+go.abhg.dev/goldmark/hashtag v0.3.1/go.mod h1:rXtvxXPL7auhPMGRdG02UrXn/9LMm6PNdP5HO64zbVU=
16 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
17 golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
18 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
1@@ -18,6 +18,7 @@ import (
2 ghtml "github.com/yuin/goldmark/renderer/html"
3 gtext "github.com/yuin/goldmark/text"
4 "go.abhg.dev/goldmark/anchor"
5+ "go.abhg.dev/goldmark/hashtag"
6 yaml "gopkg.in/yaml.v2"
7 )
8
9@@ -187,6 +188,7 @@ func ParseText(text string) (*ParsedText, error) {
10 extension.GFM,
11 extension.Footnote,
12 meta.Meta,
13+ &hashtag.Extender{},
14 hili,
15 &anchor.Extender{
16 Position: anchor.Before,
17@@ -286,10 +288,15 @@ func ParseText(text string) (*ParsedText, error) {
18 }
19 parsed.MetaData.Aliases = aliases
20
21- tags, err := toTags(metaData["tags"])
22+ rtags := metaData["tags"]
23+ tags, err := toTags(rtags)
24 if err != nil {
25 return &parsed, err
26 }
27+ // fill from hashtag ASTs as fallback
28+ if rtags == nil {
29+ tags = AstTags(doc)
30+ }
31 parsed.MetaData.Tags = tags
32
33 // Rendering happens last to allow any of the previous steps to manipulate
34@@ -303,6 +310,45 @@ func ParseText(text string) (*ParsedText, error) {
35 return &parsed, nil
36 }
37
38+func AstTags(doc ast.Node) []string {
39+ var tags []string
40+ err := ast.Walk(doc, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
41+ switch n.Kind() {
42+ // ignore hashtags inside of these sections
43+ case ast.KindBlockquote, ast.KindCodeBlock, ast.KindCodeSpan:
44+ return ast.WalkSkipChildren, nil
45+ // register hashtags
46+ case hashtag.Kind:
47+ t := n.(*hashtag.Node)
48+ if entering { // only add each tag once
49+ tags = append(tags, string(t.Tag))
50+ }
51+ }
52+ // out-of-switch default
53+ return ast.WalkContinue, nil
54+ })
55+ if err != nil {
56+ panic(err) // unreachable
57+ }
58+
59+ // sort and deduplicate results
60+ dedupe := removeDuplicateStr(tags)
61+ return dedupe
62+}
63+
64+// https://stackoverflow.com/a/66751055
65+func removeDuplicateStr(strSlice []string) []string {
66+ allKeys := make(map[string]bool)
67+ list := []string{}
68+ for _, item := range strSlice {
69+ if _, value := allKeys[item]; !value {
70+ allKeys[item] = true
71+ list = append(list, item)
72+ }
73+ }
74+ return list
75+}
76+
77 // AstTitle extracts the title (if any) from a parsed markdown document.
78 //
79 // If "clean" is true, it will also remove the heading node from the AST.