// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: MIT package markdown // nodeKind identifies a block node of the document tree. type nodeKind uint8 const ( kindDocument nodeKind = iota kindParagraph kindHeading kindCodeBlock kindHTMLBlock kindBlockquote kindList kindListItem kindThematicBreak kindTable kindFootnoteDef kindDefList kindDefTerm kindDefItem ) // listKind distinguishes bullet lists from ordered lists. type listKind uint8 const ( bulletList listKind = iota orderedList ) // Column alignment of a table, carried per column. const ( alignNone uint8 = iota alignLeft alignCentre alignRight ) // Node is one block of the parsed document. The zero value is a document // root; every other kind is created by the parser. type Node struct { kind nodeKind parent *Node children []*Node // content holds the raw text of a leaf block: paragraph or heading // inline text, code source, or the lines of an HTML block. content []byte level int // heading level, 1 to 6 fenced bool // code block opened by a fence fenceChar byte // fence character, '`' or '~' fenceLength int // length of the opening fence fenceOffset int // columns of indentation before the opening fence info string htmlType int // HTML block start condition, 1 to 7 listKind listKind bulletChar byte // bullet list: the marker character delimiter byte // ordered list: '.' or ')' start int // ordered list: number of the first item tight bool markerOffset int // item: indentation of the marker inside its container padding int // item: columns from the marker start to the content // refs collects the link reference definitions of the document; it is // carried by the root node only. refs map[string]reference // footnotes collects the footnote definitions of the document, in // document order; it is carried by the root node only. The renderer // orders the rendered section by reference. footnotes []*Node // label names a footnote definition. label string // table columns and rows, cells as raw inline content. align []uint8 header [][]byte rows [][][]byte task bool // item: the first paragraph begins with a task marker taskDone bool startLine int lastLineBlank bool lastLineChecked bool finalised bool } // reference is one link reference definition of the document. type reference struct { destination string title string hasTitle bool } // canContain reports whether parent accepts child blocks of the given kind. func canContain(parent, child nodeKind) bool { switch parent { case kindDocument, kindBlockquote, kindListItem, kindDefItem, kindFootnoteDef: return child != kindDocument case kindList: return child == kindListItem case kindDefList: return child == kindDefTerm || child == kindDefItem || child == kindParagraph } return false }