@@ -15,7 +15,7 @@ import (
15
15
"golang.org/x/text/language"
16
16
)
17
17
18
- // renderAttention renders a quote marked with i.e. "> **Note**" or "> ** Warning** " with a corresponding svg
18
+ // renderAttention renders a quote marked with i.e. "> **Note**" or "> [! Warning] " with a corresponding svg
19
19
func (r * HTMLRenderer ) renderAttention (w util.BufWriter , source []byte , node ast.Node , entering bool ) (ast.WalkStatus , error ) {
20
20
if entering {
21
21
n := node .(* Attention )
@@ -37,38 +37,93 @@ func (r *HTMLRenderer) renderAttention(w util.BufWriter, source []byte, node ast
37
37
return ast .WalkContinue , nil
38
38
}
39
39
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("]")
40
+ func (g * ASTTransformer ) extractBlockquoteAttentionEmphasis (firstParagraph ast.Node , reader text.Reader ) (string , []ast.Node ) {
41
+ if firstParagraph .ChildCount () < 1 {
42
+ return "" , nil
43
+ }
44
+ node1 , ok := firstParagraph .FirstChild ().(* ast.Emphasis )
45
+ if ! ok {
46
+ return "" , nil
47
+ }
48
+ val1 := string (node1 .Text (reader .Source ()))
49
+ attentionType := strings .ToLower (val1 )
50
+ if g .attentionTypes .Contains (attentionType ) {
51
+ return attentionType , []ast.Node {node1 }
52
+ }
53
+ return "" , nil
54
+ }
43
55
44
- // grab these nodes and make sure we adhere to the attention blockquote structure
45
- firstParagraph := v .FirstChild ()
46
- g .applyElementDir (firstParagraph )
56
+ func (g * ASTTransformer ) extractBlockquoteAttention2 (firstParagraph ast.Node , reader text.Reader ) (string , []ast.Node ) {
57
+ if firstParagraph .ChildCount () < 2 {
58
+ return "" , nil
59
+ }
60
+ node1 , ok := firstParagraph .FirstChild ().(* ast.Text )
61
+ if ! ok {
62
+ return "" , nil
63
+ }
64
+ node2 , ok := node1 .NextSibling ().(* ast.Text )
65
+ if ! ok {
66
+ return "" , nil
67
+ }
68
+ val1 := string (node1 .Segment .Value (reader .Source ()))
69
+ val2 := string (node2 .Segment .Value (reader .Source ()))
70
+ if strings .HasPrefix (val1 , `\[!` ) && val2 == `\]` {
71
+ attentionType := strings .ToLower (val1 [3 :])
72
+ if g .attentionTypes .Contains (attentionType ) {
73
+ return attentionType , []ast.Node {node1 , node2 }
74
+ }
75
+ }
76
+ return "" , nil
77
+ }
78
+
79
+ func (g * ASTTransformer ) extractBlockquoteAttention3 (firstParagraph ast.Node , reader text.Reader ) (string , []ast.Node ) {
47
80
if firstParagraph .ChildCount () < 3 {
48
- return ast . WalkContinue , nil
81
+ return "" , nil
49
82
}
50
83
node1 , ok := firstParagraph .FirstChild ().(* ast.Text )
51
84
if ! ok {
52
- return ast . WalkContinue , nil
85
+ return "" , nil
53
86
}
54
87
node2 , ok := node1 .NextSibling ().(* ast.Text )
55
88
if ! ok {
56
- return ast . WalkContinue , nil
89
+ return "" , nil
57
90
}
58
91
node3 , ok := node2 .NextSibling ().(* ast.Text )
59
92
if ! ok {
60
- return ast . WalkContinue , nil
93
+ return "" , nil
61
94
}
62
95
val1 := string (node1 .Segment .Value (reader .Source ()))
63
96
val2 := string (node2 .Segment .Value (reader .Source ()))
64
97
val3 := string (node3 .Segment .Value (reader .Source ()))
65
98
if val1 != "[" || val3 != "]" || ! strings .HasPrefix (val2 , "!" ) {
66
- return ast . WalkContinue , nil
99
+ return "" , nil
67
100
}
68
101
69
- // grab attention type from markdown source
70
102
attentionType := strings .ToLower (val2 [1 :])
71
- if ! g .attentionTypes .Contains (attentionType ) {
103
+ if g .attentionTypes .Contains (attentionType ) {
104
+ return attentionType , []ast.Node {node1 , node2 , node3 }
105
+ }
106
+ return "" , nil
107
+ }
108
+
109
+ func (g * ASTTransformer ) transformBlockquote (v * ast.Blockquote , reader text.Reader ) (ast.WalkStatus , error ) {
110
+ // We only want attention blockquotes when the AST looks like:
111
+ // > Text("[") Text("!TYPE") Text("]")
112
+ // > Text("\[!TYPE") TEXT("\]")
113
+ // > Text("**TYPE**")
114
+
115
+ // grab these nodes and make sure we adhere to the attention blockquote structure
116
+ firstParagraph := v .FirstChild ()
117
+ g .applyElementDir (firstParagraph )
118
+
119
+ attentionType , processedNodes := g .extractBlockquoteAttentionEmphasis (firstParagraph , reader )
120
+ if attentionType == "" {
121
+ attentionType , processedNodes = g .extractBlockquoteAttention2 (firstParagraph , reader )
122
+ }
123
+ if attentionType == "" {
124
+ attentionType , processedNodes = g .extractBlockquoteAttention3 (firstParagraph , reader )
125
+ }
126
+ if attentionType == "" {
72
127
return ast .WalkContinue , nil
73
128
}
74
129
@@ -88,9 +143,9 @@ func (g *ASTTransformer) transformBlockquote(v *ast.Blockquote, reader text.Read
88
143
attentionParagraph .AppendChild (attentionParagraph , NewAttention (attentionType ))
89
144
attentionParagraph .AppendChild (attentionParagraph , emphasis )
90
145
firstParagraph .Parent ().InsertBefore (firstParagraph .Parent (), firstParagraph , attentionParagraph )
91
- firstParagraph . RemoveChild ( firstParagraph , node1 )
92
- firstParagraph .RemoveChild (firstParagraph , node2 )
93
- firstParagraph . RemoveChild ( firstParagraph , node3 )
146
+ for _ , processed := range processedNodes {
147
+ firstParagraph .RemoveChild (firstParagraph , processed )
148
+ }
94
149
if firstParagraph .ChildCount () == 0 {
95
150
firstParagraph .Parent ().RemoveChild (firstParagraph .Parent (), firstParagraph )
96
151
}
0 commit comments