1// Copyright 2023 The goldmark-figure authors
 2//
 3// Use of this source code is governed by an MIT-style
 4// license that can be found in the LICENSE file or at
 5// https://opensource.org/licenses/MIT.
 6package parser
 7
 8import (
 9	"regexp"
10
11	fast "github.com/mangoumbrella/goldmark-figure/ast"
12	gast "github.com/yuin/goldmark/ast"
13	"github.com/yuin/goldmark/parser"
14	"github.com/yuin/goldmark/text"
15)
16
17var imageRegexp = regexp.MustCompile(`^!\[[^[\]]*\](\([^()]*\)|\[[^[\]]*\])\s*$`)
18
19type figureParagraphTransformer struct {
20}
21
22var defaultFigureParagraphTransformer = &figureParagraphTransformer{}
23
24// NewFigureParagraphTransformer returns a new ParagraphTransformer
25// that can transform paragraphs into figures.
26func NewFigureParagraphTransformer() parser.ParagraphTransformer {
27	return defaultFigureParagraphTransformer
28}
29
30func (b *figureParagraphTransformer) Transform(node *gast.Paragraph, reader text.Reader, pc parser.Context) {
31	lines := node.Lines()
32	if lines.Len() < 1 {
33		return
34	}
35	var first_seg = lines.At(0)
36	var first_line_str = first_seg.Value(reader.Source())
37	// Here we simply match by regex.
38	// But this simple regex ignores image descriptions that contain other links.
39	// E.g. ![foo ![bar](/url)](/url2).
40	// See CommonMark spec: https://spec.commonmark.org/0.30/#images.
41	if !imageRegexp.Match(first_line_str) {
42		return
43	}
44	figure := fast.NewFigure()
45	node.Parent().ReplaceChild(node.Parent(), node, figure)
46
47	figureImage := fast.NewFigureImage()
48	figureImage.Lines().Append(lines.At(0))
49	figure.AppendChild(figure, figureImage)
50
51	if lines.Len() >= 2 {
52		figureCaption := fast.NewFigureCaption()
53		for i := 1; i < lines.Len(); i++ {
54			seg := lines.At(i)
55			if i == lines.Len()-1 {
56				// trim last newline(\n)
57				seg.Stop = seg.Stop - 1
58			}
59			figureCaption.Lines().Append(seg)
60		}
61		figure.AppendChild(figure, figureCaption)
62	}
63}
64
65type figureASTTransformer struct {
66}
67
68var defaultFigureASTTransformer = &figureASTTransformer{}
69
70// NewFigureASTTransformer returns a parser.ASTTransformer for tables.
71func NewFigureASTTransformer() parser.ASTTransformer {
72	return defaultFigureASTTransformer
73}
74
75func (a *figureASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) {
76}