Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
+4
-12
@@ -8,18 +8,10 @@ replacement, and each removed path, column or flag.
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- A name keeps one pick: `{/misc.territory as t}` binds one row of `misc.territory` to `t`
|
- Names: `{/misc.territory as t}` binds one row of `misc.territory` to `t` and prints
|
||||||
and prints nothing, and `{t}`, `{t.capital}` and `{t.calling-code}` read that one row.
|
nothing; `{t}`, `{t.capital}` and `{lowercase(t.name)}` read that one row. A name lives
|
||||||
A name lives in the category binding it, so every field and record column of the
|
in the category binding it, and a `repeat` binding it picks again on every iteration.
|
||||||
category reads one pick, a transform reads it as `{lowercase(t.name)}`, and a name a
|
What `New` refuses is listed under [Names](README.md#names).
|
||||||
`repeat` binds picks again on every iteration. Refused at `New`: a name bound twice
|
|
||||||
outside any `repeat`, twice in one `repeat`, or both inside a `repeat` and outside it; a
|
|
||||||
name that is a field or an option; a binding of anything but a reference; a binding in a
|
|
||||||
choice's item; a binding nothing reads, or one of a whole category read once whole, which the bare reference spells; a
|
|
||||||
path through a name that selects a row; a read of a name rendering a field twice where a
|
|
||||||
path through the name reads it; reads of a name in two draw groups, or inside a
|
|
||||||
`repeat`, where what it names reads a reference path; and a binding in a table. A field, column,
|
|
||||||
category or folder name may not contain ` as `.
|
|
||||||
- First release: the CLI, the library and the shipped data set.
|
- First release: the CLI, the library and the shipped data set.
|
||||||
- Table categories: a category JSON naming a `rows` TSV beside it, with the options
|
- Table categories: a category JSON naming a `rows` TSV beside it, with the options
|
||||||
`key`, `name`, `weight` and `parent`; a path selects a row by key or name,
|
`key`, `name`, `weight` and `parent`; a path selects a row by key or name,
|
||||||
|
|||||||
@@ -708,23 +708,23 @@ row:
|
|||||||
"{/misc.territory as t}{t.flag} {t}: capital {t.capital}, calling code +{t.calling-code}"
|
"{/misc.territory as t}{t.flag} {t}: capital {t.capital}, calling code +{t.calling-code}"
|
||||||
```
|
```
|
||||||
|
|
||||||
Renders e.g. `🇳🇴 Norway: capital Oslo, calling code +47`. A name keeps each level a
|
Renders e.g. `🇳🇴 Norway: capital Oslo, calling code +47`. A name keeps what each `{n.path}`
|
||||||
`{n.path}` reads, and what it lands on, so `{n}` and `{n.path}` agree, and a
|
lands on and every level it passes, so `{n}` and `{n.path}` agree, and so does a
|
||||||
[transform](#transforms) of `n.path` reads the same value. Everything else under the name draws
|
[transform](#transforms) of `n.path`. Everything else under the name draws as it would
|
||||||
as it would anywhere. So if the category `n` names has the format `{w}-{w}`, it draws `w`
|
anywhere: if `n`'s category has the format `{w}-{w}`, it draws `w` twice, and `{n.w}` beside
|
||||||
twice, and `{n.w}` beside `{n}` is refused, since it could read either draw.
|
`{n}` is refused, since it could read either draw.
|
||||||
|
|
||||||
A name is a pick of its own: `{t.name}` and `{/misc.territory.name}` beside it are two draws. A
|
A name is a pick of its own: `{t.name}` and `{/misc.territory.name}` beside it are two draws. A
|
||||||
reference path the picked category reads is still held for the render as usual, so two names
|
reference path the picked category reads is still held for the render as usual, so two names
|
||||||
bound to `sv_SE.person`, whose fields read `{.first-name.name}`, print one person unless their
|
bound to `sv_SE.person`, whose fields read `{.first-name.name}`, print the same first and last
|
||||||
reads sit in two [draw groups](#draw-group).
|
name unless their reads sit in two [draw groups](#draw-group).
|
||||||
|
|
||||||
A name is drawn on its first read, and lives in the category binding it: any field of the
|
A name is drawn on its first read, and lives in the category binding it: any field of the
|
||||||
category reads it, and a record's columns read one pick. Each render of the category picks
|
category reads it, and a record's columns read one pick. Each render of the category picks
|
||||||
anew, and so does each bare reference to it. A name a `repeat` binds picks again on every
|
anew, and so does each bare reference to it. A name a `repeat` binds picks again on every
|
||||||
iteration, and one bound outside the repeat keeps its pick on every line.
|
iteration, and one bound outside the repeat keeps its pick on every line.
|
||||||
|
|
||||||
Rejected at load, each error naming what to write instead:
|
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;
|
||||||
@@ -734,7 +734,7 @@ Rejected at load, each error naming what to write instead:
|
|||||||
- a binding nothing reads, or a binding of a whole category read once whole where it is
|
- a binding nothing reads, or a binding of a whole category read once whole where it is
|
||||||
bound, which the bare reference spells: `{/word as w}{w}` is `{/word}`;
|
bound, which the bare reference spells: `{/word as w}{w}` is `{/word}`;
|
||||||
- a path through a name that selects a row;
|
- a path through a name that selects a row;
|
||||||
- a read of a name rendering a field twice, where a path through the name reads it;
|
- `{n}` beside `{n.w}` where `n`'s category renders `w` twice, as in `{w}-{w}`;
|
||||||
- reads of a name in two draw groups, or inside a `repeat`, where what it names reads a
|
- reads of a name in two draw groups, or inside a `repeat`, where what it names reads a
|
||||||
reference path, which each draw group and iteration draws apart;
|
reference path, which each draw group and iteration draws apart;
|
||||||
- a binding in a table's format or cell;
|
- a binding in a table's format or cell;
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ package fejkdata
|
|||||||
// an expansion holds a sibling path's head and an operand's field, its draw
|
// an expansion holds a sibling path's head and an operand's field, its draw
|
||||||
// group a reference path's: `formatOps.held` and `heldCheck` an expansion's,
|
// group a reference path's: `formatOps.held` and `heldCheck` an expansion's,
|
||||||
// `readReference` a draw group's.
|
// `readReference` a draw group's.
|
||||||
// - named pick — the draw a token such as {/person as p} binds to a name. It is drawn on its
|
// - named pick — the draw a token such as {/person as p} binds to a name, drawn
|
||||||
// first read and kept while its scope renders: a category, or one repeat iteration.
|
// on its first read and kept while its scope renders: a category, or one
|
||||||
// `nameBinding`, `nameScope`, `namedPick`, `pickFrame`.
|
// repeat iteration: `nameBinding`, `nameScope`, `namedPick`, `pickFrame`.
|
||||||
// - memo — what a hold, a draw group or a named pick keeps its draws in, the variant drawn at
|
// - memo — what a hold, a draw group or a named pick keeps its draws in, the
|
||||||
// each level and the value each path read: `drawMemo`, `readMemo`.
|
// variant drawn at each level and the value each path read: `drawMemo`,
|
||||||
|
// `readMemo`.
|
||||||
// - draw group — reference draws kept apart inside one render:
|
// - draw group — reference draws kept apart inside one render:
|
||||||
// `template.drawGroup` as the data spells it, `templateLink.drawGroupKey` as a
|
// `template.drawGroup` as the data spells it, `templateLink.drawGroupKey` as a
|
||||||
// render reads it, `renderDraws`, `groupDraws`, `renderScope`.
|
// render reads it, `renderDraws`, `groupDraws`, `renderScope`.
|
||||||
|
|||||||
+9
-8
@@ -662,7 +662,8 @@ same four columns as `geo.SE.address`, each a reference into it, and the format
|
|||||||
twice; a column is spelled the same in both, `street-number`, so the two never disagree
|
twice; a column is spelled the same in both, `street-number`, so the two never disagree
|
||||||
on a name.
|
on a name.
|
||||||
|
|
||||||
`todo.md` item 3 replaces it.
|
`todo.md` item 3 revises this decision: the locale `address` prints `{a}` whole, so the
|
||||||
|
format appears once.
|
||||||
|
|
||||||
## A postort's kommun comes from its name, its tätort or its codes, never from distance
|
## A postort's kommun comes from its name, its tätort or its codes, never from distance
|
||||||
|
|
||||||
@@ -902,13 +903,11 @@ since a read outside the item would see a binding another item leaves out. A pic
|
|||||||
its first read, so a record's columns, rendered in name order, read one pick whichever binds
|
its first read, so a record's columns, rendered in name order, read one pick whichever binds
|
||||||
it.
|
it.
|
||||||
|
|
||||||
The scope is lexical: a read entering a category, by a reference, through a name or from
|
The scope is lexical. A read entering a category, by a reference, through a name or from
|
||||||
`Fake`, sees none of the frames rendering above it, so what a category renders never depends
|
`Fake`, sees no frame (one render of a scope's picks) opened above it, so a category renders
|
||||||
on who references it. That read opens the frame of each scope around what it lands on, taken
|
the same whoever references it. That read opens the frames around where it lands from its own
|
||||||
from its own memo, so every read entering by one memo, `{n}` and `{n.path}` alike, reads one
|
memo, so reads sharing a memo, `{n}` and `{n.path}` alike, read one pick. A reference path's
|
||||||
pick: per render and group for a reference path, per pick for a path through a name, per
|
memo lasts per render and draw group, a name's per pick, and `Fake("cat.field")`'s per render.
|
||||||
render for `Fake("cat.field")`. A frame is looked up on the stack of frames rendering, and
|
|
||||||
nowhere else.
|
|
||||||
|
|
||||||
A pick keeps only the levels a read of the name addresses, so a template draws the same way
|
A pick keeps only the levels a read of the name addresses, so a template draws the same way
|
||||||
under a name as anywhere else (goal 5.2). A reference read under a pick draws in the draw group
|
under a name as anywhere else (goal 5.2). A reference read under a pick draws in the draw group
|
||||||
@@ -918,3 +917,5 @@ path, its reads stay in one draw group and outside any repeat: a reference path
|
|||||||
draw group and per iteration, so what the pick kept and what it renders afresh would come from
|
draw group and per iteration, so what the pick kept and what it renders afresh would come from
|
||||||
two draws of it. `todo.md` item 4 ends both: once every `{…}` draws afresh, nothing is held for
|
two draws of it. `todo.md` item 4 ends both: once every `{…}` draws afresh, nothing is held for
|
||||||
the render.
|
the render.
|
||||||
|
|
||||||
|
Valid while names are read only inside the category binding them.
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import "strings"
|
|||||||
|
|
||||||
// drawMemo is what a hold, a draw group or a named pick has drawn: the variant each level was
|
// drawMemo is what a hold, a draw group or a named pick has drawn: the variant each level was
|
||||||
// drawn as, so every path under it reads one variant; the value each read produced, by its path,
|
// drawn as, so every path under it reads one variant; the value each read produced, by its path,
|
||||||
// so the same read written twice reads one value; and the frame of each name scope a read
|
// so the same read written twice reads one value; and the frames a read opens for the name
|
||||||
// entered past its owner.
|
// scopes around where it lands (enter).
|
||||||
type drawMemo struct {
|
type drawMemo struct {
|
||||||
variant map[string]node
|
variant map[string]node
|
||||||
value map[string]readValue
|
value map[string]readValue
|
||||||
@@ -48,8 +48,8 @@ type renderScope struct {
|
|||||||
// base is the depth of the frame stack when the read rendering the category entered it,
|
// base is the depth of the frame stack when the read rendering the category entered it,
|
||||||
// below which no frame is the category's.
|
// below which no frame is the category's.
|
||||||
base int
|
base int
|
||||||
// pick is the named pick what renders is part of, at pickKey, its path from the name; nil
|
// pick is the named pick being rendered, nil outside one; pickKey is the path from the name
|
||||||
// outside one.
|
// to what renders.
|
||||||
pick *namedPick
|
pick *namedPick
|
||||||
pickKey string
|
pickKey string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ const (
|
|||||||
nameBind
|
nameBind
|
||||||
)
|
)
|
||||||
|
|
||||||
// asWord separates a binding's reference from the name it binds: {/person as p}.
|
|
||||||
const asWord = " as "
|
const asWord = " as "
|
||||||
|
|
||||||
// parseFormat is the one reading of a format's tokens: a '(' outside a selector makes
|
// parseFormat is the one reading of a format's tokens: a '(' outside a selector makes
|
||||||
@@ -223,9 +222,8 @@ type unboundRead struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkTokens proves every parsed token names an existing field or a known function,
|
// checkTokens proves every token's grammar, functions and field paths, and returns the reads
|
||||||
// so a typo'd or dangling reference is a New-time error. A head no field holds comes
|
// whose head no field holds, for bindNames to look up among the names.
|
||||||
// back unbound, for bindNames to look up among the names.
|
|
||||||
func checkTokens(toks []formatToken, fields map[string]node) ([]unboundRead, error) {
|
func checkTokens(toks []formatToken, fields map[string]node) ([]unboundRead, error) {
|
||||||
var unbound []unboundRead
|
var unbound []unboundRead
|
||||||
for _, t := range toks {
|
for _, t := range toks {
|
||||||
@@ -284,8 +282,8 @@ func checkReads(t formatToken, fields map[string]node, operands bool) ([]unbound
|
|||||||
return unbound, nil
|
return unbound, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkBind proves a {ref as name} token binds a reference to a name no other token
|
// checkBind proves a {ref as name} token is spelled once, binds a reference, and names a valid
|
||||||
// could read as something else.
|
// name that is no option.
|
||||||
func checkBind(t formatToken) error {
|
func checkBind(t formatToken) error {
|
||||||
ref, name := t.boundRef, t.bound
|
ref, name := t.boundRef, t.bound
|
||||||
if trimmed := strings.TrimSpace(ref) + asWord + strings.TrimSpace(name); trimmed != t.body {
|
if trimmed := strings.TrimSpace(ref) + asWord + strings.TrimSpace(name); trimmed != t.body {
|
||||||
@@ -301,7 +299,7 @@ func checkBind(t formatToken) error {
|
|||||||
return fmt.Errorf("token {%s}: a binding names nothing; write {%s as n}", t.body, ref)
|
return fmt.Errorf("token {%s}: a binding names nothing; write {%s as n}", t.body, ref)
|
||||||
}
|
}
|
||||||
if isOption(name) {
|
if isOption(name) {
|
||||||
return fmt.Errorf("token {%s}: %q is an option and can never be a name", t.body, name)
|
return fmt.Errorf("token {%s}: %q is an option and can never be a name; rename it", t.body, name)
|
||||||
}
|
}
|
||||||
if err := checkName(name); err != nil {
|
if err := checkName(name); err != nil {
|
||||||
return fmt.Errorf("token {%s}: name %w", t.body, err)
|
return fmt.Errorf("token {%s}: name %w", t.body, err)
|
||||||
@@ -534,7 +532,7 @@ func (c *formatOps) field(tok formatToken, refs map[string]refBinding, isName fu
|
|||||||
c.ops = append(c.ops, op{formatToken: tok, arms: arms})
|
c.ops = append(c.ops, op{formatToken: tok, arms: arms})
|
||||||
}
|
}
|
||||||
|
|
||||||
// compileFormat compiles a parsed format, a binding to nothing, since it prints nothing. Call
|
// compileFormat compiles a parsed format; a {ref as n} token compiles to no op. Call
|
||||||
// checkTokens first: it is what proves every token valid.
|
// checkTokens first: it is what proves every token valid.
|
||||||
func compileFormat(toks []formatToken, refs map[string]refBinding, isName func(head string) bool) formatOps {
|
func compileFormat(toks []formatToken, refs map[string]refBinding, isName func(head string) bool) formatOps {
|
||||||
var c formatOps
|
var c formatOps
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// nameScope is where a name is bound: a category, or one iteration of a repeat inside it.
|
// nameScope is where a name is bound: a category, or one iteration of a repeat inside it. A
|
||||||
// Every token of the category outside a nested repeat reads the category's names, so one
|
// token sees its scope's names and every enclosing scope's, so one field may bind a name and
|
||||||
// field may bind a name and another read it.
|
// another read it.
|
||||||
type nameScope struct {
|
type nameScope struct {
|
||||||
up *nameScope
|
up *nameScope
|
||||||
owner node // the category's root, or the repeat
|
owner node // the category's root, or the repeat
|
||||||
@@ -17,9 +17,6 @@ type nameScope struct {
|
|||||||
order []*nameBinding
|
order []*nameBinding
|
||||||
}
|
}
|
||||||
|
|
||||||
// nameBinding is one {ref as name} token: the scope it binds name in, its index among
|
|
||||||
// that scope's bindings, its uses, and, once linked, the head node and tail its
|
|
||||||
// reference reads and the keys its reads address.
|
|
||||||
type nameBinding struct {
|
type nameBinding struct {
|
||||||
name string
|
name string
|
||||||
ref string
|
ref string
|
||||||
@@ -56,7 +53,7 @@ func (sc *nameScope) lookup(name string) *nameBinding {
|
|||||||
// bindNames gives every template of a compiled category or inline template the scope its
|
// bindNames gives every template of a compiled category or inline template the scope its
|
||||||
// names live in, and refuses a name bound twice along one chain of scopes, a binding in a
|
// names live in, and refuses a name bound twice along one chain of scopes, a binding in a
|
||||||
// choice's item, a name a field spells too, a read no field or name answers, and a binding
|
// choice's item, a name a field spells too, a read no field or name answers, and a binding
|
||||||
// read by nothing, or once whole, which its reference spells.
|
// read by nothing.
|
||||||
func bindNames(root node) error {
|
func bindNames(root node) error {
|
||||||
top := &nameScope{owner: root}
|
top := &nameScope{owner: root}
|
||||||
scopes := []*nameScope{top}
|
scopes := []*nameScope{top}
|
||||||
@@ -100,8 +97,7 @@ func bindNames(root node) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// bindAll binds every name t's tokens bind. A choice's item binds none: a read outside the item
|
// bindAll binds every name t's tokens bind.
|
||||||
// would find the name bound by an item that may never be drawn.
|
|
||||||
func (sc *nameScope) bindAll(t *template, inChoice bool, where string) error {
|
func (sc *nameScope) bindAll(t *template, inChoice bool, where string) error {
|
||||||
for _, tok := range t.tokens {
|
for _, tok := range t.tokens {
|
||||||
if tok.kind != nameBind {
|
if tok.kind != nameBind {
|
||||||
@@ -221,7 +217,6 @@ func unresolved(where string, u unboundRead, seen *nameScope, scopes []*nameScop
|
|||||||
return fmt.Errorf("%s%w", where, u.err)
|
return fmt.Errorf("%s%w", where, u.err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isName reports whether a head t reads is a name: neither a reference nor a field.
|
|
||||||
func (t *template) isName(head string) bool {
|
func (t *template) isName(head string) bool {
|
||||||
return !isRef(head) && t.fields[head] == nil && t.nameScope.lookup(head) != nil
|
return !isRef(head) && t.fields[head] == nil && t.nameScope.lookup(head) != nil
|
||||||
}
|
}
|
||||||
@@ -315,10 +310,8 @@ func checkNameReads(path string, t *template) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkUses refuses a binding of a category read once whole, which the bare reference spells, and
|
// checkUses refuses a binding of a category read once whole, and reads of b in two draw groups,
|
||||||
// reads of b in two draw groups, or inside a repeat, where what b names reads a
|
// or inside a repeat, where what b names reads a reference path.
|
||||||
// reference path: that path is held per draw group and per iteration, so what the pick kept and
|
|
||||||
// what it renders afresh would come from two draws of it. todo.md item 4 ends the hold.
|
|
||||||
func (b *nameBinding) checkUses() error {
|
func (b *nameBinding) checkUses() error {
|
||||||
if r := b.uses[0]; len(b.uses) == 1 && r.tail == "" && !r.nested && len(b.tail) == 0 {
|
if r := b.uses[0]; len(b.uses) == 1 && r.tail == "" && !r.nested && len(b.tail) == 0 {
|
||||||
spelling := b.ref
|
spelling := b.ref
|
||||||
@@ -481,9 +474,9 @@ func (d *renderDraws) depth() int {
|
|||||||
return len(d.frameStack.frames)
|
return len(d.frameStack.frames)
|
||||||
}
|
}
|
||||||
|
|
||||||
// enter is sc as a read entering a category sees it, landing on n: none of the frames rendering,
|
// enter hides the frames already rendering from a read landing on n, and opens from memo a frame
|
||||||
// and, from memo, the frame of each scope binding names around n, so every read entering with
|
// for each name scope around n, so every read sharing memo reads one pick of each name. It
|
||||||
// memo reads one pick of each name. It returns the mark that closes those frames.
|
// returns the mark that closes those frames.
|
||||||
func (sc renderScope) enter(n node, memo *drawMemo) (renderScope, int) {
|
func (sc renderScope) enter(n node, memo *drawMemo) (renderScope, int) {
|
||||||
sc.base, sc.pick = sc.draws.depth(), nil
|
sc.base, sc.pick = sc.draws.depth(), nil
|
||||||
for scope := scopeAround(n); scope != nil; scope = scope.up {
|
for scope := scopeAround(n); scope != nil; scope = scope.up {
|
||||||
@@ -566,8 +559,7 @@ func (sc renderScope) drawRowOf(s *generatorState, t *table) int {
|
|||||||
return t.drawRow(s)
|
return t.drawRow(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// keeps reports whether the pick sc renders part of keeps a, a read of t: whether a read of the
|
// keeps reports whether a read of sc's name addresses the level a starts at.
|
||||||
// name addresses the level a starts at.
|
|
||||||
func (sc renderScope) keeps(a arm) bool {
|
func (sc renderScope) keeps(a arm) bool {
|
||||||
_, kept := sc.pick.named.addressed[underKey(sc.pickKey, a.head)]
|
_, kept := sc.pick.named.addressed[underKey(sc.pickKey, a.head)]
|
||||||
return kept
|
return kept
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ type Column struct {
|
|||||||
// Record is one record rendered from a template: every direct field is a column,
|
// Record is one record rendered from a template: every direct field is a column,
|
||||||
// listed in name order. Each column is its own expansion, so a sibling field is
|
// listed in name order. Each column is its own expansion, so a sibling field is
|
||||||
// local to it, while a reference that reads a path is drawn once for the whole
|
// local to it, while a reference that reads a path is drawn once for the whole
|
||||||
// record, per group, and a name once for the whole record.
|
// record, per group, and a pick bound by {ref as n} once for the whole record.
|
||||||
type Record struct {
|
type Record struct {
|
||||||
columns []Column
|
columns []Column
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ func renderRepeat(s *generatorState, t *template, sc renderScope) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// expandAnew expands one repeat iteration of t as a render of its own, in no group, inside the
|
// expandAnew expands one repeat iteration of t as a render of its own, in no group, inside the
|
||||||
// name scopes of stack from base. Inlined into render's loop, its draws would move to the heap.
|
// name scopes of stack from base. Inlined into renderRepeat's loop, its draws would move to the heap.
|
||||||
//
|
//
|
||||||
//go:noinline
|
//go:noinline
|
||||||
func expandAnew(s *generatorState, t *template, stack *frameStack, base int) string {
|
func expandAnew(s *generatorState, t *template, stack *frameStack, base int) string {
|
||||||
@@ -169,7 +169,7 @@ func expand(s *generatorState, t *template, sc renderScope) string {
|
|||||||
// token addresses by a dotted path that is not a reference, or a field an operand
|
// token addresses by a dotted path that is not a reference, or a field an operand
|
||||||
// reads — is drawn once and kept in hold, so {place.postal-code} and {place.locality}
|
// reads — is drawn once and kept in hold, so {place.postal-code} and {place.locality}
|
||||||
// read one row, either read twice gives one value, and a shown operand is the operand
|
// read one row, either read twice gives one value, and a shown operand is the operand
|
||||||
// computed. A field of a template rendering as part of a named pick is kept in the pick.
|
// computed. A field a read of a name addresses is kept in that name's pick.
|
||||||
// Every other field is drawn afresh, so {word} {word} still draws twice.
|
// Every other field is drawn afresh, so {word} {word} still draws twice.
|
||||||
func readField(s *generatorState, t *template, hold *drawMemo, sc renderScope, a arm) readValue {
|
func readField(s *generatorState, t *template, hold *drawMemo, sc renderScope, a arm) readValue {
|
||||||
if a.kind == refPathRead {
|
if a.kind == refPathRead {
|
||||||
|
|||||||
@@ -193,13 +193,13 @@ Shape: T = table, t = template, c = choice.
|
|||||||
### 3. Rewrite the shipped categories so facts that belong together come from one named pick.
|
### 3. Rewrite the shipped categories so facts that belong together come from one named pick.
|
||||||
|
|
||||||
- `sv_SE.person` and `en_US.person` bind the first name and read sex and title through it: `"first": "{.first-name as n}{n.name}"`, `"sex": "{n..sex.name}"`, a title from `{n..sex.title.name}`.
|
- `sv_SE.person` and `en_US.person` bind the first name and read sex and title through it: `"first": "{.first-name as n}{n.name}"`, `"sex": "{n..sex.name}"`, a title from `{n..sex.title.name}`.
|
||||||
- `geo.SE.address` and `geo.US.address` bind the street and read locality, postal code and region through it; the locale `address` categories bind `/geo.XX.address` once and print it whole as `{a}`, so the country record's format appears once, and the decision "A locale's `address` restates its country record's format" is revised.
|
- `geo.SE.address` and `geo.US.address` bind the street and read locality, postal code and region through it; the locale `address` categories bind `/geo.XX.address` once. They print it whole as `{a}`, so the country record's format appears once; revise the decision "A locale's `address` restates its country record's format".
|
||||||
- Needs item 2. Every shipped value must still pass its consumer's check before and after item 4.
|
- Needs item 2. Every shipped value must still pass its consumer's check before and after item 4.
|
||||||
- Re-pin seeded output in its own commit.
|
- Re-pin seeded output in its own commit.
|
||||||
|
|
||||||
### 4. Draw every `{…}` afresh, keep a pick only by name, and delete `drawGroup` with the fences that held picks implicitly.
|
### 4. Draw every `{…}` afresh, keep a pick only by name, and delete `drawGroup` with the fences that held picks implicitly.
|
||||||
|
|
||||||
- Needs items 2, 3 and 71. After it, `{/person} ({/person.first})` renders two people, as does `{/sv_SE.person as a}{/sv_SE.person as b}{a} & {b}`, `{w} {uppercase(w)}` renders `b G` where `w` is a choice of letters, and `{/city.name}, {/country[SE].name}` and `{/country[SE].name} / {/country[NO].name}` both load.
|
- Needs items 2, 3 and 71. After it, `{/person} ({/person.first})` renders two people, as does `{/sv_SE.person as a}{/sv_SE.person as b}{a} & {b}`. `{w} {uppercase(w)}` renders `b G` where `w` is a choice of letters, and `{/city.name}, {/country[SE].name}` and `{/country[SE].name} / {/country[NO].name}` both load.
|
||||||
- Deletes the token-order rules (`drawsApart`, `readFold`, `branches`, the pairwise replay), the expansion hold fence, `drawGroup`, the own-family fence and the cell-reference fences, and revises the decisions that point here. The remaining draw checks are names, paths through names, cycles and the repeat cap.
|
- Deletes the token-order rules (`drawsApart`, `readFold`, `branches`, the pairwise replay), the expansion hold fence, `drawGroup`, the own-family fence and the cell-reference fences, and revises the decisions that point here. The remaining draw checks are names, paths through names, cycles and the repeat cap.
|
||||||
- Fixes on the way: `{/sel}|{/sel}` panics out of `Fake` today where two draws land on rows whose cells select different rows of another table; it must render.
|
- Fixes on the way: `{/sel}|{/sel}` panics out of `Fake` today where two draws land on rows whose cells select different rows of another table; it must render.
|
||||||
- Rewrites the README's References, Draw group, Correlated fields, Linked tables, Names and "One draw, one spelling" sections; the Linked tables section says which pick's weights govern a family, since the bound row decides.
|
- Rewrites the README's References, Draw group, Correlated fields, Linked tables, Names and "One draw, one spelling" sections; the Linked tables section says which pick's weights govern a family, since the bound row decides.
|
||||||
@@ -339,7 +339,7 @@ Require the path step to reach a sibling category.
|
|||||||
|
|
||||||
### 73. Decide whether the default embed's partial Swedish and US place tables stand against goal 13.1, or have the goals say which goal wins.
|
### 73. Decide whether the default embed's partial Swedish and US place tables stand against goal 13.1, or have the goals say which goal wins.
|
||||||
|
|
||||||
The decision "The default embed holds every Swedish postort the import can place and give a street-delivery code and a street, and the US places of 25,000 or more" ships less than its registers hold, and names no item that ends it. Item 60 ships the full registers as packs, beside the partial default.
|
The decision "The default embed holds every Swedish postort the import can place and give a street-delivery code and a street, and the US places of 25,000 or more" serves goal 2's built-in data with no download, ships less than its registers hold, and names no item that ends it. Item 60 ships the full registers as packs, beside the partial default.
|
||||||
|
|
||||||
### 74. Decide whether `misc.timezone` may drop the 17 zones of territories `misc.territory` leaves out, against goal 13.1, or have the goals say which goal wins.
|
### 74. Decide whether `misc.timezone` may drop the 17 zones of territories `misc.territory` leaves out, against goal 13.1, or have the goals say which goal wins.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user