marksplice

package module
v0.5.0-beta.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

README

Marksplice

Go Reference CI

Marksplice is a Pure-Go, source-preserving Markdown document engine for Go — built for editors, developer tooling, and AI agents that need to understand and modify Markdown without rewriting it.

An ordinary AST parser tells you what Markdown means. Marksplice also proves which source bytes a structural operation owns, so a change can stay local, preserve author formatting, and fail closed when the source has changed.

Why use Marksplice?

  • Edit existing Markdown without a full rewrite. Rename a heading, check a task, update a table cell, move a section, and keep unrelated bytes untouched.
  • Work with structure instead of string searches. Inspect headings, sections, lists, tasks, tables, fenced blocks, links, fragments, footnotes, front matter, and more.
  • Create Markdown from structured Go values. DocumentBuilder writes deterministic GFM for new documents.
  • Understand documentation sets. Build caller-controlled document graphs, inspect backlinks, validate links/fragments, and plan conservative repairs.
  • Give tools and AI agents a safer editing surface. Use bounded structural queries, snapshot-local identities, exact source ranges, typed operations, and source-bound ChangeSets instead of fragile whole-file text rewrites.

Engineering facts

Property Current Marksplice contract
Markdown engine Marksplice-owned Native parser; CommonMark 0.31.2 base plus reviewed GFM behavior
Conformance evidence 652 CommonMark examples plus 676 parser-applicable published-GFM contracts
Source safety Exact byte ranges, immutable snapshots, stale-source detection, minimal operation-owned patches
Real-world validation Byte-certified corpus of 6,857 Markdown documents, 60.8 MB, from 195 open-source repositories
Measured parse performance v0.5 engineering freeze: 25.06 MB/s public Parse, 30.87 MB/s Native on the same preloaded 60.8 MB corpus
Robustness Focused/pathological tests, fuzz targets, race testing, static analysis, and cross-platform builds
Portability Pure Go; Go 1.26+; no third-party Markdown parser dependency
Dependencies One direct dependency: golang.org/x/text, used for full Unicode GFM reference-label folding
Authority boundary No hidden filesystem traversal, URL fetching, network access, or command execution in the document core

Performance is measured on real documents as well as focused benchmarks; correctness and source preservation are not traded away to win a parser-only microbenchmark. On the same-host v0.5 campaign, public Parse improved from 15.04 to 25.06 MB/s while allocated bytes fell from about 4.49 GB/op to 2.70 GB/op. These are engineering benchmark results for that corpus/host, not cross-machine guarantees.

Built for tools and AI agents

Marksplice turns a document-editing workflow into a small structural protocol:

bounded query -> exact target -> typed change -> optional atomic composition -> apply to exact source

An agent can ask for a limited set of sections or nodes, prepare a structural change, and apply it without regenerating the document. If another actor changed the bytes in the meantime, the prepared change fails with ErrSourceConflict instead of guessing. Graph, backlink, fragment, and workspace APIs provide the same explicit model across documentation sets.

Marksplice does not crawl your filesystem, fetch URLs, render HTML/PDF, or silently normalize existing documents.

Install

Marksplice requires Go 1.26 or newer. The current published beta is v0.5.0-beta.1:

go get github.com/zoster81/marksplice@v0.5.0-beta.1

Try a real file

Clone the repository and run the inspection example:

go run ./examples/inspect

It loads examples/inspect/project-guide.md from disk and reports its sections, tasks, fenced blocks, and links.

For a source-preserving edit over another tracked Markdown file:

go run ./examples/edit

That example prepares several changes, combines them atomically, applies them to the original bytes, and does not overwrite the fixture.

Minimal edit flow

source, err := os.ReadFile("README.md")
if err != nil {
    return err
}

doc, err := marksplice.Parse(source)
if err != nil {
    return err
}

// Select a heading ID from doc.Nodes(), QueryNodes(), or another typed view.
change, err := doc.PrepareRenameHeading(headingID, []byte("New title"))
if err != nil {
    return err
}

updated, err := change.Apply(source) // apply to the exact bytes that were parsed
if err != nil {
    return err
}

A prepared ChangeSet is bound to the parsed snapshot. Applying it to different bytes fails closed with ErrSourceConflict rather than guessing where the edit belongs.

What can it do?

Goal Examples
Inspect headings, sections, lists/tasks, tables, fenced blocks, links, front matter, alerts, footnotes, math
Query bounded source-ordered node and section queries
Edit content replacements plus structural section/list/table operations and atomic change composition
Create headings, paragraphs, lists/tasks, tables, fenced code, front matter, blockquotes/alerts, typed inline content
Navigate anchors, fragments, TOCs, link relationships
Work across documents explicit document graphs, backlinks, reachability, workspace validation, knowledge metadata
Extend read-only semantics opt-in namespaced observations through ParseWithOptions

See the concise capability matrix for current boundaries and unsupported behavior.

Start here

Status

Marksplice is beta software under active development. Until v1, public APIs may change between releases. The production parser is Marksplice's native CommonMark/GFM implementation; ordinary users do not need parser internals to use the public API.

License

Apache License 2.0. See LICENSE and NOTICE.

Marksplice was created by Giovanni Riccobene (zoster81).

Documentation

Overview

Package marksplice provides structured GitHub Flavored Markdown creation and source-preserving manipulation.

Marksplice is currently pre-v1 beta software under active development. Public APIs may change incompatibly between v0 releases until a stable v1 contract is explicitly published.

Marksplice exposes reviewed new-document construction, snapshot-scoped structural views, copied bounded source reads, and named source-preserving mutations while keeping parser and lossless source-mapping implementation details internal.

A successfully parsed Document and the immutable DocumentGraph, KnowledgeIndex, WorkspaceReport, and ChangeSet values derived from immutable snapshots may be read, queried, used for mutation planning, or applied concurrently. Public variable-length results are caller-owned unless an API explicitly documents otherwise. Callers must not concurrently mutate byte slices they pass as arguments to an operation.

DocumentBuilder is mutable and is not safe for concurrent use without caller synchronization. Resolver callbacks supplied to graph/workspace builders are invoked synchronously during that call, are not invoked concurrently by Marksplice, and are never retained after the call returns.

Core operations are synchronous and perform no implicit filesystem or network I/O. Structural queries require an explicit positive result limit; graph, workspace, and knowledge operations are bounded by the finite document collections supplied by the caller and never discover additional documents on their own.

Public sentinel errors classify actionable failure families. Callers should use errors.Is rather than compare diagnostic error strings, whose wording is not a compatibility contract.

Optional third-party extensions are explicit read-only semantic/source overlays evaluated only by ParseWithOptions after the ordinary core parse succeeds. Extension observations never enter the core Kind namespace or gain mutation/construction authority. Recognizers run synchronously as ordinary statically linked caller code and are not retained; Marksplice validates and bounds only the observations it retains and does not sandbox recognizer code.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrNodeNotFound reports that a snapshot-local node ID does not exist.
	ErrNodeNotFound = errors.New("node not found")
	// ErrInvalidReplacement reports a requested mutation that cannot preserve the required structure.
	ErrInvalidReplacement = errors.New("invalid replacement")
	// ErrInvalidTargetKind reports that an operation does not support the targeted node kind.
	ErrInvalidTargetKind = errors.New("invalid target kind")
	// ErrSourceConflict reports that a prepared change was applied to a different source snapshot.
	ErrSourceConflict = errors.New("source snapshot conflict")
	// ErrInvalidConstruction reports new-document content that cannot be proven to produce the requested GFM structure.
	ErrInvalidConstruction = errors.New("invalid construction")
	// ErrInvalidQuery reports an unbounded or malformed structural query.
	ErrInvalidQuery = errors.New("invalid query")
	// ErrInvalidGraph reports malformed explicit document-graph input or resolution.
	ErrInvalidGraph = errors.New("invalid document graph")
	// ErrInvalidWorkspace reports malformed workspace validation authority or targets.
	ErrInvalidWorkspace = errors.New("invalid workspace validation")
	// ErrInvalidKnowledge reports malformed syntax-independent knowledge metadata or references.
	ErrInvalidKnowledge = errors.New("invalid knowledge index")
	// ErrInvalidExtension reports malformed third-party extension configuration or observations.
	ErrInvalidExtension = errors.New("invalid extension")
)

Functions

This section is empty.

Types

type Alert

type Alert struct {
	// contains filtered or unexported fields
}

Alert is immutable semantic detail layered over one promoted top-level blockquote. Its ID is the underlying blockquote NodeID; alerts do not introduce a second identity namespace.

func (Alert) ID

func (a Alert) ID() NodeID

ID returns the underlying blockquote's snapshot-scoped identity.

func (Alert) Kind

func (a Alert) Kind() AlertKind

Kind returns the exact reviewed GitHub alert kind.

func (Alert) MarkerRange

func (a Alert) MarkerRange() Range

MarkerRange returns the exact inner-source range containing the alert marker such as [!NOTE].

func (Alert) Range

func (a Alert) Range() Range

Range returns the exact complete physical source owned by the underlying top-level blockquote.

type AlertKind

type AlertKind uint8

AlertKind identifies one reviewed GitHub alert semantic kind.

const (
	AlertKindUnknown AlertKind = iota
	AlertKindNote
	AlertKindTip
	AlertKindImportant
	AlertKindWarning
	AlertKindCaution
)
type AutoLink struct {
	// contains filtered or unexported fields
}

AutoLink is immutable typed detail for one promoted single-line GFM autolink.

func (AutoLink) ID

func (a AutoLink) ID() NodeID

ID returns the autolink's snapshot-scoped node identity.

func (AutoLink) IsEmail

func (a AutoLink) IsEmail() bool

IsEmail reports whether the parser classified this as an email autolink.

func (AutoLink) Range

func (a AutoLink) Range() Range

Range returns the exact autolink token content replaced by PrepareReplaceAutoLink. Angle brackets, when present, and surrounding source are outside this range.

func (AutoLink) Value

func (a AutoLink) Value() string

Value returns the parser-proven semantic autolink value.

type Blockquote

type Blockquote struct {
	// contains filtered or unexported fields
}

Blockquote is immutable typed detail for one promoted complete top-level blockquote container.

func (Blockquote) ContentRange

func (b Blockquote) ContentRange() Range

ContentRange returns the historical single-line inner source span when the promoted blockquote owns exactly one physical content segment. It returns the zero Range for segmented multiline, lazy-continuation, or multi-block source; use Document.BlockquoteContentRanges for those containers.

func (Blockquote) ID

func (b Blockquote) ID() NodeID

ID returns the blockquote's snapshot-scoped node identity.

func (Blockquote) Range

func (b Blockquote) Range() Range

Range returns the exact complete physical source owned by the top-level blockquote container. Every owned physical line terminator is included when present.

type ChangeSet

type ChangeSet struct {
	// contains filtered or unexported fields
}

ChangeSet is an opaque prepared change bound to one exact source snapshot. Its zero value is unbound and Apply reports ErrSourceConflict.

func (ChangeSet) Apply

func (c ChangeSet) Apply(source []byte) ([]byte, error)

Apply applies the prepared change only when source matches its original snapshot.

type CodeSpan

type CodeSpan struct {
	// contains filtered or unexported fields
}

CodeSpan is immutable typed detail for one promoted simple single-line code span.

func (CodeSpan) ID

func (c CodeSpan) ID() NodeID

ID returns the code span's snapshot-scoped node identity.

func (CodeSpan) Range

func (c CodeSpan) Range() Range

Range returns the exact code-span content span replaced by PrepareReplaceCodeSpan.

type Document

type Document struct {
	// contains filtered or unexported fields
}

Document is an immutable parsed Markdown source snapshot.

func Parse

func Parse(source []byte) (*Document, error)

Parse copies and parses source into an immutable document snapshot.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	source := []byte("# Title\n\nBody.\n")
	document, err := marksplice.Parse(source)
	if err != nil {
		panic(err)
	}

	for _, node := range document.Nodes() {
		if node.Kind() != marksplice.KindHeading {
			continue
		}
		heading, ok := document.Heading(node.ID())
		if !ok {
			continue
		}
		content, ok := document.SourceRange(heading.Range())
		if !ok {
			panic("heading range is not readable")
		}
		fmt.Printf("level=%d text=%s\n", heading.Level(), content)
	}

}
Output:
level=1 text=Title

func ParseWithOptions

func ParseWithOptions(source []byte, options ParseOptions) (*Document, error)

ParseWithOptions copies and parses source using the ordinary Marksplice GFM core, then optionally evaluates explicitly registered third-party read-only overlays. Extension observations never alter core nodes, parser behavior, mutation authority, or construction.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/zoster81/marksplice"
)

func main() {
	source := []byte("See [[guide]].\n")
	wiki := marksplice.Extension{
		ID: "example.org/wiki",
		Recognize: func(input marksplice.ExtensionSource) ([]marksplice.ExtensionMatch, error) {
			text := input.Text()
			start := strings.Index(text, "[[")
			if start < 0 {
				return nil, nil
			}
			close := strings.Index(text[start+2:], "]]")
			if close < 0 {
				return nil, nil
			}
			end := start + 2 + close + 2
			return []marksplice.ExtensionMatch{{
				Kind:  "wikilink",
				Range: marksplice.Range{Start: start, End: end},
				Attributes: []marksplice.ExtensionAttribute{{
					Name:  "target",
					Value: text[start+2 : end-2],
				}},
			}}, nil
		},
	}
	document, err := marksplice.ParseWithOptions(source, marksplice.ParseOptions{
		Extensions: []marksplice.Extension{wiki},
		ExtensionLimits: marksplice.ExtensionLimits{
			MaxNodes:         8,
			MaxMetadataBytes: 256,
		},
	})
	if err != nil {
		panic(err)
	}
	node := document.ExtensionNodes()[0]
	raw, _ := document.SourceRange(node.Range())
	target, _ := node.Attribute("target")
	fmt.Printf("%s -> %s\n", raw, target)

}
Output:
[[guide]] -> guide

func (*Document) Alert

func (d *Document) Alert(id NodeID) (Alert, bool)

Alert returns semantic alert detail when id identifies a promoted top-level blockquote whose first inner physical line is one exact reviewed GitHub alert marker and whose remaining owned source contains at least one non-empty body segment.

func (*Document) AlertBodyRanges

func (d *Document) AlertBodyRanges(id NodeID) ([]Range, bool)

AlertBodyRanges returns caller-owned inner source segments after the alert marker line. Marker-only blank lines are represented by valid empty ranges and lazy continuation lines retain their source-proven blockquote inner ranges.

