package extension

import (
	
	gast 
	
	
	
	
	
	
)

type strikethroughDelimiterProcessor struct {
}

func ( *strikethroughDelimiterProcessor) ( byte) bool {
	return  == '~'
}

func ( *strikethroughDelimiterProcessor) (,  *parser.Delimiter) bool {
	return .Char == .Char
}

func ( *strikethroughDelimiterProcessor) ( int) gast.Node {
	return ast.NewStrikethrough()
}

var defaultStrikethroughDelimiterProcessor = &strikethroughDelimiterProcessor{}

type strikethroughParser struct {
}

var defaultStrikethroughParser = &strikethroughParser{}

// NewStrikethroughParser return a new InlineParser that parses
// strikethrough expressions.
func () parser.InlineParser {
	return defaultStrikethroughParser
}

func ( *strikethroughParser) () []byte {
	return []byte{'~'}
}

func ( *strikethroughParser) ( gast.Node,  text.Reader,  parser.Context) gast.Node {
	 := .PrecendingCharacter()
	,  := .PeekLine()
	 := parser.ScanDelimiter(, , 1, defaultStrikethroughDelimiterProcessor)
	if  == nil || .OriginalLength > 2 ||  == '~' {
		return nil
	}

	.Segment = .WithStop(.Start + .OriginalLength)
	.Advance(.OriginalLength)
	.PushDelimiter()
	return 
}

func ( *strikethroughParser) ( gast.Node,  parser.Context) {
	// nothing to do
}

// StrikethroughHTMLRenderer is a renderer.NodeRenderer implementation that
// renders Strikethrough nodes.
type StrikethroughHTMLRenderer struct {
	html.Config
}

// NewStrikethroughHTMLRenderer returns a new StrikethroughHTMLRenderer.
func ( ...html.Option) renderer.NodeRenderer {
	 := &StrikethroughHTMLRenderer{
		Config: html.NewConfig(),
	}
	for ,  := range  {
		.SetHTMLOption(&.Config)
	}
	return 
}

// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs.
func ( *StrikethroughHTMLRenderer) ( renderer.NodeRendererFuncRegisterer) {
	.Register(ast.KindStrikethrough, .renderStrikethrough)
}

// StrikethroughAttributeFilter defines attribute names which dd elements can have.
var StrikethroughAttributeFilter = html.GlobalAttributeFilter

func ( *StrikethroughHTMLRenderer) (
	 util.BufWriter,  []byte,  gast.Node,  bool) (gast.WalkStatus, error) {
	if  {
		if .Attributes() != nil {
			_, _ = .WriteString("<del")
			html.RenderAttributes(, , StrikethroughAttributeFilter)
			_ = .WriteByte('>')
		} else {
			_, _ = .WriteString("<del>")
		}
	} else {
		_, _ = .WriteString("</del>")
	}
	return gast.WalkContinue, nil
}

type strikethrough struct {
}

// Strikethrough is an extension that allow you to use strikethrough expression like '~~text~~' .
var Strikethrough = &strikethrough{}

func ( *strikethrough) ( goldmark.Markdown) {
	.Parser().AddOptions(parser.WithInlineParsers(
		util.Prioritized(NewStrikethroughParser(), 500),
	))
	.Renderer().AddOptions(renderer.WithNodeRenderers(
		util.Prioritized(NewStrikethroughHTMLRenderer(), 500),
	))
}