@@ -15,7 +15,7 @@ import (
1515 "golang.org/x/text/language"
1616)
1717
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
1919func (r * HTMLRenderer ) renderAttention (w util.BufWriter , source []byte , node ast.Node , entering bool ) (ast.WalkStatus , error ) {
2020 if entering {
2121 n := node .(* Attention )
@@ -37,38 +37,93 @@ func (r *HTMLRenderer) renderAttention(w util.BufWriter, source []byte, node ast
3737 return ast .WalkContinue , nil
3838}
3939
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+ }
4355
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 ) {
4780 if firstParagraph .ChildCount () < 3 {
48- return ast . WalkContinue , nil
81+ return "" , nil
4982 }
5083 node1 , ok := firstParagraph .FirstChild ().(* ast.Text )
5184 if ! ok {
52- return ast . WalkContinue , nil
85+ return "" , nil
5386 }
5487 node2 , ok := node1 .NextSibling ().(* ast.Text )
5588 if ! ok {
56- return ast . WalkContinue , nil
89+ return "" , nil
5790 }
5891 node3 , ok := node2 .NextSibling ().(* ast.Text )
5992 if ! ok {
60- return ast . WalkContinue , nil
93+ return "" , nil
6194 }
6295 val1 := string (node1 .Segment .Value (reader .Source ()))
6396 val2 := string (node2 .Segment .Value (reader .Source ()))
6497 val3 := string (node3 .Segment .Value (reader .Source ()))
6598 if val1 != "[" || val3 != "]" || ! strings .HasPrefix (val2 , "!" ) {
66- return ast . WalkContinue , nil
99+ return "" , nil
67100 }
68101
69- // grab attention type from markdown source
70102 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 == "" {
72127 return ast .WalkContinue , nil
73128 }
74129
@@ -88,9 +143,9 @@ func (g *ASTTransformer) transformBlockquote(v *ast.Blockquote, reader text.Read
88143 attentionParagraph .AppendChild (attentionParagraph , NewAttention (attentionType ))
89144 attentionParagraph .AppendChild (attentionParagraph , emphasis )
90145 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+ }
94149 if firstParagraph .ChildCount () == 0 {
95150 firstParagraph .Parent ().RemoveChild (firstParagraph .Parent (), firstParagraph )
96151 }
0 commit comments