package ast

import (
	
	

	textm 
)

// A BaseBlock struct implements the Node interface partialliy.
type BaseBlock struct {
	BaseNode
	blankPreviousLines bool
	lines              *textm.Segments
}

// Type implements Node.Type.
func ( *BaseBlock) () NodeType {
	return TypeBlock
}

// IsRaw implements Node.IsRaw.
func ( *BaseBlock) () bool {
	return false
}

// HasBlankPreviousLines implements Node.HasBlankPreviousLines.
func ( *BaseBlock) () bool {
	return .blankPreviousLines
}

// SetBlankPreviousLines implements Node.SetBlankPreviousLines.
func ( *BaseBlock) ( bool) {
	.blankPreviousLines = 
}

// Lines implements Node.Lines.
func ( *BaseBlock) () *textm.Segments {
	if .lines == nil {
		.lines = textm.NewSegments()
	}
	return .lines
}

// SetLines implements Node.SetLines.
func ( *BaseBlock) ( *textm.Segments) {
	.lines = 
}

// A Document struct is a root node of Markdown text.
type Document struct {
	BaseBlock

	meta map[string]interface{}
}

// KindDocument is a NodeKind of the Document node.
var KindDocument = NewNodeKind("Document")

// Dump implements Node.Dump .
func ( *Document) ( []byte,  int) {
	DumpHelper(, , , nil, nil)
}

// Type implements Node.Type .
func ( *Document) () NodeType {
	return TypeDocument
}

// Kind implements Node.Kind.
func ( *Document) () NodeKind {
	return KindDocument
}

// OwnerDocument implements Node.OwnerDocument.
func ( *Document) () *Document {
	return 
}

// Meta returns metadata of this document.
func ( *Document) () map[string]interface{} {
	if .meta == nil {
		.meta = map[string]interface{}{}
	}
	return .meta
}

// SetMeta sets given metadata to this document.
func ( *Document) ( map[string]interface{}) {
	if .meta == nil {
		.meta = map[string]interface{}{}
	}
	for ,  := range  {
		.meta[] = 
	}
}

// AddMeta adds given metadata to this document.
func ( *Document) ( string,  interface{}) {
	if .meta == nil {
		.meta = map[string]interface{}{}
	}
	.meta[] = 
}

// NewDocument returns a new Document node.
func () *Document {
	return &Document{
		BaseBlock: BaseBlock{},
		meta:      nil,
	}
}

// A TextBlock struct is a node whose lines
// should be rendered without any containers.
type TextBlock struct {
	BaseBlock
}

// Dump implements Node.Dump .
func ( *TextBlock) ( []byte,  int) {
	DumpHelper(, , , nil, nil)
}

// KindTextBlock is a NodeKind of the TextBlock node.
var KindTextBlock = NewNodeKind("TextBlock")

// Kind implements Node.Kind.
func ( *TextBlock) () NodeKind {
	return KindTextBlock
}

// NewTextBlock returns a new TextBlock node.
func () *TextBlock {
	return &TextBlock{
		BaseBlock: BaseBlock{},
	}
}

// A Paragraph struct represents a paragraph of Markdown text.
type Paragraph struct {
	BaseBlock
}

// Dump implements Node.Dump .
func ( *Paragraph) ( []byte,  int) {
	DumpHelper(, , , nil, nil)
}

// KindParagraph is a NodeKind of the Paragraph node.
var KindParagraph = NewNodeKind("Paragraph")

// Kind implements Node.Kind.
func ( *Paragraph) () NodeKind {
	return KindParagraph
}

// NewParagraph returns a new Paragraph node.
func () *Paragraph {
	return &Paragraph{
		BaseBlock: BaseBlock{},
	}
}

// IsParagraph returns true if the given node implements the Paragraph interface,
// otherwise false.
func ( Node) bool {
	,  := .(*Paragraph)
	return 
}

// A Heading struct represents headings like SetextHeading and ATXHeading.
type Heading struct {
	BaseBlock
	// Level returns a level of this heading.
	// This value is between 1 and 6.
	Level int
}

// Dump implements Node.Dump .
func ( *Heading) ( []byte,  int) {
	 := map[string]string{
		"Level": fmt.Sprintf("%d", .Level),
	}
	DumpHelper(, , , , nil)
}

// KindHeading is a NodeKind of the Heading node.
var KindHeading = NewNodeKind("Heading")

// Kind implements Node.Kind.
func ( *Heading) () NodeKind {
	return KindHeading
}

