package parser

import (
	
	

	
	
	
)
A DelimiterProcessor interface provides a set of functions about Delimiter nodes.
IsDelimiter returns true if given character is a delimiter, otherwise false.
	IsDelimiter(byte) bool
CanOpenCloser returns true if given opener can close given closer, otherwise false.
	CanOpenCloser(opener, closer *Delimiter) bool
OnMatch will be called when new matched delimiter found. OnMatch should return a new Node correspond to the matched delimiter.
	OnMatch(consumes int) ast.Node
}
A Delimiter struct represents a delimiter like '*' of the Markdown text.
CanOpen is set true if this delimiter can open a span for a new node. See https://spec.commonmark.org/0.29/#can-open-emphasis for details.
CanClose is set true if this delimiter can close a span for a new node. See https://spec.commonmark.org/0.29/#can-open-emphasis for details.
Length is a remaining length of this delimiter.
OriginalLength is a original length of this delimiter.
Char is a character of this delimiter.
PreviousDelimiter is a previous sibling delimiter node of this delimiter.
NextDelimiter is a next sibling delimiter node of this delimiter.
Processor is a DelimiterProcessor associated with this delimiter.
Inline implements Inline.Inline.
func ( *Delimiter) () {}
Dump implements Node.Dump.
func ( *Delimiter) ( []byte,  int) {
	fmt.Printf("%sDelimiter: \"%s\"\n", strings.Repeat("    ", ), string(.Text()))
}

var kindDelimiter = ast.NewNodeKind("Delimiter")
Kind implements Node.Kind
func ( *Delimiter) () ast.NodeKind {
	return kindDelimiter
}
Text implements Node.Text
func ( *Delimiter) ( []byte) []byte {
	return .Segment.Value()
}
ConsumeCharacters consumes delimiters.
CalcComsumption calculates how many characters should be used for opening a new span correspond to given closer.
func ( *Delimiter) ( *Delimiter) int {
	if (.CanClose || .CanOpen) && (.OriginalLength+.OriginalLength)%3 == 0 && .OriginalLength%3 != 0 {
		return 0
	}
	if .Length >= 2 && .Length >= 2 {
		return 2
	}
	return 1
}
NewDelimiter returns a new Delimiter node.
func (,  bool,  int,  byte,  DelimiterProcessor) *Delimiter {
	 := &Delimiter{
		BaseInline:        ast.BaseInline{},
		CanOpen:           ,
		CanClose:          ,
		Length:            ,
		OriginalLength:    ,
		Char:              ,
		PreviousDelimiter: nil,
		NextDelimiter:     nil,
		Processor:         ,
	}
	return 
}
ScanDelimiter scans a delimiter by given DelimiterProcessor.
func ( []byte,  rune,  int,  DelimiterProcessor) *Delimiter {
	 := 0
	 := []
	 := 
	if !.IsDelimiter() {
		return nil
	}
	for ;  < len() &&  == []; ++ {
	}
	if ( - ) >=  {
		 := rune(' ')
		if  != len() {
			 = util.ToRune(, )
		}

		,  := false, false
		 := util.IsPunctRune()
		 := util.IsSpaceRune()
		 := util.IsPunctRune()
		 := util.IsSpaceRune()

		 := ! &&
			(! ||  || )
		 := ! &&
			(! ||  || )

		if [] == '_' {
			 =  && (! || )
			 =  && (! || )
		} else {
			 = 
			 = 
		}
		return NewDelimiter(, , -, , )
	}
	return nil
}
ProcessDelimiters processes the delimiter list in the context. Processing will be stop when reaching the bottom. If you implement an inline parser that can have other inline nodes as children, you should call this function when nesting span has closed.
func ( ast.Node,  Context) {
	 := .LastDelimiter()
	if  == nil {
		return
	}
	var  *Delimiter
	if  != nil {
		if  !=  {
			for  := .PreviousSibling();  != nil; {
				if ,  := .(*Delimiter);  {
					 = 
				}
				 := .PreviousSibling()
				if  ==  {
					break
				}
				 = 
			}
		}
	} else {
		 = .FirstDelimiter()
	}
	if  == nil {
		.ClearDelimiters()
		return
	}
	for  != nil {
		if !.CanClose {
			 = .NextDelimiter
			continue
		}
		 := 0
		 := false
		 := false
		var  *Delimiter
		for  = .PreviousDelimiter;  != nil;  = .PreviousDelimiter {
			if .CanOpen && .Processor.CanOpenCloser(, ) {
				 = true
				 = .CalcComsumption()
				if  > 0 {
					 = true
					break
				}
			}
		}
		if ! {
			if ! && !.CanOpen {
				.RemoveDelimiter()
			}
			 = .NextDelimiter
			continue
		}
		.ConsumeCharacters()
		.ConsumeCharacters()

		 := .Processor.OnMatch()

		 := .Parent()
		 := .NextSibling()

		for  != nil &&  !=  {
			 := .NextSibling()
			.AppendChild(, )
			 = 
		}
		.InsertAfter(, , )

		for  := .NextDelimiter;  != nil &&  != ; {
			 := .NextDelimiter
			.RemoveDelimiter()
			 = 
		}

		if .Length == 0 {
			.RemoveDelimiter()
		}

		if .Length == 0 {
			 := .NextDelimiter
			.RemoveDelimiter()
			 = 
		}
	}
	.ClearDelimiters()