Documentation
¶
Overview ¶
Package mdpp parses and renders Markdown++ documents.
MDPP keeps Markdown-compatible prose as the base syntax and adds structured nodes for technical writing features such as frontmatter, admonitions, footnotes, math, emoji shortcodes, task lists, and diagram fences. The parser is backed by gotreesitter and returns an AST that can be used by renderers, editors, formatters, diagnostics, and language service features.
Index ¶
- Constants
- Variables
- func EmojiShortcodes() []string
- func GrammarBlobHandler() http.Handler
- func Render(doc *Document, opts RenderOptions) ([]byte, error)
- func RenderString(source string) string
- func Slugify(s string) string
- type Diagnostic
- type Document
- func MustParse(source []byte) *Document
- func Parse(source []byte) (doc *Document, err error)
- func ParseIncremental(source []byte, prevTree *gotreesitter.Tree, edit gotreesitter.InputEdit) (doc *Document, tree *gotreesitter.Tree, err error)
- func ParseWithTree(source []byte) (doc *Document, tree *gotreesitter.Tree, err error)
- func SplitSlides(doc *Document) *Document
- func (d *Document) AST() *Node
- func (d *Document) Diagnostics() []Diagnostic
- func (d *Document) FormatVersion() string
- func (d *Document) Frontmatter() map[string]any
- func (d *Document) Headings() []Heading
- func (d *Document) ReadingTime() time.Duration
- func (d *Document) Slides() []*Node
- func (d *Document) TableOfContents() []TOCEntry
- func (d *Document) WordCount() int
- type Heading
- type MathOption
- type Node
- type NodeRenderer
- type NodeType
- type Option
- func WithContainerRenderer(fn func(c *Node, body string) string) Option
- func WithHardWraps(enabled bool) Option
- func WithHeadingIDs(enabled bool) Option
- func WithHighlightCode(enabled bool) Option
- func WithImageResolver(fn func(string) string) Option
- func WithNodeRenderer(typ NodeType, fn NodeRenderer) Option
- func WithSirenaRenderer(fn SirenaRenderer) Option
- func WithSourcePositions(enabled bool) Option
- func WithUnsafeHTML(enabled bool) Option
- func WithWrapEmoji(enabled bool) Option
- type Parser
- type Range
- type RenderFragment
- type RenderOptions
- type Renderer
- func (r *Renderer) Parse(source []byte) *Document
- func (r *Renderer) Render(doc *Document) string
- func (r *Renderer) RenderChildrenInto(b *strings.Builder, n *Node)
- func (r *Renderer) RenderNodeInto(b *strings.Builder, n *Node)
- func (r *Renderer) RenderString(source string) string
- func (r *Renderer) RenderWithFragments(doc *Document) (string, []RenderFragment)
- type Severity
- type SirenaFenceOptions
- type SirenaFenceResult
- type SirenaRenderer
- type TOCEntry
Constants ¶
const SpecVersion = "0.1"
SpecVersion is the Markdown++ format version implemented by this package.
const Version = "0.4.5"
Version is the Markdown++ engine version.
Variables ¶
var ( BuildCommit = "dev" BuildTime = "dev" )
BuildCommit and BuildTime may be injected by release builds with -ldflags.
Functions ¶
func EmojiShortcodes ¶
func EmojiShortcodes() []string
EmojiShortcodes returns the known emoji shortcode names in stable order.
func GrammarBlobHandler ¶
GrammarBlobHandler returns an HTTP handler that serves gotreesitter grammar blobs on demand. Mount it at /grammars/ and any browser-side WASM module can fetch language grammars one at a time.
URL pattern: /grammars/{language}.blob (e.g. /grammars/go.blob)
func Render ¶
func Render(doc *Document, opts RenderOptions) ([]byte, error)
Render produces HTML for a parsed document.
func RenderString ¶
RenderString is a package-level convenience that parses and renders Markdown to HTML with default settings.
Types ¶
type Diagnostic ¶
Diagnostic is a recoverable parser finding attached to a source range.
type Document ¶
Document is the top-level result of parsing a Markdown source.
func ParseIncremental ¶
func ParseIncremental(source []byte, prevTree *gotreesitter.Tree, edit gotreesitter.InputEdit) (doc *Document, tree *gotreesitter.Tree, err error)
ParseIncremental re-parses source by applying edit to prevTree and running the tree-sitter incremental parser. Callers must have produced prevTree from a prior ParseWithTree (or prior ParseIncremental) call against the pre-edit source. ParseIncremental takes ownership of prevTree and returns a fresh *Tree that the caller must eventually Release.
If the edit-applied source no longer satisfies the tree-sitter primary path (e.g. it now matches a container/all-indented/deep-nested fallback) this function falls back to a full parse and the returned Tree may be nil.
func ParseWithTree ¶
func ParseWithTree(source []byte) (doc *Document, tree *gotreesitter.Tree, err error)
ParseWithTree parses source and also returns the underlying tree-sitter Tree if the tree-sitter path was used. The returned *Tree is non-nil only when the primary tree-sitter path (not a fallback) produced the document. Callers that receive a non-nil Tree must eventually call tree.Release() (or feed it back into ParseIncremental, which takes ownership).
func SplitSlides ¶ added in v0.4.7
SplitSlides reinterprets a parsed document into a deck: it groups the document's top-level children into NodeSlide containers (see processSlides). It mutates and returns the same Document for chaining, and is idempotent — a second call on an already-split document is a no-op (it does not re-wrap the existing slides), so SplitSlides and Document.Slides are safe to mix on the same document.
A leading YAML/YML fenced code block on a slide is lifted into that slide's per-slide frontmatter (Attrs["frontmatter"]) and removed from its rendered children; deck-level frontmatter stays a document-level NodeFrontmatter sibling ahead of the first slide. See processSlides for the full rules.
func (*Document) Diagnostics ¶
func (d *Document) Diagnostics() []Diagnostic
Diagnostics returns recoverable parse diagnostics.
func (*Document) FormatVersion ¶
FormatVersion returns the frontmatter mdpp version, if declared.
func (*Document) Frontmatter ¶
Frontmatter returns the parsed frontmatter metadata, if any.
func (*Document) Headings ¶
Headings returns all headings in document order with their level, text, and a slugified ID.
func (*Document) ReadingTime ¶
ReadingTime estimates how long it takes to read the document at 200 words per minute. Returns a minimum of 1 minute if the document has any words.
func (*Document) Slides ¶ added in v0.4.7
Slides returns the deck's top-level NodeSlide nodes, splitting the document in place on first use. If the document has already been split it returns the existing slides without re-splitting. As with SplitSlides, a leading YAML/YML fence on a slide is lifted into Attrs["frontmatter"] (see processSlides).
func (*Document) TableOfContents ¶
TableOfContents returns a table of contents derived from all headings in the document.
type MathOption ¶
type MathOption int
MathOption selects how math nodes render.
const ( MathServer MathOption = iota MathRaw MathOmit )
type Node ¶
type Node struct {
Type NodeType
Children []*Node
Literal string
Attrs map[string]string
Range Range
}
Node is a single element in the Markdown AST.
type NodeRenderer ¶
NodeRenderer can override rendering for a node type. It should write any desired HTML into b and return true when it handled n.
type NodeType ¶
type NodeType int
NodeType classifies an AST node.
const ( NodeDocument NodeType = iota NodeHeading NodeParagraph NodeCodeBlock NodeBlockquote NodeList NodeListItem NodeTable NodeTableRow NodeTableCell NodeThematicBreak NodeLink NodeImage NodeEmphasis NodeStrong NodeStrikethrough NodeCodeSpan NodeText NodeSoftBreak NodeHardBreak NodeHTMLBlock NodeHTMLInline NodeFootnoteRef NodeFootnoteDef NodeMathInline NodeMathBlock NodeAdmonition NodeDefinitionList NodeDefinitionTerm NodeDefinitionDesc NodeSuperscript NodeSubscript NodeTaskListItem NodeFrontmatter NodeTableOfContents NodeAutoEmbed NodeEmoji NodeDiagram NodeContainerDirective // gosx-slides parse seams (Track D). Produced post-parse by reinterpreting // already-parsed nodes; the grammar is unchanged. NodeSlide // a deck slide: top-level content grouped between `---` separators NodeComponent // an inline GoSX component: <Name .../> or <Name>…</Name> NodeExpression // an inline expression interpolation: {expr} )
type Option ¶
type Option func(*Renderer)
Option configures a Renderer.
func WithContainerRenderer ¶
WithContainerRenderer sets a custom renderer for container directives.
func WithHardWraps ¶
WithHardWraps makes single newlines render as <br> instead of whitespace.
func WithHeadingIDs ¶
WithHeadingIDs enables or disables automatic id attributes on headings.
func WithHighlightCode ¶
WithHighlightCode enables or disables code highlighting placeholders.
func WithImageResolver ¶
WithImageResolver sets a function to resolve image URLs.
func WithNodeRenderer ¶
func WithNodeRenderer(typ NodeType, fn NodeRenderer) Option
WithNodeRenderer installs a custom renderer for one node type.
func WithSirenaRenderer ¶ added in v0.4.1
func WithSirenaRenderer(fn SirenaRenderer) Option
WithSirenaRenderer installs the renderer used for ```sirena / ```sir fences. Without it, sirena fences fall back to source passthrough (like an unrecognized diagram), so the library degrades gracefully.
func WithSourcePositions ¶
WithSourcePositions emits data-mdpp-source-* attributes on rendered elements.
func WithUnsafeHTML ¶
WithUnsafeHTML enables or disables raw HTML passthrough.
func WithWrapEmoji ¶
WithWrapEmoji wraps emoji output in an accessible <span> with role="img" and aria-label.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser holds per-document state that survives across ParseIncremental calls, enabling reuse of expensive work (paragraph inline reparse, container body chunk parses) for unchanged regions.
A Parser is safe for sequential use by a single caller; concurrent Parse calls on the same Parser are not supported. Typical usage is to retain one Parser per open document in an LSP-like context.
func NewParser ¶
func NewParser() *Parser
NewParser returns a fresh Parser with an empty cache and no retained tree.
func (*Parser) ApplyEdit ¶
func (p *Parser) ApplyEdit(edit gotreesitter.InputEdit)
ApplyEdit applies an InputEdit to the retained tree without reparsing. Use this when multiple edits must be applied before a single incremental parse. ParseIncremental already applies the passed edit internally, so use this only for secondary edits that precede a ParseIncremental call.
func (*Parser) LastStats ¶
LastStats returns (cacheHits, cacheMisses) recorded by the most recent Parse or ParseIncremental call. Useful for observability and tests.
func (*Parser) ParseIncremental ¶
ParseIncremental applies edit to the retained tree (if any) and runs an incremental parse, reusing cached AST subtrees for unchanged content. If no tree is retained (first parse or prior fallback), it runs a full parse.
type Range ¶
Range identifies a node's byte span in Document.Source. Lines and columns are 1-indexed; columns are byte columns.
type RenderFragment ¶
RenderFragment is a top-level rendered block with its source range.
func RenderWithFragments ¶
func RenderWithFragments(doc *Document, opts RenderOptions) ([]byte, []RenderFragment, error)
RenderWithFragments produces HTML plus top-level source-mapped fragments.
type RenderOptions ¶
type RenderOptions struct {
HighlightCode bool
HeadingIDs bool
UnsafeHTML bool
HardWraps bool
WrapEmoji bool
ImageResolver func(src string) string
ContainerRenderer func(c *Node, body string) string
SourcePositions bool
NodeRenderers map[NodeType]NodeRenderer
Math MathOption
Sanitize bool
// SirenaRenderer, when set, renders “`sirena / “`sir fences to inline
// SVG. Wired by consumers (e.g. cmd/mdpp) so the library stays sirena-free.
SirenaRenderer SirenaRenderer
}
RenderOptions is the value-typed rendering API used by the CLI and tools.
type Renderer ¶
type Renderer struct {
// contains filtered or unexported fields
}
Renderer converts Markdown source into HTML.
func NewRenderer ¶
NewRenderer creates a Renderer with the given options.
func (*Renderer) Parse ¶
Parse parses Markdown source into a Document using the package-level parser.
func (*Renderer) RenderChildrenInto ¶
RenderChildrenInto writes a node's children into b using this renderer's options.
func (*Renderer) RenderNodeInto ¶
RenderNodeInto writes one AST node into b using this renderer's options.
func (*Renderer) RenderString ¶
RenderString parses and renders a Markdown string to HTML.
func (*Renderer) RenderWithFragments ¶
func (r *Renderer) RenderWithFragments(doc *Document) (string, []RenderFragment)
RenderWithFragments renders a document and returns top-level HTML fragments suitable for preview clients that want block-level incremental updates.
type SirenaFenceOptions ¶ added in v0.4.1
type SirenaFenceOptions struct {
// View names a view file to render (the fence info-string `view=` key).
View string
// Theme is the SVG theme name (`theme=`); empty selects the default.
Theme string
// Interactive requests a GoSX island payload (`interactive`).
Interactive bool
// StrictBudget suppresses output on a budget breach (`strict-budget`).
StrictBudget bool
}
SirenaFenceOptions carries the options parsed from a ```sirena fence info-string. It is plain data so the contract stays sirena-free.
type SirenaFenceResult ¶ added in v0.4.1
type SirenaFenceResult struct {
SVG []byte
Diagnostics []Diagnostic
}
SirenaFenceResult is what a SirenaRenderer returns: an inline SVG fragment and any diagnostics produced while rendering. SVG may be empty when a diagnostic prevented rendering, in which case mdpp falls back to showing the fence source.
type SirenaRenderer ¶ added in v0.4.1
type SirenaRenderer func(body string, opts SirenaFenceOptions) (SirenaFenceResult, error)
SirenaRenderer renders a sirena fence body to SVG. It is wired via WithSirenaRenderer; the mdpp library never imports sirena, so consumers supply the implementation (typically an adapter over sirena's fence package).
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
mdpp
command
|
|
|
mdpp-lsp
command
|
|
|
Package fmt provides canonical formatting for Markdown++ source.
|
Package fmt provides canonical formatting for Markdown++ source. |
|
internal
|
|
|
Package lint provides diagnostics over Markdown++ documents.
|
Package lint provides diagnostics over Markdown++ documents. |