dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit 20ae645ae6b06044a002072f86883f2fa7f21331
parent 7d8e99cbcd9b286c5b97682efbecd5d550e99d6f
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Sun, 31 Dec 2023 11:36:48 -0500

proper renderer

Diffstat:
Apkg/database/renderer.go | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkg/database/table_forum_threads.go | 2+-
Mpkg/database/utils/processMessage.go | 19+++----------------
Mpkg/utils/utils.go | 73-------------------------------------------------------------------------
4 files changed, 100 insertions(+), 90 deletions(-)

diff --git a/pkg/database/renderer.go b/pkg/database/renderer.go @@ -0,0 +1,96 @@ +package database + +import ( + "dkforest/pkg/bfchroma" + bf "dkforest/pkg/blackfriday/v2" + "github.com/alecthomas/chroma/formatters/html" + html2 "html" + "io" + "regexp" + "strings" +) + +func MyRenderer(db *DkfDB, withLineNumbers, lineNumbersInTable bool) *Renderer { + // Defines the HTML rendering flags that are used + var flags = bf.UseXHTML | bf.SkipImages + + r := &Renderer{ + DB: db, + Base: bfchroma.NewRenderer( + bfchroma.WithoutAutodetect(), + bfchroma.ChromaOptions( + html.WithLineNumbers(withLineNumbers), + html.LineNumbersInTable(lineNumbersInTable), + ), + bfchroma.Extend( + bf.NewHTMLRenderer(bf.HTMLRendererParameters{ + Flags: flags, + }), + ), + ), + } + return r +} + +func MyRendererForum(withLineNumbers, lineNumbersInTable bool) *Renderer { + // Defines the HTML rendering flags that are used + var flags = bf.UseXHTML + + r := &Renderer{ + Base: bfchroma.NewRenderer( + bfchroma.WithoutAutodetect(), + bfchroma.ChromaOptions( + html.WithLineNumbers(withLineNumbers), + html.LineNumbersInTable(lineNumbersInTable), + ), + bfchroma.Extend( + bf.NewHTMLRenderer(bf.HTMLRendererParameters{ + Flags: flags, + }), + ), + ), + } + return r +} + +type Renderer struct { + DB *DkfDB + Base *bfchroma.Renderer +} + +var roomNameF = `\w{3,50}` +var roomTagRgx = regexp.MustCompile(`#(` + roomNameF + `)`) + +func (r Renderer) RenderNode(w io.Writer, node *bf.Node, entering bool) bf.WalkStatus { + switch node.Type { + case bf.Text: + if node.Parent.Type != bf.Link { + node.Literal = []byte(html2.UnescapeString(string(node.Literal))) + + if roomTagRgx.MatchString(string(node.Literal)) { + node.Literal = []byte(roomTagRgx.ReplaceAllStringFunc(string(node.Literal), func(s string) string { + if room, err := r.DB.GetChatRoomByName(strings.TrimPrefix(s, "#")); err == nil { + return `<a href="/chat/` + room.Name + `" target="_top">` + s + `</a>` + } + return s + })) + _, _ = w.Write(node.Literal) + return bf.GoToNext + } + } + case bf.Code: + node.Literal = []byte(html2.UnescapeString(string(node.Literal))) + case bf.CodeBlock: + node.Literal = []byte(html2.UnescapeString(string(node.Literal))) + default: + } + return r.Base.RenderNode(w, node, entering) +} + +func (r Renderer) RenderHeader(w io.Writer, ast *bf.Node) { + r.Base.RenderHeader(w, ast) +} + +func (r Renderer) RenderFooter(w io.Writer, ast *bf.Node) { + r.Base.RenderFooter(w, ast) +} diff --git a/pkg/database/table_forum_threads.go b/pkg/database/table_forum_threads.go @@ -113,7 +113,7 @@ func (m *ForumMessage) Escape(db *DkfDB) string { } res := strings.Replace(msg, "\r", "", -1) res = html2.EscapeString(res) - resBytes := bf.Run([]byte(res), bf.WithRenderer(utils.MyRendererForum(true, true)), bf.WithExtensions(bf.CommonExtensions|bf.HardLineBreak)) + resBytes := bf.Run([]byte(res), bf.WithRenderer(MyRendererForum(true, true)), bf.WithExtensions(bf.CommonExtensions|bf.HardLineBreak)) res = string(resBytes) // Tags diff --git a/pkg/database/utils/processMessage.go b/pkg/database/utils/processMessage.go @@ -115,13 +115,12 @@ func ProcessRawMessage(db *database.DkfDB, in, roomKey string, authUserID databa html = convertPGPPublicKeyToFile(db, html, authUserID) html = convertAgeMessageToFile(db, html, authUserID) html = convertLinksWithoutScheme(html) - html = convertMarkdown(html, canUseMultiline, manualML) + html = convertMarkdown(db, html, canUseMultiline, manualML) html = convertBangShortcuts(html) html = convertArchiveLinks(db, html, roomID, authUserID) html = convertLinks(html, roomID, db.GetUserByUsername, db.GetLinkByShorthand, db.GetChatMessageByUUID) html = linkDefaultRooms(html) html, taggedUsersIDsMap := ColorifyTaggedUsers(html, db.GetUsersByUsername) - html = linkRoomTags(db, html) html = emojiReplacer.Replace(html) html = styleQuote(html, quoted) html = appendUploadLink(html, upload) @@ -764,18 +763,6 @@ func ColorifyTaggedUsers(html string, getUsersByUsername getUsersByUsernameFn) ( return html, taggedUsersIDsMap } -func linkRoomTags(db *database.DkfDB, html string) string { - if roomTagRgx.MatchString(html) { - html = roomTagRgx.ReplaceAllStringFunc(html, func(s string) string { - if room, err := db.GetChatRoomByName(strings.TrimPrefix(s, "#")); err == nil { - return `<a href="/chat/` + room.Name + `" target="_top">` + s + `</a>` - } - return s - }) - } - return html -} - func linkDefaultRooms(html string) string { r := strings.NewReplacer( "#general", `<a href="/chat/general" target="_top">#general</a>`, @@ -846,14 +833,14 @@ func convertBangShortcuts(html string) string { return r.Replace(html) } -func convertMarkdown(in string, canUseMultiline, manualML bool) string { +func convertMarkdown(db *database.DkfDB, in string, canUseMultiline, manualML bool) string { out := strings.Replace(in, "\r", "", -1) flags := bf.NoIntraEmphasis | bf.Tables | bf.FencedCode | bf.Strikethrough | bf.SpaceHeadings | bf.DefinitionLists | bf.HardLineBreak | bf.NoLink if canUseMultiline && manualML { flags |= bf.ManualLineBreak } - resBytes := bf.Run([]byte(out), bf.WithRenderer(utils.MyRenderer(false, false)), bf.WithExtensions(flags)) + resBytes := bf.Run([]byte(out), bf.WithRenderer(database.MyRenderer(db, false, false)), bf.WithExtensions(flags)) out = string(resBytes) return out } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go @@ -12,8 +12,6 @@ import ( "crypto/sha256" "crypto/sha512" "crypto/x509" - "dkforest/pkg/bfchroma" - bf "dkforest/pkg/blackfriday/v2" "dkforest/pkg/hashset" "dkforest/pkg/utils/crypto" "encoding/base32" @@ -27,10 +25,8 @@ import ( "github.com/ProtonMail/go-crypto/openpgp/armor" "github.com/ProtonMail/go-crypto/openpgp/clearsign" "github.com/ProtonMail/go-crypto/openpgp/packet" - "github.com/alecthomas/chroma/formatters/html" "github.com/asaskevich/govalidator" "hash/crc32" - html2 "html" "image" "image/jpeg" "image/png" @@ -1095,75 +1091,6 @@ func CountUppercase(s string) (count, total int64) { return } -func MyRenderer(withLineNumbers, lineNumbersInTable bool) *Renderer { - // Defines the HTML rendering flags that are used - var flags = bf.UseXHTML | bf.SkipImages - - r := &Renderer{ - Base: bfchroma.NewRenderer( - bfchroma.WithoutAutodetect(), - bfchroma.ChromaOptions( - html.WithLineNumbers(withLineNumbers), - html.LineNumbersInTable(lineNumbersInTable), - ), - bfchroma.Extend( - bf.NewHTMLRenderer(bf.HTMLRendererParameters{ - Flags: flags, - }), - ), - ), - } - return r -} - -func MyRendererForum(withLineNumbers, lineNumbersInTable bool) *Renderer { - // Defines the HTML rendering flags that are used - var flags = bf.UseXHTML - - r := &Renderer{ - Base: bfchroma.NewRenderer( - bfchroma.WithoutAutodetect(), - bfchroma.ChromaOptions( - html.WithLineNumbers(withLineNumbers), - html.LineNumbersInTable(lineNumbersInTable), - ), - bfchroma.Extend( - bf.NewHTMLRenderer(bf.HTMLRendererParameters{ - Flags: flags, - }), - ), - ), - } - return r -} - -type Renderer struct { - Base *bfchroma.Renderer -} - -func (r Renderer) RenderNode(w io.Writer, node *bf.Node, entering bool) bf.WalkStatus { - switch node.Type { - case bf.Text: - if node.Parent.Type != bf.Link { - node.Literal = []byte(html2.UnescapeString(string(node.Literal))) - } - case bf.Code: - node.Literal = []byte(html2.UnescapeString(string(node.Literal))) - case bf.CodeBlock: - node.Literal = []byte(html2.UnescapeString(string(node.Literal))) - default: - } - return r.Base.RenderNode(w, node, entering) -} - -func (r Renderer) RenderHeader(w io.Writer, ast *bf.Node) { - r.Base.RenderHeader(w, ast) -} - -func (r Renderer) RenderFooter(w io.Writer, ast *bf.Node) { - r.Base.RenderFooter(w, ast) -} - func VerifyTorSign(onionAddr, msg, pemSig string) bool { block, _ := pem.Decode([]byte(pemSig)) if block == nil {