Documentation
¶
Overview ¶
Package markdown provides a markdown parser and AST for spectr specifications.
compat.go provides line-by-line matchers for compatibility with the old regex package API. These functions work on single lines and are efficient for line-by-line processing during migration from regex-based parsing.
These helpers use simple string operations instead of regex for better performance and maintainability.
Package markdown provides a token-based lexer and parser for CommonMark subset plus Spectr-specific extensions. It provides a robust, maintainable, and feature-rich approach for parsing Spectr specification files.
Architecture Overview ¶
The package uses a two-phase parsing architecture:
- Lexer: Tokenizes input into fine-grained tokens (delimiters, text, whitespace)
- Parser: Consumes tokens to build an immutable AST
This separation provides clear concerns, testable components, and flexibility for error recovery.
Source []byte --> Lexer --> []Token --> Parser --> AST (Node tree)
| |
v v
TokenError ParseError
Supported CommonMark Subset ¶
The parser supports a useful subset of CommonMark:
- Headers: ATX-style headers (H1-H6) using # prefix
- Lists: Unordered (-, *, +), ordered (1.), task checkboxes (- [ ], - [x])
- Code: Fenced code blocks (``` and ~~~), inline code (`)
- Emphasis: Bold (**, __), italic (*, _), strikethrough (~~)
- Links: Inline [text](url), reference [text][ref] with [ref]: url definitions
- Block elements: Paragraphs, blockquotes (>)
Spectr-Specific Extensions ¶
Beyond CommonMark, the parser recognizes Spectr patterns:
- Wikilinks: [[spec-name]], [[spec-name|display text]], [[target#anchor]]
- Requirement headers: ### Requirement: Name
- Scenario headers: #### Scenario: Description
- WHEN/THEN/AND bullets: - **WHEN** condition, - **THEN** result
- Delta sections: ## ADDED Requirements, ## MODIFIED Requirements, etc.
Key Types ¶
Token represents a lexical unit with position information:
type Token struct {
Type TokenType // Token classification
Start int // Byte offset from source start
End int // Byte offset past last byte (exclusive)
Source []byte // Zero-copy slice into original source
Message string // Error message (only for TokenError)
}
Node is the interface for all AST nodes:
type Node interface {
NodeType() NodeType // Type classification
Span() (start, end int) // Byte offset range
Hash() uint64 // Content hash for identity/caching
Source() []byte // Original source text
Children() []Node // Child nodes (immutable)
}
Typed node structs implement the Node interface with type-specific getters:
- NodeDocument: Root document container
- NodeSection: Header sections with Level() and Title() getters
- NodeRequirement: Spectr requirement with Name() getter
- NodeScenario: Spectr scenario with Name() getter
- NodeParagraph: Paragraph container
- NodeList: List container with Ordered() getter
- NodeListItem: List item with Checked() and Keyword() getters
- NodeCodeBlock: Fenced code with Language() and Content() getters
- NodeBlockquote: Blockquote container
- NodeText: Plain text content
- NodeStrong: Bold emphasis
- NodeEmphasis: Italic emphasis
- NodeStrikethrough: Strikethrough text
- NodeCode: Inline code
- NodeLink: Link with URL() and Title() getters
- NodeWikilink: Wikilink with Target(), Display(), and Anchor() getters
ParseError represents a parse error with location:
type ParseError struct {
Offset int // Byte offset where error occurred
Message string // Human-readable error description
Expected []TokenType // What tokens would have been valid
}
Key Functions ¶
Parse is the main entry point for parsing markdown:
func Parse(source []byte) (Node, []ParseError)
Parse is stateless and safe for concurrent calls. It returns the root document node and any errors encountered. Even with errors, a partial AST is returned.
ParseIncremental enables efficient reparsing after edits:
func ParseIncremental(oldTree Node, oldSource, newSource []byte) (Node, []ParseError)
ParseIncremental computes the diff between old and new source, identifies affected regions, reparses only changed sections, and reuses unchanged subtrees via content hash matching. This provides tree-sitter style incremental parsing.
Usage Examples ¶
Basic parsing:
source := []byte("# Hello\n\nThis is a **test**.")
root, errs := markdown.Parse(source)
if len(errs) > 0 {
for _, err := range errs {
fmt.Printf("Error at offset %d: %s\n", err.Offset, err.Message)
}
}
// Process AST...
Using the visitor pattern:
type RequirementCollector struct {
markdown.BaseVisitor
Requirements []string
}
func (c *RequirementCollector) VisitRequirement(n *markdown.NodeRequirement) error {
c.Requirements = append(c.Requirements, n.Name())
return nil
}
collector := &RequirementCollector{}
markdown.Walk(root, collector)
Using queries:
// Find all requirements
reqs := markdown.Find(root, markdown.IsType[*markdown.NodeRequirement]())
// Find requirement by name
req := markdown.FindFirst(root, markdown.And(
markdown.IsType[*markdown.NodeRequirement](),
markdown.HasName("My Requirement"),
))
Using transforms:
// Rename a requirement
newRoot, err := markdown.Transform(root, markdown.RenameRequirement("OldName", "NewName"))
Incremental parsing:
// Initial parse root1, _ := markdown.Parse(source1) // After edit, reparse incrementally root2, _ := markdown.ParseIncremental(root1, source1, source2)
Error Handling ¶
The parser uses a collected error approach rather than fail-fast:
- All errors are collected during parsing
- Parsing continues via error recovery (skip to next sync point)
- A partial AST is always returned, even with errors
- Maximum 100 errors before aborting (configurable)
Errors store byte offsets. Use LineIndex for line/column conversion:
idx := markdown.NewLineIndex(source)
for _, err := range errs {
pos := idx.PositionAt(err.Offset)
fmt.Printf("Line %d, Column %d: %s\n", pos.Line, pos.Column, err.Message)
}
Position Information ¶
All tokens and nodes track byte offsets into the original source. This is compact and efficient. For line/column display, use LineIndex:
idx := markdown.NewLineIndex(source) line, col := idx.LineCol(offset) // 1-based line numbers
For frequent position queries on an AST, use PositionIndex which builds an interval tree for O(log n) lookups:
pidx := markdown.NewPositionIndex(root) node := pidx.NodeAt(offset) // Innermost node at offset nodes := pidx.NodesAt(offset) // All nodes containing offset nodes := pidx.NodesInRange(10, 50) // All nodes overlapping range
Thread Safety ¶
Parse and ParseIncremental are safe for concurrent calls (no shared state). AST nodes are immutable after creation. Object pools use sync.Pool internally. LineIndex and PositionIndex are safe for concurrent reads after construction.
Performance ¶
The package is optimized for performance:
- Zero-copy source views ([]byte slices into original input)
- Object pooling for tokens and nodes via sync.Pool
- Content hashing for efficient subtree comparison
- Lazy line index construction
- Interval tree for O(log n) position queries
- Incremental parsing reuses unchanged subtrees
Non-Goals ¶
This package intentionally does not support:
- Full CommonMark compliance (focused subset for Spectr)
- Tables
- HTML passthrough
- Setext-style headers (underlined with === or ---)
- GFM extensions beyond task checkboxes and strikethrough
Index ¶
- Constants
- Variables
- func AffectedBlockRegion(source []byte, edit EditRegion) (start, end int)
- func ContainsKeyword(line string) (keyword string, ok bool)
- func Count(root Node, pred Predicate) int
- func CountDeltaChanges(delta *Delta) int
- func CountLeadingSpaces(line string) int
- func CountRequirements(content []byte) int
- func CountScenarios(content []byte) int
- func CountWikilinks(content []byte) int
- func DisablePoolStats()
- func EnablePoolStats()
- func Exists(root Node, pred Predicate) bool
- func ExtractDeltaContent(content []byte, deltaType DeltaType) []byte
- func ExtractHeaderLevel(line string) int
- func ExtractHeaderText(line string) string
- func ExtractListMarker(line string) (marker string, ok bool)
- func ExtractSections(content []byte) map[string]*Section
- func FindAddedRequirements(content []byte) []string
- func FindAllDeltaSections(content []byte) map[DeltaType]*Section
- func FindAllH3Requirements(content string) []string
- func FindByType[T Node](root Node) []T
- func FindDeltaSection(content []byte, deltaType DeltaType) string
- func FindDeltaSectionContent(content []byte, deltaType DeltaType) string
- func FindFirstByType[T Node](root Node) T
- func FindH2RequirementsSection(content string) []int
- func FindModifiedRequirements(content []byte) []string
- func FindNextH2Section(content string, startPos int) []int
- func FindRemovedRequirements(content []byte) []string
- func FindRenamedPairs(content []byte) map[string]string
- func GetDeltaRequirementNames(delta *Delta) []string
- func GetDeltaSummary(delta *Delta) string
- func GetRequirementNames(content []byte) []string
- func GetSectionContent(content []byte, sectionName string) string
- func GetSectionNames(content []byte) []string
- func GetWikilinkTargetType(target, projectRoot string) string
- func HasDeltaSection(content []byte, deltaType DeltaType) bool
- func HasRequirement(content []byte, name string) bool
- func HasSection(content []byte, name string) bool
- func IsBlankLine(line string) bool
- func IsBlockquote(line string) bool
- func IsCodeFence(line string) (isFence bool, delimiter rune)
- func IsH2Header(line string) bool
- func IsH3Header(line string) bool
- func IsH4Header(line string) bool
- func IsHorizontalRule(line string) bool
- func IsListItem(line string) bool
- func IsTaskChecked(state rune) bool
- func ListWikilinkTargets(content []byte) []string
- func MatchAnyRenamedFrom(line string) (name string, ok bool)
- func MatchAnyRenamedTo(line string) (name string, ok bool)
- func MatchAnySection(line string) (name, number string, ok bool)
- func MatchH2DeltaSection(line string) (deltaType string, ok bool)
- func MatchH2SectionHeader(line string) (name string, ok bool)
- func MatchNumberedSection(line string) (name string, ok bool)
- func MatchRenamedFrom(line string) (name string, ok bool)
- func MatchRenamedFromAlt(line string) (name string, ok bool)
- func MatchRenamedTo(line string) (name string, ok bool)
- func MatchRenamedToAlt(line string) (name string, ok bool)
- func MatchRequirementHeader(line string) (name string, ok bool)
- func MatchScenarioHeader(line string) (name string, ok bool)
- func MatchTaskCheckbox(line string) (status rune, ok bool)
- func MergeDelta(merged, delta *Delta)
- func NormalizeMultipleNewlines(s string) string
- func Parse(source []byte) (Node, []ParseError)
- func ParseDelta(content []byte) (*Delta, []ParseError)
- func ParseIncremental(oldTree Node, oldSource, newSource []byte) (Node, []ParseError)
- func ParseIncrementalWithState(state *IncrementalParseState, oldTree Node, oldSource, newSource []byte) (Node, []ParseError, *IncrementalParseState)
- func ParseSpec(content []byte) (*Spec, []ParseError)
- func Print(node Node) []byte
- func PrintTo(w io.Writer, node Node) error
- func PutChildren(c []Node)
- func PutNode(n Node)
- func PutToken(t *Token)
- func ResetPoolStats()
- func ResolveWikilink(target, projectRoot string) (path string, exists bool)
- func ResolveWikilinkWithAnchor(target, anchor, projectRoot string) (path string, anchorValid bool, err error)
- func TrimLeadingHashes(line string) string
- func ValidateRenamed(delta *Delta) []string
- func ValidateWikilinkTarget(target, projectRoot string) error
- func Walk(node Node, v Visitor) error
- func WalkEnterLeave(node Node, v EnterLeaveVisitor) error
- func WalkWithContext(node Node, v ContextVisitor) error
- type AdjustedNode
- type BaseContextVisitor
- func (BaseContextVisitor) VisitBlockquoteWithContext(*NodeBlockquote, *VisitorContext) error
- func (BaseContextVisitor) VisitCodeBlockWithContext(*NodeCodeBlock, *VisitorContext) error
- func (BaseContextVisitor) VisitCodeWithContext(*NodeCode, *VisitorContext) error
- func (BaseContextVisitor) VisitDocumentWithContext(*NodeDocument, *VisitorContext) error
- func (BaseContextVisitor) VisitEmphasisWithContext(*NodeEmphasis, *VisitorContext) error
- func (BaseContextVisitor) VisitLinkDefWithContext(*NodeLinkDef, *VisitorContext) error
- func (BaseContextVisitor) VisitLinkWithContext(*NodeLink, *VisitorContext) error
- func (BaseContextVisitor) VisitListItemWithContext(*NodeListItem, *VisitorContext) error
- func (BaseContextVisitor) VisitListWithContext(*NodeList, *VisitorContext) error
- func (BaseContextVisitor) VisitParagraphWithContext(*NodeParagraph, *VisitorContext) error
- func (BaseContextVisitor) VisitRequirementWithContext(*NodeRequirement, *VisitorContext) error
- func (BaseContextVisitor) VisitScenarioWithContext(*NodeScenario, *VisitorContext) error
- func (BaseContextVisitor) VisitSectionWithContext(*NodeSection, *VisitorContext) error
- func (BaseContextVisitor) VisitStrikethroughWithContext(*NodeStrikethrough, *VisitorContext) error
- func (BaseContextVisitor) VisitStrongWithContext(*NodeStrong, *VisitorContext) error
- func (BaseContextVisitor) VisitTextWithContext(*NodeText, *VisitorContext) error
- func (BaseContextVisitor) VisitWikilinkWithContext(*NodeWikilink, *VisitorContext) error
- type BaseEnterLeaveVisitor
- func (BaseEnterLeaveVisitor) EnterBlockquote(*NodeBlockquote) error
- func (BaseEnterLeaveVisitor) EnterCode(*NodeCode) error
- func (BaseEnterLeaveVisitor) EnterCodeBlock(*NodeCodeBlock) error
- func (BaseEnterLeaveVisitor) EnterDocument(*NodeDocument) error
- func (BaseEnterLeaveVisitor) EnterEmphasis(*NodeEmphasis) error
- func (BaseEnterLeaveVisitor) EnterLink(*NodeLink) error
- func (BaseEnterLeaveVisitor) EnterLinkDef(*NodeLinkDef) error
- func (BaseEnterLeaveVisitor) EnterList(*NodeList) error
- func (BaseEnterLeaveVisitor) EnterListItem(*NodeListItem) error
- func (BaseEnterLeaveVisitor) EnterParagraph(*NodeParagraph) error
- func (BaseEnterLeaveVisitor) EnterRequirement(*NodeRequirement) error
- func (BaseEnterLeaveVisitor) EnterScenario(*NodeScenario) error
- func (BaseEnterLeaveVisitor) EnterSection(*NodeSection) error
- func (BaseEnterLeaveVisitor) EnterStrikethrough(*NodeStrikethrough) error
- func (BaseEnterLeaveVisitor) EnterStrong(*NodeStrong) error
- func (BaseEnterLeaveVisitor) EnterText(*NodeText) error
- func (BaseEnterLeaveVisitor) EnterWikilink(*NodeWikilink) error
- func (BaseEnterLeaveVisitor) LeaveBlockquote(*NodeBlockquote) error
- func (BaseEnterLeaveVisitor) LeaveCode(*NodeCode) error
- func (BaseEnterLeaveVisitor) LeaveCodeBlock(*NodeCodeBlock) error
- func (BaseEnterLeaveVisitor) LeaveDocument(*NodeDocument) error
- func (BaseEnterLeaveVisitor) LeaveEmphasis(*NodeEmphasis) error
- func (BaseEnterLeaveVisitor) LeaveLink(*NodeLink) error
- func (BaseEnterLeaveVisitor) LeaveLinkDef(*NodeLinkDef) error
- func (BaseEnterLeaveVisitor) LeaveList(*NodeList) error
- func (BaseEnterLeaveVisitor) LeaveListItem(*NodeListItem) error
- func (BaseEnterLeaveVisitor) LeaveParagraph(*NodeParagraph) error
- func (BaseEnterLeaveVisitor) LeaveRequirement(*NodeRequirement) error
- func (BaseEnterLeaveVisitor) LeaveScenario(*NodeScenario) error
- func (BaseEnterLeaveVisitor) LeaveSection(*NodeSection) error
- func (BaseEnterLeaveVisitor) LeaveStrikethrough(*NodeStrikethrough) error
- func (BaseEnterLeaveVisitor) LeaveStrong(*NodeStrong) error
- func (BaseEnterLeaveVisitor) LeaveText(*NodeText) error
- func (BaseEnterLeaveVisitor) LeaveWikilink(*NodeWikilink) error
- type BaseTransformVisitor
- func (BaseTransformVisitor) TransformBlockquote(n *NodeBlockquote) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformCode(n *NodeCode) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformCodeBlock(n *NodeCodeBlock) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformDocument(n *NodeDocument) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformEmphasis(n *NodeEmphasis) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformLink(n *NodeLink) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformLinkDef(n *NodeLinkDef) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformList(n *NodeList) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformListItem(n *NodeListItem) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformParagraph(n *NodeParagraph) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformRequirement(n *NodeRequirement) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformScenario(n *NodeScenario) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformSection(n *NodeSection) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformStrikethrough(n *NodeStrikethrough) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformStrong(n *NodeStrong) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformText(n *NodeText) (Node, TransformAction, error)
- func (BaseTransformVisitor) TransformWikilink(n *NodeWikilink) (Node, TransformAction, error)
- type BaseVisitor
- func (BaseVisitor) VisitBlockquote(*NodeBlockquote) error
- func (BaseVisitor) VisitCode(*NodeCode) error
- func (BaseVisitor) VisitCodeBlock(*NodeCodeBlock) error
- func (BaseVisitor) VisitDocument(*NodeDocument) error
- func (BaseVisitor) VisitEmphasis(*NodeEmphasis) error
- func (BaseVisitor) VisitLink(*NodeLink) error
- func (BaseVisitor) VisitLinkDef(*NodeLinkDef) error
- func (BaseVisitor) VisitList(*NodeList) error
- func (BaseVisitor) VisitListItem(*NodeListItem) error
- func (BaseVisitor) VisitParagraph(*NodeParagraph) error
- func (BaseVisitor) VisitRequirement(*NodeRequirement) error
- func (BaseVisitor) VisitScenario(*NodeScenario) error
- func (BaseVisitor) VisitSection(*NodeSection) error
- func (BaseVisitor) VisitStrikethrough(*NodeStrikethrough) error
- func (BaseVisitor) VisitStrong(*NodeStrong) error
- func (BaseVisitor) VisitText(*NodeText) error
- func (BaseVisitor) VisitWikilink(*NodeWikilink) error
- type BuilderValidationError
- type ContextVisitor
- type Delta
- type DeltaType
- type EditRegion
- type EnterLeaveVisitor
- type FlexibleTaskMatch
- type IncrementalParseState
- type LexError
- type LexerState
- type LineIndex
- type Named
- type Node
- type NodeBlockquote
- func (n *NodeBlockquote) Children() []Node
- func (n *NodeBlockquote) Equal(other Node) bool
- func (n *NodeBlockquote) Hash() uint64
- func (n *NodeBlockquote) NodeType() NodeType
- func (n *NodeBlockquote) Source() []byte
- func (n *NodeBlockquote) Span() (start, end int)
- func (n *NodeBlockquote) ToBuilder() *NodeBuilder
- type NodeBuilder
- func (b *NodeBuilder) Build() Node
- func (b *NodeBuilder) Validate() error
- func (b *NodeBuilder) WithAnchor(anchor []byte) *NodeBuilder
- func (b *NodeBuilder) WithChecked(checked *bool) *NodeBuilder
- func (b *NodeBuilder) WithChildren(children []Node) *NodeBuilder
- func (b *NodeBuilder) WithContent(content []byte) *NodeBuilder
- func (b *NodeBuilder) WithDeltaType(deltaType string) *NodeBuilder
- func (b *NodeBuilder) WithDisplay(display []byte) *NodeBuilder
- func (b *NodeBuilder) WithEnd(end int) *NodeBuilder
- func (b *NodeBuilder) WithKeyword(keyword string) *NodeBuilder
- func (b *NodeBuilder) WithLanguage(language []byte) *NodeBuilder
- func (b *NodeBuilder) WithLevel(level int) *NodeBuilder
- func (b *NodeBuilder) WithLinkTitle(title []byte) *NodeBuilder
- func (b *NodeBuilder) WithName(name string) *NodeBuilder
- func (b *NodeBuilder) WithOrdered(ordered bool) *NodeBuilder
- func (b *NodeBuilder) WithSource(source []byte) *NodeBuilder
- func (b *NodeBuilder) WithStart(start int) *NodeBuilder
- func (b *NodeBuilder) WithTarget(target []byte) *NodeBuilder
- func (b *NodeBuilder) WithTitle(title []byte) *NodeBuilder
- func (b *NodeBuilder) WithURL(url []byte) *NodeBuilder
- type NodeCode
- func (n *NodeCode) Children() []Node
- func (n *NodeCode) Code() string
- func (n *NodeCode) Equal(other Node) bool
- func (n *NodeCode) Hash() uint64
- func (n *NodeCode) NodeType() NodeType
- func (n *NodeCode) Source() []byte
- func (n *NodeCode) Span() (start, end int)
- func (n *NodeCode) ToBuilder() *NodeBuilder
- type NodeCodeBlock
- func (n *NodeCodeBlock) Children() []Node
- func (n *NodeCodeBlock) Content() []byte
- func (n *NodeCodeBlock) Equal(other Node) bool
- func (n *NodeCodeBlock) Hash() uint64
- func (n *NodeCodeBlock) Language() []byte
- func (n *NodeCodeBlock) NodeType() NodeType
- func (n *NodeCodeBlock) Source() []byte
- func (n *NodeCodeBlock) Span() (start, end int)
- func (n *NodeCodeBlock) ToBuilder() *NodeBuilder
- type NodeDocument
- func (n *NodeDocument) Children() []Node
- func (n *NodeDocument) Equal(other Node) bool
- func (n *NodeDocument) Hash() uint64
- func (n *NodeDocument) NodeType() NodeType
- func (n *NodeDocument) Source() []byte
- func (n *NodeDocument) Span() (start, end int)
- func (n *NodeDocument) ToBuilder() *NodeBuilder
- type NodeEmphasis
- func (n *NodeEmphasis) Children() []Node
- func (n *NodeEmphasis) Equal(other Node) bool
- func (n *NodeEmphasis) Hash() uint64
- func (n *NodeEmphasis) NodeType() NodeType
- func (n *NodeEmphasis) Source() []byte
- func (n *NodeEmphasis) Span() (start, end int)
- func (n *NodeEmphasis) ToBuilder() *NodeBuilder
- type NodeLink
- func (n *NodeLink) Children() []Node
- func (n *NodeLink) Equal(other Node) bool
- func (n *NodeLink) Hash() uint64
- func (n *NodeLink) NodeType() NodeType
- func (n *NodeLink) Source() []byte
- func (n *NodeLink) Span() (start, end int)
- func (n *NodeLink) Title() []byte
- func (n *NodeLink) ToBuilder() *NodeBuilder
- func (n *NodeLink) URL() []byte
- type NodeLinkDef
- func (n *NodeLinkDef) Children() []Node
- func (n *NodeLinkDef) Equal(other Node) bool
- func (n *NodeLinkDef) Hash() uint64
- func (n *NodeLinkDef) NodeType() NodeType
- func (n *NodeLinkDef) Source() []byte
- func (n *NodeLinkDef) Span() (start, end int)
- func (n *NodeLinkDef) Title() []byte
- func (n *NodeLinkDef) ToBuilder() *NodeBuilder
- func (n *NodeLinkDef) URL() []byte
- type NodeList
- func (n *NodeList) Children() []Node
- func (n *NodeList) Equal(other Node) bool
- func (n *NodeList) Hash() uint64
- func (n *NodeList) NodeType() NodeType
- func (n *NodeList) Ordered() bool
- func (n *NodeList) Source() []byte
- func (n *NodeList) Span() (start, end int)
- func (n *NodeList) ToBuilder() *NodeBuilder
- type NodeListItem
- func (n *NodeListItem) Checked() (isChecked, hasCheckbox bool)
- func (n *NodeListItem) Children() []Node
- func (n *NodeListItem) Equal(other Node) bool
- func (n *NodeListItem) Hash() uint64
- func (n *NodeListItem) Keyword() string
- func (n *NodeListItem) NodeType() NodeType
- func (n *NodeListItem) Source() []byte
- func (n *NodeListItem) Span() (start, end int)
- func (n *NodeListItem) ToBuilder() *NodeBuilder
- type NodeParagraph
- func (n *NodeParagraph) Children() []Node
- func (n *NodeParagraph) Equal(other Node) bool
- func (n *NodeParagraph) Hash() uint64
- func (n *NodeParagraph) NodeType() NodeType
- func (n *NodeParagraph) Source() []byte
- func (n *NodeParagraph) Span() (start, end int)
- func (n *NodeParagraph) ToBuilder() *NodeBuilder
- type NodeRequirement
- func (n *NodeRequirement) Children() []Node
- func (n *NodeRequirement) Equal(other Node) bool
- func (n *NodeRequirement) Hash() uint64
- func (n *NodeRequirement) Name() string
- func (n *NodeRequirement) NodeType() NodeType
- func (n *NodeRequirement) Source() []byte
- func (n *NodeRequirement) Span() (start, end int)
- func (n *NodeRequirement) ToBuilder() *NodeBuilder
- type NodeScenario
- func (n *NodeScenario) Children() []Node
- func (n *NodeScenario) Equal(other Node) bool
- func (n *NodeScenario) Hash() uint64
- func (n *NodeScenario) Name() string
- func (n *NodeScenario) NodeType() NodeType
- func (n *NodeScenario) Source() []byte
- func (n *NodeScenario) Span() (start, end int)
- func (n *NodeScenario) ToBuilder() *NodeBuilder
- type NodeSection
- func (n *NodeSection) Children() []Node
- func (n *NodeSection) DeltaType() string
- func (n *NodeSection) Equal(other Node) bool
- func (n *NodeSection) Hash() uint64
- func (n *NodeSection) Level() int
- func (n *NodeSection) NodeType() NodeType
- func (n *NodeSection) Source() []byte
- func (n *NodeSection) Span() (start, end int)
- func (n *NodeSection) Title() []byte
- func (n *NodeSection) ToBuilder() *NodeBuilder
- type NodeStrikethrough
- func (n *NodeStrikethrough) Children() []Node
- func (n *NodeStrikethrough) Equal(other Node) bool
- func (n *NodeStrikethrough) Hash() uint64
- func (n *NodeStrikethrough) NodeType() NodeType
- func (n *NodeStrikethrough) Source() []byte
- func (n *NodeStrikethrough) Span() (start, end int)
- func (n *NodeStrikethrough) ToBuilder() *NodeBuilder
- type NodeStrong
- type NodeText
- func (n *NodeText) Children() []Node
- func (n *NodeText) Equal(other Node) bool
- func (n *NodeText) Hash() uint64
- func (n *NodeText) NodeType() NodeType
- func (n *NodeText) Source() []byte
- func (n *NodeText) Span() (start, end int)
- func (n *NodeText) Text() string
- func (n *NodeText) ToBuilder() *NodeBuilder
- type NodeType
- type NodeTypeStats
- type NodeWikilink
- func (n *NodeWikilink) Anchor() []byte
- func (n *NodeWikilink) Children() []Node
- func (n *NodeWikilink) Display() []byte
- func (n *NodeWikilink) Equal(other Node) bool
- func (n *NodeWikilink) Hash() uint64
- func (n *NodeWikilink) NodeType() NodeType
- func (n *NodeWikilink) Source() []byte
- func (n *NodeWikilink) Span() (start, end int)
- func (n *NodeWikilink) Target() []byte
- func (n *NodeWikilink) ToBuilder() *NodeBuilder
- type NumberedTaskMatch
- type ParseError
- type PoolStats
- type Position
- type PositionIndex
- func (pi *PositionIndex) EnclosingRequirement(offset int) *NodeRequirement
- func (pi *PositionIndex) EnclosingScenario(offset int) *NodeScenario
- func (pi *PositionIndex) EnclosingSection(offset int) *NodeSection
- func (pi *PositionIndex) IsStale(root Node) bool
- func (pi *PositionIndex) LineIndex() *LineIndex
- func (pi *PositionIndex) NodeAt(offset int) Node
- func (pi *PositionIndex) NodeCount() int
- func (pi *PositionIndex) NodePosition(node Node) Position
- func (pi *PositionIndex) NodesAt(offset int) []Node
- func (pi *PositionIndex) NodesInRange(start, end int) []Node
- func (pi *PositionIndex) PositionAt(offset int) Position
- func (pi *PositionIndex) Rebuild(root Node, source []byte)
- func (pi *PositionIndex) Root() Node
- type Predicate
- func All(preds ...Predicate) Predicate
- func And(p1, p2 Predicate) Predicate
- func Any(preds ...Predicate) Predicate
- func HasChild(pred Predicate) Predicate
- func HasDescendant(pred Predicate) Predicate
- func HasName(name string) Predicate
- func InRange(start, end int) Predicate
- func IsType[T Node]() Predicate
- func Not(p Predicate) Predicate
- func Or(p1, p2 Predicate) Predicate
- type RenamedRequirement
- type Requirement
- type Scenario
- type Section
- type Spec
- type Token
- type TokenType
- type TransformAction
- type TransformVisitor
- func AddScenario(reqName string, scenario *NodeScenario) TransformVisitor
- func Compose(t1, t2 TransformVisitor) TransformVisitor
- func Filter(pred func(Node) bool) TransformVisitor
- func Map(f func(Node) Node) TransformVisitor
- func Pipeline(transforms ...TransformVisitor) TransformVisitor
- func RemoveRequirement(name string) TransformVisitor
- func RenameRequirement(oldName, newName string) TransformVisitor
- func When(pred func(Node) bool, transform TransformVisitor) TransformVisitor
- type Visitor
- type VisitorContext
- type Wikilink
- type WikilinkError
Constants ¶
const DefaultMaxErrors = 100
DefaultMaxErrors is the maximum number of parse errors before aborting.
Variables ¶
var SkipChildren = errors.New("skip children")
ErrSkipChildren is a sentinel error that can be returned from a visitor method to skip traversal of the current node's children. The traversal will continue with the next sibling. This is NOT treated as an actual error.
Functions ¶
func AffectedBlockRegion ¶
func AffectedBlockRegion( source []byte, edit EditRegion, ) (start, end int)
AffectedBlockRegion identifies the block-level region affected by an edit. This is useful for determining what portion of the document needs reparsing. It expands the edit region to block boundaries (blank lines, headers, etc.)
func ContainsKeyword ¶
ContainsKeyword checks if a line contains one of the Spectr keywords (WHEN, THEN, AND, GIVEN) typically used in scenario descriptions. Returns the keyword found and true, or empty and false.
func Count ¶
Count returns the number of nodes matching pred without allocating a slice. Traverses the entire tree and increments a counter for each match.
func CountDeltaChanges ¶
CountDeltaChanges returns the total number of changes in a delta.
func CountLeadingSpaces ¶
CountLeadingSpaces returns the number of leading space characters in a line. Tabs are counted as 1 character (not expanded).
func CountRequirements ¶
CountRequirements returns the total number of requirements in the content.
func CountScenarios ¶
CountScenarios returns the total number of scenarios in the content.
func CountWikilinks ¶
CountWikilinks returns the total number of wikilinks in the content.
func EnablePoolStats ¶
func EnablePoolStats()
EnablePoolStats enables pool statistics tracking. This adds some overhead to pool operations.
func Exists ¶
Exists returns true if any node matches pred. Uses short-circuit evaluation: stops on first match.
func ExtractDeltaContent ¶
ExtractDeltaContent extracts content from a specific delta section type. This is useful when you need the raw markdown content of a delta section.
func ExtractHeaderLevel ¶
ExtractHeaderLevel returns the header level (1-6) for a line that starts with hash characters followed by a space. Returns 0 if not a valid header.
Example:
ExtractHeaderLevel("# Title") // returns 1
ExtractHeaderLevel("### Section") // returns 3
ExtractHeaderLevel("Not a header") // returns 0
func ExtractHeaderText ¶
ExtractHeaderText returns the header text without the "#" prefix and leading/trailing whitespace. Returns empty string if not a valid header.
Example:
ExtractHeaderText("## My Section") // returns "My Section"
ExtractHeaderText("# Title ") // returns "Title"
func ExtractListMarker ¶
ExtractListMarker extracts the list marker from a line if present. Returns the marker string and true if found, or empty and false otherwise. For unordered lists, returns "-", "*", or "+". For ordered lists, returns the number with dot (e.g., "1.", "23.").
func ExtractSections ¶
ExtractSections parses content and returns a map of section name to Section. The keys are the exact section titles (case-preserved).
func FindAddedRequirements ¶
FindAddedRequirements returns the names of all added requirements.
func FindAllDeltaSections ¶
FindAllDeltaSections returns all delta sections in the content. Returns a map from delta type to the section content.
func FindAllH3Requirements ¶
FindAllH3Requirements finds all requirement headers in content and returns their names. This function scans for "### Requirement: Name" patterns and extracts the names.
Example:
content := "### Requirement: Auth\n\nContent\n\n### Requirement: Logging\n" names := FindAllH3Requirements(content) // names = ["Auth", "Logging"]
func FindByType ¶
FindByType returns all nodes of type T in the AST. Results are properly typed and in traversal order. The type parameter T must implement the Node interface.
func FindDeltaSection ¶
FindDeltaSection returns the content of a specific delta section type. It searches for sections matching the given delta type (ADDED, MODIFIED, REMOVED, RENAMED). Returns empty string if no matching section is found.
func FindDeltaSectionContent ¶
FindDeltaSectionContent extracts the content from a delta section (ADDED, MODIFIED, REMOVED, RENAMED) without the header line. This is a compatibility function that matches the behavior of the old regex.FindDeltaSectionContent function.
Returns the content between the section header and the next H2 header, or empty string if the section is not found.
Example:
content := `# Delta ## ADDED Requirements ### Requirement: New Feature Content here. ## MODIFIED Requirements ...` FindDeltaSectionContent([]byte(content), DeltaAdded) // returns "\n### Requirement: New Feature\nContent here.\n"
func FindFirstByType ¶
FindFirstByType returns the first node of type T, or nil if none exists. The type parameter T must implement the Node interface.
func FindH2RequirementsSection ¶
FindH2RequirementsSection finds the "## Requirements" section header in content. Returns the start and end indices of the header match, or nil if not found. The end index points to the end of the header line (after "## Requirements").
Example:
indices := FindH2RequirementsSection("# Title\n\n## Requirements\n\nContent")
// indices = [9, 24] (pointing to "## Requirements")
func FindModifiedRequirements ¶
FindModifiedRequirements returns the names of all modified requirements.
func FindNextH2Section ¶
FindNextH2Section finds the next "## " header in content starting from startPos. Returns the start and end indices of the header match relative to the beginning of the content, or nil if no H2 header is found after startPos.
Example:
content := "## First\n\nSome text\n\n## Second\n" indices := FindNextH2Section(content, 9) // Search after "## First\n" // indices = [22, 31] (pointing to "## Second")
func FindRemovedRequirements ¶
FindRemovedRequirements returns the names of all removed requirements.
func FindRenamedPairs ¶
FindRenamedPairs extracts all FROM/TO pairs from the content. This is a convenience function for getting just the rename mappings.
func GetDeltaRequirementNames ¶
GetDeltaRequirementNames returns all requirement names affected by the delta. This includes added, modified, removed, and renamed requirements.
func GetDeltaSummary ¶
GetDeltaSummary returns a human-readable summary of delta changes.
func GetRequirementNames ¶
GetRequirementNames returns the names of all requirements in the content.
func GetSectionContent ¶
GetSectionContent returns the text content of a section by name. Returns empty string if section not found.
func GetSectionNames ¶
GetSectionNames returns the names of all sections in the content.
func GetWikilinkTargetType ¶
GetWikilinkTargetType returns the type of target a wikilink refers to. Returns "spec", "change", or "unknown".
func HasDeltaSection ¶
HasDeltaSection checks if the content contains a specific delta section type.
func HasRequirement ¶
HasRequirement checks if a requirement with the given name exists.
func HasSection ¶
HasSection checks if a section with the given name exists (case-insensitive).
func IsBlankLine ¶
IsBlankLine checks if a line is empty or contains only whitespace.
func IsBlockquote ¶
IsBlockquote checks if a line starts with a blockquote marker (>).
func IsCodeFence ¶
IsCodeFence checks if a line starts a code fence (``` or ~~~). Returns true and the fence character ('`' or '~') if it's a fence, or false and 0 otherwise.
func IsH2Header ¶
IsH2Header checks if a line starts with "## " (any H2 header).
func IsH3Header ¶
IsH3Header checks if a line starts with "### " (any H3 header).
func IsH4Header ¶
IsH4Header checks if a line starts with "#### " (any H4 header).
func IsHorizontalRule ¶
IsHorizontalRule checks if a line is a horizontal rule (---, ***, ___).
func IsListItem ¶
IsListItem checks if a line starts with a list marker. Supports unordered markers (-, *, +) and ordered markers (1., 2., etc.) after optional leading whitespace.
func IsTaskChecked ¶
IsTaskChecked returns true if the checkbox state indicates completion. Accepts 'x' or 'X' as checked states.
func ListWikilinkTargets ¶
ListWikilinkTargets extracts all wikilink targets from content. Returns a slice of unique target strings.
func MatchAnyRenamedFrom ¶
MatchAnyRenamedFrom tries both backtick and non-backtick FROM formats. Returns the requirement name and true if either format matches. Tries backtick format first, then falls back to non-backtick.
func MatchAnyRenamedTo ¶
MatchAnyRenamedTo tries both backtick and non-backtick TO formats. Returns the requirement name and true if either format matches. Tries backtick format first, then falls back to non-backtick.
func MatchAnySection ¶ added in v0.0.9
MatchAnySection parses any H2 section header from tasks.md format. Accepts both numbered and unnumbered formats:
- "## 1. Setup" -> name="Setup", number="1", ok=true
- "## Implementation" -> name="Implementation", number="", ok=true
Returns the section name, optional number, and true if matched.
func MatchH2DeltaSection ¶
MatchH2DeltaSection checks if a line is a delta section header (## ADDED|MODIFIED|REMOVED|RENAMED Requirements). Returns the delta type and true if matched, or empty string and false.
Example:
deltaType, ok := MatchH2DeltaSection("## ADDED Requirements")
// deltaType = "ADDED", ok = true
func MatchH2SectionHeader ¶
MatchH2SectionHeader checks if a line is an H2 section header and extracts the name. Returns the section name and true if matched, or empty string and false otherwise. This is a compatibility wrapper matching the old regex API.
Example:
name, ok := MatchH2SectionHeader("## Purpose")
// name = "Purpose", ok = true
func MatchNumberedSection ¶
MatchNumberedSection parses a numbered section header from tasks.md format. Format: "## 1. Section Name" Returns the section name (without number prefix) and true if matched, or empty string and false otherwise.
Example:
name, ok := MatchNumberedSection("## 1. Core Accept Command")
// name = "Core Accept Command", ok = true
func MatchRenamedFrom ¶
MatchRenamedFrom checks if a line matches the backtick-wrapped FROM format for renamed requirements. Returns the requirement name and true if matched, or empty string and false otherwise.
Expected format: "- FROM: `### Requirement: Old Name`"
Example:
name, ok := MatchRenamedFrom("- FROM: `### Requirement: Old Name`")
// name = "Old Name", ok = true
func MatchRenamedFromAlt ¶
MatchRenamedFromAlt checks if a line matches the non-backtick FROM format for renamed requirements. Returns the requirement name and true if matched, or empty string and false otherwise.
Expected format: "- FROM: ### Requirement: Old Name"
Example:
name, ok := MatchRenamedFromAlt("- FROM: ### Requirement: Old Name")
// name = "Old Name", ok = true
func MatchRenamedTo ¶
MatchRenamedTo checks if a line matches the backtick-wrapped TO format for renamed requirements. Returns the requirement name and true if matched, or empty string and false otherwise.
Expected format: "- TO: `### Requirement: New Name`"
Example:
name, ok := MatchRenamedTo("- TO: `### Requirement: New Name`")
// name = "New Name", ok = true
func MatchRenamedToAlt ¶
MatchRenamedToAlt checks if a line matches the non-backtick TO format for renamed requirements. Returns the requirement name and true if matched, or empty string and false otherwise.
Expected format: "- TO: ### Requirement: New Name"
Example:
name, ok := MatchRenamedToAlt("- TO: ### Requirement: New Name")
// name = "New Name", ok = true
func MatchRequirementHeader ¶
MatchRequirementHeader checks if a line is a requirement header ("### Requirement: Name") and extracts the name. Returns the requirement name and true if matched, or empty string and false. This function allows flexible whitespace between ### and "Requirement:" and after the colon, matching the behavior of the original regex.
Example:
name, ok := MatchRequirementHeader("### Requirement: User Authentication")
// name = "User Authentication", ok = true
func MatchScenarioHeader ¶
MatchScenarioHeader checks if a line is a scenario header ("#### Scenario: Name") and extracts the name. Returns the scenario name and true if matched, or empty string and false. This function allows flexible whitespace between #### and "Scenario:" and after the colon, matching the behavior of the original regex.
Example:
name, ok := MatchScenarioHeader("#### Scenario: User logs in")
// name = "User logs in", ok = true
func MatchTaskCheckbox ¶
MatchTaskCheckbox checks if a line contains a task checkbox and extracts the state. The line must start with optional whitespace, followed by "- [x]" or "- [ ]". Returns the checkbox state (' ' for unchecked, 'x' or 'X' for checked) and true if matched, or 0 and false otherwise.
Example:
state, ok := MatchTaskCheckbox("- [ ] Unchecked task")
// state = ' ', ok = true
state, ok := MatchTaskCheckbox("- [x] Checked task")
// state = 'x', ok = true
func MergeDelta ¶
func MergeDelta(merged, delta *Delta)
MergeDelta merges delta changes into the merged delta. This is useful for combining multiple delta files.
func NormalizeMultipleNewlines ¶
NormalizeMultipleNewlines collapses sequences of 3 or more consecutive newlines into exactly 2 newlines. This replaces the inline regex pattern `\n{3,}` with a string-based implementation.
Example:
result := NormalizeMultipleNewlines("text\n\n\n\nmore")
// result = "text\n\nmore"
func Parse ¶
func Parse(source []byte) (Node, []ParseError)
Parse transforms source bytes into an immutable AST. It returns the root document node and any parse errors encountered. This function is stateless and safe for concurrent calls.
func ParseDelta ¶
func ParseDelta( content []byte, ) (*Delta, []ParseError)
ParseDelta parses markdown content as a delta specification and returns a Delta with categorized requirement changes.
func ParseIncremental ¶
func ParseIncremental( oldTree Node, oldSource, newSource []byte, ) (Node, []ParseError)
ParseIncremental performs incremental parsing by reusing parts of the old AST. It computes the diff between oldSource and newSource, identifies affected regions, and attempts to reuse unchanged subtrees from oldTree.
This is a tree-sitter style incremental parser that: 1. Computes diff between old and new source 2. Identifies affected region(s) 3. Reuses unchanged subtrees (matched by content hash) 4. Adjusts offsets for nodes after edit point 5. Reparses only the changed regions
For large changes (>20% of file), falls back to full reparse.
func ParseIncrementalWithState ¶
func ParseIncrementalWithState( state *IncrementalParseState, oldTree Node, oldSource, newSource []byte, ) (Node, []ParseError, *IncrementalParseState)
ParseIncrementalWithState performs incremental parsing using cached state. This is more efficient than ParseIncremental when the state is available.
func ParseSpec ¶
func ParseSpec( content []byte, ) (*Spec, []ParseError)
ParseSpec parses markdown content and returns a Spec with structured access to sections, requirements, and scenarios.
func Print ¶
Print renders the AST node to normalized markdown. It returns the rendered markdown as a byte slice. The output uses consistent formatting (ATX headers, dash bullets) with minimal whitespace.
func PrintTo ¶
PrintTo renders the AST node to the provided io.Writer. It streams output without buffering the entire result. Returns any write errors encountered.
func PutChildren ¶
func PutChildren(c []Node)
PutChildren returns a children slice to the appropriate pool. The slice is cleared before being returned to prevent memory leaks.
func PutNode ¶
func PutNode(n Node)
PutNode returns a node to the appropriate pool based on its type. The node should not be used after this call.
func PutToken ¶
func PutToken(t *Token)
PutToken returns a Token to the pool after clearing its fields. The token should not be used after this call.
func ResolveWikilink ¶
ResolveWikilink resolves a wikilink target to a file path within the project. It follows the Spectr resolution rules:
- First check spectr/specs/{target}/spec.md
- Then check spectr/changes/{target}/proposal.md
- If target contains "/", treat first segment as directory type
Returns the resolved path and whether the file exists. The projectRoot should be the root directory containing the spectr/ folder.
func ResolveWikilinkWithAnchor ¶
func ResolveWikilinkWithAnchor( target, anchor, projectRoot string, ) (path string, anchorValid bool, err error)
ResolveWikilinkWithAnchor resolves a wikilink target and validates anchor. It first resolves the target path using ResolveWikilink, then parses the target file to validate that the anchor exists as a header.
Returns:
- path: the resolved file path
- anchorValid: true if anchor exists in target (or if no anchor given)
- err: any error encountered during resolution or file reading
Anchor matching rules:
- Anchors are matched case-insensitively
- "Requirement: Name" matches ### Requirement: Name headers
- "Scenario: Name" matches #### Scenario: Name headers
- Plain text matches any header containing that text
func TrimLeadingHashes ¶
TrimLeadingHashes removes leading hash characters and the following space from a header line, returning the header content.
func ValidateRenamed ¶
ValidateRenamed checks that all renamed requirements have both From and To values. Returns the names of any incomplete rename operations.
func ValidateWikilinkTarget ¶
ValidateWikilinkTarget checks if a single wikilink target is valid. This is a convenience function for validating individual targets.
func Walk ¶
Walk traverses the AST in pre-order depth-first order, calling the appropriate visitor method for each node. It handles the traversal logic including child recursion and error handling.
If a visitor method returns SkipChildren, the children of that node are skipped but traversal continues with the next sibling.
If a visitor method returns any other non-nil error, traversal stops immediately and that error is returned.
Walk safely handles nil nodes by returning nil without calling any visitor methods.
func WalkEnterLeave ¶
func WalkEnterLeave( node Node, v EnterLeaveVisitor, ) error
WalkEnterLeave traverses the AST calling Enter methods before visiting children and Leave methods after visiting children.
If an Enter method returns SkipChildren, the children are skipped but the corresponding Leave method is still called.
If an Enter method returns any other non-nil error, traversal stops immediately and the Leave method is NOT called.
If a Leave method returns a non-nil error, traversal stops immediately.
WalkEnterLeave safely handles nil nodes by returning nil.
func WalkWithContext ¶
func WalkWithContext( node Node, v ContextVisitor, ) error
WalkWithContext traverses the AST like Walk but provides context information including parent node access to the visitor.
Types ¶
type AdjustedNode ¶
type AdjustedNode struct {
// contains filtered or unexported fields
}
AdjustedNode represents a node with adjusted offsets for incremental parsing. Used when reusing nodes from the old tree that appear after an edit point.
type BaseContextVisitor ¶
type BaseContextVisitor struct{}
BaseContextVisitor provides no-op defaults for all ContextVisitor methods.
func (BaseContextVisitor) VisitBlockquoteWithContext ¶
func (BaseContextVisitor) VisitBlockquoteWithContext( *NodeBlockquote, *VisitorContext, ) error
VisitBlockquoteWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitCodeBlockWithContext ¶
func (BaseContextVisitor) VisitCodeBlockWithContext( *NodeCodeBlock, *VisitorContext, ) error
VisitCodeBlockWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitCodeWithContext ¶
func (BaseContextVisitor) VisitCodeWithContext( *NodeCode, *VisitorContext, ) error
VisitCodeWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitDocumentWithContext ¶
func (BaseContextVisitor) VisitDocumentWithContext( *NodeDocument, *VisitorContext, ) error
VisitDocumentWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitEmphasisWithContext ¶
func (BaseContextVisitor) VisitEmphasisWithContext( *NodeEmphasis, *VisitorContext, ) error
VisitEmphasisWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitLinkDefWithContext ¶
func (BaseContextVisitor) VisitLinkDefWithContext( *NodeLinkDef, *VisitorContext, ) error
VisitLinkDefWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitLinkWithContext ¶
func (BaseContextVisitor) VisitLinkWithContext( *NodeLink, *VisitorContext, ) error
VisitLinkWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitListItemWithContext ¶
func (BaseContextVisitor) VisitListItemWithContext( *NodeListItem, *VisitorContext, ) error
VisitListItemWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitListWithContext ¶
func (BaseContextVisitor) VisitListWithContext( *NodeList, *VisitorContext, ) error
VisitListWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitParagraphWithContext ¶
func (BaseContextVisitor) VisitParagraphWithContext( *NodeParagraph, *VisitorContext, ) error
VisitParagraphWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitRequirementWithContext ¶
func (BaseContextVisitor) VisitRequirementWithContext( *NodeRequirement, *VisitorContext, ) error
VisitRequirementWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitScenarioWithContext ¶
func (BaseContextVisitor) VisitScenarioWithContext( *NodeScenario, *VisitorContext, ) error
VisitScenarioWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitSectionWithContext ¶
func (BaseContextVisitor) VisitSectionWithContext( *NodeSection, *VisitorContext, ) error
VisitSectionWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitStrikethroughWithContext ¶
func (BaseContextVisitor) VisitStrikethroughWithContext( *NodeStrikethrough, *VisitorContext, ) error
VisitStrikethroughWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitStrongWithContext ¶
func (BaseContextVisitor) VisitStrongWithContext( *NodeStrong, *VisitorContext, ) error
VisitStrongWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitTextWithContext ¶
func (BaseContextVisitor) VisitTextWithContext( *NodeText, *VisitorContext, ) error
VisitTextWithContext is a no-op that returns nil.
func (BaseContextVisitor) VisitWikilinkWithContext ¶
func (BaseContextVisitor) VisitWikilinkWithContext( *NodeWikilink, *VisitorContext, ) error
VisitWikilinkWithContext is a no-op that returns nil.
type BaseEnterLeaveVisitor ¶
type BaseEnterLeaveVisitor struct{}
BaseEnterLeaveVisitor provides no-op default implementations for all EnterLeaveVisitor methods. Embed this struct in custom visitors to only override the methods you need.
func (BaseEnterLeaveVisitor) EnterBlockquote ¶
func (BaseEnterLeaveVisitor) EnterBlockquote( *NodeBlockquote, ) error
EnterBlockquote is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterCode ¶
func (BaseEnterLeaveVisitor) EnterCode( *NodeCode, ) error
EnterCode is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterCodeBlock ¶
func (BaseEnterLeaveVisitor) EnterCodeBlock( *NodeCodeBlock, ) error
EnterCodeBlock is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterDocument ¶
func (BaseEnterLeaveVisitor) EnterDocument( *NodeDocument, ) error
EnterDocument is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterEmphasis ¶
func (BaseEnterLeaveVisitor) EnterEmphasis( *NodeEmphasis, ) error
EnterEmphasis is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterLink ¶
func (BaseEnterLeaveVisitor) EnterLink( *NodeLink, ) error
EnterLink is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterLinkDef ¶
func (BaseEnterLeaveVisitor) EnterLinkDef( *NodeLinkDef, ) error
EnterLinkDef is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterList ¶
func (BaseEnterLeaveVisitor) EnterList( *NodeList, ) error
EnterList is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterListItem ¶
func (BaseEnterLeaveVisitor) EnterListItem( *NodeListItem, ) error
EnterListItem is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterParagraph ¶
func (BaseEnterLeaveVisitor) EnterParagraph( *NodeParagraph, ) error
EnterParagraph is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterRequirement ¶
func (BaseEnterLeaveVisitor) EnterRequirement( *NodeRequirement, ) error
EnterRequirement is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterScenario ¶
func (BaseEnterLeaveVisitor) EnterScenario( *NodeScenario, ) error
EnterScenario is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterSection ¶
func (BaseEnterLeaveVisitor) EnterSection( *NodeSection, ) error
EnterSection is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterStrikethrough ¶
func (BaseEnterLeaveVisitor) EnterStrikethrough( *NodeStrikethrough, ) error
EnterStrikethrough is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterStrong ¶
func (BaseEnterLeaveVisitor) EnterStrong( *NodeStrong, ) error
EnterStrong is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterText ¶
func (BaseEnterLeaveVisitor) EnterText( *NodeText, ) error
EnterText is a no-op that returns nil.
func (BaseEnterLeaveVisitor) EnterWikilink ¶
func (BaseEnterLeaveVisitor) EnterWikilink( *NodeWikilink, ) error
EnterWikilink is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveBlockquote ¶
func (BaseEnterLeaveVisitor) LeaveBlockquote( *NodeBlockquote, ) error
LeaveBlockquote is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveCode ¶
func (BaseEnterLeaveVisitor) LeaveCode( *NodeCode, ) error
LeaveCode is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveCodeBlock ¶
func (BaseEnterLeaveVisitor) LeaveCodeBlock( *NodeCodeBlock, ) error
LeaveCodeBlock is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveDocument ¶
func (BaseEnterLeaveVisitor) LeaveDocument( *NodeDocument, ) error
LeaveDocument is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveEmphasis ¶
func (BaseEnterLeaveVisitor) LeaveEmphasis( *NodeEmphasis, ) error
LeaveEmphasis is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveLink ¶
func (BaseEnterLeaveVisitor) LeaveLink( *NodeLink, ) error
LeaveLink is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveLinkDef ¶
func (BaseEnterLeaveVisitor) LeaveLinkDef( *NodeLinkDef, ) error
LeaveLinkDef is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveList ¶
func (BaseEnterLeaveVisitor) LeaveList( *NodeList, ) error
LeaveList is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveListItem ¶
func (BaseEnterLeaveVisitor) LeaveListItem( *NodeListItem, ) error
LeaveListItem is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveParagraph ¶
func (BaseEnterLeaveVisitor) LeaveParagraph( *NodeParagraph, ) error
LeaveParagraph is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveRequirement ¶
func (BaseEnterLeaveVisitor) LeaveRequirement( *NodeRequirement, ) error
LeaveRequirement is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveScenario ¶
func (BaseEnterLeaveVisitor) LeaveScenario( *NodeScenario, ) error
LeaveScenario is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveSection ¶
func (BaseEnterLeaveVisitor) LeaveSection( *NodeSection, ) error
LeaveSection is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveStrikethrough ¶
func (BaseEnterLeaveVisitor) LeaveStrikethrough( *NodeStrikethrough, ) error
LeaveStrikethrough is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveStrong ¶
func (BaseEnterLeaveVisitor) LeaveStrong( *NodeStrong, ) error
LeaveStrong is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveText ¶
func (BaseEnterLeaveVisitor) LeaveText( *NodeText, ) error
LeaveText is a no-op that returns nil.
func (BaseEnterLeaveVisitor) LeaveWikilink ¶
func (BaseEnterLeaveVisitor) LeaveWikilink( *NodeWikilink, ) error
LeaveWikilink is a no-op that returns nil.
type BaseTransformVisitor ¶
type BaseTransformVisitor struct{}
BaseTransformVisitor provides default no-op implementations for all TransformVisitor methods. Each method returns (original, ActionKeep, nil) by default. Embed this struct in custom transform visitors to only override the methods you need.
func (BaseTransformVisitor) TransformBlockquote ¶
func (BaseTransformVisitor) TransformBlockquote( n *NodeBlockquote, ) (Node, TransformAction, error)
TransformBlockquote returns the blockquote unchanged.
func (BaseTransformVisitor) TransformCode ¶
func (BaseTransformVisitor) TransformCode( n *NodeCode, ) (Node, TransformAction, error)
TransformCode returns the code unchanged.
func (BaseTransformVisitor) TransformCodeBlock ¶
func (BaseTransformVisitor) TransformCodeBlock( n *NodeCodeBlock, ) (Node, TransformAction, error)
TransformCodeBlock returns the code block unchanged.
func (BaseTransformVisitor) TransformDocument ¶
func (BaseTransformVisitor) TransformDocument( n *NodeDocument, ) (Node, TransformAction, error)
TransformDocument returns the document unchanged.
func (BaseTransformVisitor) TransformEmphasis ¶
func (BaseTransformVisitor) TransformEmphasis( n *NodeEmphasis, ) (Node, TransformAction, error)
TransformEmphasis returns the emphasis unchanged.
func (BaseTransformVisitor) TransformLink ¶
func (BaseTransformVisitor) TransformLink( n *NodeLink, ) (Node, TransformAction, error)
TransformLink returns the link unchanged.
func (BaseTransformVisitor) TransformLinkDef ¶
func (BaseTransformVisitor) TransformLinkDef( n *NodeLinkDef, ) (Node, TransformAction, error)
TransformLinkDef returns the link definition unchanged.
func (BaseTransformVisitor) TransformList ¶
func (BaseTransformVisitor) TransformList( n *NodeList, ) (Node, TransformAction, error)
TransformList returns the list unchanged.
func (BaseTransformVisitor) TransformListItem ¶
func (BaseTransformVisitor) TransformListItem( n *NodeListItem, ) (Node, TransformAction, error)
TransformListItem returns the list item unchanged.
func (BaseTransformVisitor) TransformParagraph ¶
func (BaseTransformVisitor) TransformParagraph( n *NodeParagraph, ) (Node, TransformAction, error)
TransformParagraph returns the paragraph unchanged.
func (BaseTransformVisitor) TransformRequirement ¶
func (BaseTransformVisitor) TransformRequirement( n *NodeRequirement, ) (Node, TransformAction, error)
TransformRequirement returns the requirement unchanged.
func (BaseTransformVisitor) TransformScenario ¶
func (BaseTransformVisitor) TransformScenario( n *NodeScenario, ) (Node, TransformAction, error)
TransformScenario returns the scenario unchanged.
func (BaseTransformVisitor) TransformSection ¶
func (BaseTransformVisitor) TransformSection( n *NodeSection, ) (Node, TransformAction, error)
TransformSection returns the section unchanged.
func (BaseTransformVisitor) TransformStrikethrough ¶
func (BaseTransformVisitor) TransformStrikethrough( n *NodeStrikethrough, ) (Node, TransformAction, error)
TransformStrikethrough returns the strikethrough unchanged.
func (BaseTransformVisitor) TransformStrong ¶
func (BaseTransformVisitor) TransformStrong( n *NodeStrong, ) (Node, TransformAction, error)
TransformStrong returns the strong unchanged.
func (BaseTransformVisitor) TransformText ¶
func (BaseTransformVisitor) TransformText( n *NodeText, ) (Node, TransformAction, error)
TransformText returns the text unchanged.
func (BaseTransformVisitor) TransformWikilink ¶
func (BaseTransformVisitor) TransformWikilink( n *NodeWikilink, ) (Node, TransformAction, error)
TransformWikilink returns the wikilink unchanged.
type BaseVisitor ¶
type BaseVisitor struct{}
BaseVisitor provides no-op default implementations for all Visitor methods. Embed this struct in custom visitors to only override the methods you need.
func (BaseVisitor) VisitBlockquote ¶
func (BaseVisitor) VisitBlockquote( *NodeBlockquote, ) error
VisitBlockquote is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitCode ¶
func (BaseVisitor) VisitCode( *NodeCode, ) error
VisitCode is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitCodeBlock ¶
func (BaseVisitor) VisitCodeBlock( *NodeCodeBlock, ) error
VisitCodeBlock is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitDocument ¶
func (BaseVisitor) VisitDocument( *NodeDocument, ) error
VisitDocument is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitEmphasis ¶
func (BaseVisitor) VisitEmphasis( *NodeEmphasis, ) error
VisitEmphasis is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitLink ¶
func (BaseVisitor) VisitLink( *NodeLink, ) error
VisitLink is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitLinkDef ¶
func (BaseVisitor) VisitLinkDef( *NodeLinkDef, ) error
VisitLinkDef is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitList ¶
func (BaseVisitor) VisitList( *NodeList, ) error
VisitList is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitListItem ¶
func (BaseVisitor) VisitListItem( *NodeListItem, ) error
VisitListItem is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitParagraph ¶
func (BaseVisitor) VisitParagraph( *NodeParagraph, ) error
VisitParagraph is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitRequirement ¶
func (BaseVisitor) VisitRequirement( *NodeRequirement, ) error
VisitRequirement is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitScenario ¶
func (BaseVisitor) VisitScenario( *NodeScenario, ) error
VisitScenario is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitSection ¶
func (BaseVisitor) VisitSection( *NodeSection, ) error
VisitSection is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitStrikethrough ¶
func (BaseVisitor) VisitStrikethrough( *NodeStrikethrough, ) error
VisitStrikethrough is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitStrong ¶
func (BaseVisitor) VisitStrong( *NodeStrong, ) error
VisitStrong is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitText ¶
func (BaseVisitor) VisitText( *NodeText, ) error
VisitText is a no-op that returns nil (continue traversal).
func (BaseVisitor) VisitWikilink ¶
func (BaseVisitor) VisitWikilink( *NodeWikilink, ) error
VisitWikilink is a no-op that returns nil (continue traversal).
type BuilderValidationError ¶
type BuilderValidationError struct {
Field string
Message string
Index int // For array fields, the index of the problematic element
}
BuilderValidationError represents a validation error in the builder.
func (*BuilderValidationError) Error ¶
func (e *BuilderValidationError) Error() string
type ContextVisitor ¶
type ContextVisitor interface {
VisitDocumentWithContext(
*NodeDocument,
*VisitorContext,
) error
VisitSectionWithContext(
*NodeSection,
*VisitorContext,
) error
VisitRequirementWithContext(
*NodeRequirement,
*VisitorContext,
) error
VisitScenarioWithContext(
*NodeScenario,
*VisitorContext,
) error
VisitParagraphWithContext(
*NodeParagraph,
*VisitorContext,
) error
VisitListWithContext(
*NodeList,
*VisitorContext,
) error
VisitListItemWithContext(
*NodeListItem,
*VisitorContext,
) error
VisitCodeBlockWithContext(
*NodeCodeBlock,
*VisitorContext,
) error
VisitBlockquoteWithContext(
*NodeBlockquote,
*VisitorContext,
) error
VisitTextWithContext(
*NodeText,
*VisitorContext,
) error
VisitStrongWithContext(
*NodeStrong,
*VisitorContext,
) error
VisitEmphasisWithContext(
*NodeEmphasis,
*VisitorContext,
) error
VisitStrikethroughWithContext(
*NodeStrikethrough,
*VisitorContext,
) error
VisitCodeWithContext(
*NodeCode,
*VisitorContext,
) error
VisitLinkWithContext(
*NodeLink,
*VisitorContext,
) error
VisitLinkDefWithContext(
*NodeLinkDef,
*VisitorContext,
) error
VisitWikilinkWithContext(
*NodeWikilink,
*VisitorContext,
) error
}
ContextVisitor is a visitor interface that receives context information during traversal, including parent node access.
type Delta ¶
type Delta struct {
// Root is the document node containing the entire AST.
Root Node
// Added contains requirements that are being added.
Added []*Requirement
// Modified contains requirements that are being modified.
Modified []*Requirement
// Removed contains the names of requirements being removed.
// Only names are stored since the requirements no longer exist.
Removed []string
// Renamed contains rename operations with from/to pairs.
Renamed []*RenamedRequirement
// Errors contains all parse errors encountered during parsing.
Errors []ParseError
}
Delta represents a parsed delta specification file. Delta files describe changes to requirements: additions, modifications, removals, and renames.
type DeltaType ¶
type DeltaType string
DeltaType represents the type of change in a delta specification.
type EditRegion ¶
type EditRegion struct {
StartOffset int // Where edit begins (same in both old and new)
OldEndOffset int // Where old content ended (exclusive)
NewEndOffset int // Where new content ends (exclusive)
}
EditRegion describes a contiguous edit between old and new source. It represents the region where content differs between the two versions.
func (EditRegion) Delta ¶
func (e EditRegion) Delta() int
Delta returns the byte offset change caused by this edit. Positive means content was added, negative means content was removed.
func (EditRegion) IsDelete ¶
func (e EditRegion) IsDelete() bool
IsDelete returns true if this edit is a pure deletion (no content added).
func (EditRegion) IsInsert ¶
func (e EditRegion) IsInsert() bool
IsInsert returns true if this edit is a pure insertion (no content removed).
func (EditRegion) IsReplace ¶
func (e EditRegion) IsReplace() bool
IsReplace returns true if this edit replaces content (both removes and adds).
func (EditRegion) NewLength ¶
func (e EditRegion) NewLength() int
NewLength returns the number of bytes added in the new source.
func (EditRegion) OldLength ¶
func (e EditRegion) OldLength() int
OldLength returns the number of bytes removed from the old source.
type EnterLeaveVisitor ¶
type EnterLeaveVisitor interface {
EnterDocument(*NodeDocument) error
LeaveDocument(*NodeDocument) error
EnterSection(*NodeSection) error
LeaveSection(*NodeSection) error
EnterRequirement(*NodeRequirement) error
LeaveRequirement(*NodeRequirement) error
EnterScenario(*NodeScenario) error
LeaveScenario(*NodeScenario) error
EnterParagraph(*NodeParagraph) error
LeaveParagraph(*NodeParagraph) error
EnterList(*NodeList) error
LeaveList(*NodeList) error
EnterListItem(*NodeListItem) error
LeaveListItem(*NodeListItem) error
EnterCodeBlock(*NodeCodeBlock) error
LeaveCodeBlock(*NodeCodeBlock) error
EnterBlockquote(*NodeBlockquote) error
LeaveBlockquote(*NodeBlockquote) error
EnterText(*NodeText) error
LeaveText(*NodeText) error
EnterStrong(*NodeStrong) error
LeaveStrong(*NodeStrong) error
EnterEmphasis(*NodeEmphasis) error
LeaveEmphasis(*NodeEmphasis) error
EnterStrikethrough(*NodeStrikethrough) error
LeaveStrikethrough(*NodeStrikethrough) error
EnterCode(*NodeCode) error
LeaveCode(*NodeCode) error
EnterLink(*NodeLink) error
LeaveLink(*NodeLink) error
EnterLinkDef(*NodeLinkDef) error
LeaveLinkDef(*NodeLinkDef) error
EnterWikilink(*NodeWikilink) error
LeaveWikilink(*NodeWikilink) error
}
EnterLeaveVisitor defines the interface for visitors that need to perform actions both before (Enter) and after (Leave) visiting a node's children. This is useful for operations that need to maintain state or perform cleanup, such as building output or managing a stack.
type FlexibleTaskMatch ¶ added in v0.0.9
type FlexibleTaskMatch struct {
Number string // Explicit number if present (e.g., "1.1", "1.", "1"), empty otherwise
Status rune // ' ' for unchecked, 'x' or 'X' for checked
Content string // The task description
}
FlexibleTaskMatch holds the parsed result of any task checkbox line. Unlike NumberedTaskMatch, this accepts tasks with or without numbers.
func MatchFlexibleTask ¶ added in v0.0.9
func MatchFlexibleTask( line string, ) (*FlexibleTaskMatch, bool)
MatchFlexibleTask parses any task checkbox line from tasks.md format. Accepts all formats:
- "- [ ] 1.1 Task description" (decimal)
- "- [ ] 1. Task description" (simple dot)
- "- [ ] 1 Task description" (number only)
- "- [ ] Task description" (no number)
Returns the parsed task match and true if matched, or nil and false.
type IncrementalParseState ¶
type IncrementalParseState struct {
// LinkDefs contains collected link definitions from the document.
// These can be reused if the link definition section hasn't changed.
LinkDefs map[string]linkDefinition
// LineIndex is the cached line index for position calculations.
// May be partially reusable if only part of the document changed.
LineIndex *LineIndex
// RootHash is the content hash of the root document node.
// Used to detect if the document has changed.
RootHash uint64
}
IncrementalParseState holds state that can be reused across incremental parses. This includes link definitions, line index data, and cached information.
func NewIncrementalParseState ¶
func NewIncrementalParseState( tree Node, source []byte, ) *IncrementalParseState
NewIncrementalParseState creates a new incremental parse state from a parsed tree.
func (*IncrementalParseState) CanReuseLinkDefs ¶
func (s *IncrementalParseState) CanReuseLinkDefs( edit EditRegion, oldTree Node, ) bool
CanReuseLinkDefs determines if link definitions can be reused from old state. Link definitions can be reused if the edit region doesn't overlap with any link definition in the document.
func (*IncrementalParseState) UpdateLineIndex ¶
func (s *IncrementalParseState) UpdateLineIndex( edit EditRegion, oldSource, newSource []byte, )
UpdateLineIndex updates the line index for an edit. If the edit only affects content within a single line (no newlines added/removed), the existing line index can be adjusted rather than rebuilt from scratch.
type LexError ¶
type LexError struct {
Offset int // Byte offset where error occurred
Message string // Error description
}
LexError represents an error encountered during lexing. It captures position and message from TokenError tokens.
type LexerState ¶
type LexerState uint8
LexerState represents the current context of the lexer. Different states affect how characters are tokenized.
const ( // StateNormal is the default state for normal markdown content. StateNormal LexerState = iota // StateFencedCode is active inside a fenced code block (“` or ~~~). // In this state, only TokenText and TokenNewline are emitted. StateFencedCode // StateInlineCode is active inside inline code (backticks). // Content is emitted as TokenText until matching backticks. StateInlineCode // StateLinkURL is active inside a link URL parentheses. // Special characters are treated as TokenText. StateLinkURL )
type LineIndex ¶
type LineIndex struct {
// contains filtered or unexported fields
}
LineIndex provides efficient conversion from byte offsets to line/column positions. It uses lazy construction - the line index is only built on the first query. The index supports O(log n) lookups via binary search.
func NewLineIndex ¶
NewLineIndex creates a new LineIndex for the given source. The index is lazily constructed on the first query.
func (*LineIndex) LineCol ¶
LineCol returns the 1-based line number and 0-based column for a byte offset. If the offset is beyond the source length, returns the position at end of source. If the offset is negative, returns line 1, column 0.
func (*LineIndex) LineCount ¶
LineCount returns the total number of lines in the source. This triggers index construction if not already built.
func (*LineIndex) LineEnd ¶
LineEnd returns the byte offset of the end of the given 1-based line number. The end is the offset of the newline character (or end of source for last line). Returns 0 for line <= 0 or if source is empty.
func (*LineIndex) LineStart ¶
LineStart returns the byte offset of the start of the given 1-based line number. Returns 0 for line <= 0 or if source is empty. Returns the start of the last line if lineNum exceeds the total line count.
func (*LineIndex) OffsetAt ¶
OffsetAt converts a 1-based line and 0-based column to a byte offset. Returns -1 if the line number is invalid. Clamps the column to the line's length if it exceeds it.
func (*LineIndex) PositionAt ¶
PositionAt returns a Position struct for the given byte offset. This combines the line, column, and original offset into a single struct.
type Named ¶
type Named interface {
// Name returns the name of the node.
Name() string
}
Named is an interface for nodes that have a Name() method. This includes NodeRequirement and NodeScenario.
type Node ¶
type Node interface {
// NodeType returns the type classification of this node.
NodeType() NodeType
// Span returns the byte offset range (start, end) of this node.
// Start is inclusive, end is exclusive.
Span() (start, end int)
// Hash returns a content hash for identity tracking and caching.
// Nodes with the same hash have the same semantic content.
Hash() uint64
// Source returns a zero-copy byte slice view into the original source.
// This remains valid as long as the original source buffer is retained.
Source() []byte
// Children returns an immutable copy of child nodes.
// Modifications to the returned slice do not affect the node.
Children() []Node
// Equal performs deep structural comparison with another node.
Equal(other Node) bool
}
Node is the interface implemented by all AST nodes. All nodes are immutable after creation - modifications require creating new nodes via builders.
func Find ¶
Find returns all nodes in the AST where pred returns true. Results are in pre-order traversal order (depth-first). Returns an empty slice (not nil) if no nodes match.
func FindFirst ¶
FindFirst returns the first node where pred returns true, or nil if none. Traversal stops immediately upon finding a match (short-circuit).
func GetChildren ¶
GetChildren retrieves a children slice from the appropriate pool based on capacity. The returned slice has length 0 and capacity >= the requested capacity.
func NodeAtOffset ¶
NodeAtOffset finds the innermost node containing the given byte offset. This is useful for editor integrations to find what the cursor is on.
func NodesAtOffset ¶
NodesAtOffset finds all nodes containing the given byte offset, from outermost to innermost.
func Transform ¶
func Transform( root Node, v TransformVisitor, ) (Node, error)
Transform applies a TransformVisitor to an AST using post-order traversal. Children are transformed before their parent, so parent transform methods see the results of child transformations.
The original AST is not modified; Transform returns a new tree with the transformations applied.
If the root node is deleted (ActionDelete returned for root), Transform returns (nil, nil).
If any transform method returns a non-nil error, Transform stops immediately and returns the error. Partial results are not returned.
type NodeBlockquote ¶
type NodeBlockquote struct {
// contains filtered or unexported fields
}
NodeBlockquote represents blockquoted content (lines starting with >).
func GetBlockquote ¶
func GetBlockquote() *NodeBlockquote
GetBlockquote retrieves a NodeBlockquote from the pool.
func (*NodeBlockquote) Children ¶
func (n *NodeBlockquote) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeBlockquote) Equal ¶
func (n *NodeBlockquote) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeBlockquote) Hash ¶
func (n *NodeBlockquote) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeBlockquote) NodeType ¶
func (n *NodeBlockquote) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeBlockquote) Source ¶
func (n *NodeBlockquote) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeBlockquote) Span ¶
func (n *NodeBlockquote) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeBlockquote) ToBuilder ¶
func (n *NodeBlockquote) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeBuilder ¶
type NodeBuilder struct {
// contains filtered or unexported fields
}
NodeBuilder provides a fluent API for constructing AST nodes. It supports building new nodes and transforming existing ones.
func NewNodeBuilder ¶
func NewNodeBuilder( nodeType NodeType, ) *NodeBuilder
NewNodeBuilder creates a new builder for the specified node type.
func (*NodeBuilder) Build ¶
func (b *NodeBuilder) Build() Node
Build creates the immutable node from the builder state. It validates the builder and computes the content hash. Returns nil if validation fails (caller should check Validate() first for error details).
func (*NodeBuilder) Validate ¶
func (b *NodeBuilder) Validate() error
Validate checks that the builder state is valid. Returns an error if validation fails.
func (*NodeBuilder) WithAnchor ¶
func (b *NodeBuilder) WithAnchor( anchor []byte, ) *NodeBuilder
WithAnchor sets the anchor (for Wikilink nodes).
func (*NodeBuilder) WithChecked ¶
func (b *NodeBuilder) WithChecked( checked *bool, ) *NodeBuilder
WithChecked sets the checkbox state (for ListItem nodes). Pass nil for no checkbox, pointer to bool for checkbox state.
func (*NodeBuilder) WithChildren ¶
func (b *NodeBuilder) WithChildren( children []Node, ) *NodeBuilder
WithChildren sets the children nodes.
func (*NodeBuilder) WithContent ¶
func (b *NodeBuilder) WithContent( content []byte, ) *NodeBuilder
WithContent sets the code content (for CodeBlock nodes).
func (*NodeBuilder) WithDeltaType ¶
func (b *NodeBuilder) WithDeltaType( deltaType string, ) *NodeBuilder
WithDeltaType sets the delta type (for Section nodes).
func (*NodeBuilder) WithDisplay ¶
func (b *NodeBuilder) WithDisplay( display []byte, ) *NodeBuilder
WithDisplay sets the display text (for Wikilink nodes).
func (*NodeBuilder) WithEnd ¶
func (b *NodeBuilder) WithEnd( end int, ) *NodeBuilder
WithEnd sets the end byte offset.
func (*NodeBuilder) WithKeyword ¶
func (b *NodeBuilder) WithKeyword( keyword string, ) *NodeBuilder
WithKeyword sets the keyword (for ListItem nodes).
func (*NodeBuilder) WithLanguage ¶
func (b *NodeBuilder) WithLanguage( language []byte, ) *NodeBuilder
WithLanguage sets the language (for CodeBlock nodes).
func (*NodeBuilder) WithLevel ¶
func (b *NodeBuilder) WithLevel( level int, ) *NodeBuilder
WithLevel sets the header level (for Section nodes).
func (*NodeBuilder) WithLinkTitle ¶
func (b *NodeBuilder) WithLinkTitle( title []byte, ) *NodeBuilder
WithLinkTitle sets the link title (for Link nodes).
func (*NodeBuilder) WithName ¶
func (b *NodeBuilder) WithName( name string, ) *NodeBuilder
WithName sets the name (for Requirement and Scenario nodes).
func (*NodeBuilder) WithOrdered ¶
func (b *NodeBuilder) WithOrdered( ordered bool, ) *NodeBuilder
WithOrdered sets whether the list is ordered (for List nodes).
func (*NodeBuilder) WithSource ¶
func (b *NodeBuilder) WithSource( source []byte, ) *NodeBuilder
WithSource sets the source byte slice.
func (*NodeBuilder) WithStart ¶
func (b *NodeBuilder) WithStart( start int, ) *NodeBuilder
WithStart sets the start byte offset.
func (*NodeBuilder) WithTarget ¶
func (b *NodeBuilder) WithTarget( target []byte, ) *NodeBuilder
WithTarget sets the target (for Wikilink nodes).
func (*NodeBuilder) WithTitle ¶
func (b *NodeBuilder) WithTitle( title []byte, ) *NodeBuilder
WithTitle sets the title (for Section nodes).
func (*NodeBuilder) WithURL ¶
func (b *NodeBuilder) WithURL( url []byte, ) *NodeBuilder
WithURL sets the URL (for Link nodes).
type NodeCode ¶
type NodeCode struct {
// contains filtered or unexported fields
}
NodeCode represents inline code (`code`).
func (*NodeCode) Children ¶
func (n *NodeCode) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeCode) Code ¶
Code returns the code content as a string. This creates a copy; use Source() for zero-copy access.
func (*NodeCode) Hash ¶
func (n *NodeCode) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeCode) NodeType ¶
func (n *NodeCode) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeCode) Source ¶
func (n *NodeCode) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeCode) Span ¶
func (n *NodeCode) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeCode) ToBuilder ¶
func (n *NodeCode) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeCodeBlock ¶
type NodeCodeBlock struct {
// contains filtered or unexported fields
}
NodeCodeBlock represents a fenced code block (``` or ~~~).
func GetCodeBlock ¶
func GetCodeBlock() *NodeCodeBlock
GetCodeBlock retrieves a NodeCodeBlock from the pool.
func (*NodeCodeBlock) Children ¶
func (n *NodeCodeBlock) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeCodeBlock) Content ¶
func (n *NodeCodeBlock) Content() []byte
Content returns the code content (without fence lines) as a byte slice.
func (*NodeCodeBlock) Equal ¶
func (n *NodeCodeBlock) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeCodeBlock) Hash ¶
func (n *NodeCodeBlock) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeCodeBlock) Language ¶
func (n *NodeCodeBlock) Language() []byte
Language returns the language identifier as a byte slice. Returns nil if no language was specified.
func (*NodeCodeBlock) NodeType ¶
func (n *NodeCodeBlock) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeCodeBlock) Source ¶
func (n *NodeCodeBlock) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeCodeBlock) Span ¶
func (n *NodeCodeBlock) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeCodeBlock) ToBuilder ¶
func (n *NodeCodeBlock) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeDocument ¶
type NodeDocument struct {
// contains filtered or unexported fields
}
NodeDocument is the root node of an AST. It contains all top-level block nodes from the parsed document.
func GetDocument ¶
func GetDocument() *NodeDocument
GetDocument retrieves a NodeDocument from the pool.
func (*NodeDocument) Children ¶
func (n *NodeDocument) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeDocument) Equal ¶
func (n *NodeDocument) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeDocument) Hash ¶
func (n *NodeDocument) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeDocument) NodeType ¶
func (n *NodeDocument) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeDocument) Source ¶
func (n *NodeDocument) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeDocument) Span ¶
func (n *NodeDocument) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeDocument) ToBuilder ¶
func (n *NodeDocument) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeEmphasis ¶
type NodeEmphasis struct {
// contains filtered or unexported fields
}
NodeEmphasis represents italic emphasis (*text* or _text_).
func GetEmphasis ¶
func GetEmphasis() *NodeEmphasis
GetEmphasis retrieves a NodeEmphasis from the pool.
func (*NodeEmphasis) Children ¶
func (n *NodeEmphasis) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeEmphasis) Equal ¶
func (n *NodeEmphasis) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeEmphasis) Hash ¶
func (n *NodeEmphasis) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeEmphasis) NodeType ¶
func (n *NodeEmphasis) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeEmphasis) Source ¶
func (n *NodeEmphasis) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeEmphasis) Span ¶
func (n *NodeEmphasis) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeEmphasis) ToBuilder ¶
func (n *NodeEmphasis) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeLink ¶
type NodeLink struct {
// contains filtered or unexported fields
}
NodeLink represents a link [text](url "title") or [text][ref].
func (*NodeLink) Children ¶
func (n *NodeLink) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeLink) Hash ¶
func (n *NodeLink) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeLink) NodeType ¶
func (n *NodeLink) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeLink) Source ¶
func (n *NodeLink) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeLink) Span ¶
func (n *NodeLink) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeLink) Title ¶
Title returns the optional link title as a byte slice. Returns nil if no title was specified.
func (*NodeLink) ToBuilder ¶
func (n *NodeLink) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeLinkDef ¶
type NodeLinkDef struct {
// contains filtered or unexported fields
}
NodeLinkDef represents a link definition [ref]: url "title". Link definitions are collected during parsing and used to resolve reference links.
func (*NodeLinkDef) Children ¶
func (n *NodeLinkDef) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeLinkDef) Equal ¶
func (n *NodeLinkDef) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeLinkDef) Hash ¶
func (n *NodeLinkDef) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeLinkDef) NodeType ¶
func (n *NodeLinkDef) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeLinkDef) Source ¶
func (n *NodeLinkDef) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeLinkDef) Span ¶
func (n *NodeLinkDef) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeLinkDef) Title ¶
func (n *NodeLinkDef) Title() []byte
Title returns the optional link title as a byte slice. Returns nil if no title was specified.
func (*NodeLinkDef) ToBuilder ¶
func (n *NodeLinkDef) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
func (*NodeLinkDef) URL ¶
func (n *NodeLinkDef) URL() []byte
URL returns the link destination as a byte slice.
type NodeList ¶
type NodeList struct {
// contains filtered or unexported fields
}
NodeList represents an unordered or ordered list. Its children are NodeListItem nodes.
func (*NodeList) Children ¶
func (n *NodeList) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeList) Hash ¶
func (n *NodeList) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeList) NodeType ¶
func (n *NodeList) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeList) Source ¶
func (n *NodeList) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeList) Span ¶
func (n *NodeList) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeList) ToBuilder ¶
func (n *NodeList) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeListItem ¶
type NodeListItem struct {
// contains filtered or unexported fields
}
NodeListItem represents a single list item. It may be a task item with a checkbox, or a Spectr bullet with WHEN/THEN/AND keyword.
func GetListItem ¶
func GetListItem() *NodeListItem
GetListItem retrieves a NodeListItem from the pool.
func (*NodeListItem) Checked ¶
func (n *NodeListItem) Checked() (isChecked, hasCheckbox bool)
Checked returns the checkbox state and whether a checkbox is present. If no checkbox, returns (false, false). If unchecked checkbox, returns (false, true). If checked checkbox, returns (true, true).
func (*NodeListItem) Children ¶
func (n *NodeListItem) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeListItem) Equal ¶
func (n *NodeListItem) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeListItem) Hash ¶
func (n *NodeListItem) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeListItem) Keyword ¶
func (n *NodeListItem) Keyword() string
Keyword returns the Spectr bullet keyword (WHEN, THEN, AND) or empty string.
func (*NodeListItem) NodeType ¶
func (n *NodeListItem) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeListItem) Source ¶
func (n *NodeListItem) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeListItem) Span ¶
func (n *NodeListItem) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeListItem) ToBuilder ¶
func (n *NodeListItem) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeParagraph ¶
type NodeParagraph struct {
// contains filtered or unexported fields
}
NodeParagraph represents a paragraph of text. Its children are inline nodes (text, emphasis, links, etc.).
func GetParagraph ¶
func GetParagraph() *NodeParagraph
GetParagraph retrieves a NodeParagraph from the pool.
func (*NodeParagraph) Children ¶
func (n *NodeParagraph) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeParagraph) Equal ¶
func (n *NodeParagraph) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeParagraph) Hash ¶
func (n *NodeParagraph) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeParagraph) NodeType ¶
func (n *NodeParagraph) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeParagraph) Source ¶
func (n *NodeParagraph) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeParagraph) Span ¶
func (n *NodeParagraph) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeParagraph) ToBuilder ¶
func (n *NodeParagraph) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeRequirement ¶
type NodeRequirement struct {
// contains filtered or unexported fields
}
NodeRequirement represents a Spectr requirement header (### Requirement: Name).
func GetRequirement ¶
func GetRequirement() *NodeRequirement
GetRequirement retrieves a NodeRequirement from the pool.
func (*NodeRequirement) Children ¶
func (n *NodeRequirement) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeRequirement) Equal ¶
func (n *NodeRequirement) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeRequirement) Hash ¶
func (n *NodeRequirement) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeRequirement) Name ¶
func (n *NodeRequirement) Name() string
Name returns the requirement name extracted from the header.
func (*NodeRequirement) NodeType ¶
func (n *NodeRequirement) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeRequirement) Source ¶
func (n *NodeRequirement) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeRequirement) Span ¶
func (n *NodeRequirement) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeRequirement) ToBuilder ¶
func (n *NodeRequirement) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeScenario ¶
type NodeScenario struct {
// contains filtered or unexported fields
}
NodeScenario represents a Spectr scenario header (#### Scenario: Name).
func GetScenario ¶
func GetScenario() *NodeScenario
GetScenario retrieves a NodeScenario from the pool.
func (*NodeScenario) Children ¶
func (n *NodeScenario) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeScenario) Equal ¶
func (n *NodeScenario) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeScenario) Hash ¶
func (n *NodeScenario) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeScenario) Name ¶
func (n *NodeScenario) Name() string
Name returns the scenario name extracted from the header.
func (*NodeScenario) NodeType ¶
func (n *NodeScenario) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeScenario) Source ¶
func (n *NodeScenario) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeScenario) Span ¶
func (n *NodeScenario) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeScenario) ToBuilder ¶
func (n *NodeScenario) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeSection ¶
type NodeSection struct {
// contains filtered or unexported fields
}
NodeSection represents an ATX-style header (H1-H6) and its content. For Spectr delta files, it may have a DeltaType indicating the change type.
func (*NodeSection) Children ¶
func (n *NodeSection) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeSection) DeltaType ¶
func (n *NodeSection) DeltaType() string
DeltaType returns the delta type for Spectr delta sections. Returns one of "ADDED", "MODIFIED", "REMOVED", "RENAMED", or empty string.
func (*NodeSection) Equal ¶
func (n *NodeSection) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeSection) Hash ¶
func (n *NodeSection) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeSection) NodeType ¶
func (n *NodeSection) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeSection) Source ¶
func (n *NodeSection) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeSection) Span ¶
func (n *NodeSection) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeSection) Title ¶
func (n *NodeSection) Title() []byte
Title returns the header text as a byte slice.
func (*NodeSection) ToBuilder ¶
func (n *NodeSection) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeStrikethrough ¶
type NodeStrikethrough struct {
// contains filtered or unexported fields
}
NodeStrikethrough represents struck text (~~text~~).
func GetStrikethrough ¶
func GetStrikethrough() *NodeStrikethrough
GetStrikethrough retrieves a NodeStrikethrough from the pool.
func (*NodeStrikethrough) Children ¶
func (n *NodeStrikethrough) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeStrikethrough) Equal ¶
func (n *NodeStrikethrough) Equal( other Node, ) bool
Equal performs deep structural comparison with another node.
func (*NodeStrikethrough) Hash ¶
func (n *NodeStrikethrough) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeStrikethrough) NodeType ¶
func (n *NodeStrikethrough) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeStrikethrough) Source ¶
func (n *NodeStrikethrough) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeStrikethrough) Span ¶
func (n *NodeStrikethrough) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeStrikethrough) ToBuilder ¶
func (n *NodeStrikethrough) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeStrong ¶
type NodeStrong struct {
// contains filtered or unexported fields
}
NodeStrong represents bold/strong emphasis (**text** or __text__).
func (*NodeStrong) Children ¶
func (n *NodeStrong) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeStrong) Equal ¶
func (n *NodeStrong) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeStrong) Hash ¶
func (n *NodeStrong) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeStrong) NodeType ¶
func (n *NodeStrong) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeStrong) Source ¶
func (n *NodeStrong) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeStrong) Span ¶
func (n *NodeStrong) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeStrong) ToBuilder ¶
func (n *NodeStrong) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeText ¶
type NodeText struct {
// contains filtered or unexported fields
}
NodeText represents plain text content.
func (*NodeText) Children ¶
func (n *NodeText) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeText) Hash ¶
func (n *NodeText) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeText) NodeType ¶
func (n *NodeText) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeText) Source ¶
func (n *NodeText) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeText) Span ¶
func (n *NodeText) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeText) Text ¶
Text returns the text content as a string. This creates a copy; use Source() for zero-copy access.
func (*NodeText) ToBuilder ¶
func (n *NodeText) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NodeType ¶
type NodeType uint8
NodeType represents the type of an AST node. Each type corresponds to a different markdown construct.
const ( // NodeTypeDocument is the root node containing all top-level nodes. NodeTypeDocument NodeType = iota // NodeTypeSection represents an H2+ header and its content. NodeTypeSection // NodeTypeRequirement represents a ### Requirement: header. NodeTypeRequirement // NodeTypeScenario represents a #### Scenario: header. NodeTypeScenario // NodeTypeParagraph represents paragraph content. NodeTypeParagraph // NodeTypeList represents an unordered or ordered list. NodeTypeList // NodeTypeListItem represents a single list item. NodeTypeListItem // NodeTypeCodeBlock represents a fenced code block. NodeTypeCodeBlock // NodeTypeBlockquote represents blockquoted content. NodeTypeBlockquote // NodeTypeText represents plain text content. NodeTypeText // NodeTypeStrong represents bold/strong emphasis (**text** or __text__). NodeTypeStrong // NodeTypeEmphasis represents italic emphasis (*text* or _text_). NodeTypeEmphasis // NodeTypeStrikethrough represents struck text (~~text~~). NodeTypeStrikethrough // NodeTypeCode represents inline code (`code`). NodeTypeCode // NodeTypeLink represents a link [text](url) or [text][ref]. NodeTypeLink // NodeTypeLinkDef represents a link definition [ref]: url. NodeTypeLinkDef // NodeTypeWikilink represents a wikilink [[target|display#anchor]]. NodeTypeWikilink )
type NodeTypeStats ¶
NodeTypeStats contains get/put counts for a specific node type.
func GetNodeStats ¶
func GetNodeStats() []NodeTypeStats
GetNodeStats returns statistics for all node types.
type NodeWikilink ¶
type NodeWikilink struct {
// contains filtered or unexported fields
}
NodeWikilink represents a wikilink [[target|display#anchor]].
func GetWikilink ¶
func GetWikilink() *NodeWikilink
GetWikilink retrieves a NodeWikilink from the pool.
func (*NodeWikilink) Anchor ¶
func (n *NodeWikilink) Anchor() []byte
Anchor returns the optional anchor as a byte slice. Returns nil if no anchor was specified.
func (*NodeWikilink) Children ¶
func (n *NodeWikilink) Children() []Node
Children returns an immutable copy of child nodes.
func (*NodeWikilink) Display ¶
func (n *NodeWikilink) Display() []byte
Display returns the optional display text as a byte slice. Returns nil if no display text was specified (defaults to target).
func (*NodeWikilink) Equal ¶
func (n *NodeWikilink) Equal(other Node) bool
Equal performs deep structural comparison with another node.
func (*NodeWikilink) Hash ¶
func (n *NodeWikilink) Hash() uint64
Hash returns the content hash for identity tracking and caching.
func (*NodeWikilink) NodeType ¶
func (n *NodeWikilink) NodeType() NodeType
NodeType returns the type classification of this node.
func (*NodeWikilink) Source ¶
func (n *NodeWikilink) Source() []byte
Source returns a zero-copy byte slice view into the original source.
func (*NodeWikilink) Span ¶
func (n *NodeWikilink) Span() (start, end int)
Span returns the byte offset range (start, end) of this node.
func (*NodeWikilink) Target ¶
func (n *NodeWikilink) Target() []byte
Target returns the link target as a byte slice.
func (*NodeWikilink) ToBuilder ¶
func (n *NodeWikilink) ToBuilder() *NodeBuilder
ToBuilder creates a builder pre-populated with this node's data.
type NumberedTaskMatch ¶
type NumberedTaskMatch struct {
Section string // The section number (e.g., "1")
Number string // The task number (e.g., "1.1")
Status rune // ' ' for unchecked, 'x' or 'X' for checked
Content string // The task description
}
NumberedTaskMatch holds the parsed result of a numbered task line.
func MatchNumberedTask ¶
func MatchNumberedTask( line string, ) (*NumberedTaskMatch, bool)
MatchNumberedTask parses a numbered task line from tasks.md format. Format: "- [ ] 1.1 Task description" or "- [x] 2.3 Another task" Also accepts simpler format: "- [ ] 1. Task description" (no digits after dot) Returns the parsed task match and true if matched, or nil and false.
Example:
match, ok := MatchNumberedTask("- [ ] 1.1 Create the parser")
// match.Number = "1.1", match.Status = ' ', match.Content = "Create the parser"
match, ok := MatchNumberedTask("- [ ] 1. Simple task")
// match.Number = "1.", match.Status = ' ', match.Content = "Simple task"
type ParseError ¶
type ParseError struct {
Offset int // Byte offset where error occurred
Message string // Human-readable error description
Expected []TokenType // What tokens would have been valid (may be nil)
}
ParseError represents an error encountered during parsing. It contains the byte offset where the error occurred, a human-readable message, and optionally a list of expected token types.
func (ParseError) Position ¶
func (e ParseError) Position( idx *LineIndex, ) Position
Position converts the byte offset to a Position using the provided LineIndex.
type PoolStats ¶
PoolStats contains statistics about pool usage. All fields are accessed atomically when stats are enabled.
func GetPoolStats ¶
func GetPoolStats() PoolStats
GetPoolStats returns current pool statistics. Statistics are only collected when enabled via EnablePoolStats.
type Position ¶
type Position struct {
Line int // 1-based line number
Column int // 0-based byte offset within line
Offset int // Original byte offset in source
}
Position represents a location in the source as line/column coordinates. Line numbers are 1-based (line 1 is the first line). Column numbers are 0-based byte offsets from the start of the line.
type PositionIndex ¶
type PositionIndex struct {
// contains filtered or unexported fields
}
PositionIndex provides efficient O(log n) queries for finding AST nodes at a given source position. It uses a sorted interval structure internally and is built lazily on the first query.
The index becomes stale when the AST is modified. Use Rebuild() to update the index with a new AST root, or create a new index.
func NewPositionIndex ¶
func NewPositionIndex( root Node, source []byte, ) *PositionIndex
NewPositionIndex creates a new PositionIndex for the given AST root. The index is built lazily on the first query. If root is nil, the index will be empty and queries return nil/empty.
func (*PositionIndex) EnclosingRequirement ¶
func (pi *PositionIndex) EnclosingRequirement( offset int, ) *NodeRequirement
EnclosingRequirement returns the NodeRequirement containing the given offset. Returns nil if the offset is not within any requirement.
This finds the innermost requirement if requirements are nested.
func (*PositionIndex) EnclosingScenario ¶
func (pi *PositionIndex) EnclosingScenario( offset int, ) *NodeScenario
EnclosingScenario returns the NodeScenario containing the given offset. Returns nil if the offset is not within any scenario.
func (*PositionIndex) EnclosingSection ¶
func (pi *PositionIndex) EnclosingSection( offset int, ) *NodeSection
EnclosingSection returns the NodeSection containing the given offset. Returns nil if the offset is not within any section.
This finds the innermost section if sections are nested.
func (*PositionIndex) IsStale ¶
func (pi *PositionIndex) IsStale( root Node, ) bool
IsStale returns true if the index may be stale due to AST modifications. This checks if the root node's hash has changed since the index was created.
func (*PositionIndex) LineIndex ¶
func (pi *PositionIndex) LineIndex() *LineIndex
LineIndex returns the integrated LineIndex for line/column calculations. Returns nil if no source was provided.
func (*PositionIndex) NodeAt ¶
func (pi *PositionIndex) NodeAt( offset int, ) Node
NodeAt returns the innermost (most specific) node at the given offset. Returns nil if the offset is outside all nodes or if the AST is empty.
Query time is O(log n + k) where k is the number of nodes at that position.
func (*PositionIndex) NodeCount ¶
func (pi *PositionIndex) NodeCount() int
NodeCount returns the total number of nodes in the index. This triggers index building if not already built.
func (*PositionIndex) NodePosition ¶
func (pi *PositionIndex) NodePosition( node Node, ) Position
NodePosition returns the Position for the start of the given node. This is a convenience method equivalent to PositionAt(node.Start()).
func (*PositionIndex) NodesAt ¶
func (pi *PositionIndex) NodesAt( offset int, ) []Node
NodesAt returns all nodes containing the given offset, ordered from outermost (root/document) to innermost (leaf/text). Returns an empty slice if the offset is outside all nodes.
Query time is O(log n + k) where k is the number of matching nodes.
func (*PositionIndex) NodesInRange ¶
func (pi *PositionIndex) NodesInRange( start, end int, ) []Node
NodesInRange returns all nodes overlapping the given [start, end) range. A node overlaps if any part of its range intersects with [start, end).
The result includes nodes that: - Fully contain the range - Are fully contained within the range - Partially overlap the range
Query time is O(log n + k) where k is the number of overlapping nodes.
func (*PositionIndex) PositionAt ¶
func (pi *PositionIndex) PositionAt( offset int, ) Position
PositionAt returns the Position (line, column, offset) for the given byte offset. This uses the integrated LineIndex for efficient conversion.
If no source was provided, returns a Position with just the offset.
func (*PositionIndex) Rebuild ¶
func (pi *PositionIndex) Rebuild( root Node, source []byte, )
Rebuild discards the current index and rebuilds it for the given root. This should be called when the AST has been modified.
func (*PositionIndex) Root ¶
func (pi *PositionIndex) Root() Node
Root returns the root node of the indexed AST.
type Predicate ¶
Predicate is a function type for node matching predicates.
func All ¶
All returns a predicate that is true when all preds are true. Uses short-circuit evaluation: stops on first false. Returns true for empty predicate list.
func And ¶
And returns a predicate that is true when both p1 AND p2 are true. Uses short-circuit evaluation: p2 is not called if p1 is false.
func Any ¶
Any returns a predicate that is true when any pred is true. Uses short-circuit evaluation: stops on first true. Returns false for empty predicate list.
func HasChild ¶
HasChild returns a predicate that is true if any direct child matches pred. Only immediate children are checked (not descendants).
func HasDescendant ¶
HasDescendant returns a predicate true if any descendant matches pred. All descendants are checked recursively.
func HasName ¶
HasName returns a predicate matching nodes with Name() == name. Works for NodeRequirement, NodeScenario, and any type implementing Named.
func InRange ¶
InRange returns a predicate matching nodes within [start, end). A node is in range if its span overlaps the given range. Overlap occurs when node.start < end AND node.end > start.
func IsType ¶
IsType returns a predicate that matches nodes of type T. Type checking uses Go type assertion.
type RenamedRequirement ¶
type RenamedRequirement struct {
// From is the original requirement name.
From string
// To is the new requirement name.
To string
// Node is the AST node if parsed from a requirement header.
// May be nil if parsed from a list item.
Node *NodeRequirement
}
RenamedRequirement represents a requirement rename operation. It contains the old name and the new name of the requirement.
type Requirement ¶
type Requirement struct {
// Name is the requirement name (text after "Requirement:").
Name string
// Section is the name of the parent section containing this requirement.
Section string
// Scenarios contains all scenarios within this requirement.
Scenarios []*Scenario
// Node is the underlying AST node for this requirement.
Node *NodeRequirement
}
Requirement represents a parsed requirement.
func ExtractRequirements ¶
func ExtractRequirements( content []byte, ) []*Requirement
ExtractRequirements parses content and returns all requirements.
func FindRequirement ¶
func FindRequirement( content []byte, name string, ) (*Requirement, bool)
FindRequirement finds a requirement by name (case-insensitive). Returns the requirement and true if found, nil and false otherwise.
type Scenario ¶
type Scenario struct {
// Name is the scenario name (text after "Scenario:").
Name string
// Node is the underlying AST node for this scenario.
Node *NodeScenario
}
Scenario represents a parsed scenario.
type Section ¶
type Section struct {
// Name is the section title text.
Name string
// Level is the header level (1-6).
Level int
// Start is the byte offset where the section starts.
Start int
// End is the byte offset where the section ends.
End int
// Content is the raw source content of the section.
Content []byte
// Node is the underlying AST node for this section.
Node *NodeSection
}
Section represents a document section (header and its content).
type Spec ¶
type Spec struct {
// Root is the document node containing the entire AST.
Root Node
// Sections contains all sections indexed by their name (case-preserved).
// Use FindSection for case-insensitive lookup.
Sections map[string]*Section
// Requirements contains all requirements found in the document.
Requirements []*Requirement
// Errors contains all parse errors encountered during parsing.
Errors []ParseError
}
Spec represents a fully parsed specification file. It provides convenient access to sections, requirements, and parse errors.
type Token ¶
type Token struct {
// Type identifies the lexical category of this token.
Type TokenType
// Start is the byte offset from the beginning of the source.
Start int
// End is the byte offset past the last byte of this token (exclusive).
// The token's content spans source[Start:End].
End int
// Source is a zero-copy slice view into the original source text.
// It remains valid as long as the original source is retained.
// For most tokens, this contains the token's text content.
Source []byte
// Message contains an error description for TokenError tokens.
// For all other token types, this field is empty.
Message string
}
Token represents a single lexical unit from the source text. It has position info and a zero-copy view into the original source.
func GetToken ¶
func GetToken() *Token
GetToken retrieves a Token from the pool. The returned token's fields are zeroed and ready for use.
func (Token) IsDelimiter ¶
IsDelimiter returns true if the token is a punctuation delimiter.
func (Token) IsStructural ¶
IsStructural returns true if the token is structural (EOF, newline, etc).
type TokenType ¶
type TokenType uint8
TokenType represents the type of a lexical token. Each delimiter character has its own type for fine-grained tokenization, enabling maximum flexibility for error recovery and precise error messages.
const ( // TokenEOF signals end of input. Start == End == len(source). TokenEOF TokenType = iota // TokenNewline represents a line ending (\n or \r\n normalized). TokenNewline // TokenWhitespace represents contiguous ASCII spaces or tabs. TokenWhitespace // TokenText represents plain text content (not a delimiter). TokenText // TokenError represents invalid input with an error message. TokenError // TokenHash represents a single '#' character. TokenHash // TokenAsterisk represents a single '*' character. TokenAsterisk // TokenUnderscore represents a single '_' character. TokenUnderscore // TokenTilde represents a single '~' character. TokenTilde // TokenBacktick represents a single '`' character. TokenBacktick // TokenDash represents a single '-' character. TokenDash // TokenPlus represents a single '+' character. TokenPlus // TokenDot represents a single '.' character. TokenDot // TokenColon represents a single ':' character. TokenColon // TokenPipe represents a single '|' character. TokenPipe // TokenBracketOpen represents a '[' character. TokenBracketOpen // TokenBracketClose represents a ']' character. TokenBracketClose // TokenParenOpen represents a '(' character. TokenParenOpen // TokenParenClose represents a ')' character. TokenParenClose // TokenGreaterThan represents a '>' character. TokenGreaterThan // TokenNumber represents a sequence of digits (for ordered lists). TokenNumber // TokenX represents 'x' or 'X' in checkbox syntax. TokenX )
type TransformAction ¶
type TransformAction uint8
TransformAction signals the intended action for a node during transformation. It is returned by TransformVisitor methods to indicate whether to keep, replace, or delete the visited node.
const ( // ActionKeep indicates the node should remain unchanged. // The returned Node value is ignored when this action is specified. ActionKeep TransformAction = iota // ActionReplace indicates the node should be replaced with the returned Node. // The returned Node will take the place of the original in the parent's children. ActionReplace // ActionDelete indicates the node should be removed from its parent's children. // The returned Node value is ignored when this action is specified. ActionDelete )
func (TransformAction) String ¶
func (a TransformAction) String() string
String returns a human-readable name for the transform action.
type TransformVisitor ¶
type TransformVisitor interface {
TransformDocument(
*NodeDocument,
) (Node, TransformAction, error)
TransformSection(
*NodeSection,
) (Node, TransformAction, error)
TransformRequirement(
*NodeRequirement,
) (Node, TransformAction, error)
TransformScenario(
*NodeScenario,
) (Node, TransformAction, error)
TransformParagraph(
*NodeParagraph,
) (Node, TransformAction, error)
TransformList(
*NodeList,
) (Node, TransformAction, error)
TransformListItem(
*NodeListItem,
) (Node, TransformAction, error)
TransformCodeBlock(
*NodeCodeBlock,
) (Node, TransformAction, error)
TransformBlockquote(
*NodeBlockquote,
) (Node, TransformAction, error)
TransformText(
*NodeText,
) (Node, TransformAction, error)
TransformStrong(
*NodeStrong,
) (Node, TransformAction, error)
TransformEmphasis(
*NodeEmphasis,
) (Node, TransformAction, error)
TransformStrikethrough(
*NodeStrikethrough,
) (Node, TransformAction, error)
TransformCode(
*NodeCode,
) (Node, TransformAction, error)
TransformLink(
*NodeLink,
) (Node, TransformAction, error)
TransformLinkDef(
*NodeLinkDef,
) (Node, TransformAction, error)
TransformWikilink(
*NodeWikilink,
) (Node, TransformAction, error)
}
TransformVisitor defines the interface for AST transformation via the visitor pattern. Each method receives a typed node and returns (replacement, action, error).
The Transform function uses post-order traversal, so children are transformed before their parent. This allows parent transform methods to see the results of child transformations.
When ActionKeep is returned, the replacement Node is ignored and the original is kept. When ActionReplace is returned, the replacement Node takes the place of the original. When ActionDelete is returned, the node is removed from its parent's children.
func AddScenario ¶
func AddScenario( reqName string, scenario *NodeScenario, ) TransformVisitor
AddScenario creates a TransformVisitor that adds a scenario to the requirement matching reqName. The scenario is appended to the requirement's children. Other nodes pass through unchanged.
func Compose ¶
func Compose( t1, t2 TransformVisitor, ) TransformVisitor
Compose creates a TransformVisitor that applies t1 first, then t2. The result of t1 is passed to t2, allowing sequential transformations.
func Filter ¶
func Filter( pred func(Node) bool, ) TransformVisitor
Filter creates a TransformVisitor that deletes nodes where the predicate returns false. Nodes matching the predicate (returns true) are kept.
func Map ¶
func Map(f func(Node) Node) TransformVisitor
Map creates a TransformVisitor that applies the given function to every node. If f returns the same node (by pointer equality), it is treated as ActionKeep. Otherwise, it is treated as ActionReplace with the returned node.
func Pipeline ¶
func Pipeline( transforms ...TransformVisitor, ) TransformVisitor
Pipeline creates a TransformVisitor that applies all transforms in order. This is a convenience wrapper around multiple Compose calls.
func RemoveRequirement ¶
func RemoveRequirement( name string, ) TransformVisitor
RemoveRequirement creates a TransformVisitor that deletes requirements matching the given name. The action is ActionDelete for matching requirements. Other nodes pass through unchanged.
func RenameRequirement ¶
func RenameRequirement( oldName, newName string, ) TransformVisitor
RenameRequirement creates a TransformVisitor that renames requirements matching oldName to newName. Only requirements with Name() == oldName are affected; other nodes pass through unchanged.
func When ¶
func When( pred func(Node) bool, transform TransformVisitor, ) TransformVisitor
When creates a conditional TransformVisitor that only applies the given transform when the predicate returns true. Nodes not matching the predicate pass through unchanged (ActionKeep).
type Visitor ¶
type Visitor interface {
VisitDocument(*NodeDocument) error
VisitSection(*NodeSection) error
VisitRequirement(*NodeRequirement) error
VisitScenario(*NodeScenario) error
VisitParagraph(*NodeParagraph) error
VisitList(*NodeList) error
VisitListItem(*NodeListItem) error
VisitCodeBlock(*NodeCodeBlock) error
VisitBlockquote(*NodeBlockquote) error
VisitText(*NodeText) error
VisitStrong(*NodeStrong) error
VisitEmphasis(*NodeEmphasis) error
VisitStrikethrough(*NodeStrikethrough) error
VisitCode(*NodeCode) error
VisitLink(*NodeLink) error
VisitLinkDef(*NodeLinkDef) error
VisitWikilink(*NodeWikilink) error
}
Visitor defines the interface for AST node visitors. Each method receives a typed node and returns an error to control traversal. Return nil to continue traversal, SkipChildren to skip children, or any other error to stop traversal immediately.
type VisitorContext ¶
type VisitorContext struct {
// contains filtered or unexported fields
}
VisitorContext provides context information during traversal, including access to the parent node and current depth.
func (*VisitorContext) Depth ¶
func (c *VisitorContext) Depth() int
Depth returns the current depth in the tree. The root node has depth 0.
func (*VisitorContext) Parent ¶
func (c *VisitorContext) Parent() Node
Parent returns the parent node of the current node being visited. Returns nil for the root node.
type Wikilink ¶
type Wikilink struct {
// Target is the link target (e.g., "validation" or "changes/my-change").
Target string
// Display is the optional display text (empty if not specified).
Display string
// Anchor is the optional anchor/fragment (empty if not specified).
Anchor string
// Start is the byte offset where the wikilink starts.
Start int
// End is the byte offset where the wikilink ends.
End int
// Node is the underlying AST node for this wikilink.
Node *NodeWikilink
}
Wikilink represents an extracted wikilink with parsed components.
func ExtractWikilinks ¶
ExtractWikilinks parses content and returns all wikilinks found. Uses a visitor to traverse the AST and collect all NodeWikilink nodes.
type WikilinkError ¶
type WikilinkError struct {
// Target is the wikilink target that failed to resolve.
Target string
// Display is the optional display text of the wikilink.
Display string
// Anchor is the optional anchor/fragment of the wikilink.
Anchor string
// Offset is the byte offset where the wikilink starts in the source.
Offset int
// Message describes why the wikilink is invalid.
Message string
}
WikilinkError represents an error found during wikilink validation. It contains details about the broken wikilink and where it was found.
func ValidateWikilinks ¶
func ValidateWikilinks( root Node, _ []byte, projectRoot string, ) []WikilinkError
ValidateWikilinks checks all wikilinks in a parsed document and returns errors for any that cannot be resolved or have invalid anchors.
Parameters:
- root: the root node of the parsed document
- source: the original source bytes (reserved for future use)
- projectRoot: the project root directory containing spectr/
Returns a slice of WikilinkError for each invalid wikilink found.
func (WikilinkError) Error ¶
func (e WikilinkError) Error() string
Error implements the error interface.