package parser

import (
	
	
	
)
A HeadingConfig struct is a data structure that holds configuration of the renderers related to headings.
SetOption implements SetOptioner.
func ( *HeadingConfig) ( OptionName,  interface{}) {
	switch  {
	case optAutoHeadingID:
		.AutoHeadingID = true
	case optAttribute:
		.Attribute = true
	}
}
A HeadingOption interface sets options for heading parsers.
type HeadingOption interface {
	Option
	SetHeadingOption(*HeadingConfig)
}
AutoHeadingID is an option name that enables auto IDs for headings.
WithAutoHeadingID is a functional option that enables custom heading ids and auto generated heading ids.
WithHeadingAttribute is a functional option that enables custom heading attributes.
NewATXHeadingParser return a new BlockParser that can parse ATX headings.
func ( ...HeadingOption) BlockParser {
	 := &atxHeadingParser{}
	for ,  := range  {
		.SetHeadingOption(&.HeadingConfig)
	}
	return 
}

func ( *atxHeadingParser) () []byte {
	return []byte{'#'}
}

func ( *atxHeadingParser) ( ast.Node,  text.Reader,  Context) (ast.Node, State) {
	,  := .PeekLine()
	 := .BlockOffset()
	if  < 0 {
		return nil, NoChildren
	}
	 := 
	for ;  < len() && [] == '#'; ++ {
	}
	 :=  - 
	if  ==  ||  > 6 {
		return nil, NoChildren
	}
	 := util.TrimLeftSpaceLength([:])
	if  == 0 {
		return nil, NoChildren
	}
	 :=  + 
	if  >= len() {
		 = len() - 1
	}
	 := 
	 := len() - util.TrimRightSpaceLength()

	 := ast.NewHeading()
	 := false
	if .Attribute { // handles special case like ### heading ### {#id}
		--
		 := -1
		 := -1
		for  := ;  < ; {
			 := []
			if util.IsEscapedPunctuation(, ) {
				 += 2
			} else if util.IsSpace() &&  < -1 && [+1] == '#' {
				 =  + 1
				 :=  + 1
				for ;  <  && [] == '#'; ++ {
				}
				 = 
				break
			} else {
				++
			}
		}
		if  > 0 {
			.Advance()
			,  := ParseAttributes()
			,  := .PeekLine()
			 =  && util.IsBlank()
			if  {
				for ,  := range  {
					.SetAttribute(.Name, .Value)
				}
				.Lines().Append(text.NewSegment(.Start++1-.Padding, .Start+-.Padding))
			}
		}
	}
	if ! {
		 = 
		 := len() - util.TrimRightSpaceLength()
		if  <=  { // empty headings like '##[space]'
			 = 
		} else {
			 =  - 1
			for ; [] == '#' &&  >= ; -- {
			}
			if  != -1 && !util.IsSpace([]) {
				 =  - 1
			}
			++
			 = 
		}

		if len(util.TrimRight([:], []byte{'#'})) != 0 { // empty heading like '### ###'
			.Lines().Append(text.NewSegment(.Start+-.Padding, .Start+-.Padding))
		}
	}
	return , NoChildren
}

func ( *atxHeadingParser) ( ast.Node,  text.Reader,  Context) State {
	return Close
}

func ( *atxHeadingParser) ( ast.Node,  text.Reader,  Context) {
	if .Attribute {
		,  := .AttributeString("id")
		if ! {
			parseLastLineAttributes(, , )
		}
	}

	if .AutoHeadingID {
		,  := .AttributeString("id")
		if ! {
			generateAutoHeadingID(.(*ast.Heading), , )
		} else {
			.IDs().Put(.([]byte))
		}
	}
}

func ( *atxHeadingParser) () bool {
	return true
}

func ( *atxHeadingParser) () bool {
	return false
}

func ( *ast.Heading,  text.Reader,  Context) {
	var  []byte
	 := .Lines().Len() - 1
	if  > -1 {
		 := .Lines().At()
		 = .Value(.Source())
	}
	 := .IDs().Generate(, ast.KindHeading)
	.SetAttribute(attrNameID, )
}

func ( ast.Node,  text.Reader,  Context) {
	 := .Lines().Len() - 1
	if  < 0 { // empty headings
		return
	}
	 := .Lines().At()
	 := .Value(.Source())
	 := text.NewReader()
	var  Attributes
	var  bool
	var  text.Segment
	var  int
	var  text.Segment
	for {
		 := .Peek()
		if  == text.EOF {
			break
		}
		if  == '\\' {
			.Advance(1)
			if .Peek() == '{' {
				.Advance(1)
			}
			continue
		}
		if  == '{' {
			,  = .Position()
			,  = ParseAttributes()
			_,  = .Position()
			.SetPosition(, )
		}
		.Advance(1)
	}
	if  && util.IsBlank([.Start:]) {
		for ,  := range  {
			.SetAttribute(.Name, .Value)
		}
		.Stop = .Start + .Start
		.Lines().Set(, )
	}