func (*Document) Alerts

func (d *Document) Alerts() []Alert

Alerts returns all recognized top-level GitHub alerts in source order. The returned slice is caller-owned. Recognition adds no persistent semantic index.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	document, err := marksplice.Parse([]byte("> [!WARNING]\n> Back up first.\n"))
	if err != nil {
		panic(err)
	}
	alert := document.Alerts()[0]
	marker, ok := document.SourceRange(alert.MarkerRange())
	if !ok {
		panic("alert marker is not readable")
	}
	bodyRanges, ok := document.AlertBodyRanges(alert.ID())
	if !ok || len(bodyRanges) == 0 {
		panic("alert body is not readable")
	}
	body, ok := document.SourceRange(bodyRanges[0])
	if !ok {
		panic("alert body range is not readable")
	}
	fmt.Printf("%s: %s\n", marker, body)

}
Output:
[!WARNING]: Back up first.
func (d *Document) AutoLink(id NodeID) (AutoLink, bool)

AutoLink returns typed detail for one promoted single-line GFM autolink.

func (*Document) Blockquote

func (d *Document) Blockquote(id NodeID) (Blockquote, bool)

Blockquote returns typed detail for one promoted complete top-level blockquote container.

func (*Document) BlockquoteContentRanges

func (d *Document) BlockquoteContentRanges(id NodeID) ([]Range, bool)

BlockquoteContentRanges returns caller-owned inner source segments for every physical line owned by one promoted top-level blockquote, in source order. Marker-only lines are represented by valid empty ranges. Lazy continuation lines have no synthetic marker removal: their complete physical content is returned.

func (*Document) CodeSpan

func (d *Document) CodeSpan(id NodeID) (CodeSpan, bool)

CodeSpan returns typed detail for one promoted simple single-line code span.

func (*Document) ComposeChanges

func (d *Document) ComposeChanges(changes ...ChangeSet) (ChangeSet, error)

ComposeChanges combines already-prepared mutations from this exact document snapshot into one atomic source-bound change. Overlapping or semantically interacting prepared mutations fail closed.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	source := []byte("# Old title\n\nOld body.\n")
	document, err := marksplice.Parse(source)
	if err != nil {
		panic(err)
	}

	var headingID, paragraphID marksplice.NodeID
	for _, node := range document.Nodes() {
		switch node.Kind() {
		case marksplice.KindHeading:
			headingID = node.ID()
		case marksplice.KindParagraph:
			paragraphID = node.ID()
		}
	}
	rename, err := document.PrepareRenameHeading(headingID, []byte("New title"))
	if err != nil {
		panic(err)
	}
	replace, err := document.PrepareReplaceParagraph(paragraphID, []byte("New body."))
	if err != nil {
		panic(err)
	}
	combined, err := document.ComposeChanges(rename, replace)
	if err != nil {
		panic(err)
	}
	updated, err := combined.Apply(source)
	if err != nil {
		panic(err)
	}
	fmt.Print(string(updated))

}
Output:
# New title

New body.

func (*Document) Emphasis

func (d *Document) Emphasis(id NodeID) (Emphasis, bool)

Emphasis returns typed detail for one promoted simple emphasis span.

func (*Document) ExtensionNodes

func (d *Document) ExtensionNodes() []ExtensionNode

ExtensionNodes returns caller-owned immutable extension observations in registration order and each recognizer's returned order. Core structural nodes remain separate.

func (*Document) FencedBlock

func (d *Document) FencedBlock(id NodeID) (FencedBlock, bool)

FencedBlock returns one source-proven top-level fenced block by snapshot ID.

func (*Document) FencedBlockContentRanges

func (d *Document) FencedBlockContentRanges(id NodeID) ([]Range, bool)

FencedBlockContentRanges returns caller-owned source-backed payload ranges, one per parser-proven physical body line. Empty payloads return an empty slice with ok=true. These ranges are read-only source ownership, not generic mutation spans.

func (*Document) FencedBlocks

func (d *Document) FencedBlocks() []FencedBlock

FencedBlocks returns every source-proven top-level fenced block in source order. Readability is broader than the historical FencedCode edit capability: empty, non-contiguous, or unclosed blocks may be returned without gaining mutation authority.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	document, err := marksplice.Parse([]byte("```mermaid\ngraph TD\n```\n"))
	if err != nil {
		panic(err)
	}
	block := document.FencedBlocks()[0]
	language, ok := block.Language()
	if !ok {
		panic("fenced block language is not available")
	}
	bodyRanges, ok := document.FencedBlockContentRanges(block.ID())
	if !ok || len(bodyRanges) != 1 {
		panic("fenced block body is not readable")
	}
	body, ok := document.SourceRange(bodyRanges[0])
	if !ok {
		panic("fenced block body range is not readable")
	}
	fmt.Printf("language=%s closed=%t body=%s\n", language, block.Closed(), body)

}
Output:
language=mermaid closed=true body=graph TD

func (*Document) FencedCode

func (d *Document) FencedCode(id NodeID) (FencedCode, bool)

FencedCode returns typed detail for one promoted supported fenced code block.

func (*Document) FootnoteDefinition

func (d *Document) FootnoteDefinition(id NodeID) (FootnoteDefinition, bool)

FootnoteDefinition returns one source-proven top-level definition by snapshot ID.

func (*Document) FootnoteDefinitionBodyRanges

func (d *Document) FootnoteDefinitionBodyRanges(id NodeID) ([]Range, bool)

FootnoteDefinitionBodyRanges returns caller-owned parser-proven body segments in physical source order. They are read-only source metadata, not generic edit spans.

func (*Document) FootnoteDefinitions

func (d *Document) FootnoteDefinitions() []FootnoteDefinition

FootnoteDefinitions returns every source-proven top-level footnote definition in physical source order, including unused definitions.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	source := []byte("Text[^note].\n\n[^note]: Original body.\n")
	document, err := marksplice.Parse(source)
	if err != nil {
		panic(err)
	}
	definition := document.FootnoteDefinitions()[0]
	references := document.FootnoteReferences()
	fmt.Printf("label=%s references=%d occurrence=%d\n", definition.Label(), len(references), references[0].Occurrence())

	change, err := document.PrepareRenameFootnote(definition.ID(), []byte("renamed"))
	if err != nil {
		panic(err)
	}
	updated, err := change.Apply(source)
	if err != nil {
		panic(err)
	}
	fmt.Print(string(updated))

}
Output:
label=note references=1 occurrence=0
Text[^renamed].

[^renamed]: Original body.

func (*Document) FootnoteReferences

func (d *Document) FootnoteReferences() []FootnoteReference

FootnoteReferences returns every parser-proven footnote reference in source order. The returned slice is caller-owned and no relationship index is retained.

func (*Document) FrontMatter

func (d *Document) FrontMatter() (FrontMatter, bool)

FrontMatter returns the recognized document-leading YAML/TOML metadata envelope. Complex or duplicate metadata can be readable through this envelope even when no individual field is safe to promote for source-preserving mutation.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	source := []byte("---\ntags:\n  - source-preserving\n---\n\n# Marksplice\n")
	document, err := marksplice.Parse(source)
	if err != nil {
		panic(err)
	}
	frontMatter, ok := document.FrontMatter()
	if !ok {
		panic("front matter is not available")
	}
	metadata, ok := document.SourceRange(frontMatter.Range())
	if !ok {
		panic("front matter range is not readable")
	}
	fmt.Printf("format=%d bytes=%d\n", frontMatter.Format(), len(metadata))

}
Output:
format=1 bytes=35

func (*Document) FrontMatterField

func (d *Document) FrontMatterField(id NodeID) (FrontMatterField, bool)

FrontMatterField returns typed detail for one promoted simple leading YAML/TOML scalar field.

func (*Document) GenerateTOC

func (d *Document) GenerateTOC() []byte

GenerateTOC returns deterministic Markdown for the current section hierarchy. Generated output uses LF line endings; source synchronization preserves the target body's line-ending style.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	source := []byte("# Root\n\n## Child\n\n## Child\n")
	document, err := marksplice.Parse(source)
	if err != nil {
		panic(err)
	}
	fmt.Print(string(document.GenerateTOC()))

}
Output:
- [Root](#root)
  - [Child](#child)
  - [Child](#child-1)

func (*Document) HTMLAnchor

func (d *Document) HTMLAnchor(id NodeID) (HTMLAnchor, bool)

HTMLAnchor returns typed detail for one promoted simple quoted id/name attribute on an <a> tag.

func (*Document) HTMLComment

func (d *Document) HTMLComment(id NodeID) (HTMLComment, bool)

HTMLComment returns typed detail for one promoted single-line HTML comment.

func (*Document) Heading

func (d *Document) Heading(id NodeID) (Heading, bool)

Heading returns typed detail for one promoted top-level heading.

func (*Document) HeadingAnchor

func (d *Document) HeadingAnchor(id NodeID) (HeadingAnchor, bool)

HeadingAnchor returns the derived anchor for one promoted heading.

func (*Document) HeadingAnchors

func (d *Document) HeadingAnchors() []HeadingAnchor

HeadingAnchors derives all promoted heading anchors in source order. Duplicate disambiguation is recomputed from the immutable snapshot on each call.

func (*Document) Image

func (d *Document) Image(id NodeID) (Image, bool)

Image returns typed detail for one promoted simple inline image.

func (d *Document) InlineLink(id NodeID) (InlineLink, bool)

InlineLink returns typed detail for one promoted simple inline link.

func (*Document) LinkRelationships

func (d *Document) LinkRelationships() []LinkRelationship

LinkRelationships returns all parser-resolved outgoing link/image/autolink relationships in source order. The returned slice is caller-owned and does not persist any relationship index or graph in the snapshot.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	source := []byte("# Guide\n\n[local](#guide) [web](https://example.com)\n")
	document, err := marksplice.Parse(source)
	if err != nil {
		panic(err)
	}
	for _, relationship := range document.LinkRelationships() {
		_, local := relationship.FragmentTarget()
		fmt.Printf("%s local=%t\n", relationship.Destination(), local)
	}

}
Output:
#guide local=true
https://example.com local=false

func (*Document) ListItem

func (d *Document) ListItem(id NodeID) (ListItem, bool)

ListItem returns typed detail for one promoted single-line list item.

func (*Document) MathExpression

func (d *Document) MathExpression(id NodeID) (MathExpression, bool)

MathExpression returns one reviewed mathematical expression by snapshot ID.

func (*Document) MathExpressionPayloadRanges

func (d *Document) MathExpressionPayloadRanges(id NodeID) ([]Range, bool)

MathExpressionPayloadRanges returns caller-owned source-backed payload ranges. Fenced math may expose zero, one, or multiple physical payload ranges.

func (*Document) MathExpressions

func (d *Document) MathExpressions() []MathExpression

MathExpressions returns reviewed mathematical expressions in source order. Exact-info `math` fenced blocks reuse their existing FencedBlock identity rather than creating a second structural node.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	source := []byte("Inline $x+1$.\n\n$$x^2$$\n")
	document, err := marksplice.Parse(source)
	if err != nil {
		panic(err)
	}
	for _, expression := range document.MathExpressions() {
		payload, ok := expression.PayloadRange()
		if !ok {
			continue
		}
		value, _ := document.SourceRange(payload)
		fmt.Printf("style=%d payload=%s\n", expression.Style(), value)
	}

}
Output:
style=1 payload=x+1
style=3 payload=x^2

func (*Document) Node

func (d *Document) Node(id NodeID) (Node, bool)

Node returns one node summary by snapshot-local ID.

func (*Document) Nodes

func (d *Document) Nodes() []Node

Nodes returns summaries for node kinds promoted into the public API.

func (*Document) Paragraph

func (d *Document) Paragraph(id NodeID) (Paragraph, bool)

func (*Document) PrepareAppendListItemChild

func (d *Document) PrepareAppendListItemChild(parentID NodeID, fragment []byte) (ChangeSet, error)

PrepareAppendListItemChild prepares appending one complete direct-child subtree to a fully supported list-item subtree.

func (*Document) PrepareAppendSectionChild

func (d *Document) PrepareAppendSectionChild(parentHeadingID NodeID, fragment []byte) (ChangeSet, error)

PrepareAppendSectionChild prepares appending one direct child section subtree to a promoted parent section.

func (*Document) PrepareAppendTableRow

func (d *Document) PrepareAppendTableRow(id NodeID, fragment []byte) (ChangeSet, error)

PrepareAppendTableRow prepares appending one caller-owned compatible body row to a promoted GFM table.

func (*Document) PrepareInsertListItemAfter

func (d *Document) PrepareInsertListItemAfter(anchorID NodeID, fragment []byte) (ChangeSet, error)

PrepareInsertListItemAfter prepares insertion of one complete same-shape supported list-item subtree immediately after a complete supported anchor subtree.

func (*Document) PrepareInsertListItemBefore

func (d *Document) PrepareInsertListItemBefore(anchorID NodeID, fragment []byte) (ChangeSet, error)

PrepareInsertListItemBefore prepares insertion of one complete same-shape supported list-item subtree immediately before a complete supported anchor subtree.

func (*Document) PrepareInsertSectionAfter

func (d *Document) PrepareInsertSectionAfter(headingID NodeID, fragment []byte) (ChangeSet, error)

PrepareInsertSectionAfter prepares insertion of one sibling section subtree immediately after the target section subtree.

func (*Document) PrepareInsertSectionBefore

func (d *Document) PrepareInsertSectionBefore(headingID NodeID, fragment []byte) (ChangeSet, error)

PrepareInsertSectionBefore prepares insertion of one sibling section subtree immediately before the target section.

func (*Document) PrepareInsertTableColumn

func (d *Document) PrepareInsertTableColumn(id NodeID, column int, header []byte, alignment TableAlignment, body [][]byte) (ChangeSet, error)

PrepareInsertTableColumn prepares source-preserving insertion of one complete promoted GFM table column.

func (*Document) PrepareInsertTableRowAfter

func (d *Document) PrepareInsertTableRowAfter(anchorID NodeID, fragment []byte) (ChangeSet, error)

PrepareInsertTableRowAfter prepares insertion of one complete compatible body row after a promoted row.

func (*Document) PrepareInsertTableRowBefore

func (d *Document) PrepareInsertTableRowBefore(anchorID NodeID, fragment []byte) (ChangeSet, error)

PrepareInsertTableRowBefore prepares insertion of one complete compatible body row before a promoted row.

func (*Document) PrepareMoveListItemAfter

func (d *Document) PrepareMoveListItemAfter(id, anchorID NodeID) (ChangeSet, error)

PrepareMoveListItemAfter prepares moving one complete supported list-item subtree immediately after a complete same-shape anchor subtree.

func (*Document) PrepareMoveListItemBefore

func (d *Document) PrepareMoveListItemBefore(id, anchorID NodeID) (ChangeSet, error)

PrepareMoveListItemBefore prepares moving one complete supported list-item subtree immediately before a complete same-shape anchor subtree.

func (*Document) PrepareMoveSectionAfter

func (d *Document) PrepareMoveSectionAfter(headingID, anchorHeadingID NodeID) (ChangeSet, error)

PrepareMoveSectionAfter prepares moving one complete promoted section subtree immediately after a same-level anchor subtree.

func (*Document) PrepareMoveSectionBefore

func (d *Document) PrepareMoveSectionBefore(headingID, anchorHeadingID NodeID) (ChangeSet, error)

PrepareMoveSectionBefore prepares moving one complete promoted section subtree immediately before a same-level anchor section.

func (*Document) PrepareMoveTableColumn

func (d *Document) PrepareMoveTableColumn(id NodeID, from, to int) (ChangeSet, error)

PrepareMoveTableColumn prepares moving one complete promoted GFM table column to a new zero-based position.

func (*Document) PrepareMoveTableRowAfter

func (d *Document) PrepareMoveTableRowAfter(id, anchorID NodeID) (ChangeSet, error)

PrepareMoveTableRowAfter prepares moving one complete body row after another promoted row in the same table.

func (*Document) PrepareMoveTableRowBefore

func (d *Document) PrepareMoveTableRowBefore(id, anchorID NodeID) (ChangeSet, error)

PrepareMoveTableRowBefore prepares moving one complete body row before another promoted row in the same table.

func (*Document) PrepareRemoveBlockquote

func (d *Document) PrepareRemoveBlockquote(id NodeID) (ChangeSet, error)

PrepareRemoveBlockquote prepares source-preserving removal of one complete promoted top-level blockquote container.

func (*Document) PrepareRemoveListItem

func (d *Document) PrepareRemoveListItem(id NodeID) (ChangeSet, error)

PrepareRemoveListItem prepares removal of one complete supported list-item subtree.

func (*Document) PrepareRemoveReferenceDefinition

func (d *Document) PrepareRemoveReferenceDefinition(id NodeID) (ChangeSet, error)

PrepareRemoveReferenceDefinition prepares source-preserving removal of one complete promoted single-line reference-definition line.

func (*Document) PrepareRemoveSection

func (d *Document) PrepareRemoveSection(headingID NodeID) (ChangeSet, error)

PrepareRemoveSection prepares source-preserving removal of one complete promoted section subtree.

func (*Document) PrepareRemoveTableColumn

func (d *Document) PrepareRemoveTableColumn(id NodeID, column int) (ChangeSet, error)

PrepareRemoveTableColumn prepares source-preserving removal of one complete promoted GFM table column.

func (*Document) PrepareRemoveTableRow

func (d *Document) PrepareRemoveTableRow(id NodeID) (ChangeSet, error)

PrepareRemoveTableRow prepares source-preserving removal of one promoted GFM table body row.

func (*Document) PrepareRemoveThematicBreak

func (d *Document) PrepareRemoveThematicBreak(id NodeID) (ChangeSet, error)

PrepareRemoveThematicBreak prepares source-preserving removal of one complete promoted top-level thematic-break line.

func (*Document) PrepareRenameFootnote

func (d *Document) PrepareRenameFootnote(id NodeID, replacement []byte) (ChangeSet, error)

PrepareRenameFootnote atomically renames one promoted footnote definition and every parser-proven reference occurrence bound to that definition.

func (*Document) PrepareRenameHeading

func (d *Document) PrepareRenameHeading(id NodeID, replacement []byte) (ChangeSet, error)

PrepareRenameHeading prepares a source-preserving rename of promoted heading content.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	source := []byte("##  Old title  ##\n\nBody.\n")
	document, err := marksplice.Parse(source)
	if err != nil {
		panic(err)
	}

	var heading marksplice.Heading
	for _, node := range document.Nodes() {
		if node.Kind() != marksplice.KindHeading {
			continue
		}
		var ok bool
		heading, ok = document.Heading(node.ID())
		if ok {
			break
		}
	}

	change, err := document.PrepareRenameHeading(heading.ID(), []byte("New title"))
	if err != nil {
		panic(err)
	}
	updated, err := change.Apply(source)
	if err != nil {
		panic(err)
	}
	fmt.Print(string(updated))

}
Output:
##  New title  ##

