sequence

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 5, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package sequence reads the declared structure of a study path: which rows a course lists, which branch each row belongs to, what role the author gave that branch, and what could not be determined. It is the one place that answers those questions, so navigation and the judge read one interpretation rather than scanning the Markdown twice and disagreeing silently.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HeadingName

func HeadingName(line string, level int) string

HeadingName is what a heading is called once the role it declares comes off: the words before the marker when the line declares a role, and the line exactly as it was written when it does not. A branch is a heading from level 2 to 6, so a marker on a level-1 heading declares nothing and stays part of the name — the author is told about that one, and a report quoting words the page does not show cannot be acted on.

A declaration that is the whole heading stays as well: with it off the heading has no words at all, so a reader would meet a blank row in the contents and could address the section only by the name every nameless heading shares. The course lists such a branch unnamed, having no name to list, while the page shows the line the author typed.

The line may be a heading's markdown source or the inner markup its rendered form carries, because a role is read only as the last thing on its line: a marker the author quoted in code keeps a closing backtick or a closing tag after it in either form, so it stays the text about the grammar that it is. Reading a name is all this does; whether the heading stands where a course could open a branch is the caller's question.

func Marker

func Marker(role Role) string

Marker is the declaration an author writes to give a branch a role, spelled from the same three values a declaration is read with, so a page teaching the grammar cannot drift from the parser that accepts it. Only a role a line can declare has a marker: the two a branch is left with when it declared nothing return the empty string, since no line can say them.

Types

type Candidate

type Candidate struct {
	Text   string
	Target string
	Line   int
	Span   Span
	// TargetSpan is where Target is written: the bytes of that one wikilink. A
	// row can carry others, so a consumer matching a link it read itself back
	// to this entry joins on these bytes. It is zero exactly when Target is empty.
	TargetSpan Span
	State      EntryState
}

Candidate is one source row the grammar recognizes: a list item carrying a live wikilink in its own target scope. Target is the row's single live target and is empty for a multi-target row; Text is what the author wrote to be read; Line is 1-based in the file; Span is the row's own first text block.

func (*Candidate) Accepted

func (c *Candidate) Accepted() bool

Accepted reports whether this row passed canonical validation. Every other state still makes the row a row for the purpose of its branch's state.

type Diagnostic

type Diagnostic struct {
	Rule     Rule
	Line     int
	Message  string
	Evidence string
}

Diagnostic is one thing the author has to decide, addressed to the author. Rule is the stable identifier; Line is 1-based in the file.

type Document

type Document struct {
	Groups      []*Group
	Diagnostics []Diagnostic
}

Document is a study path's whole interpretation: its branches in document order, and everything that could not be determined.

func Parse

func Parse(body string, bodyStartLine int) Document

Parse reads one study path body into its declared structure. bodyStartLine is the file line the body begins on, so a note with frontmatter reports the lines an editor shows.

type EntryState

type EntryState uint8

EntryState is what canonical validation decided about one candidate. Only EntryAccepted may become a lesson; every other state keeps the row a row.

const (
	// EntryUnread is the state of a row nobody has judged. Parse never returns
	// it, so acceptance is something a row is given rather than something a
	// half-built one already holds.
	EntryUnread EntryState = iota
	// EntryAccepted is a canonical row: its single live link is the first
	// visible inline, so the row is the lesson it names.
	EntryAccepted
	// EntryNoncanonical is a row whose single live link comes after something
	// else — a label, an embed, a same-file anchor, inline code.
	EntryNoncanonical
	// EntryMultiTarget is a row whose target scope names more than one note.
	// Choosing the first would be a guess.
	EntryMultiTarget
	// EntryRoleOnEntry is a row that is both a lesson and a branch container.
	// Neither projects until the author splits them apart.
	EntryRoleOnEntry
)

func (EntryState) String

func (s EntryState) String() string

String names an entry state for a diagnostic or a consumer's log line.

type Group

