summaryrefslogtreecommitdiff
path: root/vendor/github.com/mangoumbrella/goldmark-figure/parser/parser.go
blob: 573ef2b29a1dc96969cb762f2984ac4c4febac0b (plain)
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
// Copyright 2023 The goldmark-figure authors
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
package parser

import (
	"regexp"

	fast "github.com/mangoumbrella/goldmark-figure/ast"
	gast "github.com/yuin/goldmark/ast"
	"github.com/yuin/goldmark/parser"
	"github.com/yuin/goldmark/text"
)

var imageRegexp = regexp.MustCompile(`^!\[[^[\]]*\](\([^()]*\)|\[[^[\]]*\])\s*$`)

type figureParagraphTransformer struct {
}

var defaultFigureParagraphTransformer = &figureParagraphTransformer{}

// NewFigureParagraphTransformer returns a new ParagraphTransformer
// that can transform paragraphs into figures.
func NewFigureParagraphTransformer() parser.ParagraphTransformer {
	return defaultFigureParagraphTransformer
}

func (b *figureParagraphTransformer) Transform(node *gast.Paragraph, reader text.Reader, pc parser.Context) {
	lines := node.Lines()
	if lines.Len() < 1 {
		return
	}
	var first_seg = lines.At(0)
	var first_line_str = first_seg.Value(reader.Source())
	// Here we simply match by regex.
	// But this simple regex ignores image descriptions that contain other links.
	// E.g. ![foo ![bar](/url)](/url2).
	// See CommonMark spec: https://spec.commonmark.org/0.30/#images.
	if !imageRegexp.Match(first_line_str) {
		return
	}
	figure := fast.NewFigure()
	node.Parent().ReplaceChild(node.Parent(), node, figure)

	figureImage := fast.NewFigureImage()
	figureImage.Lines().Append(lines.At(0))
	figure.AppendChild(figure, figureImage)

	if lines.Len() >= 2 {
		figureCaption := fast.NewFigureCaption()
		for i := 1; i < lines.Len(); i++ {
			seg := lines.At(i)
			if i == lines.Len()-1 {
				// trim last newline(\n)
				seg.Stop = seg.Stop - 1
			}
			figureCaption.Lines().Append(seg)
		}
		figure.AppendChild(figure, figureCaption)
	}
}

type figureASTTransformer struct {
}

var defaultFigureASTTransformer = &figureASTTransformer{}

// NewFigureASTTransformer returns a parser.ASTTransformer for tables.
func NewFigureASTTransformer() parser.ASTTransformer {
	return defaultFigureASTTransformer
}

func (a *figureASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) {
}