dkforest

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

renderer.go (2402B)


      1 package database
      2 
      3 import (
      4 	"dkforest/pkg/bfchroma"
      5 	bf "dkforest/pkg/blackfriday/v2"
      6 	"github.com/alecthomas/chroma/formatters/html"
      7 	html2 "html"
      8 	"io"
      9 	"regexp"
     10 	"strings"
     11 )
     12 
     13 func MyRenderer(db *DkfDB, withLineNumbers, lineNumbersInTable bool) *Renderer {
     14 	// Defines the HTML rendering flags that are used
     15 	var flags = bf.UseXHTML | bf.SkipImages
     16 
     17 	r := &Renderer{
     18 		DB: db,
     19 		Base: bfchroma.NewRenderer(
     20 			bfchroma.WithoutAutodetect(),
     21 			bfchroma.ChromaOptions(
     22 				html.WithLineNumbers(withLineNumbers),
     23 				html.LineNumbersInTable(lineNumbersInTable),
     24 			),
     25 			bfchroma.Extend(
     26 				bf.NewHTMLRenderer(bf.HTMLRendererParameters{
     27 					Flags: flags,
     28 				}),
     29 			),
     30 		),
     31 	}
     32 	return r
     33 }
     34 
     35 func MyRendererForum(db *DkfDB, withLineNumbers, lineNumbersInTable bool) *Renderer {
     36 	// Defines the HTML rendering flags that are used
     37 	var flags = bf.UseXHTML
     38 
     39 	r := &Renderer{
     40 		DB: db,
     41 		Base: bfchroma.NewRenderer(
     42 			bfchroma.WithoutAutodetect(),
     43 			bfchroma.ChromaOptions(
     44 				html.WithLineNumbers(withLineNumbers),
     45 				html.LineNumbersInTable(lineNumbersInTable),
     46 			),
     47 			bfchroma.Extend(
     48 				bf.NewHTMLRenderer(bf.HTMLRendererParameters{
     49 					Flags: flags,
     50 				}),
     51 			),
     52 		),
     53 	}
     54 	return r
     55 }
     56 
     57 type Renderer struct {
     58 	DB   *DkfDB
     59 	Base *bfchroma.Renderer
     60 }
     61 
     62 var roomNameF = `\w{3,50}`
     63 var roomTagRgx = regexp.MustCompile(`#(` + roomNameF + `)`)
     64 
     65 func (r Renderer) RenderNode(w io.Writer, node *bf.Node, entering bool) bf.WalkStatus {
     66 	switch node.Type {
     67 	case bf.Text:
     68 		if node.Parent.Type != bf.Link {
     69 			node.Literal = []byte(html2.UnescapeString(string(node.Literal)))
     70 
     71 			if roomTagRgx.MatchString(string(node.Literal)) {
     72 				node.Literal = []byte(roomTagRgx.ReplaceAllStringFunc(string(node.Literal), func(s string) string {
     73 					if room, err := r.DB.GetChatRoomByName(strings.TrimPrefix(s, "#")); err == nil {
     74 						return `<a href="/chat/` + room.Name + `" target="_top">` + s + `</a>`
     75 					}
     76 					return s
     77 				}))
     78 				_, _ = w.Write(node.Literal)
     79 				return bf.GoToNext
     80 			}
     81 		}
     82 	case bf.Code:
     83 		node.Literal = []byte(html2.UnescapeString(string(node.Literal)))
     84 	case bf.CodeBlock:
     85 		node.Literal = []byte(html2.UnescapeString(string(node.Literal)))
     86 	default:
     87 	}
     88 	return r.Base.RenderNode(w, node, entering)
     89 }
     90 
     91 func (r Renderer) RenderHeader(w io.Writer, ast *bf.Node) {
     92 	r.Base.RenderHeader(w, ast)
     93 }
     94 
     95 func (r Renderer) RenderFooter(w io.Writer, ast *bf.Node) {
     96 	r.Base.RenderFooter(w, ast)
     97 }