package parser

import (
	
	

	
	
	
)

type rawHTMLParser struct {
}

var defaultRawHTMLParser = &rawHTMLParser{}

// NewRawHTMLParser return a new InlineParser that can parse
// inline htmls.
func () InlineParser {
	return defaultRawHTMLParser
}

func ( *rawHTMLParser) () []byte {
	return []byte{'<'}
}

func ( *rawHTMLParser) ( ast.Node,  text.Reader,  Context) ast.Node {
	,  := .PeekLine()
	if len() > 1 && util.IsAlphaNumeric([1]) {
		return .parseMultiLineRegexp(openTagRegexp, , )
	}
	if len() > 2 && [1] == '/' && util.IsAlphaNumeric([2]) {
		return .parseMultiLineRegexp(closeTagRegexp, , )
	}
	if bytes.HasPrefix(, openComment) {
		return .parseComment(, )
	}
	if bytes.HasPrefix(, openProcessingInstruction) {
		return .parseUntil(, closeProcessingInstruction, )
	}
	if len() > 2 && [1] == '!' && [2] >= 'A' && [2] <= 'Z' {
		return .parseUntil(, closeDecl, )
	}
	if bytes.HasPrefix(, openCDATA) {
		return .parseUntil(, closeCDATA, )
	}
	return nil
}

var tagnamePattern = `([A-Za-z][A-Za-z0-9-]*)`
var spaceOrOneNewline = `(?:[ \t]|(?:\r\n|\n){0,1})`
var attributePattern = `(?:[\r\n \t]+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:[\r\n \t]*=[\r\n \t]*(?:[^\"'=<>` + "`" + `\x00-\x20]+|'[^']*'|"[^"]*"))?)` //nolint:golint,lll
var openTagRegexp = regexp.MustCompile("^<" + tagnamePattern + attributePattern + `*` + spaceOrOneNewline + `*/?>`)
var closeTagRegexp = regexp.MustCompile("^</" + tagnamePattern + spaceOrOneNewline + `*>`)

var openProcessingInstruction = []byte("<?")
var closeProcessingInstruction = []byte("?>")
var openCDATA = []byte("<![CDATA[")
var closeCDATA = []byte("]]>")
var closeDecl = []byte(">")
var emptyComment1 = []byte("<!-->")
var emptyComment2 = []byte("<!--->")
var openComment = []byte("<!--")
var closeComment = []byte("-->")

func ( *rawHTMLParser) ( text.Reader,  Context) ast.Node {
	,  := .Position()
	 := ast.NewRawHTML()
	,  := .PeekLine()
	if bytes.HasPrefix(, emptyComment1) {
		.Segments.Append(.WithStop(.Start + len(emptyComment1)))
		.Advance(len(emptyComment1))
		return 
	}
	if bytes.HasPrefix(, emptyComment2) {
		.Segments.Append(.WithStop(.Start + len(emptyComment2)))
		.Advance(len(emptyComment2))
		return 
	}
	 := len(openComment)
	 = [:]
	for {
		 := bytes.Index(, closeComment)
		if  > -1 {
			.Segments.Append(.WithStop(.Start +  +  + len(closeComment)))
			.Advance( +  + len(closeComment))
			return 
		}
		 = 0
		.Segments.Append()
		.AdvanceLine()
		,  = .PeekLine()
		if  == nil {
			break
		}
	}
	.SetPosition(, )
	return nil
}

func ( *rawHTMLParser) ( text.Reader,  []byte,  Context) ast.Node {
	,  := .Position()
	 := ast.NewRawHTML()
	for {
		,  := .PeekLine()
		if  == nil {
			break
		}
		 := bytes.Index(, )
		if  > -1 {
			.Segments.Append(.WithStop(.Start +  + len()))
			.Advance( + len())
			return 
		}
		.Segments.Append()
		.AdvanceLine()
	}
	.SetPosition(, )
	return nil
}

func ( *rawHTMLParser) ( *regexp.Regexp,  text.Reader,  Context) ast.Node {
	,  := .Position()
	if .Match() {
		 := ast.NewRawHTML()
		,  := .Position()
		.SetPosition(, )
		for {
			,  := .PeekLine()
			if  == nil {
				break
			}
			,  := .Position()
			 := .Start
			if  ==  {
				 = .Start
			}
			 := .Stop
			if  ==  {
				 = .Start
			}

			.Segments.Append(text.NewSegment(, ))
			if  ==  {
				.Advance( - )
				break
			}
			.AdvanceLine()
		}
		return 
	}
	return nil
}