mirror of
https://github.com/aljazceru/njump.git
synced 2025-12-17 14:24:27 +01:00
Add markdown support for long format content
This commit is contained in:
1
go.mod
1
go.mod
@@ -24,6 +24,7 @@ require (
|
|||||||
github.com/gobwas/httphead v0.1.0 // indirect
|
github.com/gobwas/httphead v0.1.0 // indirect
|
||||||
github.com/gobwas/pool v0.2.1 // indirect
|
github.com/gobwas/pool v0.2.1 // indirect
|
||||||
github.com/gobwas/ws v1.2.0 // indirect
|
github.com/gobwas/ws v1.2.0 // indirect
|
||||||
|
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -53,6 +53,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a h1:AWZzzFrqyjYlRloN6edwTLTUbKxf5flLXNuTBDm3Ews=
|
||||||
|
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
|||||||
@@ -87,12 +87,11 @@ func render(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
maxAge = 900
|
maxAge = 900
|
||||||
} else {
|
} else {
|
||||||
if event.Kind == 1 || event.Kind == 7 || event.Kind == 30023 {
|
if event.Kind == 1 || event.Kind == 7 || event.Kind == 30023 || event.Kind == 30024 {
|
||||||
typ = "note"
|
typ = "note"
|
||||||
note, _ = nip19.EncodeNote(event.ID)
|
note, _ = nip19.EncodeNote(event.ID)
|
||||||
content = event.Content
|
content = event.Content
|
||||||
parentNevent = findParentNevent(event)
|
parentNevent = findParentNevent(event)
|
||||||
|
|
||||||
} else if event.Kind == 6 {
|
} else if event.Kind == 6 {
|
||||||
typ = "note"
|
typ = "note"
|
||||||
if reposted := event.Tags.GetFirst([]string{"e", ""}); reposted != nil {
|
if reposted := event.Tags.GetFirst([]string{"e", ""}); reposted != nil {
|
||||||
@@ -223,6 +222,7 @@ func render(w http.ResponseWriter, r *http.Request) {
|
|||||||
"naddr": naddr,
|
"naddr": naddr,
|
||||||
"metadata": metadata,
|
"metadata": metadata,
|
||||||
"authorLong": authorLong,
|
"authorLong": authorLong,
|
||||||
|
"subject": subject,
|
||||||
"description": description,
|
"description": description,
|
||||||
"content": content,
|
"content": content,
|
||||||
"textImageURL": textImageURL,
|
"textImageURL": textImageURL,
|
||||||
@@ -251,6 +251,7 @@ func render(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"basicFormatting": basicFormatting,
|
"basicFormatting": basicFormatting,
|
||||||
|
"mdToHTML": mdToHTML,
|
||||||
"sanitizeString": html.EscapeString,
|
"sanitizeString": html.EscapeString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ body {
|
|||||||
|
|
||||||
h1, h2 {
|
h1, h2 {
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
|
line-height: 1.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme--default a {
|
.theme--default a {
|
||||||
@@ -337,6 +338,34 @@ h1, h2 {
|
|||||||
.theme--dark .container .column_content .field.boxed .label {
|
.theme--dark .container .column_content .field.boxed .label {
|
||||||
background: #191919;
|
background: #191919;
|
||||||
}
|
}
|
||||||
|
.container .column_content .field pre {
|
||||||
|
overflow-x: scroll;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
.theme--default .container .column_content .field pre {
|
||||||
|
background: #f3f3f3;
|
||||||
|
}
|
||||||
|
.theme--dark .container .column_content .field pre {
|
||||||
|
background: #2d2d2d;
|
||||||
|
}
|
||||||
|
.container .column_content .field hr {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.container .column_content .field .footnotes {
|
||||||
|
padding-top: 1rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
.theme--default .container .column_content .field .footnotes {
|
||||||
|
border-top: 6px solid #f3f3f3;
|
||||||
|
}
|
||||||
|
.theme--dark .container .column_content .field .footnotes {
|
||||||
|
border-top: 6px solid #2d2d2d;
|
||||||
|
}
|
||||||
|
.container .column_content .field .footnotes ol {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 0 0 1rem;
|
||||||
|
}
|
||||||
.container .column_content .field.last_notes a {
|
.container .column_content .field.last_notes a {
|
||||||
display: block;
|
display: block;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ body {
|
|||||||
}
|
}
|
||||||
h1, h2 {
|
h1, h2 {
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
|
line-height: 1.1em;
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
@include themed() {
|
@include themed() {
|
||||||
@@ -356,6 +357,28 @@ a {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pre {
|
||||||
|
overflow-x: scroll;
|
||||||
|
@include themed() {
|
||||||
|
background: t($over-bg);
|
||||||
|
}
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.footnotes {
|
||||||
|
padding-top: 1rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
@include themed() {
|
||||||
|
border-top: 6px solid t($over-bg);
|
||||||
|
}
|
||||||
|
font-size: 0.8rem;
|
||||||
|
ol {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 0 0 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
&.last_notes {
|
&.last_notes {
|
||||||
a {
|
a {
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -36,7 +36,14 @@
|
|||||||
<div class="field separator"></div>
|
<div class="field separator"></div>
|
||||||
|
|
||||||
<div class="field content">
|
<div class="field content">
|
||||||
{{.content | sanitizeString | basicFormatting }}
|
{{ if (not (eq .subject ""))}}
|
||||||
|
<h1>{{.subject | sanitizeString}}</h1>
|
||||||
|
{{ end }}
|
||||||
|
{{ if (or (eq .kindID 30023) (eq .kindID 30024))}}
|
||||||
|
{{.content | sanitizeString | mdToHTML }}
|
||||||
|
{{ else }}
|
||||||
|
{{.content | sanitizeString | basicFormatting }}
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field separator"></div>
|
<div class="field separator"></div>
|
||||||
|
|||||||
25
utils.go
25
utils.go
@@ -7,6 +7,9 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gomarkdown/markdown"
|
||||||
|
"github.com/gomarkdown/markdown/html"
|
||||||
|
"github.com/gomarkdown/markdown/parser"
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
"github.com/nbd-wtf/go-nostr/nip10"
|
"github.com/nbd-wtf/go-nostr/nip10"
|
||||||
"github.com/nbd-wtf/go-nostr/nip19"
|
"github.com/nbd-wtf/go-nostr/nip19"
|
||||||
@@ -103,7 +106,7 @@ func generateClientList(code string, event *nostr.Event) []map[string]string {
|
|||||||
}
|
}
|
||||||
} else if strings.HasPrefix(code, "npub") || strings.HasPrefix(code, "nprofile") {
|
} else if strings.HasPrefix(code, "npub") || strings.HasPrefix(code, "nprofile") {
|
||||||
return []map[string]string{
|
return []map[string]string{
|
||||||
{"name": "native client", "url": "nostr:" + code},
|
{"name": "Your native client", "url": "nostr:" + code},
|
||||||
{"name": "Snort", "url": "https://snort.social/p/" + code},
|
{"name": "Snort", "url": "https://snort.social/p/" + code},
|
||||||
{"name": "Coracle", "url": "https://coracle.social/" + code},
|
{"name": "Coracle", "url": "https://coracle.social/" + code},
|
||||||
{"name": "Satellite", "url": "https://satellite.earth/@" + code},
|
{"name": "Satellite", "url": "https://satellite.earth/@" + code},
|
||||||
@@ -116,9 +119,9 @@ func generateClientList(code string, event *nostr.Event) []map[string]string {
|
|||||||
}
|
}
|
||||||
} else if strings.HasPrefix(code, "naddr") {
|
} else if strings.HasPrefix(code, "naddr") {
|
||||||
return []map[string]string{
|
return []map[string]string{
|
||||||
{"name": "native client", "url": "nostr:" + code},
|
{"name": "Your native client", "url": "nostr:" + code},
|
||||||
{"name": "habla", "url": "https://habla.news/a/" + code},
|
{"name": "Habla", "url": "https://habla.news/a/" + code},
|
||||||
{"name": "blogstack", "url": "https://blogstack.io/" + code},
|
{"name": "Blogstack", "url": "https://blogstack.io/" + code},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return []map[string]string{
|
return []map[string]string{
|
||||||
@@ -254,3 +257,17 @@ func findParentNevent(event *nostr.Event) string {
|
|||||||
}
|
}
|
||||||
return parentNevent
|
return parentNevent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mdToHTML(md string) string {
|
||||||
|
// create markdown parser with extensions
|
||||||
|
extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock | parser.Footnotes
|
||||||
|
p := parser.NewWithExtensions(extensions)
|
||||||
|
doc := p.Parse([]byte(md))
|
||||||
|
|
||||||
|
// create HTML renderer with extensions
|
||||||
|
htmlFlags := html.CommonFlags | html.HrefTargetBlank
|
||||||
|
opts := html.RendererOptions{Flags: htmlFlags}
|
||||||
|
renderer := html.NewRenderer(opts)
|
||||||
|
|
||||||
|
return string(markdown.Render(doc, renderer))
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user