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  }