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
5 changed files with 18 additions and 17 deletions
Showing only changes of commit bf81c38315 - Show all commits
+3 -3
View File
@@ -16,9 +16,9 @@ replacement, and each removed path, column or flag.
`{w} {uppercase(w)}` and `{/person.first} {/person.last}` are two draws each, which `{w} {uppercase(w)}` and `{/person.first} {/person.last}` are two draws each, which
`{p as q}{q.a} {q.b}` and `{/person as n}{n.first} {n.last}` make one. `{p as q}{q.a} {q.b}` and `{/person as n}{n.first} {n.last}` make one.
`{/misc.territory as t}` binds one row of `misc.territory` to `t` and prints nothing; `{/misc.territory as t}` binds one row of `misc.territory` to `t` and prints nothing;
`{t}`, `{t.capital}` and `{lowercase(t.name)}` read that one row. A name binds a `{t}`, `{t.capital}` and `{lowercase(t.name)}` read that one row. `{x as n}` binds a
reference, a sibling field or a path into one, lives in the category binding it, and reference, a sibling field or a path into one; a name lives in the category binding it,
picks again on every iteration of a `repeat` binding it. A struct's tags share its and picks again on every iteration of a `repeat` binding it. A struct's tags share its
names, `{/sv_SE.person as p}{p.first}` beside `{p.sex}`. A name is a `{calc()}` names, `{/sv_SE.person as p}{p.first}` beside `{p.sex}`. A name is a `{calc()}`
operand: `{/misc.coordinate.lat as lat}{calc(lat * 60)}`. What `New` refuses is listed operand: `{/misc.coordinate.lat as lat}{calc(lat * 60)}`. What `New` refuses is listed
under [Names](README.md#names). under [Names](README.md#names).
+4 -3
View File
@@ -345,8 +345,8 @@ naming a kind that holds it. The tags are a record's columns, so they share its
describe one person, while two path tags into `sv_SE.person` are two draws. The fields an describe one person, while two path tags into `sv_SE.person` are two draws. The fields an
embedded struct promotes are columns of the same record; a named struct field, or a embedded struct promotes are columns of the same record; a named struct field, or a
pointer to one, fills from its own tags as a record of its own, so its names and picks are pointer to one, fills from its own tags as a record of its own, so its names and picks are
its own. `fake:"-"` leaves a struct field, embedded or named, or a pointer to one, unfilled. Untagged fields keep its own. `fake:"-"` leaves a struct field, embedded or named, or a pointer to one, unfilled.
their values, and so does a pointer back to a struct already being filled; a type Untagged fields keep their values, and so does a pointer back to a struct already being filled; a type
whose fields reach more than 1024 structs is refused, naming `fake:"-"` to cut it. The whose fields reach more than 1024 structs is refused, naming `fake:"-"` to cut it. The
first call for a type compiles its tags and reports what they get wrong, with the same first call for a type compiles its tags and reports what they get wrong, with the same
error on every later call; a `datatype` in a tag names the Go type that already sets it. error on every later call; a `datatype` in a tag names the Go type that already sets it.
@@ -756,7 +756,8 @@ Refused at `New`, each error naming what to write instead:
- a name bound twice outside any `repeat`, twice in one `repeat`, or both inside a `repeat` - a name bound twice outside any `repeat`, twice in one `repeat`, or both inside a `repeat`
and outside it; and outside it;
- a name that is a field or an option; - a name that is a field or an option;
- a binding of anything but a reference or a path into a field of the template binding it; - a binding of anything but a reference, or a field of the template binding it or a path into
one;
- a read of a name inside the field bound to it: read it outside that field; - a read of a name inside the field bound to it: read it outside that field;
- a binding in a choice's item, which every other item would leave unbound; - a binding in a choice's item, which every other item would leave unbound;
- a binding nothing reads, or one read only once, unless that read sits in a `repeat` - a binding nothing reads, or one read only once, unless that read sits in a `repeat`
+5 -5
View File
@@ -135,13 +135,13 @@ from the one pick a name keeps.
- `{p.a} {p.b}`, `{w} {uppercase(w)}`, `{/p.first} {/p.last}` and `{/p} {/p}` are two draws - `{p.a} {p.b}`, `{w} {uppercase(w)}`, `{/p.first} {/p.last}` and `{/p} {/p}` are two draws
each, and `{p as q}{q.a} {q.b}` is one. Nothing is kept per format or per render, so the each, and `{p as q}{q.a} {q.b}` is one. Nothing is kept per format or per render, so the
only load checks on draws are names, paths through names, cycles and the repeat cap. only load checks on draws are names, paths through names, cycles and the repeat cap.
- A name binds a reference, or a field of the template binding it or a path into one, `{place as - `{x as n}` binds a reference, or a field of the template binding it or a path into one,
p}`: an inline template, and a choice of rows inside one category, have no reference to `{place as p}`: an inline template, and a choice of rows inside one category, have no reference to
bind, and goal 4.1 holds there too. bind, and goal 4.1 holds there too.
- A name read once is refused where writing what it binds in its place draws the same, and - A name read once is refused where writing what it binds in its place draws the same, and
the error names that spelling (goal 5.7): `{/x as n}{n.y}` is `{/x.y}`. A calc reads no reference or the error names that spelling (goal 5.7): `{/x as n}{n.y}` is `{/x.y}`. A calc cannot read
path, and a read inside a nested repeat keeps one pick on every line, so neither is a reference or a path, so a calc's one read of a name bound to either is not refused, and
refused. neither is a read inside a nested repeat, which keeps one pick on every line.
Valid while goal 5.2 has each `{…}` make a new pick. Valid while goal 5.2 has each `{…}` make a new pick.
+3 -3
View File
@@ -59,9 +59,9 @@ func rendersInside(nodes []node, t *template) bool {
} }
// checkUses refuses a binding read once at a spot the bound spelling can stand: that spelling // checkUses refuses a binding read once at a spot the bound spelling can stand: that spelling
// draws the same way without the name. A bound field can stand in only where the reading template // draws the same way without the name. A bound field can stand in only where the reading
// reaches the binder through fields. Where the spelling would be a CLI argument or tag of one reference alone, // template reaches the binder through fields. Where the spelling would be a CLI argument or tag
// that entry point's own refusal then names the bare path. // of one reference alone, that entry point's own refusal then names the bare path.
func (b *nameBinding) checkUses() error { func (b *nameBinding) checkUses() error {
r := b.uses[0] r := b.uses[0]
if len(b.uses) > 1 || r.nested { if len(b.uses) > 1 || r.nested {
+3 -3
View File
@@ -154,7 +154,7 @@ func (t *template) resolveLink(folder []string, path, category string, root map[
return link, nil return link, nil
} }
// columnRead is a record's column read by a format of that one reference or name read alone, // columnRead is a record's column read by a format that only reads one reference or name,
// which is the column: it takes the column's datatype and null. category and field name it; // which is the column: it takes the column's datatype and null. category and field name it;
// category is "" for a column of the reading template's own record, which checkColumns reaches // category is "" for a column of the reading template's own record, which checkColumns reaches
// on its own. // on its own.
@@ -164,8 +164,8 @@ type columnRead struct {
column node column node
} }
// linkColumnRead sets the record's column t's format reads, where it is one reference or name // linkColumnRead sets the record's column t's format reads, where the format only reads one
// read alone, once the names are linked. // reference or name, once the names are linked.
func linkColumnRead(_ string, t *template) error { func linkColumnRead(_ string, t *template) error {
ops := t.compiled.ops ops := t.compiled.ops
if t.repeat != 1 || len(ops) != 1 || ops[0].kind != nameRead || len(ops[0].arms) != 1 { if t.repeat != 1 || len(ops) != 1 || ops[0].kind != nameRead || len(ops[0].arms) != 1 {