File: parser_hook.go

package info (click to toggle)
golang-github-gomarkdown-markdown 0.0~git20231115.a660076-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,168 kB
  • sloc: sh: 26; makefile: 5
file content (102 lines) | stat: -rw-r--r-- 2,113 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package main

// example for https://blog.kowalczyk.info/article/cxn3/advanced-markdown-processing-in-go.html

import (
	"fmt"

	"github.com/gomarkdown/markdown"
	"github.com/gomarkdown/markdown/ast"
	"github.com/gomarkdown/markdown/html"
	"github.com/gomarkdown/markdown/parser"

	"bytes"
	"io"
	"strings"
)

type Gallery struct {
	ast.Leaf
	ImageURLS []string
}

var gallery = []byte(":gallery\n")

func parseGallery(data []byte) (ast.Node, []byte, int) {
	if !bytes.HasPrefix(data, gallery) {
		return nil, nil, 0
	}
	fmt.Printf("Found a gallery!\n\n")
	i := len(gallery)
	// find empty line
	// TODO: should also consider end of document
	end := bytes.Index(data[i:], []byte("\n\n"))
	if end < 0 {
		return nil, data, 0
	}
	end = end + i
	lines := string(data[i:end])
	parts := strings.Split(lines, "\n")
	res := &Gallery{
		ImageURLS: parts,
	}
	return res, nil, end
}

func parserHook(data []byte) (ast.Node, []byte, int) {
	if node, d, n := parseGallery(data); node != nil {
		return node, d, n
	}
	return nil, nil, 0
}

func newMarkdownParser() *parser.Parser {
	extensions := parser.CommonExtensions
	p := parser.NewWithExtensions(extensions)
	p.Opts.ParserHook = parserHook
	return p
}

func galleryRenderHook(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) {
	if _, ok := node.(*Gallery); ok {
		if entering {
			// note: just for illustration purposes
			// actual implemenation of gallery in HTML / JavaScript is long
			io.WriteString(w, "\n<gallery></gallery>\n\n")
		}
		return ast.GoToNext, true
	}
	return ast.GoToNext, false
}

func newGalleryRender() *html.Renderer {
	opts := html.RendererOptions{
		Flags:          html.CommonFlags,
		RenderNodeHook: galleryRenderHook,
	}
	return html.NewRenderer(opts)
}

var mds = `document

:gallery
/img/image-1.png
/img/image-2.png

Rest of the document.`

func parserHookExample() {
	md := []byte(mds)

	p := newMarkdownParser()
	doc := p.Parse([]byte(md))

	renderer := newGalleryRender()
	html := markdown.Render(doc, renderer)

	fmt.Printf("--- Markdown:\n%s\n\n--- HTML:\n%s\n", md, html)
}

func main() {
	parserHookExample()
}