summaryrefslogtreecommitdiffstats
path: root/modules/markup/markdown/transform_list.go
blob: b982fd4a8306afe948e0f4425992faf439a7a3b2 (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
77
78
79
80
81
82
83
84
85
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package markdown

import (
	"fmt"

	"code.gitea.io/gitea/modules/markup"

	"github.com/yuin/goldmark/ast"
	east "github.com/yuin/goldmark/extension/ast"
	"github.com/yuin/goldmark/renderer/html"
	"github.com/yuin/goldmark/util"
)

func (r *HTMLRenderer) renderTaskCheckBoxListItem(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
	n := node.(*TaskCheckBoxListItem)
	if entering {
		if n.Attributes() != nil {
			_, _ = w.WriteString("<li")
			html.RenderAttributes(w, n, html.ListItemAttributeFilter)
			_ = w.WriteByte('>')
		} else {
			_, _ = w.WriteString("<li>")
		}
		fmt.Fprintf(w, `<input type="checkbox" disabled="" data-source-position="%d"`, n.SourcePosition)
		if n.IsChecked {
			_, _ = w.WriteString(` checked=""`)
		}
		if r.XHTML {
			_, _ = w.WriteString(` />`)
		} else {
			_ = w.WriteByte('>')
		}
		fc := n.FirstChild()
		if fc != nil {
			if _, ok := fc.(*ast.TextBlock); !ok {
				_ = w.WriteByte('\n')
			}
		}
	} else {
		_, _ = w.WriteString("</li>\n")
	}
	return ast.WalkContinue, nil
}

func (r *HTMLRenderer) renderTaskCheckBox(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
	return ast.WalkContinue, nil
}

func (g *ASTTransformer) transformList(_ *markup.RenderContext, v *ast.List, rc *RenderConfig) {
	if v.HasChildren() {
		children := make([]ast.Node, 0, v.ChildCount())
		child := v.FirstChild()
		for child != nil {
			children = append(children, child)
			child = child.NextSibling()
		}
		v.RemoveChildren(v)

		for _, child := range children {
			listItem := child.(*ast.ListItem)
			if !child.HasChildren() || !child.FirstChild().HasChildren() {
				v.AppendChild(v, child)
				continue
			}
			taskCheckBox, ok := child.FirstChild().FirstChild().(*east.TaskCheckBox)
			if !ok {
				v.AppendChild(v, child)
				continue
			}
			newChild := NewTaskCheckBoxListItem(listItem)
			newChild.IsChecked = taskCheckBox.IsChecked
			newChild.SetAttributeString("class", []byte("task-list-item"))
			segments := newChild.FirstChild().Lines()
			if segments.Len() > 0 {
				segment := segments.At(0)
				newChild.SourcePosition = rc.metaLength + segment.Start
			}
			v.AppendChild(v, newChild)
		}
	}
	g.applyElementDir(v)
}