Body.
func (d *Document) PrepareReplaceAutoLink(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceAutoLink prepares a source-preserving replacement of a promoted GFM autolink token.

func (*Document) PrepareReplaceCodeSpan

func (d *Document) PrepareReplaceCodeSpan(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceCodeSpan prepares a source-preserving replacement of promoted code-span content.

func (*Document) PrepareReplaceEmphasis

func (d *Document) PrepareReplaceEmphasis(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceEmphasis prepares a source-preserving replacement of promoted emphasis content.

func (*Document) PrepareReplaceFencedCode

func (d *Document) PrepareReplaceFencedCode(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceFencedCode prepares a source-preserving replacement of promoted fenced-code content.

func (*Document) PrepareReplaceFootnoteDefinitionBody

func (d *Document) PrepareReplaceFootnoteDefinitionBody(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceFootnoteDefinitionBody prepares a source-preserving replacement of the conservative simple editable body of one promoted footnote definition.

func (*Document) PrepareReplaceFrontMatterValue

func (d *Document) PrepareReplaceFrontMatterValue(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceFrontMatterValue prepares a source-preserving replacement of a promoted simple front-matter scalar value.

func (*Document) PrepareReplaceHTMLAnchor

func (d *Document) PrepareReplaceHTMLAnchor(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceHTMLAnchor prepares a source-preserving replacement of a promoted HTML anchor id/name value.

func (*Document) PrepareReplaceHTMLComment

func (d *Document) PrepareReplaceHTMLComment(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceHTMLComment prepares a source-preserving replacement of a promoted HTML comment payload.

func (*Document) PrepareReplaceImageDestination

func (d *Document) PrepareReplaceImageDestination(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceImageDestination prepares a source-preserving replacement of a promoted image destination.

func (*Document) PrepareReplaceInlineLinkDestination

func (d *Document) PrepareReplaceInlineLinkDestination(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceInlineLinkDestination prepares a source-preserving replacement of a promoted inline-link destination.

func (*Document) PrepareReplaceListItem

func (d *Document) PrepareReplaceListItem(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceListItem prepares a source-preserving replacement of promoted list-item content.

func (*Document) PrepareReplaceListItemSubtree

func (d *Document) PrepareReplaceListItemSubtree(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceListItemSubtree prepares replacement of one complete supported list-item subtree while preserving its external sibling shape and semantic parent.

func (*Document) PrepareReplaceMathExpression

func (d *Document) PrepareReplaceMathExpression(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceMathExpression prepares a source-preserving replacement of one reviewed mathematical payload while retaining its exact delimiter/container form.

func (*Document) PrepareReplaceParagraph

func (d *Document) PrepareReplaceParagraph(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceParagraph prepares a source-preserving paragraph replacement.

func (*Document) PrepareReplaceReferenceDefinitionDestination

func (d *Document) PrepareReplaceReferenceDefinitionDestination(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceReferenceDefinitionDestination prepares a source-preserving replacement of a promoted reference-definition destination.

func (*Document) PrepareReplaceReferenceDefinitionTitle

func (d *Document) PrepareReplaceReferenceDefinitionTitle(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceReferenceDefinitionTitle prepares a source-preserving replacement of an existing promoted reference-definition title payload.

func (*Document) PrepareReplaceSection

func (d *Document) PrepareReplaceSection(headingID NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceSection prepares source-preserving replacement of one complete promoted section subtree.

func (*Document) PrepareReplaceSectionBody

func (d *Document) PrepareReplaceSectionBody(headingID NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceSectionBody prepares source-preserving replacement of one promoted section's direct body.

func (*Document) PrepareReplaceStrikethrough

func (d *Document) PrepareReplaceStrikethrough(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceStrikethrough prepares a source-preserving replacement of promoted strikethrough content.

func (*Document) PrepareReplaceStrong

func (d *Document) PrepareReplaceStrong(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceStrong prepares a source-preserving replacement of promoted strong-emphasis content.

func (*Document) PrepareReplaceTableCell

func (d *Document) PrepareReplaceTableCell(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceTableCell prepares a source-preserving replacement of promoted table-cell content.

func (*Document) PrepareReplaceTableRow

func (d *Document) PrepareReplaceTableRow(id NodeID, replacement []byte) (ChangeSet, error)

PrepareReplaceTableRow prepares source-preserving replacement of one complete promoted GFM table body row.

func (*Document) PrepareSetTableAlignments

func (d *Document) PrepareSetTableAlignments(id NodeID, alignments []TableAlignment) (ChangeSet, error)

PrepareSetTableAlignments prepares one atomic source-preserving alignment update for every promoted GFM table column.

func (*Document) PrepareSetTableColumnAlignment

func (d *Document) PrepareSetTableColumnAlignment(id NodeID, column int, alignment TableAlignment) (ChangeSet, error)

PrepareSetTableColumnAlignment prepares a source-preserving alignment change for one promoted GFM table column.

func (*Document) PrepareSetTaskChecked

func (d *Document) PrepareSetTaskChecked(id NodeID, checked bool) (ChangeSet, error)

PrepareSetTaskChecked prepares a source-preserving GFM task state change.

func (*Document) PrepareSyncTOC

func (d *Document) PrepareSyncTOC(headingID NodeID) (ChangeSet, error)

PrepareSyncTOC prepares source-preserving synchronization of an explicitly designated empty/TOC-shaped section body. Arbitrary section bodies fail closed.

func (*Document) QueryNodes

func (d *Document) QueryNodes(query NodeQuery) ([]NodeMatch, error)

QueryNodes returns at most query.Limit promoted nodes in existing structural source order. The returned slice is caller-owned and no query state is retained.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	source := []byte("# One\n\nBody.\n\n## Two\n")
	document, err := marksplice.Parse(source)
	if err != nil {
		panic(err)
	}
	matches, err := document.QueryNodes(marksplice.NodeQuery{
		Kinds: []marksplice.Kind{marksplice.KindHeading},
		Limit: 10,
	})
	if err != nil {
		panic(err)
	}
	for _, match := range matches {
		content, ok := document.SourceRange(match.Range())
		if !ok {
			panic("query range is not readable")
		}
		fmt.Println(string(content))
	}

}
Output:
One
Two

func (*Document) QuerySections

func (d *Document) QuerySections(query SectionQuery) ([]Section, error)

QuerySections returns at most query.Limit derived sections in source order. The returned slice is caller-owned and contains the existing immutable Section representation rather than a second query-specific section model.

func (*Document) ReferenceDefinition

func (d *Document) ReferenceDefinition(id NodeID) (ReferenceDefinition, bool)

ReferenceDefinition returns typed detail for one promoted single-line reference definition.

func (*Document) ResolveFragment

func (d *Document) ResolveFragment(fragment string) (FragmentTarget, bool)

ResolveFragment resolves an optional-leading-# URI fragment against heading-derived and supported explicit HTML anchors. Zero or multiple matches fail closed.

func (*Document) Section

func (d *Document) Section(headingID NodeID) (Section, bool)

Section returns the derived section governed by headingID.

func (*Document) SectionChildHeadingIDs

func (d *Document) SectionChildHeadingIDs(headingID NodeID) ([]NodeID, bool)

SectionChildHeadingIDs returns one section's immediate child heading identities in source order.

func (*Document) Sections

func (d *Document) Sections() []Section

Sections returns all derived document sections in source order.

func (*Document) SourceRange

func (d *Document) SourceRange(range_ Range) ([]byte, bool)

SourceRange returns a copy of one valid byte range from the immutable source snapshot. Caller mutations of the returned bytes do not affect the document.

func (*Document) Strikethrough

func (d *Document) Strikethrough(id NodeID) (Strikethrough, bool)

Strikethrough returns typed detail for one promoted simple GFM strikethrough.

func (*Document) Strong

func (d *Document) Strong(id NodeID) (Strong, bool)

Strong returns typed detail for one promoted simple strong-emphasis span.

func (*Document) TOCStale

func (d *Document) TOCStale(headingID NodeID) (bool, bool)

TOCStale reports whether one explicitly designated section body is a recognized TOC shape that differs from the TOC derived from this snapshot. The second result is false when the target is missing or its direct body is not TOC-shaped.

func (*Document) Table

func (d *Document) Table(id NodeID) (Table, bool)

Table returns typed detail for one promoted GFM table.

func (*Document) TableAlignments

func (d *Document) TableAlignments(tableID NodeID) ([]TableAlignment, bool)

TableAlignments returns one semantic alignment per source-proven table column. The returned slice is caller-owned.

func (*Document) TableCell

func (d *Document) TableCell(id NodeID) (TableCell, bool)

TableCell returns typed detail for one promoted non-empty GFM table cell.

func (*Document) TableHeaderCellIDs

func (d *Document) TableHeaderCellIDs(tableID NodeID) ([]NodeID, bool)

TableHeaderCellIDs returns the promoted non-empty header-cell identities owned by one promoted table in source order. Empty or otherwise unpromoted header cells are omitted.

func (*Document) TableRow

func (d *Document) TableRow(id NodeID) (TableRow, bool)

TableRow returns typed detail for one promoted GFM table body row.

func (*Document) TableRowAlignments

func (d *Document) TableRowAlignments(rowID NodeID) ([]TableAlignment, bool)

TableRowAlignments returns the semantic column alignments for the table that owns one promoted body row. The returned slice has exactly TableRow.ColumnCount entries and is caller-owned.

func (*Document) TableRowCellIDs

func (d *Document) TableRowCellIDs(rowID NodeID) ([]NodeID, bool)

TableRowCellIDs returns the promoted non-empty cells owned by one promoted body row in source order. Empty cells are omitted because they do not receive public cell identities.

func (*Document) TableRowHeaderCellIDs

func (d *Document) TableRowHeaderCellIDs(rowID NodeID) ([]NodeID, bool)

TableRowHeaderCellIDs returns the promoted non-empty header cells for the table that owns one promoted body row. Empty header cells are omitted because they do not receive public cell identities.

func (*Document) TableRowIDs

func (d *Document) TableRowIDs(tableID NodeID) ([]NodeID, bool)

TableRowIDs returns the promoted body-row identities owned by one promoted table in source order. The returned slice is caller-owned and can be empty even when BodyRowCount is non-zero.

func (*Document) Task

func (d *Document) Task(id NodeID) (Task, bool)

Task returns typed detail for one promoted GFM task marker.

func (*Document) ThematicBreak

func (d *Document) ThematicBreak(id NodeID) (ThematicBreak, bool)

ThematicBreak returns typed detail for one promoted top-level thematic break.

func (*Document) ValidateFragment

func (d *Document) ValidateFragment(fragment string) bool

ValidateFragment reports whether fragment uniquely resolves in this exact snapshot.

type DocumentBuilder

type DocumentBuilder struct {
	// contains filtered or unexported fields
}

DocumentBuilder constructs a new GFM document independently from parsed source snapshots. It is mutable and is not safe for concurrent use without caller synchronization; its zero value is a valid empty builder.

Reviewed construction includes one optional document-leading YAML/TOML front-matter envelope, ATX headings, paragraphs, thematic breaks, blockquotes/alerts, flat or homogeneous nested lists/tasks, fenced code, reference/footnote definitions, mathematical blocks, GFM tables, and typed inline content. Generated documents use canonical LF line endings, one blank line between GFM blocks, one blank line between retained front matter and a non-empty body, and one final line ending.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	builder := marksplice.NewDocumentBuilder()
	if err := builder.AppendHeadingContent(1, marksplice.TextInline("Marksplice")); err != nil {
		panic(err)
	}
	if err := builder.AppendParagraphContent(marksplice.TextInline("Source preserving GFM")); err != nil {
		panic(err)
	}

	source, err := builder.Markdown()
	if err != nil {
		panic(err)
	}
	fmt.Print(string(source))

}
Output:
# Marksplice

Source preserving GFM

func NewDocumentBuilder

func NewDocumentBuilder() *DocumentBuilder

NewDocumentBuilder returns an empty new-document builder.

func (*DocumentBuilder) AppendAlert

func (b *DocumentBuilder) AppendAlert(kind AlertKind, inlineGFM string) error

AppendAlert appends one canonical top-level GitHub alert containing one parser-proven paragraph. kind must be one of Note, Tip, Important, Warning, or Caution. inlineGFM follows the same LF-only paragraph contract as AppendBlockquote.

func (*DocumentBuilder) AppendAlertBlocks

func (b *DocumentBuilder) AppendAlertBlocks(kind AlertKind, content *DocumentBuilder) error

AppendAlertBlocks appends one canonical top-level GitHub alert from the current reviewed body blocks of content. The child builder is snapshotted and later changes do not affect this builder. Alerts cannot be nested inside blockquotes or other alerts, so child alert blocks are rejected.

func (*DocumentBuilder) AppendAlertContent

func (b *DocumentBuilder) AppendAlertContent(kind AlertKind, content ...Inline) error

AppendAlertContent appends one canonical top-level GitHub alert from typed inline paragraph content.

func (*DocumentBuilder) AppendBlockquote

func (b *DocumentBuilder) AppendBlockquote(inlineGFM string) error

AppendBlockquote appends one top-level blockquote containing one paragraph.

Non-empty LF-separated paragraph GFM is written with canonical '> ' on every physical line. The block is retained only when construction-only source and semantic proof reproduce exactly one top-level blockquote paragraph; broader existing-source blockquote promotion remains unchanged.

func (*DocumentBuilder) AppendBlockquoteBlocks

func (b *DocumentBuilder) AppendBlockquoteBlocks(depth int, content *DocumentBuilder) error

AppendBlockquoteBlocks appends one blockquote container from an existing child builder.

depth must be between 1 and 64. content is treated as an immutable construction snapshot: its current reviewed body blocks are copied into the new container, while later changes to content do not affect this builder. Every reviewed body-block construction family is accepted, including recursive blockquote children whose total structural depth remains at most 64. Front matter remains a document envelope and is never accepted as a blockquote child.

func (*DocumentBuilder) AppendBlockquoteContent

func (b *DocumentBuilder) AppendBlockquoteContent(content ...Inline) error

AppendBlockquoteContent appends one simple top-level blockquote from typed inline content.

func (*DocumentBuilder) AppendFencedCode

func (b *DocumentBuilder) AppendFencedCode(content, info string) error

AppendFencedCode appends one top-level fenced code block.

Content may be empty or LF-separated multiline text. The canonical unindented backtick fence is at least three bytes and grows beyond every potentially closing run in a non-empty body. info is an optional single-line raw GFM info string and must not contain backticks. Empty content produces adjacent opening/closing fence lines without inventing a payload line.

func (*DocumentBuilder) AppendFootnoteDefinition

func (b *DocumentBuilder) AppendFootnoteDefinition(label, body string) error

AppendFootnoteDefinition appends one canonical top-level footnote definition. Body is one non-empty physical line; broader multiline parsed definitions remain readable but are not synthesized by this conservative construction contract.

func (*DocumentBuilder) AppendHeading

func (b *DocumentBuilder) AppendHeading(level int, inlineGFM string) error

AppendHeading appends one top-level ATX heading.

inlineGFM must be one non-empty physical line of valid UTF-8 GFM source. The generated source is accepted only when reparsing proves the requested heading level and exact content range.

func (*DocumentBuilder) AppendHeadingContent

func (b *DocumentBuilder) AppendHeadingContent(level int, content ...Inline) error

AppendHeadingContent appends one top-level ATX heading from typed inline content.

func (*DocumentBuilder) AppendMathBlock

func (b *DocumentBuilder) AppendMathBlock(payload string) error

AppendMathBlock appends one canonical top-level `$$...$$` mathematical block. Multiline mathematical payload belongs in an exact-info `math` fenced block.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	builder := marksplice.NewDocumentBuilder()
	if err := builder.AppendParagraphContent(marksplice.TextInline("Value "), marksplice.MathInline("x+1")); err != nil {
		panic(err)
	}
	if err := builder.AppendMathBlock("x^2+y^2"); err != nil {
		panic(err)
	}
	markdown, err := builder.Markdown()
	if err != nil {
		panic(err)
	}
	fmt.Print(string(markdown))

}
Output:
Value $x+1$

$$x^2+y^2$$

func (*DocumentBuilder) AppendNestedBlockquote

func (b *DocumentBuilder) AppendNestedBlockquote(depth int, inlineGFM string) error

AppendNestedBlockquote appends one explicitly nested blockquote containing one paragraph.

depth is structural container depth and must be between 2 and 64. The writer derives the canonical repeated "> " prefix on every physical line; caller content remains raw paragraph GFM and must not introduce container structure that changes the requested nesting hierarchy.

func (*DocumentBuilder) AppendNestedBlockquoteContent

func (b *DocumentBuilder) AppendNestedBlockquoteContent(depth int, content ...Inline) error

AppendNestedBlockquoteContent appends one explicitly nested blockquote from typed inline content.

func (*DocumentBuilder) AppendNestedOrderedList

func (b *DocumentBuilder) AppendNestedOrderedList(items ...ListItemInput) error

AppendNestedOrderedList appends one homogeneous nested ordered list.

The same structural depth contract as AppendNestedUnorderedList applies. Decimal numbering starts at 1 in every list container and indentation follows the generated parent marker width, including transitions such as '9.' to '10.'.

func (*DocumentBuilder) AppendNestedOrderedTaskList

func (b *DocumentBuilder) AppendNestedOrderedTaskList(items ...TaskListItemInput) error

AppendNestedOrderedTaskList appends one homogeneous nested ordered GFM task list. Numbering/indentation is container-local and each canonical task marker/state is proven.

func (*DocumentBuilder) AppendNestedUnorderedList

func (b *DocumentBuilder) AppendNestedUnorderedList(items ...ListItemInput) error

AppendNestedUnorderedList appends one homogeneous nested unordered list.

Source-ordered ListItemInput values use Depth to describe the parent/child hierarchy. The writer uses canonical '-' markers and derives each nested indentation from the generated parent's exact content column.

func (*DocumentBuilder) AppendNestedUnorderedTaskList

func (b *DocumentBuilder) AppendNestedUnorderedTaskList(items ...TaskListItemInput) error

AppendNestedUnorderedTaskList appends one homogeneous nested unordered GFM task list. Structural depth follows ListItemInput and each canonical task marker/state is proven.

func (*DocumentBuilder) AppendOrderedList

func (b *DocumentBuilder) AppendOrderedList(items ...string) error

AppendOrderedList appends one flat top-level ordered list.

The writer uses canonical sequential decimal markers beginning at 1 with '.' as the delimiter. The generated items must reparse as one ordered list container.

func (*DocumentBuilder) AppendOrderedTaskList

func (b *DocumentBuilder) AppendOrderedTaskList(items ...TaskListItem) error

AppendOrderedTaskList appends one flat top-level ordered GFM task list.

The writer combines canonical sequential '1.', '2.', ... list markers with the same semantic task proof used by unordered task lists.

func (*DocumentBuilder) AppendParagraph

func (b *DocumentBuilder) AppendParagraph(inlineGFM string) error

AppendParagraph appends one top-level paragraph.

The input must be non-empty valid UTF-8 GFM source with canonical LF line endings. The complete input must reparse as exactly one top-level paragraph; input that becomes multiple blocks or another block kind fails closed instead of being escaped or normalized implicitly.

func (*DocumentBuilder) AppendParagraphContent

func (b *DocumentBuilder) AppendParagraphContent(content ...Inline) error

AppendParagraphContent appends one top-level single-line paragraph from typed inline content.

func (*DocumentBuilder) AppendReferenceDefinition

func (b *DocumentBuilder) AppendReferenceDefinition(label, destination string) error

AppendReferenceDefinition appends one top-level single-line link reference definition.

The writer uses canonical angle-bracket destination syntax without a title. The generated definition is retained only when reparsing reproduces the exact label, destination, and source mapping.

func (*DocumentBuilder) AppendReferenceDefinitionWithTitle

func (b *DocumentBuilder) AppendReferenceDefinitionWithTitle(label, destination, title string) error

AppendReferenceDefinitionWithTitle appends one top-level single-line link reference definition with a canonical double-quoted title.

The writer keeps canonical angle-bracket destination syntax and accepts the block only when reparsing reproduces the exact label, destination, title, and source mapping. title must not require escaping in the canonical form.

func (*DocumentBuilder) AppendTable

func (b *DocumentBuilder) AppendTable(header []string, rows ...[]string) error

AppendTable appends one top-level unaligned GFM table.

At least one header column is required; body rows are optional. Every body row must have the same width as header. Cell strings are caller-provided single-line GFM source; empty cells are allowed. The builder writes canonical outer pipes and '---' delimiter cells and retains the table only after exact table-container proof plus body-row proof for every row that is present.

func (*DocumentBuilder) AppendTableWithAlignments

func (b *DocumentBuilder) AppendTableWithAlignments(header []string, alignments []TableAlignment, rows ...[]string) error

AppendTableWithAlignments appends one top-level GFM table with explicit semantic column alignments.

The canonical outer-pipe/padding policy writes delimiter cells as '---', ':---', '---:', or ':---:' for default, left, right, or center alignment. alignments must have exactly one entry per header column; body rows remain optional.

func (*DocumentBuilder) AppendThematicBreak

func (b *DocumentBuilder) AppendThematicBreak() error

AppendThematicBreak appends one canonical top-level thematic break.

The builder writes exactly three hyphens and retains the block only when reparsing observes one top-level thematic break over those exact bytes.

func (*DocumentBuilder) AppendUnorderedList

func (b *DocumentBuilder) AppendUnorderedList(items ...string) error

AppendUnorderedList appends one flat top-level unordered list.

Each item must be one non-empty physical line of valid UTF-8 inline GFM. The writer uses the canonical '-' marker and accepts the block only when reparsing proves that every generated item belongs to the one requested list container.

func (*DocumentBuilder) AppendUnorderedTaskList

func (b *DocumentBuilder) AppendUnorderedTaskList(items ...TaskListItem) error

AppendUnorderedTaskList appends one flat top-level unordered GFM task list.

The writer uses canonical '-' list markers and '[ ]'/'[x]' task markers. The block is retained only when reparsing proves both the requested list container and each requested semantic task marker/state.

func (*DocumentBuilder) DeferFootnoteDefinition

func (b *DocumentBuilder) DeferFootnoteDefinition(label, body string) error

DeferFootnoteDefinition schedules one canonical top-level footnote definition after ordinary body blocks and deferred ordinary reference definitions.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	builder := marksplice.NewDocumentBuilder()
	if err := builder.DeferFootnoteDefinition("note", "Built body."); err != nil {
		panic(err)
	}
	if err := builder.AppendParagraphContent(marksplice.TextInline("Text"), marksplice.FootnoteReferenceInline("note")); err != nil {
		panic(err)
	}
	markdown, err := builder.Markdown()
	if err != nil {
		panic(err)
	}
	fmt.Print(string(markdown))

}
Output:
Text[^note]

[^note]: Built body.

func (*DocumentBuilder) DeferReferenceDefinition

func (b *DocumentBuilder) DeferReferenceDefinition(label, destination string) error

DeferReferenceDefinition schedules one canonical top-level reference definition after the ordinary constructed body. ForwardReferenceLinkInline and ForwardReferenceImageInline resolve only against explicitly deferred definitions; ReferenceLinkInline and ReferenceImageInline still require prior definitions.

func (*DocumentBuilder) DeferReferenceDefinitionWithTitle

func (b *DocumentBuilder) DeferReferenceDefinitionWithTitle(label, destination, title string) error

DeferReferenceDefinitionWithTitle schedules one canonical top-level reference definition with a conservative double-quoted title after the ordinary body.

func (*DocumentBuilder) Markdown

func (b *DocumentBuilder) Markdown() ([]byte, error)

Markdown returns newly generated canonical GFM source.

The returned bytes are caller-owned. The zero-value builder produces an empty document. A nil builder reports ErrInvalidConstruction.

func (*DocumentBuilder) SetTOMLFrontMatter

func (b *DocumentBuilder) SetTOMLFrontMatter(fields ...FrontMatterFieldInput) error

SetTOMLFrontMatter configures one canonical leading TOML front-matter envelope. A DocumentBuilder can own at most one front-matter envelope.

func (*DocumentBuilder) SetYAMLFrontMatter

func (b *DocumentBuilder) SetYAMLFrontMatter(fields ...FrontMatterFieldInput) error

SetYAMLFrontMatter configures one canonical leading YAML front-matter envelope. A DocumentBuilder can own at most one front-matter envelope.

type DocumentGraph

type DocumentGraph struct {
	// contains filtered or unexported fields
}

DocumentGraph is an immutable graph over an explicit caller-provided document set. It stores resolved edges plus compact adjacency indexes and performs no I/O.

func BuildDocumentGraph

func BuildDocumentGraph(documents []GraphDocument, resolver DocumentResolver) (*DocumentGraph, error)

BuildDocumentGraph builds a deterministic graph over documents already supplied by the caller. Local #fragment relationships resolve to their source document without invoking resolver. Every other relationship is included only when resolver explicitly maps it to a document key from the supplied set.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	index, err := marksplice.Parse([]byte("# Index\n\n[guide](guide.md#guide)\n"))
	if err != nil {
		panic(err)
	}
	guide, err := marksplice.Parse([]byte("# Guide\n"))
	if err != nil {
		panic(err)
	}
	graph, err := marksplice.BuildDocumentGraph([]marksplice.GraphDocument{
		{Key: "index", Document: index},
		{Key: "guide", Document: guide},
	}, func(_ marksplice.DocumentKey, relationship marksplice.LinkRelationship) (marksplice.DocumentResolution, bool) {
		if relationship.Destination() != "guide.md#guide" {
			return marksplice.DocumentResolution{}, false
		}
		return marksplice.DocumentResolution{Target: "guide", Fragment: "#guide"}, true
	})
	if err != nil {
		panic(err)
	}
	for _, edge := range graph.Edges() {
		_, fragmentResolved := edge.FragmentTarget()
		fmt.Printf("%s -> %s fragment=%t\n", edge.SourceDocument(), edge.TargetDocument(), fragmentResolved)
	}

}
Output:
index -> guide fragment=true
func (g *DocumentGraph) Backlinks(key DocumentKey) ([]GraphEdge, bool)

Backlinks returns resolved edges whose target is key in global edge order.

func (*DocumentGraph) Document

func (g *DocumentGraph) Document(key DocumentKey) (*Document, bool)

Document returns one immutable document snapshot by caller-defined key.

func (*DocumentGraph) DocumentKeys

func (g *DocumentGraph) DocumentKeys() []DocumentKey

DocumentKeys returns caller-defined document keys in graph-input order.

func (*DocumentGraph) Edges

func (g *DocumentGraph) Edges() []GraphEdge

Edges returns all resolved graph edges in deterministic document/source order.

func (*DocumentGraph) Outgoing

func (g *DocumentGraph) Outgoing(key DocumentKey) ([]GraphEdge, bool)

Outgoing returns resolved edges whose source is key in relationship source order.

func (*DocumentGraph) ReachableFrom

func (g *DocumentGraph) ReachableFrom(key DocumentKey) ([]DocumentKey, bool)

ReachableFrom returns every other document reachable from key using resolved graph edges. Results are in deterministic breadth-first discovery order; self cycles are omitted.

func (*DocumentGraph) RelatedDocuments

func (g *DocumentGraph) RelatedDocuments(key DocumentKey) ([]DocumentKey, bool)

RelatedDocuments returns direct incoming-or-outgoing neighboring documents in the original graph-input order. Self edges and duplicate neighbors are omitted.

type DocumentKey

type DocumentKey string

DocumentKey is a caller-defined logical identity for one document in a graph. Marksplice treats it as opaque data and does not interpret it as a filesystem path or URL.

type DocumentResolution

type DocumentResolution struct {
	Target   DocumentKey
	Fragment string
}

DocumentResolution is a caller-authorized resolution of one non-local relationship to a document that is already present in the explicit graph input set. Fragment is optional and uses the same optional-leading-# syntax accepted by Document.ResolveFragment.

type DocumentResolver

type DocumentResolver func(source DocumentKey, relationship LinkRelationship) (DocumentResolution, bool)

DocumentResolver resolves one non-local relationship against the caller's own authorization/domain model. Returning false leaves the relationship outside the graph. Marksplice invokes the resolver synchronously and never concurrently during one build, never retains it, and never performs filesystem or network access.

type Emphasis

type Emphasis struct {
	// contains filtered or unexported fields
}

Emphasis is immutable typed detail for one promoted simple emphasis span.

func (Emphasis) ID

func (e Emphasis) ID() NodeID

ID returns the emphasis span's snapshot-scoped node identity.

func (Emphasis) Range

func (e Emphasis) Range() Range

Range returns the exact emphasis content span replaced by PrepareReplaceEmphasis.

type Extension

type Extension struct {
	ID        ExtensionID
	Recognize ExtensionRecognizer
}

Extension registers one explicitly opted-in third-party recognizer under one namespace. Registration does not grant Marksplice filesystem, network, command, mutation, or construction authority. Recognizers are ordinary statically linked caller code: Marksplice validates their returned observations but cannot sandbox or preempt their own CPU, memory, goroutine, filesystem, network, or command behavior.

type ExtensionAttribute

type ExtensionAttribute struct {
	Name  string
	Value string
}

ExtensionAttribute is one extension-defined immutable scalar metadata entry. Attribute names must be non-empty tokens; values must be valid UTF-8 without NUL.

type ExtensionID

type ExtensionID string

ExtensionID is the caller-defined namespace of one explicitly registered third-party syntax/semantic extension. It is separate from the closed core Kind namespace.

type ExtensionKind

type ExtensionKind string

ExtensionKind is one extension-local semantic kind name.

type ExtensionLimits

type ExtensionLimits struct {
	MaxNodes         int
	MaxMetadataBytes int
}

ExtensionLimits bounds extension observations retained by one ParseWithOptions call. Both limits must be positive when at least one extension is registered. MaxNodes is the total retained node count across all extensions. MaxMetadataBytes bounds the total bytes retained for each node's extension ID, kind, attribute names, and attribute values; it does not attempt to sandbox allocations performed inside third-party recognizers.

type ExtensionMatch

type ExtensionMatch struct {
	Kind       ExtensionKind
	Range      Range
	Attributes []ExtensionAttribute
}

ExtensionMatch is one source-owned observation returned by a third-party recognizer. Range must be a non-empty byte range within the exact parsed source snapshot.

type ExtensionNode

type ExtensionNode struct {
	// contains filtered or unexported fields
}

ExtensionNode is one immutable validated third-party source observation attached to a Document snapshot. It never replaces or reclassifies a core Node.

func (ExtensionNode) Attribute

func (n ExtensionNode) Attribute(name string) (string, bool)

Attribute returns the unique extension metadata value named name.

func (ExtensionNode) Attributes

func (n ExtensionNode) Attributes() []ExtensionAttribute

Attributes returns caller-owned extension metadata in recognizer-provided order.

func (ExtensionNode) ExtensionID

func (n ExtensionNode) ExtensionID() ExtensionID

ExtensionID returns the namespace that produced this observation.

func (ExtensionNode) Kind

func (n ExtensionNode) Kind() ExtensionKind

Kind returns the extension-local semantic kind.

func (ExtensionNode) Range

func (n ExtensionNode) Range() Range

Range returns the exact snapshot-local source range claimed by the extension.

type ExtensionRecognizer

type ExtensionRecognizer func(source ExtensionSource) ([]ExtensionMatch, error)

ExtensionRecognizer observes extension-specific syntax or semantics over one exact source snapshot. Marksplice invokes recognizers synchronously and serially during ParseWithOptions and never retains the callback after the call returns. Returned slices must not be mutated concurrently after return.

type ExtensionSource

type ExtensionSource struct {
	// contains filtered or unexported fields
}

ExtensionSource is the immutable source view supplied to one extension recognizer. Text returns the exact parsed source bytes represented as a Go string.

func (ExtensionSource) Text

func (s ExtensionSource) Text() string

Text returns the complete immutable source snapshot as a string.

type FencedBlock

type FencedBlock struct {
	// contains filtered or unexported fields
}

FencedBlock is immutable read-only detail for one source-proven top-level GFM fenced block. It owns the complete physical container independently from the narrower historical FencedCode replacement capability.

func (FencedBlock) Closed

func (f FencedBlock) Closed() bool

Closed reports whether a matching closing fence is present in source.

func (FencedBlock) ClosingFenceLength

func (f FencedBlock) ClosingFenceLength() (int, bool)

ClosingFenceLength returns the number of delimiter bytes in the closing fence.

func (FencedBlock) ClosingFenceRange

func (f FencedBlock) ClosingFenceRange() (Range, bool)

ClosingFenceRange returns the exact closing delimiter run when the block is closed.

func (FencedBlock) ClosingIndent

func (f FencedBlock) ClosingIndent() (int, bool)

ClosingIndent returns the source indentation before the closing delimiter.

func (FencedBlock) FenceChar

func (f FencedBlock) FenceChar() byte

FenceChar returns the opening delimiter byte, either '`' or '~'.

func (FencedBlock) ID

func (f FencedBlock) ID() NodeID

ID returns the snapshot-scoped identity shared with FencedCode when the same block also satisfies the historical contiguous replacement contract.

func (FencedBlock) Info

func (f FencedBlock) Info() (string, bool)

Info returns the parser-proven trimmed info string when one is present.

func (FencedBlock) InfoRange

func (f FencedBlock) InfoRange() (Range, bool)

InfoRange returns the exact source bytes corresponding to Info.

func (FencedBlock) Language

func (f FencedBlock) Language() (string, bool)

Language returns the parser-proven language token derived from the info string. Marksplice treats the value only as metadata and does not interpret the payload.

func (FencedBlock) OpeningFenceLength

func (f FencedBlock) OpeningFenceLength() int

OpeningFenceLength returns the number of delimiter bytes in the opening fence.

func (FencedBlock) OpeningFenceRange

func (f FencedBlock) OpeningFenceRange() Range

OpeningFenceRange returns the exact opening delimiter run, excluding indentation and info-string source.

func (FencedBlock) OpeningIndent

func (f FencedBlock) OpeningIndent() int

OpeningIndent returns the source indentation before the opening delimiter.

func (FencedBlock) Range

func (f FencedBlock) Range() Range

Range returns the exact complete physical source owned by the fenced block. A closing-fence line terminator is included when present; an unclosed block owns source through EOF.

type FencedCode

type FencedCode struct {
	// contains filtered or unexported fields
}

FencedCode is immutable typed detail for one fenced code block whose payload is proven to be one exact contiguous source span suitable for the historical source-preserving replacement API. Use Document.FencedBlocks for broader read-only fenced-container ownership.

func (FencedCode) ID

func (f FencedCode) ID() NodeID

ID returns the fenced code block's snapshot-scoped node identity.

func (FencedCode) Range

func (f FencedCode) Range() Range

Range returns the exact fenced-code content span replaced by PrepareReplaceFencedCode. Internal body line endings are part of this span. Fence lines, info-string source, and the final line ending immediately before a closing fence are outside it. For an unclosed block the payload still excludes the preserved trailing source line ending when one is present.

type FootnoteDefinition

type FootnoteDefinition struct {
	// contains filtered or unexported fields
}

FootnoteDefinition is immutable typed detail for one source-proven top-level footnote definition. Range owns the complete physical definition container; BodyRange is available only for the conservative simple editable subset.

func (FootnoteDefinition) BodyRange

func (f FootnoteDefinition) BodyRange() (Range, bool)

BodyRange returns the exact simple body span suitable for source-preserving replacement. Segmented or multiline definitions return false; use Document.FootnoteDefinitionBodyRanges for read-only semantic body segments.

func (FootnoteDefinition) ID

func (f FootnoteDefinition) ID() NodeID

ID returns the definition's snapshot-scoped structural identity.

func (FootnoteDefinition) Label

func (f FootnoteDefinition) Label() string

Label returns the parser-proven footnote label.

func (FootnoteDefinition) LabelRange

func (f FootnoteDefinition) LabelRange() Range

LabelRange returns the exact source bytes containing Label.

func (FootnoteDefinition) Range

func (f FootnoteDefinition) Range() Range

Range returns the exact complete physical source owned by the definition.

type FootnoteReference

type FootnoteReference struct {
	// contains filtered or unexported fields
}

FootnoteReference is one immutable parser-proven footnote reference occurrence. It is relationship data and does not grant generic mutation authority.

func (FootnoteReference) DefinitionID

func (r FootnoteReference) DefinitionID() (NodeID, bool)

DefinitionID returns the promoted definition that owns this reference when complete top-level source ownership is proven.

func (FootnoteReference) Label

func (r FootnoteReference) Label() string

Label returns the parser-proven footnote label.

func (FootnoteReference) LabelRange

func (r FootnoteReference) LabelRange() Range

LabelRange returns the exact source bytes containing Label.

func (FootnoteReference) Occurrence

func (r FootnoteReference) Occurrence() int

Occurrence returns the zero-based source-order occurrence for this definition.

func (FootnoteReference) Range

func (r FootnoteReference) Range() Range

Range returns the exact `[^label]` source token span.

type FragmentTarget

type FragmentTarget struct {
	// contains filtered or unexported fields
}

FragmentTarget is one uniquely resolved fragment destination in this snapshot.

func (FragmentTarget) Kind

Kind returns whether this target is a derived heading anchor or supported explicit HTML anchor.

func (FragmentTarget) NodeID

func (t FragmentTarget) NodeID() NodeID

NodeID returns the snapshot-scoped node identity owning the fragment target.

func (FragmentTarget) Value

func (t FragmentTarget) Value() string

Value returns the resolved fragment value without a leading '#'.

type FragmentTargetKind

type FragmentTargetKind uint8

FragmentTargetKind identifies one supported intra-document fragment target kind.

const (
	FragmentTargetUnknown FragmentTargetKind = iota
	FragmentTargetHeading
	FragmentTargetHTMLAnchor
)

type FrontMatter

type FrontMatter struct {
	// contains filtered or unexported fields
}

FrontMatter is immutable source ownership for one recognized document-leading metadata envelope. It is document-envelope state rather than a structural Markdown node.

func (FrontMatter) ClosingRange

func (f FrontMatter) ClosingRange() Range

ClosingRange returns the exact closing delimiter bytes.

func (FrontMatter) Format

func (f FrontMatter) Format() FrontMatterFormat

Format returns whether the envelope uses the reviewed YAML or TOML delimiters.

func (FrontMatter) OpeningRange

func (f FrontMatter) OpeningRange() Range

OpeningRange returns the exact opening delimiter bytes.

func (FrontMatter) Range

func (f FrontMatter) Range() Range

Range returns the complete envelope from the opening delimiter through the closing delimiter. A physical line terminator following the closing delimiter is outside this range.

type FrontMatterField

type FrontMatterField struct {
	// contains filtered or unexported fields
}

FrontMatterField is immutable typed detail for one promoted simple leading YAML/TOML scalar field.

func (FrontMatterField) Format

Format returns whether the field belongs to a YAML or TOML front-matter envelope.

func (FrontMatterField) ID

func (f FrontMatterField) ID() NodeID

ID returns the field's snapshot-scoped node identity.

func (FrontMatterField) Key

func (f FrontMatterField) Key() string

Key returns the recognized simple scalar field key.

func (FrontMatterField) Range

func (f FrontMatterField) Range() Range

Range returns the exact scalar value span replaced by PrepareReplaceFrontMatterValue. Delimiters, key spelling, separator spacing, quote wrappers, comments, and line endings are outside this range.

type FrontMatterFieldInput

type FrontMatterFieldInput struct {
	Key   string
	Value string
}

FrontMatterFieldInput is construction-only input for one canonical simple YAML/TOML string scalar.

Key uses the existing conservative front-matter key alphabet. Value is written as one double-quoted string and therefore must not require escaping.

type FrontMatterFormat

type FrontMatterFormat uint8

FrontMatterFormat identifies the source format of a recognized front-matter envelope or promoted field.

const (
	FrontMatterFormatUnknown FrontMatterFormat = iota
	FrontMatterFormatYAML
	FrontMatterFormatTOML
)

type GraphDocument

type GraphDocument struct {
	Key      DocumentKey
	Document *Document
}

GraphDocument binds one caller-defined logical key to an immutable parsed document.

type GraphEdge

type GraphEdge struct {
	// contains filtered or unexported fields
}

GraphEdge is one immutable resolved relationship between two caller-provided documents.

func (GraphEdge) Fragment

func (e GraphEdge) Fragment() (string, bool)

Fragment returns the local target fragment when the edge carries one. For cross-document relationships this is the fragment supplied by the resolver.

func (GraphEdge) FragmentTarget

func (e GraphEdge) FragmentTarget() (FragmentTarget, bool)

FragmentTarget returns the uniquely resolved target snapshot fragment when one exists.

func (GraphEdge) Relationship

func (e GraphEdge) Relationship() LinkRelationship

Relationship returns the immutable link relationship that produced this edge.

func (GraphEdge) SourceDocument

func (e GraphEdge) SourceDocument() DocumentKey

SourceDocument returns the caller-defined logical source document key.

func (GraphEdge) TargetDocument

func (e GraphEdge) TargetDocument() DocumentKey

TargetDocument returns the caller-defined logical target document key.

type HTMLAnchor

type HTMLAnchor struct {
	// contains filtered or unexported fields
}

HTMLAnchor is immutable typed detail for one promoted simple quoted id/name attribute on an <a> tag.

func (HTMLAnchor) Attribute

func (a HTMLAnchor) Attribute() HTMLAnchorAttribute

Attribute returns whether the promoted anchor targets an id or name attribute.

func (HTMLAnchor) ID

func (a HTMLAnchor) ID() NodeID

ID returns the HTML anchor's snapshot-scoped node identity.

func (HTMLAnchor) Range

func (a HTMLAnchor) Range() Range

Range returns the exact quoted attribute value span replaced by PrepareReplaceHTMLAnchor. Tag/attribute spelling, spacing, quote wrappers, and other attributes are outside this range.

type HTMLAnchorAttribute

type HTMLAnchorAttribute uint8

HTMLAnchorAttribute identifies the semantic anchor attribute targeted by an HTMLAnchor.

const (
	HTMLAnchorAttributeUnknown HTMLAnchorAttribute = iota
	HTMLAnchorAttributeID
	HTMLAnchorAttributeName
)

type HTMLComment

type HTMLComment struct {
	// contains filtered or unexported fields
}

HTMLComment is immutable typed detail for one promoted single-line HTML comment payload.

func (HTMLComment) ID

func (c HTMLComment) ID() NodeID

ID returns the HTML comment's snapshot-scoped node identity.

func (HTMLComment) Range

func (c HTMLComment) Range() Range

Range returns the exact comment payload span replaced by PrepareReplaceHTMLComment. Comment delimiters and preserved inner horizontal padding are outside this range.

type Heading

type Heading struct {
	// contains filtered or unexported fields
}

Heading is immutable typed detail for one promoted top-level heading.

func (Heading) ID

func (h Heading) ID() NodeID

ID returns the heading's snapshot-scoped node identity.

func (Heading) Level

func (h Heading) Level() int

Level returns the GFM heading level from 1 through 6.

func (Heading) Range

func (h Heading) Range() Range

Range returns the exact heading-content byte span replaced by PrepareRenameHeading. ATX markers, optional closing markers, Setext underlines, and line endings are outside this range.

func (Heading) Style

func (h Heading) Style() HeadingStyle

Style returns whether the heading uses ATX or Setext source syntax.

type HeadingAnchor

type HeadingAnchor struct {
	// contains filtered or unexported fields
}

HeadingAnchor is an immutable GitHub-compatible anchor derived from one heading.

func (HeadingAnchor) HeadingID

func (a HeadingAnchor) HeadingID() NodeID

HeadingID returns the snapshot-scoped heading identity that owns this anchor.

func (HeadingAnchor) Value

func (a HeadingAnchor) Value() string

Value returns the fragment value without a leading '#'.

type HeadingStyle

type HeadingStyle uint8

HeadingStyle identifies the source syntax of a promoted heading.

const (
	HeadingStyleUnknown HeadingStyle = iota
	HeadingStyleATX
	HeadingStyleSetext
)

type Image

type Image struct {
	// contains filtered or unexported fields
}

Image is immutable typed detail for one promoted simple inline image.

func (Image) ID

func (i Image) ID() NodeID

ID returns the image's snapshot-scoped node identity.

func (Image) Range

func (i Image) Range() Range

Range returns the exact destination span replaced by PrepareReplaceImageDestination. The image marker, alt text, parentheses, destination wrappers, title syntax, and surrounding source are outside this range.

type Inline

type Inline struct {
	// contains filtered or unexported fields
}

Inline is a construction-only typed inline value.

Its zero value is invalid. Use the exported Inline construction functions rather than depending on its private representation.

func AutoLinkInline

func AutoLinkInline(value string) Inline

AutoLinkInline returns one canonical angle-autolink construction value. Validation succeeds only when reparsing produces the existing source-proven AutoLink capability.

func BareAutoLinkInline

func BareAutoLinkInline(value string) Inline

BareAutoLinkInline returns one parser-proven GFM extended autolink token without adding angle brackets. The complete requested token must be owned by one AutoLink observation after reparsing or construction fails closed.

func CodeInline

func CodeInline(code string) Inline

CodeInline returns one conservative single-line code span construction value.

The writer selects an adaptive backtick delimiter longer than every internal run. Leading/trailing horizontal space and leading/trailing backticks are rejected because supporting those shapes would require semantic whitespace or delimiter normalization beyond the existing source-proven parsed CodeSpan capability.

func CollapsedReferenceImageInline

func CollapsedReferenceImageInline(alt ...Inline) Inline

CollapsedReferenceImageInline returns one `![alt][]` construction value.

func CollapsedReferenceLinkInline

func CollapsedReferenceLinkInline(label ...Inline) Inline

CollapsedReferenceLinkInline returns one `[label][]` construction value. The emitted label must resolve to exactly one available normalized definition.

func EmphasisInline

func EmphasisInline(content ...Inline) Inline

EmphasisInline returns one conservative emphasis construction value. It permits bounded nesting of code, emphasis, strong, and strikethrough children while keeping links/images/autolinks outside this wrapper slice.

func FootnoteReferenceInline

func FootnoteReferenceInline(label string) Inline

FootnoteReferenceInline returns one typed `[^label]` reference. The label must resolve to exactly one already-appended or explicitly deferred footnote definition in the destination DocumentBuilder when the value is appended.

func ForwardReferenceImageInline

func ForwardReferenceImageInline(reference string, alt ...Inline) Inline

ForwardReferenceImageInline returns one full reference-image construction value resolved only against one explicitly deferred top-level definition.

func ForwardReferenceLinkInline

func ForwardReferenceLinkInline(reference string, label ...Inline) Inline

ForwardReferenceLinkInline returns one full reference-link construction value resolved only against one explicitly deferred top-level definition.

func ImageInline

func ImageInline(destination string, alt ...Inline) Inline

ImageInline returns one conservative inline-image construction value.

The destination is written in angle brackets and alt content may contain the reviewed bounded structured-inline children; use ImageInlineWithTitle for a title.

func ImageInlineWithTitle

func ImageInlineWithTitle(destination, title string, alt ...Inline) Inline

ImageInlineWithTitle returns one conservative inline-image construction value with a canonical double-quoted title. It applies the same conservative title policy as LinkInlineWithTitle.

func LinkInline

func LinkInline(destination string, label ...Inline) Inline

LinkInline returns one conservative inline-link construction value.

The destination is written in angle brackets and labels may contain the reviewed bounded structured-inline children; use LinkInlineWithTitle for a title.

func LinkInlineWithTitle

func LinkInlineWithTitle(destination, title string, label ...Inline) Inline

LinkInlineWithTitle returns one conservative inline-link construction value with a canonical double-quoted title. The title must be non-empty and require no GFM escape or entity interpretation.

func MathBacktickInline

func MathBacktickInline(payload string) Inline

MathBacktickInline returns one conservative GitHub-compatible `$`-backtick construction value for payload that would otherwise overlap Markdown syntax.

func MathInline

func MathInline(payload string) Inline

MathInline returns one conservative GitHub-compatible `$...$` construction value. Mathematical payload remains opaque and must fit on one physical line.

func ReferenceImageInline

func ReferenceImageInline(reference string, alt ...Inline) Inline

ReferenceImageInline returns one conservative full reference-image construction value. It follows the same exact-definition and structured-alt requirements as ReferenceLinkInline.

func ReferenceLinkInline

func ReferenceLinkInline(reference string, label ...Inline) Inline

ReferenceLinkInline returns one conservative full reference-link construction value. The exact reference label must identify one already-appended top-level reference definition in the destination DocumentBuilder when the value is appended. It permits the same reviewed bounded structured-inline label children as direct links.

func ShortcutReferenceImageInline

func ShortcutReferenceImageInline(alt ...Inline) Inline

ShortcutReferenceImageInline returns one `![alt]` construction value.

func ShortcutReferenceLinkInline

func ShortcutReferenceLinkInline(label ...Inline) Inline

ShortcutReferenceLinkInline returns one `[label]` construction value. The emitted label must resolve to exactly one available normalized definition.

func StrikethroughInline

func StrikethroughInline(content ...Inline) Inline

StrikethroughInline returns one conservative GFM strikethrough construction value. It permits bounded code/emphasis/strong children but rejects direct strikethrough-in-strikethrough nesting because adjacent tilde runs are ambiguous.

func StrongInline

func StrongInline(content ...Inline) Inline

StrongInline returns one conservative strong-emphasis construction value. It applies the same bounded structured-child policy as EmphasisInline.

func TextInline

func TextInline(text string) Inline

TextInline returns semantic plain text for typed inline construction.

ASCII punctuation is encoded with canonical GFM backslash escapes so caller text cannot become Markdown syntax implicitly. Validation occurs when the value is appended to a DocumentBuilder.

type InlineLink struct {
	// contains filtered or unexported fields
}

InlineLink is immutable typed detail for one promoted simple inline link.

func (InlineLink) Destination

func (l InlineLink) Destination() string

Destination returns the parser-proven semantic link destination.

func (InlineLink) ID

func (l InlineLink) ID() NodeID

ID returns the inline link's snapshot-scoped node identity.

func (InlineLink) Range

func (l InlineLink) Range() Range

Range returns the exact destination span replaced by PrepareReplaceInlineLinkDestination. Label, parentheses, destination wrappers, title syntax, and surrounding source are outside this range.

func (InlineLink) Title

func (l InlineLink) Title() (string, bool)

Title returns the parser-proven semantic link title when one is present.

type Kind

type Kind uint8

Kind identifies a Marksplice core structural Markdown node category. Third-party extension identities are intentionally outside this core enum.

const (
	KindUnknown Kind = iota
	KindParagraph
	KindHeading
	KindListItem
	KindTask
	KindTableCell
	KindFencedCode
	KindStrikethrough
	KindCodeSpan
	KindEmphasis
	KindStrong
	KindInlineLink
	KindReferenceDefinition
	KindAutoLink
	KindFrontMatterField
	KindHTMLComment
	KindHTMLAnchor
	KindImage
	KindTableRow
	KindTable
	KindThematicBreak
	KindBlockquote
	KindFootnoteDefinition
	KindMathExpression
)

type KnowledgeAlias

type KnowledgeAlias string

KnowledgeAlias is one exact, syntax-independent alternate name for a document. Marksplice does not normalize, parse, or derive aliases from Markdown or metadata source.

type KnowledgeDocument

type KnowledgeDocument struct {
	Document   DocumentKey
	Aliases    []KnowledgeAlias
	Tags       []KnowledgeTag
	References []DocumentKey
}

KnowledgeDocument supplies caller-owned semantic metadata for one document already present in the explicit DocumentGraph. Graph documents omitted from the input simply have no knowledge metadata; this value never changes the underlying document snapshot.

type KnowledgeIndex

type KnowledgeIndex struct {
	// contains filtered or unexported fields
}

KnowledgeIndex is an immutable syntax-independent semantic overlay on one DocumentGraph. It retains no parser, resolver callback, filesystem/network authority, or source mutation capability.

func BuildKnowledgeIndex

func BuildKnowledgeIndex(graph *DocumentGraph, documents []KnowledgeDocument) (*KnowledgeIndex, error)

BuildKnowledgeIndex builds syntax-independent aliases, tags, and logical references over an already-authorized document graph. Metadata may be supplied for any subset of graph documents. Every logical reference target must already belong to the graph; aliases never resolve or discover additional documents.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	a, err := marksplice.Parse([]byte("# A\n\n[to-b](b.md)\n"))
	if err != nil {
		panic(err)
	}
	b, err := marksplice.Parse([]byte("# B\n"))
	if err != nil {
		panic(err)
	}
	graph, err := marksplice.BuildDocumentGraph([]marksplice.GraphDocument{
		{Key: "a", Document: a},
		{Key: "b", Document: b},
	}, func(_ marksplice.DocumentKey, relationship marksplice.LinkRelationship) (marksplice.DocumentResolution, bool) {
		if relationship.Destination() == "b.md" {
			return marksplice.DocumentResolution{Target: "b"}, true
		}
		return marksplice.DocumentResolution{}, false
	})
	if err != nil {
		panic(err)
	}
	knowledge, err := marksplice.BuildKnowledgeIndex(graph, []marksplice.KnowledgeDocument{
		{Document: "a", Aliases: []marksplice.KnowledgeAlias{"start"}, Tags: []marksplice.KnowledgeTag{"guide"}},
		{Document: "b", Tags: []marksplice.KnowledgeTag{"guide"}, References: []marksplice.DocumentKey{"a"}},
	})
	if err != nil {
		panic(err)
	}
	alias, _ := knowledge.ResolveAlias("start")
	related, _ := knowledge.RelatedDocuments("a")
	fmt.Printf("alias=%s tagged=%d related=%v\n", alias, len(knowledge.DocumentsWithTag("guide")), related)

}
Output:
alias=a tagged=2 related=[b]

func (*KnowledgeIndex) Aliases

func (k *KnowledgeIndex) Aliases(key DocumentKey) ([]KnowledgeAlias, bool)

Aliases returns exact aliases for key in caller-provided order. The returned slice is caller-owned.

func (*KnowledgeIndex) DocumentsWithTag

func (k *KnowledgeIndex) DocumentsWithTag(tag KnowledgeTag) []DocumentKey

DocumentsWithTag returns graph documents carrying the exact tag in original graph-input order.

func (*KnowledgeIndex) ReachableFrom

func (k *KnowledgeIndex) ReachableFrom(key DocumentKey) ([]DocumentKey, bool)

ReachableFrom returns every other document reachable through the union of resolved Markdown graph edges and caller-declared logical references. For each visited source, graph edges are considered first, then logical references. Results are deterministic breadth-first discovery order and self/cyclic paths never duplicate a document.

func (*KnowledgeIndex) ReferencedBy

func (k *KnowledgeIndex) ReferencedBy(key DocumentKey) ([]KnowledgeReference, bool)

ReferencedBy returns logical references whose target is key in global reference order.

func (*KnowledgeIndex) References

func (k *KnowledgeIndex) References() []KnowledgeReference

References returns all logical references in graph document order and per-document caller order.

func (*KnowledgeIndex) ReferencesFrom

func (k *KnowledgeIndex) ReferencesFrom(key DocumentKey) ([]KnowledgeReference, bool)

ReferencesFrom returns logical references whose source is key in caller order.

func (*KnowledgeIndex) RelatedDocuments

func (k *KnowledgeIndex) RelatedDocuments(key DocumentKey) ([]DocumentKey, bool)

RelatedDocuments returns unique direct neighbors across both resolved Markdown graph edges and caller-declared logical references in original graph-input order. Self relationships are omitted.

func (*KnowledgeIndex) ResolveAlias

func (k *KnowledgeIndex) ResolveAlias(alias KnowledgeAlias) (DocumentKey, bool)

ResolveAlias resolves one exact globally unique alias to an existing graph document. Canonical DocumentKey values are not aliases and should be queried through DocumentGraph.

func (*KnowledgeIndex) Tags

func (k *KnowledgeIndex) Tags(key DocumentKey) ([]KnowledgeTag, bool)

Tags returns exact tags for key in caller-provided order. The returned slice is caller-owned.

type KnowledgeReference

type KnowledgeReference struct {
	// contains filtered or unexported fields
}

KnowledgeReference is one immutable caller-declared logical document relationship. It has no source offset because the knowledge layer does not infer Markdown or metadata syntax.

func (KnowledgeReference) SourceDocument

func (r KnowledgeReference) SourceDocument() DocumentKey

SourceDocument returns the caller-defined logical source document key.

func (KnowledgeReference) TargetDocument

func (r KnowledgeReference) TargetDocument() DocumentKey

TargetDocument returns the caller-defined logical target document key.

type KnowledgeTag

type KnowledgeTag string

KnowledgeTag is one exact, syntax-independent classification value for a document. Matching is byte-exact and case-sensitive; Marksplice performs no normalization.

type LinkFragmentStatus

type LinkFragmentStatus uint8

LinkFragmentStatus reports whether a relationship destination is an intra-document fragment and, when applicable, how it resolves in this snapshot.

const (
	LinkFragmentNotApplicable LinkFragmentStatus = iota
	LinkFragmentResolved
	LinkFragmentMissing
	LinkFragmentAmbiguous
	LinkFragmentInvalid
)

type LinkRelationship

type LinkRelationship struct {
	// contains filtered or unexported fields
}

LinkRelationship is an immutable semantic outgoing link/image/autolink fact. It does not define generic source ownership or mutation authority.

func (LinkRelationship) Destination

func (r LinkRelationship) Destination() string

Destination returns the parser-resolved semantic destination. Other-document paths and URLs remain opaque data; Marksplice does not access them.

func (LinkRelationship) FragmentStatus

func (r LinkRelationship) FragmentStatus() LinkFragmentStatus

FragmentStatus reports intra-document fragment resolution using the same semantics as ResolveFragment for destinations beginning with '#'. Other destinations return NotApplicable.

func (LinkRelationship) FragmentTarget

func (r LinkRelationship) FragmentTarget() (FragmentTarget, bool)

FragmentTarget returns the resolved target when FragmentStatus is Resolved.

func (LinkRelationship) IsEmail

func (r LinkRelationship) IsEmail() bool

IsEmail reports whether an autolink relationship was parser-classified as an email autolink. It is false for every non-autolink relationship.

func (LinkRelationship) Kind

Kind returns the semantic relationship/source-form family.

func (LinkRelationship) Reference

func (r LinkRelationship) Reference() (string, ReferenceForm, bool)

Reference returns the parser-resolved reference label and source form for a reference link/image. Direct links/images and autolinks return false.

func (LinkRelationship) ReferenceDefinitionID

func (r LinkRelationship) ReferenceDefinitionID() (NodeID, bool)

ReferenceDefinitionID returns the promoted single-line definition that can be proven to uniquely own this reference relationship. Unsupported or ambiguous definition ownership returns false without invalidating the relationship.

func (LinkRelationship) SourceNodeID

func (r LinkRelationship) SourceNodeID() (NodeID, bool)

SourceNodeID returns an existing promoted source node identity when this exact relationship already belongs to the ordinary public node model.

func (LinkRelationship) SourceOffset

func (r LinkRelationship) SourceOffset() int

SourceOffset returns the parser-proven byte offset where the relationship's source syntax starts. It is diagnostic/ordering metadata, not a mutation range.

func (LinkRelationship) Title

func (r LinkRelationship) Title() (string, bool)

Title returns the parser-resolved title when one is present.

type LinkRelationshipKind

type LinkRelationshipKind uint8

LinkRelationshipKind identifies one semantic outgoing link/image relationship.

const (
	LinkRelationshipUnknown LinkRelationshipKind = iota
	LinkRelationshipInlineLink
	LinkRelationshipReferenceLink
	LinkRelationshipInlineImage
	LinkRelationshipReferenceImage
	LinkRelationshipAutoLink
)

type ListItem

type ListItem struct {
	// contains filtered or unexported fields
}

ListItem is immutable typed detail for one promoted single-line list item.

func (ListItem) ChildIDs

func (i ListItem) ChildIDs() []NodeID

ChildIDs returns the immediate supported list-item child identities in source order. Semantic children outside the promoted public subset are omitted.

func (ListItem) HasChildren

func (i ListItem) HasChildren() bool

HasChildren reports whether the supported single-line item owns one or more semantic direct child list items. It can be true even when ChildIDs is empty because unsupported children are not assigned public identities.

func (ListItem) ID

func (i ListItem) ID() NodeID

ID returns the list item's snapshot-scoped node identity.

func (ListItem) Marker

func (i ListItem) Marker() byte

Marker returns the source marker/delimiter byte. Unordered items use '-', '*', or '+'; ordered items use '.' or ')'.

func (ListItem) Ordered

func (i ListItem) Ordered() bool

Ordered reports whether the item belongs to an ordered list.

func (ListItem) ParentID

func (i ListItem) ParentID() (NodeID, bool)

ParentID returns the immediate supported list-item parent's snapshot-scoped identity. The boolean is false for root items and when the semantic parent exists but is not publicly promoted.

func (ListItem) Range

func (i ListItem) Range() Range

Range returns the exact list-item content span replaced by PrepareReplaceListItem. Indentation, list numbering, marker/delimiter bytes, post-marker spacing, and line endings are outside this range.

func (ListItem) SubtreeRange

func (i ListItem) SubtreeRange() (Range, bool)

SubtreeRange returns the exact complete supported subtree source span used by structural list-item operations. The boolean is false when Marksplice cannot prove that every semantic descendant belongs to the supported list-item model.

type ListItemInput

type ListItemInput struct {
	InlineGFM string
	Depth     int
}

ListItemInput is construction-only structured input for one item in a nested list.

Depth is structural depth, not source indentation: zero denotes a top-level item and each child is exactly one level deeper than its parent. DocumentBuilder derives canonical indentation from the generated parent marker width.

type ManagedTOC

type ManagedTOC struct {
	Document  DocumentKey
	HeadingID NodeID
}

ManagedTOC identifies one caller-designated section whose body is expected to use the conservative managed TOC shape recognized by TOCStale and PrepareSyncTOC.

type MathExpression

type MathExpression struct {
	// contains filtered or unexported fields
}

MathExpression is immutable typed detail for one reviewed mathematical source form. Mathematical payload is opaque data; Marksplice does not parse or render LaTeX.

func (MathExpression) ID

func (m MathExpression) ID() NodeID

ID returns the snapshot-scoped identity. Fenced math shares the underlying FencedBlock ID.

func (MathExpression) PayloadRange

func (m MathExpression) PayloadRange() (Range, bool)

PayloadRange returns one exact contiguous payload span when available. Dollar/backtick forms always expose it; fenced math may be non-contiguous or empty.

func (MathExpression) Range

func (m MathExpression) Range() Range

Range returns the complete source-owned mathematical syntax/container.

func (MathExpression) Style

Style returns the exact reviewed source delimiter/container form.

type MathExpressionStyle

type MathExpressionStyle uint8

MathExpressionStyle identifies one reviewed GitHub-compatible mathematical source form.

const (
	MathExpressionUnknown MathExpressionStyle = iota
	MathExpressionInlineDollar
	MathExpressionInlineBacktick
	MathExpressionBlockDollar
	MathExpressionFencedBlock
)

type Node

type Node struct {
	// contains filtered or unexported fields
}

Node is an immutable public summary of one promoted structural node.

Syntax-specific details and source ranges are intentionally not part of this common value until their public semantics are reviewed.

func (Node) ID

func (n Node) ID() NodeID

ID returns the snapshot-scoped node identity.

func (Node) Kind

func (n Node) Kind() Kind

Kind returns the structural node category.

type NodeID

type NodeID struct {
	// contains filtered or unexported fields
}

NodeID identifies a node within one parsed source snapshot.

Node IDs are deterministic for a snapshot, but they are not durable identities across arbitrary source changes or reparses. The representation is opaque; String is for diagnostics and does not define a persistence or round-trip format.

func (NodeID) String

func (id NodeID) String() string

String returns a diagnostic representation of the snapshot-scoped ID.

type NodeMatch

type NodeMatch struct {
	// contains filtered or unexported fields
}

NodeMatch is one immutable structural query result.

func (NodeMatch) Node

func (m NodeMatch) Node() Node

Node returns the promoted structural node summary.

func (NodeMatch) Range

func (m NodeMatch) Range() Range

Range returns the same operation-oriented source range already exposed by the matched node kind's typed Range() accessor. It is a query-selection span, not independent mutation authority.

type NodeQuery

type NodeQuery struct {
	Kinds  []Kind
	Within *Range
	Limit  int
}

NodeQuery selects promoted structural nodes from one immutable document snapshot.

Limit must be positive so result allocation is always caller-bounded. An empty Kinds slice selects every currently promoted public node kind. Within, when non-nil, requires the selected node's existing typed Range() span to be fully contained by that snapshot-local byte range.

type Paragraph

type Paragraph struct {
	// contains filtered or unexported fields
}

Paragraph is immutable typed detail for one promoted top-level paragraph.

func (Paragraph) ID

func (p Paragraph) ID() NodeID

ID returns the paragraph's snapshot-scoped node identity.

func (Paragraph) Range

func (p Paragraph) Range() Range

Range returns the exact paragraph byte span replaced by PrepareReplaceParagraph. A line ending immediately following the paragraph is outside this range.

type ParseOptions

type ParseOptions struct {
	Extensions      []Extension
	ExtensionLimits ExtensionLimits
}

ParseOptions configures optional third-party semantic/source overlays. Zero options are exactly equivalent to Parse.

type Range

type Range struct {
	Start int
	End   int
}

Range is a half-open byte range [Start, End) in a source snapshot. The accessor returning a Range defines the semantic meaning of that span.

func (Range) Valid

func (r Range) Valid(total int) bool

Valid reports whether r is ordered and contained in a source of total bytes.

type ReferenceDefinition

type ReferenceDefinition struct {
	// contains filtered or unexported fields
}

ReferenceDefinition is immutable typed detail for one promoted single-line reference definition.

func (ReferenceDefinition) Destination

func (r ReferenceDefinition) Destination() string

Destination returns the parser-proven semantic reference destination.

func (ReferenceDefinition) ID

func (r ReferenceDefinition) ID() NodeID

ID returns the reference definition's snapshot-scoped node identity.

func (ReferenceDefinition) Label

func (r ReferenceDefinition) Label() string

Label returns the parser-proven reference-definition label as authored.

func (ReferenceDefinition) Range

func (r ReferenceDefinition) Range() Range

Range returns the exact destination span replaced by PrepareReplaceReferenceDefinitionDestination. Label, colon, destination wrappers, title syntax, indentation, trailing spaces, and line endings are outside this range.

func (ReferenceDefinition) Title

func (r ReferenceDefinition) Title() (string, bool)

Title returns the parser-proven semantic reference title when one is present.

type ReferenceForm

type ReferenceForm uint8

ReferenceForm identifies one GFM reference-link/image source form.

const (
	ReferenceFormUnknown ReferenceForm = iota
	ReferenceFormFull
	ReferenceFormCollapsed
	ReferenceFormShortcut
)

type Section

type Section struct {
	// contains filtered or unexported fields
}

Section is an immutable source-bound view governed by one promoted document heading.

func (Section) BodyRange

func (s Section) BodyRange() Range

BodyRange returns the direct body source span after the heading line and before the next heading of any level. Nested subsection headings and their content are outside this range.

func (Section) HeadingID

func (s Section) HeadingID() NodeID

HeadingID returns the snapshot-scoped heading node identity governing this section.

func (Section) Level

func (s Section) Level() int

Level returns the governing GFM heading level from 1 through 6.

func (Section) ParentHeadingID

func (s Section) ParentHeadingID() (NodeID, bool)

ParentHeadingID returns the governing heading ID of the nearest enclosing section.

func (Section) Range

func (s Section) Range() Range

Range returns the complete section subtree source span, including its heading. The range ends immediately before the next heading of equal or higher level, or at end of source.

type SectionQuery

type SectionQuery struct {
	Levels []int
	Within *Range
	Limit  int
}

SectionQuery selects derived document sections from one immutable snapshot.

Limit must be positive. An empty Levels slice selects every heading level. Within, when non-nil, requires the complete Section.Range() to be fully contained by that snapshot-local byte range.

type Strikethrough

type Strikethrough struct {
	// contains filtered or unexported fields
}

Strikethrough is immutable typed detail for one promoted simple GFM strikethrough.

func (Strikethrough) ID

func (s Strikethrough) ID() NodeID

ID returns the strikethrough's snapshot-scoped node identity.

func (Strikethrough) Range

func (s Strikethrough) Range() Range

Range returns the exact strikethrough content span replaced by PrepareReplaceStrikethrough.

type Strong

type Strong struct {
	// contains filtered or unexported fields
}

Strong is immutable typed detail for one promoted simple strong-emphasis span.

func (Strong) ID

func (s Strong) ID() NodeID

ID returns the strong span's snapshot-scoped node identity.

func (Strong) Range

func (s Strong) Range() Range

Range returns the exact strong content span replaced by PrepareReplaceStrong.

type Table

type Table struct {
	// contains filtered or unexported fields
}

Table is immutable typed detail for one promoted GFM table.

func (Table) BodyRowCount

func (t Table) BodyRowCount() int

BodyRowCount returns the semantic number of body rows, including rows outside the promoted public row subset.

func (Table) ColumnCount

func (t Table) ColumnCount() int

ColumnCount returns the semantic/source-proven number of table columns.

func (Table) ID

func (t Table) ID() NodeID

ID returns the table's snapshot-scoped node identity.

func (Table) Range

func (t Table) Range() Range

Range returns the exact complete table source span. It owns the header row, delimiter row, and every semantic body row; when present, the final owned line terminator is included.

type TableAlignment

type TableAlignment uint8

TableAlignment identifies the semantic alignment of a GFM table column. It is used for new-document construction and read-only parsed table alignment access.

const (
	TableAlignmentDefault TableAlignment = iota
	TableAlignmentLeft
	TableAlignmentRight
	TableAlignmentCenter
)

type TableCell

type TableCell struct {
	// contains filtered or unexported fields
}

TableCell is immutable typed detail for one promoted non-empty GFM table cell.

func (TableCell) Column

func (c TableCell) Column() int

Column returns the zero-based column index within the mapped table row.

func (TableCell) Header

func (c TableCell) Header() bool

Header reports whether the cell belongs to the table header row.

func (TableCell) ID

func (c TableCell) ID() NodeID

ID returns the table cell's snapshot-scoped node identity.

func (TableCell) Range

func (c TableCell) Range() Range

Range returns the exact table-cell content span replaced by PrepareReplaceTableCell. Pipes, cell padding, alignment syntax, neighboring cells, and line endings are outside this range.

func (TableCell) RowID

func (c TableCell) RowID() (NodeID, bool)

RowID returns the promoted GFM body row that owns this cell. The boolean is false for header cells and when no promoted body-row identity is available.

func (TableCell) TableID

func (c TableCell) TableID() (NodeID, bool)

TableID returns the promoted GFM table that owns this cell. The boolean is false when no promoted table identity is available.

type TableRow

type TableRow struct {
	// contains filtered or unexported fields
}

TableRow is immutable typed detail for one promoted GFM table body row.

func (TableRow) ColumnCount

func (r TableRow) ColumnCount() int

ColumnCount returns the semantic/source-proven number of columns in the body row.

func (TableRow) ID

func (r TableRow) ID() NodeID

ID returns the table row's snapshot-scoped node identity.

func (TableRow) NextID

func (r TableRow) NextID() (NodeID, bool)

NextID returns the nearest promoted body row after this row in the same table.

func (TableRow) PreviousID

func (r TableRow) PreviousID() (NodeID, bool)

PreviousID returns the nearest promoted body row before this row in the same table.

func (TableRow) Range

func (r TableRow) Range() Range

Range returns the exact complete physical body-row span used by structural row operations. When present, the row's own line terminator is included; header and delimiter rows are never part of this range.

func (TableRow) TableID

func (r TableRow) TableID() (NodeID, bool)

TableID returns the promoted GFM table that owns this body row. The boolean is false when no promoted table identity is available.

type Task

type Task struct {
	// contains filtered or unexported fields
}

Task is immutable typed detail for one promoted GFM task marker.

func (Task) Checked

func (t Task) Checked() bool

Checked reports the semantic task state.

func (Task) ID

func (t Task) ID() NodeID

ID returns the task's snapshot-scoped node identity.

func (Task) Range

func (t Task) Range() Range

Range returns the exact one-byte task state span changed by PrepareSetTaskChecked. The surrounding brackets and list-item source are outside this range.

type TaskListItem

type TaskListItem struct {
	InlineGFM string
	Checked   bool
}

TaskListItem is structured input for one newly constructed GFM task-list item. InlineGFM is caller-provided inline GFM source; Checked selects the canonical '[x]' or '[ ]' task marker written before that content.

type TaskListItemInput

type TaskListItemInput struct {
	InlineGFM string
	Checked   bool
	Depth     int
}

TaskListItemInput is construction-only structured input for one item in a nested task list. Depth follows the same structural contract as ListItemInput.

type ThematicBreak

type ThematicBreak struct {
	// contains filtered or unexported fields
}

ThematicBreak is immutable typed detail for one promoted top-level thematic break.

func (ThematicBreak) ID

func (t ThematicBreak) ID() NodeID

ID returns the thematic break's snapshot-scoped node identity.

func (ThematicBreak) Range

func (t ThematicBreak) Range() Range

Range returns the exact complete physical line owned by structural thematic-break operations. When present, the line terminator is included.

type UnresolvedReference

type UnresolvedReference struct {
	// contains filtered or unexported fields
}

UnresolvedReference is immutable semantic metadata for one conservative explicit full/collapsed reference whose parser context contains no matching definition.

func (UnresolvedReference) Form

Form returns the explicit full or collapsed reference form.

func (UnresolvedReference) IsImage

func (r UnresolvedReference) IsImage() bool

IsImage reports whether the unresolved reference is an image reference.

func (UnresolvedReference) Reference

func (r UnresolvedReference) Reference() string

Reference returns the unresolved reference label.

type WorkspaceDiagnostic

type WorkspaceDiagnostic struct {
	// contains filtered or unexported fields
}

WorkspaceDiagnostic is one immutable workspace validation finding. Accessors expose only metadata meaningful for the diagnostic kind; absent metadata returns false.

func (WorkspaceDiagnostic) Fragment

func (d WorkspaceDiagnostic) Fragment() (string, bool)

Fragment returns the fragment associated with a fragment/document diagnostic.

func (WorkspaceDiagnostic) Kind

Kind returns the diagnostic category.

func (WorkspaceDiagnostic) NodeID

func (d WorkspaceDiagnostic) NodeID() (NodeID, bool)

NodeID returns the snapshot-local node associated with a generated-index diagnostic.

func (WorkspaceDiagnostic) Relationship

func (d WorkspaceDiagnostic) Relationship() (LinkRelationship, bool)

Relationship returns the link relationship associated with this diagnostic.

func (WorkspaceDiagnostic) SourceDocument

func (d WorkspaceDiagnostic) SourceDocument() (DocumentKey, bool)

SourceDocument returns the caller-defined source document identity associated with this finding.

func (WorkspaceDiagnostic) SourceOffset

func (d WorkspaceDiagnostic) SourceOffset() (int, bool)

SourceOffset returns source-order diagnostic metadata when one exact source anchor exists.

func (WorkspaceDiagnostic) TargetDocument

func (d WorkspaceDiagnostic) TargetDocument() (DocumentKey, bool)

TargetDocument returns the caller-defined target document identity associated with this finding.

func (WorkspaceDiagnostic) UnresolvedReference

func (d WorkspaceDiagnostic) UnresolvedReference() (UnresolvedReference, bool)

UnresolvedReference returns conservative explicit unresolved reference metadata. Shortcut bracket text is never reported because it is ambiguous with ordinary text.

type WorkspaceDiagnosticKind

type WorkspaceDiagnosticKind uint8

WorkspaceDiagnosticKind identifies one deterministic workspace validation finding.

const (
	WorkspaceDiagnosticUnknown WorkspaceDiagnosticKind = iota
	WorkspaceDiagnosticMissingFragment
	WorkspaceDiagnosticAmbiguousFragment
	WorkspaceDiagnosticInvalidFragment
	WorkspaceDiagnosticMissingDocument
	WorkspaceDiagnosticUnresolvedReference
	WorkspaceDiagnosticOrphanDocument
	WorkspaceDiagnosticStaleGeneratedIndex
	WorkspaceDiagnosticUnrecognizedGeneratedIndex
)

type WorkspaceRepair

type WorkspaceRepair struct {
	// contains filtered or unexported fields
}

WorkspaceRepair is one deterministic safe repair prepared through the ordinary snapshot-bound mutation machinery.

func (WorkspaceRepair) Change

func (r WorkspaceRepair) Change() ChangeSet

Change returns the ordinary source-bound prepared change for this repair.

func (WorkspaceRepair) Document

func (r WorkspaceRepair) Document() DocumentKey

Document returns the caller-defined document key to which the repair applies.

type WorkspaceRepairPlan

type WorkspaceRepairPlan struct {
	// contains filtered or unexported fields
}

WorkspaceRepairPlan is an immutable ordered set of provably safe repairs.

func (WorkspaceRepairPlan) Repairs

func (p WorkspaceRepairPlan) Repairs() []WorkspaceRepair

Repairs returns caller-owned repair values in deterministic planning order.

type WorkspaceReport

type WorkspaceReport struct {
	// contains filtered or unexported fields
}

WorkspaceReport combines the resolved DocumentGraph, deterministic diagnostics, and conservative repair plan for one explicit validation run.

func ValidateWorkspace

func ValidateWorkspace(documents []GraphDocument, resolver WorkspaceResolver, options WorkspaceValidationOptions) (*WorkspaceReport, error)

ValidateWorkspace validates relationships and explicitly managed generated indexes over a finite caller-provided document set. Marksplice performs no filesystem or network discovery and never retains resolver or validation authority callbacks.

Example
package main

import (
	"fmt"

	"github.com/zoster81/marksplice"
)

func main() {
	document, err := marksplice.Parse([]byte("# Guide\n\n[missing](#missing)\n"))
	if err != nil {
		panic(err)
	}
	report, err := marksplice.ValidateWorkspace([]marksplice.GraphDocument{
		{Key: "guide", Document: document},
	}, nil, marksplice.WorkspaceValidationOptions{})
	if err != nil {
		panic(err)
	}
	diagnostic := report.Diagnostics()[0]
	fragment, _ := diagnostic.Fragment()
	fmt.Printf("missing fragment=%t %s\n", diagnostic.Kind() == marksplice.WorkspaceDiagnosticMissingFragment, fragment)
	fmt.Printf("repairs=%d\n", len(report.RepairPlan().Repairs()))

}
Output:
missing fragment=true #missing
repairs=0

func (*WorkspaceReport) Diagnostics

func (r *WorkspaceReport) Diagnostics() []WorkspaceDiagnostic

Diagnostics returns caller-owned diagnostics in deterministic validation order.

func (*WorkspaceReport) Graph

func (r *WorkspaceReport) Graph() *DocumentGraph

Graph returns the immutable document graph produced by this validation run.

func (*WorkspaceReport) RepairPlan

func (r *WorkspaceReport) RepairPlan() WorkspaceRepairPlan

RepairPlan returns the immutable conservative repair plan.

type WorkspaceResolution

type WorkspaceResolution struct {
	Kind     WorkspaceResolutionKind
	Target   DocumentKey
	Fragment string
}

WorkspaceResolution is one caller-authorized classification of a non-local relationship. Target identities are opaque caller data; Marksplice performs no I/O.

type WorkspaceResolutionKind

type WorkspaceResolutionKind uint8

WorkspaceResolutionKind describes how the caller classifies one non-local relationship while validating an explicit workspace document set.

const (
	WorkspaceResolutionUnknown WorkspaceResolutionKind = iota
	// WorkspaceResolutionIgnore leaves the relationship outside workspace validation.
	// This is appropriate for intentionally external or otherwise out-of-scope targets.
	WorkspaceResolutionIgnore
	// WorkspaceResolutionResolved maps the relationship to a document already present
	// in the explicit caller-provided set, optionally with a target fragment.
	WorkspaceResolutionResolved
	// WorkspaceResolutionMissing states that the caller expected a workspace document
	// target but that target is absent from the explicit document set.
	WorkspaceResolutionMissing
)

type WorkspaceResolver

type WorkspaceResolver func(source DocumentKey, relationship LinkRelationship) WorkspaceResolution

WorkspaceResolver classifies one non-local link relationship for workspace validation. It is invoked synchronously, never concurrently during one ValidateWorkspace call, and is never retained.

type WorkspaceValidationOptions

type WorkspaceValidationOptions struct {
	Roots       []DocumentKey
	ManagedTOCs []ManagedTOC
}

WorkspaceValidationOptions supplies explicit validation authority beyond the document set itself. Empty Roots disables orphan/reachability diagnostics.

Directories

Path Synopsis
examples
build command
edit command
extensions command
inspect command
query command
workspace command
internal
parser/native
Package native implements Marksplice's native CommonMark/GFM parser.
Package native implements Marksplice's native CommonMark/GFM parser.
publictest
Package publictest hosts black-box tests of the public Marksplice API.
Package publictest hosts black-box tests of the public Marksplice API.
testutil/commonmarkspec
Package commonmarkspec loads the approved published CommonMark specification snapshot for tests.
Package commonmarkspec loads the approved published CommonMark specification snapshot for tests.
testutil/gfmspec
Package gfmspec loads the approved published GFM specification snapshot for tests.
Package gfmspec loads the approved published GFM specification snapshot for tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL