@@ -27,7 +27,21 @@ import (
27
27
)
28
28
29
29
// ASTTransformer is a default transformer of the goldmark tree.
30
- type ASTTransformer struct {}
30
+ type ASTTransformer struct {
31
+ AttentionTypes container.Set [string ]
32
+ }
33
+
34
+ func NewASTTransformer () * ASTTransformer {
35
+ return & ASTTransformer {
36
+ AttentionTypes : container .SetOf ("note" , "tip" , "important" , "warning" , "caution" ),
37
+ }
38
+ }
39
+
40
+ func (g * ASTTransformer ) applyElementDir (n ast.Node ) {
41
+ if markup .DefaultProcessorHelper .ElementDir != "" {
42
+ n .SetAttributeString ("dir" , []byte (markup .DefaultProcessorHelper .ElementDir ))
43
+ }
44
+ }
31
45
32
46
// Transform transforms the given AST tree.
33
47
func (g * ASTTransformer ) Transform (node * ast.Document , reader text.Reader , pc parser.Context ) {
@@ -45,12 +59,6 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
45
59
tocMode = rc .TOC
46
60
}
47
61
48
- applyElementDir := func (n ast.Node ) {
49
- if markup .DefaultProcessorHelper .ElementDir != "" {
50
- n .SetAttributeString ("dir" , []byte (markup .DefaultProcessorHelper .ElementDir ))
51
- }
52
- }
53
-
54
62
_ = ast .Walk (node , func (n ast.Node , entering bool ) (ast.WalkStatus , error ) {
55
63
if ! entering {
56
64
return ast .WalkContinue , nil
@@ -72,9 +80,9 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
72
80
header .ID = util .BytesToReadOnlyString (id .([]byte ))
73
81
}
74
82
tocList = append (tocList , header )
75
- applyElementDir (v )
83
+ g . applyElementDir (v )
76
84
case * ast.Paragraph :
77
- applyElementDir (v )
85
+ g . applyElementDir (v )
78
86
case * ast.Image :
79
87
// Images need two things:
80
88
//
@@ -174,7 +182,7 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
174
182
v .AppendChild (v , newChild )
175
183
}
176
184
}
177
- applyElementDir (v )
185
+ g . applyElementDir (v )
178
186
case * ast.Text :
179
187
if v .SoftLineBreak () && ! v .HardLineBreak () {
180
188
if ctx .Metas ["mode" ] != "document" {
@@ -189,51 +197,7 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
189
197
v .AppendChild (v , NewColorPreview (colorContent ))
190
198
}
191
199
case * ast.Blockquote :
192
- // We only want attention blockquotes when the AST looks like:
193
- // Text: "["
194
- // Text: "!TYPE"
195
- // Text(SoftLineBreak): "]"
196
-
197
- // grab these nodes and make sure we adhere to the attention blockquote structure
198
- firstParagraph := v .FirstChild ()
199
- if firstParagraph .ChildCount () < 3 {
200
- return ast .WalkContinue , nil
201
- }
202
- firstTextNode , ok := firstParagraph .FirstChild ().(* ast.Text )
203
- if ! ok || string (firstTextNode .Segment .Value (reader .Source ())) != "[" {
204
- return ast .WalkContinue , nil
205
- }
206
- secondTextNode , ok := firstTextNode .NextSibling ().(* ast.Text )
207
- if ! ok || ! attentionTypeRE .MatchString (string (secondTextNode .Segment .Value (reader .Source ()))) {
208
- return ast .WalkContinue , nil
209
- }
210
- thirdTextNode , ok := secondTextNode .NextSibling ().(* ast.Text )
211
- if ! ok || string (thirdTextNode .Segment .Value (reader .Source ())) != "]" {
212
- return ast .WalkContinue , nil
213
- }
214
-
215
- // grab attention type from markdown source
216
- attentionType := strings .ToLower (strings .TrimPrefix (string (secondTextNode .Segment .Value (reader .Source ())), "!" ))
217
-
218
- // color the blockquote
219
- v .SetAttributeString ("class" , []byte ("attention-header attention-" + attentionType ))
220
-
221
- // create an emphasis to make it bold
222
- attentionParagraph := ast .NewParagraph ()
223
- emphasis := ast .NewEmphasis (2 )
224
- emphasis .SetAttributeString ("class" , []byte ("attention-" + attentionType ))
225
-
226
- // capitalize first letter
227
- attentionText := ast .NewString ([]byte (strings .ToUpper (string (attentionType [0 ])) + attentionType [1 :]))
228
-
229
- // replace the ![TYPE] with a dedicated paragraph of icon+Type
230
- emphasis .AppendChild (emphasis , attentionText )
231
- attentionParagraph .AppendChild (attentionParagraph , NewAttention (attentionType ))
232
- attentionParagraph .AppendChild (attentionParagraph , emphasis )
233
- firstParagraph .Parent ().InsertBefore (firstParagraph .Parent (), firstParagraph , attentionParagraph )
234
- firstParagraph .RemoveChild (firstParagraph , firstTextNode )
235
- firstParagraph .RemoveChild (firstParagraph , secondTextNode )
236
- firstParagraph .RemoveChild (firstParagraph , thirdTextNode )
200
+ return g .transformBlockquote (v , reader )
237
201
}
238
202
return ast .WalkContinue , nil
239
203
})
@@ -268,7 +232,7 @@ func (p *prefixedIDs) Generate(value []byte, kind ast.NodeKind) []byte {
268
232
return p .GenerateWithDefault (value , dft )
269
233
}
270
234
271
- // Generate generates a new element id.
235
+ // GenerateWithDefault generates a new element id.
272
236
func (p * prefixedIDs ) GenerateWithDefault (value , dft []byte ) []byte {
273
237
result := common .CleanValue (value )
274
238
if len (result ) == 0 {
@@ -303,7 +267,8 @@ func newPrefixedIDs() *prefixedIDs {
303
267
// in the gitea form.
304
268
func NewHTMLRenderer (opts ... html.Option ) renderer.NodeRenderer {
305
269
r := & HTMLRenderer {
306
- Config : html .NewConfig (),
270
+ Config : html .NewConfig (),
271
+ reValidName : regexp .MustCompile ("^[a-z ]+$" ),
307
272
}
308
273
for _ , opt := range opts {
309
274
opt .SetHTMLOption (& r .Config )
@@ -315,6 +280,7 @@ func NewHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
315
280
// renders gitea specific features.
316
281
type HTMLRenderer struct {
317
282
html.Config
283
+ reValidName * regexp.Regexp
318
284
}
319
285
320
286
// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs.
@@ -442,11 +408,6 @@ func (r *HTMLRenderer) renderSummary(w util.BufWriter, source []byte, node ast.N
442
408
return ast .WalkContinue , nil
443
409
}
444
410
445
- var (
446
- validNameRE = regexp .MustCompile ("^[a-z ]+$" )
447
- attentionTypeRE = regexp .MustCompile ("^!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)$" )
448
- )
449
-
450
411
func (r * HTMLRenderer ) renderIcon (w util.BufWriter , source []byte , node ast.Node , entering bool ) (ast.WalkStatus , error ) {
451
412
if ! entering {
452
413
return ast .WalkContinue , nil
@@ -461,7 +422,7 @@ func (r *HTMLRenderer) renderIcon(w util.BufWriter, source []byte, node ast.Node
461
422
return ast .WalkContinue , nil
462
423
}
463
424
464
- if ! validNameRE .MatchString (name ) {
425
+ if ! r . reValidName .MatchString (name ) {
465
426
// skip this
466
427
return ast .WalkContinue , nil
467
428
}
0 commit comments