117 lines
2.9 KiB
Go
117 lines
2.9 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (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
|
|
}
|