repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

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
M go.sum
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=
M shared/mdparser.go
+47, -1
 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.