Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33

Open
lilleman wants to merge 966 commits from worktree-todo-relative-dates-exact-counts into main
3 changed files with 19 additions and 24 deletions
Showing only changes of commit 01a60d06f1 - Show all commits
+8 -15
View File
@@ -200,14 +200,10 @@ func inlineScope(n node, label string) nodeScope {
// NewTemplate and FakeStruct share; its fields are where they differ. // NewTemplate and FakeStruct share; its fields are where they differ.
type binding struct { type binding struct {
scope nodeScope scope nodeScope
// link binds the references: a loaded tree's relative to each category's folder, an link func() error
// inline node's from the root alone. // A loaded tree's cycle fence; an inline node's refusal of a drawGroup at its root.
link func() error referenceFence func() error
// noCycles refuses a reference cycle, which only a loaded tree can close: nothing // checkField proves a struct's columns instead.
// references an inline node.
noCycles func() error
// typedByGo marks a struct's columns, whose datatypes its Go types set and checkField
// proves, so checkColumns skips them.
typedByGo bool typedByGo bool
} }
@@ -221,7 +217,7 @@ func treeBinding(root map[string]node) binding {
} }
return linkRefs(root) return linkRefs(root)
}, },
noCycles: func() error { return checkNoCycles(root) }, referenceFence: func() error { return checkNoCycles(root) },
} }
} }
@@ -229,10 +225,8 @@ func (b binding) bind() error {
if err := b.link(); err != nil { if err := b.link(); err != nil {
return err return err
} }
if b.noCycles != nil { if err := b.referenceFence(); err != nil {
if err := b.noCycles(); err != nil { return err
return err
}
} }
if !b.typedByGo { if !b.typedByGo {
if err := checkColumns(b.scope); err != nil { if err := checkColumns(b.scope); err != nil {
@@ -244,8 +238,7 @@ func (b binding) bind() error {
// checkRenders runs the per-node fences over a scope, each over the whole scope // checkRenders runs the per-node fences over a scope, each over the whole scope
// before the next, so which of several broken nodes is reported does not depend on // before the next, so which of several broken nodes is reported does not depend on
// the walk. Its walks terminate only where nothing renders itself, so run it over a // the walk. Its walks terminate only where nothing renders itself.
// loaded tree after checkNoCycles.
func checkRenders(s nodeScope) error { func checkRenders(s nodeScope) error {
mem := renderCounts{} mem := renderCounts{}
if err := s(func(path string, n node) error { return repeatCheck(path, n, mem) }); err != nil { if err := s(func(path string, n node) error { return repeatCheck(path, n, mem) }); err != nil {
+2 -1
View File
@@ -58,7 +58,8 @@ tags and any other caller read one.
`New` proves the loaded tree acyclic, an inline node is a finite tree of its own, and `New` proves the loaded tree acyclic, an inline node is a finite tree of its own, and
nothing in the tree can reference it, so no render of it reaches itself. Every other nothing in the tree can reference it, so no render of it reaches itself. Every other
fence runs over both, from one `binding.bind`, except that struct tags leave column fence runs over both, from one `binding.bind`, except that struct tags leave column
agreement to their Go types. agreement to their Go types, and an inline node refuses a `drawGroup` at its root,
which nothing can name.
## An inline template that does not compile is misuse (exit 2), including a reference that resolves to nothing ## An inline template that does not compile is misuse (exit 2), including a reference that resolves to nothing
+9 -8
View File
@@ -146,17 +146,18 @@ func inputValue(input string) (any, error) {
return raw, nil return raw, nil
} }
// inlineBinding binds an inline node against root, naming its nodes from label.
func inlineBinding(n node, label string, root map[string]node) binding { func inlineBinding(n node, label string, root map[string]node) binding {
scope := inlineScope(n, label) scope := inlineScope(n, label)
return binding{scope: scope, link: func() error { return linkInline(n, label, scope, root) }} return binding{
} scope: scope,
link: func() error { return linkNodeRefs(scope, root) },
func linkInline(n node, label string, scope nodeScope, root map[string]node) error { referenceFence: func() error {
if t, isTemplate := n.(*template); isTemplate && t.drawGroup != "" { if t, isTemplate := n.(*template); isTemplate && t.drawGroup != "" {
return fmt.Errorf("%s: drawGroup %q names nothing, since nothing can reference an inline template; drop it", label, t.drawGroup) return fmt.Errorf("%s: drawGroup %q names nothing, since nothing can reference an inline template; drop it", label, t.drawGroup)
}
return nil
},
} }
return linkNodeRefs(scope, root)
} }
// linkNodeRefs binds the references in an inline node's templates against the // linkNodeRefs binds the references in an inline node's templates against the