type Group struct {
	Name string
	// Level is the heading level, 2 through 6. A container group has level 0:
	// its place comes from the list it sits in, not from a heading rank.
	Level int
	Line  int
	Role  Role
	// Container is true for a group opened by a nested list item rather than a
	// heading. Its rows belong to it alone, not to the entry it hangs from.
	Container bool
	// AnchorTarget names the entry a container hangs from, empty for a heading
	// group. It is the resolution target of the enclosing list row.
	AnchorTarget string
	// AnchorSpan is the enclosing candidate's Span, still unique when two rows
	// name the same note. Zero for a heading group and for an orphan.
	AnchorSpan Span
	// Invalid marks a branch carrying a structural error the author has to
	// resolve. It keeps its rows and its diagnostics, nothing projects from it,
	// and a consumer reads this field rather than re-deriving the verdict.
	Invalid bool
	// Items hold everything this branch lists, in source order. A consumer
	// never reconstructs this order from targets, lines or parallel slices.
	Items []Item
}

Group is one branch of a study path: a heading, or a nested list container the author marked with a role. Name is the author's text with a recognized marker removed; the source bytes are untouched.

func (*Group) Carries

func (g *Group) Carries() bool

Carries reports whether a walk may descend through this branch to reach the course beneath it. A branch that merely groups others never projects but the parts under it do; one carrying a structural error stops the walk, because what sits under an error is not known to belong to the course.

func (*Group) Projectable

func (g *Group) Projectable() bool

Projectable reports whether navigation may read this branch's accepted entries: a declared primary or local branch free of structural error. It is the one verdict, so no consumer reads the diagnostics its own way.

type Item

type Item struct {
	Entry  *Candidate
	Branch *Group
}

Item is one thing a branch holds in source order: a row it lists, or a branch opened beneath it. Exactly one field is set.

type Role

type Role uint8

Role is a branch's declared part in the course order.

const (
	// RoleStructural is a branch that lists no rows of its own but groups
	// other branches. Declaring nothing on it is correct.
	RoleStructural Role = iota
	// RoleUnclassified is a branch that lists rows but was never given a role.
	// It is the one state the author has to resolve; nothing projects from it.
	RoleUnclassified
	// RolePrimary is the course's main line. Consecutive primary groups join
	// end to end in declared order.
	RolePrimary
	// RoleLocal is a side branch: its own order, its own count, hanging from
	// the entry it is nested under and never rejoining the main line.
	RoleLocal
	// RoleNone is an authored answer, not an omission: prose that reads
	// normally and stays out of the course entirely.
	RoleNone
)

func (Role) Declared

func (r Role) Declared() bool

Declared reports whether the author wrote this role, as opposed to it being what remained once nothing was written.

func (Role) String

func (r Role) String() string

String names a role for a diagnostic message, and for the page that shows a reader the value to type. The three a line can declare answer with the parser's own values rather than a second copy of them, so the words shown and the words accepted cannot come apart. The two left over are named only for a message: no line can declare them, so no reader will ever type one.

type Rule

type Rule string

Rule is the stable identifier of one thing this grammar reports. The set is closed and Rules is all of it, so a consumer that must cover every rule asks for the set rather than keeping a list that can fall behind.

const (
	RuleRoleMissing        Rule = "path.role_missing"
	RuleRoleDuplicate      Rule = "path.role_duplicate"
	RuleRoleConflict       Rule = "path.role_conflict"
	RuleLocalOrphan        Rule = "path.local_orphan"
	RuleNestingTooDeep     Rule = "path.nesting_too_deep"
	RuleRoleOnEntry        Rule = "path.role_on_entry"
	RuleRoleInvalid        Rule = "path.role_invalid"
	RuleRoleMisplaced      Rule = "path.role_misplaced"
	RuleEntryOutsideBranch Rule = "path.entry_outside_branch"
	RuleEntryMultiTarget   Rule = "path.entry_multi_target"
	RuleEntryNoncanonical  Rule = "path.entry_noncanonical"
)

The rules this grammar reports. Every one names a decision only the author can make: yomihon reports, and a human edits the file.

func Rules

func Rules() []Rule

Rules are every rule this grammar can report, in declaration order — the order consumers already list them in. A rule added beside the constants above reaches every consumer from here. The caller owns the returned slice.

type Span

type Span struct{ Start, Stop int }

Span is a half-open byte range into the body a document was parsed from, always counted from the body's first byte. It is a row's stable identity: two rows naming the same note still differ by where they sit in the source.

func (Span) Zero

func (s Span) Zero() bool

Zero reports whether this span identifies nothing — a heading group's anchor, or an orphan's.

Jump to

Keyboard shortcuts

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