@@ -6,6 +6,7 @@ package markdown
6
6
import (
7
7
"strings"
8
8
9
+ "code.gitea.io/gitea/modules/markup/markdown/math"
9
10
"code.gitea.io/gitea/modules/svg"
10
11
11
12
"github.com/yuin/goldmark/ast"
@@ -37,41 +38,57 @@ func (r *HTMLRenderer) renderAttention(w util.BufWriter, source []byte, node ast
37
38
return ast .WalkContinue , nil
38
39
}
39
40
40
- func (g * ASTTransformer ) transformBlockquote ( v * ast. Blockquote , reader text.Reader ) (ast. WalkStatus , error ) {
41
- // We only want attention blockquotes when the AST looks like:
42
- // > Text("[") Text("!TYPE") Text("]" )
41
+ func popAttentionTypeFromMathBlock (g * ASTTransformer , mathBlock * math. Block , reader text.Reader ) string {
42
+ line := mathBlock . Lines (). At ( 0 )
43
+ innerText := line . Value ( reader . Source () )
43
44
44
- // grab these nodes and make sure we adhere to the attention blockquote structure
45
- firstParagraph := v .FirstChild ()
46
- g .applyElementDir (firstParagraph )
47
- if firstParagraph .ChildCount () < 3 {
48
- return ast .WalkContinue , nil
45
+ // make sure it's a !TYPE
46
+ if innerText [0 ] != '!' {
47
+ return ""
48
+ }
49
+ attentionType := strings .ToLower (string (innerText [1 :]))
50
+ if ! g .attentionTypes .Contains (attentionType ) {
51
+ return ""
52
+ }
53
+ return attentionType
54
+ }
55
+
56
+ func popAttentionTypeFromParagraph (g * ASTTransformer , paragraph * ast.Paragraph , reader text.Reader ) string {
57
+ g .applyElementDir (paragraph )
58
+ if paragraph .ChildCount () < 3 {
59
+ return ""
49
60
}
50
- node1 , ok := firstParagraph .FirstChild ().(* ast.Text )
61
+ node1 , ok := paragraph .FirstChild ().(* ast.Text )
51
62
if ! ok {
52
- return ast . WalkContinue , nil
63
+ return ""
53
64
}
54
65
node2 , ok := node1 .NextSibling ().(* ast.Text )
55
66
if ! ok {
56
- return ast . WalkContinue , nil
67
+ return ""
57
68
}
58
69
node3 , ok := node2 .NextSibling ().(* ast.Text )
59
70
if ! ok {
60
- return ast . WalkContinue , nil
71
+ return ""
61
72
}
62
73
val1 := string (node1 .Segment .Value (reader .Source ()))
63
74
val2 := string (node2 .Segment .Value (reader .Source ()))
64
75
val3 := string (node3 .Segment .Value (reader .Source ()))
65
76
if val1 != "[" || val3 != "]" || ! strings .HasPrefix (val2 , "!" ) {
66
- return ast . WalkContinue , nil
77
+ return ""
67
78
}
68
79
69
- // grab attention type from markdown source
70
80
attentionType := strings .ToLower (val2 [1 :])
71
81
if ! g .attentionTypes .Contains (attentionType ) {
72
- return ast . WalkContinue , nil
82
+ return ""
73
83
}
74
84
85
+ paragraph .RemoveChild (paragraph , node1 )
86
+ paragraph .RemoveChild (paragraph , node2 )
87
+ paragraph .RemoveChild (paragraph , node3 )
88
+ return attentionType
89
+ }
90
+
91
+ func newAttentionParagraph (v * ast.Blockquote , attentionType string , g * ASTTransformer ) * ast.Paragraph {
75
92
// color the blockquote
76
93
v .SetAttributeString ("class" , []byte ("attention-header attention-" + attentionType ))
77
94
@@ -87,12 +104,38 @@ func (g *ASTTransformer) transformBlockquote(v *ast.Blockquote, reader text.Read
87
104
emphasis .AppendChild (emphasis , attentionAstString )
88
105
attentionParagraph .AppendChild (attentionParagraph , NewAttention (attentionType ))
89
106
attentionParagraph .AppendChild (attentionParagraph , emphasis )
90
- firstParagraph .Parent ().InsertBefore (firstParagraph .Parent (), firstParagraph , attentionParagraph )
91
- firstParagraph .RemoveChild (firstParagraph , node1 )
92
- firstParagraph .RemoveChild (firstParagraph , node2 )
93
- firstParagraph .RemoveChild (firstParagraph , node3 )
94
- if firstParagraph .ChildCount () == 0 {
95
- firstParagraph .Parent ().RemoveChild (firstParagraph .Parent (), firstParagraph )
107
+ return attentionParagraph
108
+ }
109
+
110
+ func (g * ASTTransformer ) transformBlockquote (v * ast.Blockquote , reader text.Reader ) (ast.WalkStatus , error ) {
111
+ // We only want attention blockquotes when the AST looks like:
112
+ // > Text("[") Text("!TYPE") Text("]")
113
+ //
114
+ // or, in case of a math block: \[!TYPE\]
115
+
116
+ firstChild := v .FirstChild ()
117
+ var attentionType string
118
+
119
+ // grab attention type from markdown source
120
+ if paragraph , ok := firstChild .(* ast.Paragraph ); ok {
121
+ attentionType = popAttentionTypeFromParagraph (g , paragraph , reader )
122
+ } else {
123
+ mathBlock , ok := firstChild .(* math.Block )
124
+ if ! ok {
125
+ return ast .WalkContinue , nil
126
+ }
127
+ attentionType = popAttentionTypeFromMathBlock (g , mathBlock , reader )
128
+ }
129
+
130
+ // it's possible this isn't an attention block
131
+ if attentionType == "" {
132
+ return ast .WalkContinue , nil
133
+ }
134
+
135
+ attentionParagraph := newAttentionParagraph (v , attentionType , g )
136
+ v .InsertBefore (v , firstChild , attentionParagraph )
137
+ if firstChild .ChildCount () == 0 {
138
+ v .RemoveChild (v , firstChild )
96
139
}
97
140
return ast .WalkContinue , nil
98
141
}
0 commit comments