...

Source file src/github.com/yuin/goldmark/extension/strikethrough.go

Documentation: github.com/yuin/goldmark/extension

     1  package extension
     2  
     3  import (
     4  	"github.com/yuin/goldmark"
     5  	gast "github.com/yuin/goldmark/ast"
     6  	"github.com/yuin/goldmark/extension/ast"
     7  	"github.com/yuin/goldmark/parser"
     8  	"github.com/yuin/goldmark/renderer"
     9  	"github.com/yuin/goldmark/renderer/html"
    10  	"github.com/yuin/goldmark/text"
    11  	"github.com/yuin/goldmark/util"
    12  )
    13  
    14  type strikethroughDelimiterProcessor struct {
    15  }
    16  
    17  func (p *strikethroughDelimiterProcessor) IsDelimiter(b byte) bool {
    18  	return b == '~'
    19  }
    20  
    21  func (p *strikethroughDelimiterProcessor) CanOpenCloser(opener, closer *parser.Delimiter) bool {
    22  	return opener.Char == closer.Char
    23  }
    24  
    25  func (p *strikethroughDelimiterProcessor) OnMatch(consumes int) gast.Node {
    26  	return ast.NewStrikethrough()
    27  }
    28  
    29  var defaultStrikethroughDelimiterProcessor = &strikethroughDelimiterProcessor{}
    30  
    31  type strikethroughParser struct {
    32  }
    33  
    34  var defaultStrikethroughParser = &strikethroughParser{}
    35  
    36  // NewStrikethroughParser return a new InlineParser that parses
    37  // strikethrough expressions.
    38  func NewStrikethroughParser() parser.InlineParser {
    39  	return defaultStrikethroughParser
    40  }
    41  
    42  func (s *strikethroughParser) Trigger() []byte {
    43  	return []byte{'~'}
    44  }
    45  
    46  func (s *strikethroughParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node {
    47  	before := block.PrecendingCharacter()
    48  	line, segment := block.PeekLine()
    49  	node := parser.ScanDelimiter(line, before, 2, defaultStrikethroughDelimiterProcessor)
    50  	if node == nil {
    51  		return nil
    52  	}
    53  	node.Segment = segment.WithStop(segment.Start + node.OriginalLength)
    54  	block.Advance(node.OriginalLength)
    55  	pc.PushDelimiter(node)
    56  	return node
    57  }
    58  
    59  func (s *strikethroughParser) CloseBlock(parent gast.Node, pc parser.Context) {
    60  	// nothing to do
    61  }
    62  
    63  // StrikethroughHTMLRenderer is a renderer.NodeRenderer implementation that
    64  // renders Strikethrough nodes.
    65  type StrikethroughHTMLRenderer struct {
    66  	html.Config
    67  }
    68  
    69  // NewStrikethroughHTMLRenderer returns a new StrikethroughHTMLRenderer.
    70  func NewStrikethroughHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
    71  	r := &StrikethroughHTMLRenderer{
    72  		Config: html.NewConfig(),
    73  	}
    74  	for _, opt := range opts {
    75  		opt.SetHTMLOption(&r.Config)
    76  	}
    77  	return r
    78  }
    79  
    80  // RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs.
    81  func (r *StrikethroughHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
    82  	reg.Register(ast.KindStrikethrough, r.renderStrikethrough)
    83  }
    84  
    85  // StrikethroughAttributeFilter defines attribute names which dd elements can have.
    86  var StrikethroughAttributeFilter = html.GlobalAttributeFilter
    87  
    88  func (r *StrikethroughHTMLRenderer) renderStrikethrough(w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) {
    89  	if entering {
    90  		if n.Attributes() != nil {
    91  			_, _ = w.WriteString("<del")
    92  			html.RenderAttributes(w, n, StrikethroughAttributeFilter)
    93  			_ = w.WriteByte('>')
    94  		} else {
    95  			_, _ = w.WriteString("<del>")
    96  		}
    97  	} else {
    98  		_, _ = w.WriteString("</del>")
    99  	}
   100  	return gast.WalkContinue, nil
   101  }
   102  
   103  type strikethrough struct {
   104  }
   105  
   106  // Strikethrough is an extension that allow you to use strikethrough expression like '~~text~~' .
   107  var Strikethrough = &strikethrough{}
   108  
   109  func (e *strikethrough) Extend(m goldmark.Markdown) {
   110  	m.Parser().AddOptions(parser.WithInlineParsers(
   111  		util.Prioritized(NewStrikethroughParser(), 500),
   112  	))
   113  	m.Renderer().AddOptions(renderer.WithNodeRenderers(
   114  		util.Prioritized(NewStrikethroughHTMLRenderer(), 500),
   115  	))
   116  }
   117  

View as plain text