// NewHeading returns a new Heading node.
func ( int) *Heading {
	return &Heading{
		BaseBlock: BaseBlock{},
		Level:     ,
	}
}

// A ThematicBreak struct represents a thematic break of Markdown text.
type ThematicBreak struct {
	BaseBlock
}

// Dump implements Node.Dump .
func ( *ThematicBreak) ( []byte,  int) {
	DumpHelper(, , , nil, nil)
}

// KindThematicBreak is a NodeKind of the ThematicBreak node.
var KindThematicBreak = NewNodeKind("ThematicBreak")

// Kind implements Node.Kind.
func ( *ThematicBreak) () NodeKind {
	return KindThematicBreak
}

// NewThematicBreak returns a new ThematicBreak node.
func () *ThematicBreak {
	return &ThematicBreak{
		BaseBlock: BaseBlock{},
	}
}

// A CodeBlock interface represents an indented code block of Markdown text.
type CodeBlock struct {
	BaseBlock
}

// IsRaw implements Node.IsRaw.
func ( *CodeBlock) () bool {
	return true
}

// Dump implements Node.Dump .
func ( *CodeBlock) ( []byte,  int) {
	DumpHelper(, , , nil, nil)
}

// KindCodeBlock is a NodeKind of the CodeBlock node.
var KindCodeBlock = NewNodeKind("CodeBlock")

// Kind implements Node.Kind.
func ( *CodeBlock) () NodeKind {
	return KindCodeBlock
}

// NewCodeBlock returns a new CodeBlock node.
func () *CodeBlock {
	return &CodeBlock{
		BaseBlock: BaseBlock{},
	}
}

// A FencedCodeBlock struct represents a fenced code block of Markdown text.
type FencedCodeBlock struct {
	BaseBlock
	// Info returns a info text of this fenced code block.
	Info *Text

	language []byte
}

// Language returns an language in an info string.
// Language returns nil if this node does not have an info string.
func ( *FencedCodeBlock) ( []byte) []byte {
	if .language == nil && .Info != nil {
		 := .Info.Segment
		 := .Value()
		 := 0
		for ;  < len(); ++ {
			if [] == ' ' {
				break
			}
		}
		.language = [:]
	}
	return .language
}

// IsRaw implements Node.IsRaw.
func ( *FencedCodeBlock) () bool {
	return true
}

// Dump implements Node.Dump .
func ( *FencedCodeBlock) ( []byte,  int) {
	 := map[string]string{}
	if .Info != nil {
		["Info"] = fmt.Sprintf("\"%s\"", .Info.Text())
	}
	DumpHelper(, , , , nil)
}

// KindFencedCodeBlock is a NodeKind of the FencedCodeBlock node.
var KindFencedCodeBlock = NewNodeKind("FencedCodeBlock")

// Kind implements Node.Kind.
func ( *FencedCodeBlock) () NodeKind {
	return KindFencedCodeBlock
}

// NewFencedCodeBlock return a new FencedCodeBlock node.
func ( *Text) *FencedCodeBlock {
	return &FencedCodeBlock{
		BaseBlock: BaseBlock{},
		Info:      ,
	}
}

// A Blockquote struct represents an blockquote block of Markdown text.
type Blockquote struct {
	BaseBlock
}

// Dump implements Node.Dump .
func ( *Blockquote) ( []byte,  int) {
	DumpHelper(, , , nil, nil)
}

// KindBlockquote is a NodeKind of the Blockquote node.
var KindBlockquote = NewNodeKind("Blockquote")

// Kind implements Node.Kind.
func ( *Blockquote) () NodeKind {
	return KindBlockquote
}

// NewBlockquote returns a new Blockquote node.
func () *Blockquote {
	return &Blockquote{
		BaseBlock: BaseBlock{},
	}
}

// A List struct represents a list of Markdown text.
type List struct {
	BaseBlock

	// Marker is a marker character like '-', '+', ')' and '.'.
	Marker byte

	// IsTight is a true if this list is a 'tight' list.
	// See https://spec.commonmark.org/0.30/#loose for details.
	IsTight bool

	// Start is an initial number of this ordered list.
	// If this list is not an ordered list, Start is 0.
	Start int
}

// IsOrdered returns true if this list is an ordered list, otherwise false.
func ( *List) () bool {
	return .Marker == '.' || .Marker == ')'
}

