right now the button's text gets added without the around it. can't figure out why. am i missing sth obvious ?
+2
-1
go.mod
+2
-1
go.mod
···
29
29
github.com/resend/resend-go/v2 v2.15.0
30
30
github.com/sethvargo/go-envconfig v1.1.0
31
31
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e
32
-
github.com/yuin/goldmark v1.4.13
32
+
github.com/yuin/goldmark v1.4.15
33
+
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
33
34
golang.org/x/net v0.39.0
34
35
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028
35
36
)
+8
-1
go.sum
+8
-1
go.sum
···
9
9
github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
10
10
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
11
11
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
12
+
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
12
13
github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc=
13
14
github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio=
15
+
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
14
16
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
15
17
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
16
18
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
···
55
57
github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU=
56
58
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
57
59
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
60
+
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
61
+
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
58
62
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
59
63
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
60
64
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
···
279
283
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
280
284
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
281
285
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
282
-
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
283
286
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
287
+
github.com/yuin/goldmark v1.4.15 h1:CFa84T0goNn/UIXYS+dmjjVxMyTAvpOmzld40N/nfK0=
288
+
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
289
+
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
290
+
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
284
291
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRySiX3drau9C6Q5CAbNIApmLdat5jPMqChvDA=
285
292
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8=
286
293
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q=
+3
-1
appview/pages/funcmap.go
+3
-1
appview/pages/funcmap.go
···
145
145
},
146
146
"markdown": func(text string) template.HTML {
147
147
rctx := &markup.RenderContext{RendererType: markup.RendererTypeDefault}
148
-
return template.HTML(bluemonday.UGCPolicy().Sanitize(rctx.RenderMarkdown(text)))
148
+
return template.HTML(
149
+
rctx.RenderMarkdown(text, bluemonday.UGCPolicy().Sanitize),
150
+
)
149
151
},
150
152
"isNil": func(t any) bool {
151
153
// returns false for other "zero" values
+4
-4
appview/pages/pages.go
+4
-4
appview/pages/pages.go
···
432
432
ext := filepath.Ext(params.ReadmeFileName)
433
433
switch ext {
434
434
case ".md", ".markdown", ".mdown", ".mkdn", ".mkd":
435
-
htmlString = p.rctx.RenderMarkdown(params.Readme)
435
+
htmlString = p.rctx.RenderMarkdown(params.Readme, p.rctx.Sanitize)
436
436
params.Raw = false
437
-
params.HTMLReadme = template.HTML(p.rctx.Sanitize(htmlString))
437
+
params.HTMLReadme = template.HTML(htmlString)
438
438
default:
439
439
htmlString = string(params.Readme)
440
440
params.Raw = true
···
564
564
case markup.FormatMarkdown:
565
565
p.rctx.RepoInfo = params.RepoInfo
566
566
p.rctx.RendererType = markup.RendererTypeRepoMarkdown
567
-
htmlString := p.rctx.RenderMarkdown(params.Contents)
568
-
params.RenderedContents = template.HTML(p.rctx.Sanitize(htmlString))
567
+
htmlString := p.rctx.RenderMarkdown(params.Contents, p.rctx.Sanitize)
568
+
params.RenderedContents = template.HTML(htmlString)
569
569
}
570
570
}
571
571
+5
input.css
+5
input.css
+68
appview/pages/markup/markdown.go
+68
appview/pages/markup/markdown.go
···
20
20
"github.com/yuin/goldmark/text"
21
21
"github.com/yuin/goldmark/util"
22
22
htmlparse "golang.org/x/net/html"
23
+
"golang.org/x/net/html/atom"
23
24
24
25
"tangled.sh/tangled.sh/core/appview/pages/repoinfo"
25
26
)
···
153
154
}
154
155
}
155
156
157
+
if node.Data == "pre" {
158
+
// TODO only show when :hover or :focus on the pre element
159
+
button := &htmlparse.Node{
160
+
Type: htmlparse.ElementNode,
161
+
DataAtom: atom.Button,
162
+
Data: "button",
163
+
Attr: []htmlparse.Attribute{
164
+
{
165
+
Key: "class",
166
+
Val: "absolute top-2 right-2 btn",
167
+
},
168
+
{
169
+
Key: "style",
170
+
// FIXME .#watch-tailwind doesnt seem to catch top-2 and right-2, probably cuz it's not used anywhere inside of templates/ ?
171
+
Val: "top: 0.5rem; right: 0.5rem;",
172
+
},
173
+
{
174
+
Key: "onclick",
175
+
Val: `
176
+
navigator.clipboard.writeText(this.closest('pre').querySelector('code').innerText);
177
+
this.innerText = 'Copied!';
178
+
setTimeout(() => { this.innerText = 'Copy' }, 1500);
179
+
`,
180
+
},
181
+
{
182
+
Key: "onload",
183
+
Val: "this.removeAttribute('aria-hidden')",
184
+
},
185
+
{
186
+
Key: "aria-hidden",
187
+
Val: "true",
188
+
},
189
+
{
190
+
Key: "title",
191
+
Val: "Copy to clipboard",
192
+
},
193
+
},
194
+
}
195
+
196
+
// TODO
197
+
// if copyIcon, err := icons.IconNode("copy", "h-4", "w-4"); err != nil {
198
+
// button.AppendChild(copyIcon)
199
+
// } else {
200
+
button.AppendChild(&htmlparse.Node{
201
+
Type: htmlparse.TextNode,
202
+
Data: "Copy",
203
+
})
204
+
205
+
var classWasSetOnNode bool
206
+
for i, attr := range node.Attr {
207
+
if attr.Key == "class" {
208
+
node.Attr[i].Val += " relative"
209
+
classWasSetOnNode = true
210
+
break
211
+
}
212
+
}
213
+
214
+
if !classWasSetOnNode {
215
+
node.Attr = append(node.Attr, htmlparse.Attribute{
216
+
Key: "class",
217
+
Val: "relative",
218
+
})
219
+
}
220
+
221
+
node.AppendChild(button)
222
+
}
223
+
156
224
for n := node.FirstChild; n != nil; n = n.NextSibling {
157
225
visitNode(ctx, n)
158
226
}