lesson

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: 12 Imported by: 0

Documentation

Overview

Package lesson loads the hand-authored data that enriches lesson reading pages: Japanese slot-machine sentence patterns from System/slots/*.yaml and the cross-domain concept-note index used by in-page sheets. Everything here is read-only, and the sidecar's shape is yomihon's own vocabulary rather than the note frontmatter contract vault-schema.toml governs.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AbstractTemplate

func AbstractTemplate(tmpl string) string

AbstractTemplate renders the template with each {Key} shown as its bare key, e.g. "{A}は {B}です" -> "Aは Bです" — the card's heading label.

func GlossInitial

func GlossInitial(p Pattern) string

GlossInitial renders the gloss with each {Key} replaced by its first fill's Chinese, the default the page shows before any interaction. Only template keys are substituted, so this default and PatternJSON agree.

func IsSlotSidecar

func IsSlotSidecar(relPath string) bool

IsSlotSidecar reports whether relPath names a direct YAML child of System/slots. Generation scanners use it to capture exactly those bytes.

func NewSlotIndex

func NewSlotIndex(files map[string][]byte) (SlotIndex, []Problem)

NewSlotIndex parses the captured *.yaml children of System/slots and keys them by the slug each declares, retaining neither the map nor its bytes. A malformed sidecar, or two files claiming one slug, is a reported problem.

func PatternJSON

func PatternJSON(p Pattern) string

PatternJSON serialises a pattern into the slot-data blob. json.Marshal escapes < > &, so the blob cannot break out of its <script> element even if a fill holds markup — the sole reason this is not string assembly.

func TemplateKeys

func TemplateKeys(tmpl string) []string

TemplateKeys returns the slot keys in first-appearance order, deduplicated.

Types

type ConceptDoc

type ConceptDoc struct {
	ID    string
	Title string
	HTML  string
}

ConceptDoc is one concept note rendered for the sheet: its stable ID (the <template> id), a human title, and the body HTML.

type ConceptIndex

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

ConceptIndex is the immutable lookup from a vault-relative concept-note path to its stable sheet ID and captured content — the shape a rendered wikilink href decodes to. The zero value is an empty index.

func NewConceptIndex

func NewConceptIndex(notes []*vault.Note) (ConceptIndex, error)

NewConceptIndex indexes parsed concept notes captured by one vault generation, copying only each concept's path, title and body. A vault with no concept notes yields an empty index.

func (ConceptIndex) Document

func (x ConceptIndex) Document(renderBody func(relPath, body string) string, relPath string) (ConceptDoc, bool)

Document renders one captured concept into a sheet document. renderBody receives the concept's own path along with its body, because the sheet opens over a different note and a body rendered against the reader's location would address the wrong files. A nil renderBody is a wiring fault and panics.

func (ConceptIndex) IDForPath

func (x ConceptIndex) IDForPath(relPath string) (string, bool)

IDForPath reports the sheet ID for a vault-relative path, and whether it names a concept note.

func (ConceptIndex) Len

func (x ConceptIndex) Len() int

Len reports the number of indexed concept notes.

type Fill

type Fill struct {
	JP      string `yaml:"jp" json:"jp"`
	Reading string `yaml:"reading" json:"reading"`
	ZH      string `yaml:"zh" json:"zh"`
}

Fill is one selectable value for a slot: the Japanese surface form, its kana reading (copied verbatim from the lesson's ruby), and the Chinese gloss.

func FirstFill

func FirstFill(p Position) Fill

FirstFill returns a slot's first candidate — the server-rendered default — or the zero Fill when the slot has none.

type Pattern

type Pattern struct {
	ID       string              `yaml:"id"`
	Template string              `yaml:"template"` // {Key} placeholders
	GlossZH  string              `yaml:"gloss_zh"`
	Note     string              `yaml:"note"`
	Slots    map[string]Position `yaml:"slots"`
}

Pattern is one sentence frame, e.g. "{A}は {B}です", with the fills that may drop into each of its {Key} positions.

type Position

type Position struct {
	LabelZH string `yaml:"label_zh"`
	Color   string `yaml:"color"` // one of slotColors, or empty for a neutral (uncoloured) slot
	Fills   []Fill `yaml:"fills"`
}

Position is one replaceable slot in a pattern template, keyed by its placeholder name. It carries only yaml tags; PatternJSON assembles the compact JSON the slot machine consumes.

type Problem

type Problem struct {
	Source  string
	Message string
}

Problem is one sidecar yomihon could not use, and why. yomihon reports and a human edits the file; nothing here repairs anything.

type Segment

type Segment struct {
	Text string
	Key  string
}

Segment is one piece of a parsed template: literal text (Key == "") or a slot reference (Key == the slot name).

func ParseTemplate

func ParseTemplate(tmpl string) []Segment

ParseTemplate splits a template like "{A}は {B}です" into ordered segments: [{Key:"A"}, {Text:"は "}, {Key:"B"}, {Text:"です"}].

type Sidecar

type Sidecar struct {
	Lesson string `yaml:"lesson"`
	Slug   string `yaml:"slug"`
	Title  string `yaml:"title"`
	// Note is what this drill does not cover, in the author's own words — a
	// rule holding across the lesson has nowhere to go among the patterns.
	Note     string    `yaml:"note"`
	Patterns []Pattern `yaml:"patterns"`
}

Sidecar is the slot-machine data for one lesson. It joins to a lesson note by Slug, never by filename: the note's slug and this file's Slug field match, while their filenames deliberately do not.

func (*Sidecar) Validate

func (s *Sidecar) Validate() []string

Validate reports every contract problem in the sidecar, one message per problem; an empty result means valid. It reports only and never repairs: a human edits the file.

type SlotIndex

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

SlotIndex is the immutable lookup from a lesson slug to its parsed slot sidecar. The key is the slug declared inside each file, never the filename: the two are deliberately unrelated. Its zero value is an empty index.

func (SlotIndex) Len

func (x SlotIndex) Len() int

Len reports the number of indexed sidecars.

func (SlotIndex) Lookup

func (x SlotIndex) Lookup(slug string) (*Sidecar, bool)

Lookup returns an independent copy of the slot sidecar for a lesson slug, and whether one exists. A lesson with no sidecar is normal. The copy is deep, so a caller cannot mutate the index or race a reader through the value.

Jump to

Keyboard shortcuts

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