feat: render Markdown, mathematics and Mermaid diagrams server-side
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user