// CanContinue returns true if this list can continue with
// the given mark and a list type, otherwise false.
func ( *List) ( byte,  bool) bool {
	return  == .Marker &&  == .IsOrdered()
}

// Dump implements Node.Dump.
func ( *List) ( []byte,  int) {
	 := map[string]string{
		"Ordered": fmt.Sprintf("%v", .IsOrdered()),
		"Marker":  fmt.Sprintf("%c", .Marker),
		"Tight":   fmt.Sprintf("%v", .IsTight),
	}
	if .IsOrdered() {
		["Start"] = fmt.Sprintf("%d", .Start)
	}
	DumpHelper(, , , , nil)
}

// KindList is a NodeKind of the List node.
var KindList = NewNodeKind("List")

// Kind implements Node.Kind.
func ( *List) () NodeKind {
	return KindList
}

// NewList returns a new List node.
func ( byte) *List {
	return &List{
		BaseBlock: BaseBlock{},
		Marker:    ,
		IsTight:   true,
	}
}

// A ListItem struct represents a list item of Markdown text.
type ListItem struct {
	BaseBlock

	// Offset is an offset position of this item.
	Offset int
}

// Dump implements Node.Dump.
func ( *ListItem) ( []byte,  int) {
	 := map[string]string{
		"Offset": fmt.Sprintf("%d", .Offset),
	}
	DumpHelper(, , , , nil)
}

// KindListItem is a NodeKind of the ListItem node.
var KindListItem = NewNodeKind("ListItem")

// Kind implements Node.Kind.
func ( *ListItem) () NodeKind {
	return KindListItem
}

// NewListItem returns a new ListItem node.
func ( int) *ListItem {
	return &ListItem{
		BaseBlock: BaseBlock{},
		Offset:    ,
	}
}

// HTMLBlockType represents kinds of an html blocks.
// See https://spec.commonmark.org/0.30/#html-blocks
type HTMLBlockType int

const (
	// HTMLBlockType1 represents type 1 html blocks.
	HTMLBlockType1 HTMLBlockType = iota + 1
	// HTMLBlockType2 represents type 2 html blocks.
	HTMLBlockType2
	// HTMLBlockType3 represents type 3 html blocks.
	HTMLBlockType3
	// HTMLBlockType4 represents type 4 html blocks.
	HTMLBlockType4
	// HTMLBlockType5 represents type 5 html blocks.
	HTMLBlockType5
	// HTMLBlockType6 represents type 6 html blocks.
	HTMLBlockType6
	// HTMLBlockType7 represents type 7 html blocks.
	HTMLBlockType7
)

// An HTMLBlock struct represents an html block of Markdown text.
type HTMLBlock struct {
	BaseBlock

	// Type is a type of this html block.
	HTMLBlockType HTMLBlockType

	// ClosureLine is a line that closes this html block.
	ClosureLine textm.Segment
}

// IsRaw implements Node.IsRaw.
func ( *HTMLBlock) () bool {
	return true
}

// HasClosure returns true if this html block has a closure line,
// otherwise false.
func ( *HTMLBlock) () bool {
	return .ClosureLine.Start >= 0
}

// Dump implements Node.Dump.
func ( *HTMLBlock) ( []byte,  int) {
	 := strings.Repeat("    ", )
	fmt.Printf("%s%s {\n", , "HTMLBlock")
	 := strings.Repeat("    ", +1)
	fmt.Printf("%sRawText: \"", )
	for  := 0;  < .Lines().Len(); ++ {
		 := .Lines().At()
		fmt.Print(string([.Start:.Stop]))
	}
	fmt.Printf("\"\n")
	for  := .FirstChild();  != nil;  = .NextSibling() {
		.Dump(, +1)
	}
	if .HasClosure() {
		 := .ClosureLine
		fmt.Printf("%sClosure: \"%s\"\n", , string(.Value()))
	}
	fmt.Printf("%s}\n", )
}

// KindHTMLBlock is a NodeKind of the HTMLBlock node.
var KindHTMLBlock = NewNodeKind("HTMLBlock")

// Kind implements Node.Kind.
func ( *HTMLBlock) () NodeKind {
	return KindHTMLBlock
}

// NewHTMLBlock returns a new HTMLBlock node.
func ( HTMLBlockType) *HTMLBlock {
	return &HTMLBlock{
		BaseBlock:     BaseBlock{},
		HTMLBlockType: ,
		ClosureLine:   textm.NewSegment(-1, -1),
	}
}