github.com/anakojm/hugo-katex@v0.0.0-20231023141351-42d6f5de9c0b/markup/goldmark/images/transform.go (about) 1 package images 2 3 import ( 4 "github.com/yuin/goldmark" 5 "github.com/yuin/goldmark/ast" 6 "github.com/yuin/goldmark/parser" 7 "github.com/yuin/goldmark/text" 8 "github.com/yuin/goldmark/util" 9 ) 10 11 type ( 12 imagesExtension struct { 13 wrapStandAloneImageWithinParagraph bool 14 } 15 ) 16 17 const ( 18 // Used to signal to the rendering step that an image is used in a block context. 19 // Dont's change this; the prefix must match the internalAttrPrefix in the root goldmark package. 20 AttrIsBlock = "_h__isBlock" 21 AttrOrdinal = "_h__ordinal" 22 ) 23 24 func New(wrapStandAloneImageWithinParagraph bool) goldmark.Extender { 25 return &imagesExtension{wrapStandAloneImageWithinParagraph: wrapStandAloneImageWithinParagraph} 26 } 27 28 func (e *imagesExtension) Extend(m goldmark.Markdown) { 29 m.Parser().AddOptions( 30 parser.WithASTTransformers( 31 util.Prioritized(&Transformer{wrapStandAloneImageWithinParagraph: e.wrapStandAloneImageWithinParagraph}, 300), 32 ), 33 ) 34 } 35 36 type Transformer struct { 37 wrapStandAloneImageWithinParagraph bool 38 } 39 40 // Transform transforms the provided Markdown AST. 41 func (t *Transformer) Transform(doc *ast.Document, reader text.Reader, pctx parser.Context) { 42 var ordinal int 43 ast.Walk(doc, func(node ast.Node, enter bool) (ast.WalkStatus, error) { 44 if !enter { 45 return ast.WalkContinue, nil 46 } 47 48 if n, ok := node.(*ast.Image); ok { 49 parent := n.Parent() 50 n.SetAttributeString(AttrOrdinal, ordinal) 51 ordinal++ 52 53 if !t.wrapStandAloneImageWithinParagraph { 54 isBlock := parent.ChildCount() == 1 55 if isBlock { 56 n.SetAttributeString(AttrIsBlock, true) 57 } 58 59 if isBlock && parent.Kind() == ast.KindParagraph { 60 for _, attr := range parent.Attributes() { 61 // Transfer any attribute set down to the image. 62 // Image elements does not support attributes on its own, 63 // so it's safe to just set without checking first. 64 n.SetAttribute(attr.Name, attr.Value) 65 } 66 grandParent := parent.Parent() 67 grandParent.ReplaceChild(grandParent, parent, n) 68 } 69 } 70 71 } 72 73 return ast.WalkContinue, nil 74 75 }) 76 77 }