Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
@@ -968,7 +968,7 @@ record.go records: Record, the JSON/CSV/SQL serializers, and their entry p
|
|||||||
struct.go structs: FakeStruct, fake tags as one record's columns, and a field's Go type as its column's datatype
|
struct.go structs: FakeStruct, fake tags as one record's columns, and a field's Go type as its column's datatype
|
||||||
inline.go inline templates: Template, NewTemplate, FakeTemplate, IsTemplate, and their compile and resolve
|
inline.go inline templates: Template, NewTemplate, FakeTemplate, IsTemplate, and their compile and resolve
|
||||||
format.go a format's tokens checked against their fields, and compiled into ops
|
format.go a format's tokens checked against their fields, and compiled into ops
|
||||||
arm.go the compiled read: an arm, the path from its head to its leaf, and the op holding it
|
arm.go the compiled read of one {a|b} alternative or operand: its head, the path to its leaf, and the op holding it
|
||||||
reference.go one reference's resolution: its sigil, its category, its tail
|
reference.go one reference's resolution: its sigil, its category, its tail
|
||||||
resolve.go resolving templates against the assembled tree in steps, each over every template before the next
|
resolve.go resolving templates against the assembled tree in steps, each over every template before the next
|
||||||
graph.go the node graph: tree walks, containment and render edges, and the cycle and repeat fences
|
graph.go the node graph: tree walks, containment and render edges, and the cycle and repeat fences
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import (
|
|||||||
"github.com/larvit/fejkdata/internal/invariant"
|
"github.com/larvit/fejkdata/internal/invariant"
|
||||||
)
|
)
|
||||||
|
|
||||||
// checkCalcFields leaves an operand no field holds for a name, which checkCalcNames checks once
|
// checkCalcFields checks each calc operand a field holds; an operand no field holds is a name,
|
||||||
// names resolve.
|
// which checkCalcNames checks once names resolve.
|
||||||
func checkCalcFields(args []string, fields map[string]node) error {
|
func checkCalcFields(args []string, fields map[string]node) error {
|
||||||
return checkOperands(args[0], builtinfunc.ParsedCalc(args[0]), func(name string) []node {
|
return checkOperands(args[0], builtinfunc.ParsedCalc(args[0]), func(name string) []node {
|
||||||
if n, ok := fields[name]; ok {
|
if n, ok := fields[name]; ok {
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ NVDB_PAGE = 50000
|
|||||||
OUT = Path(__file__).resolve().parent.parent / "data" / "geo" / "SE"
|
OUT = Path(__file__).resolve().parent.parent / "data" / "geo" / "SE"
|
||||||
CACHE = Path(__file__).resolve().parent / "cache"
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
TIMEZONE = "Europe/Stockholm"
|
TIMEZONE = "Europe/Stockholm"
|
||||||
# This script's reading of the "exceptions in big cities" in docs/research/research-geo-se.md, postnummer Structure.
|
# This script's reading of the "exceptions in big cities" in docs/research/research-geo-se.md, Postal codes → Structure.
|
||||||
ONE_POSITION = {"Stockholm", "Göteborg", "Malmö"}
|
ONE_POSITION = {"Stockholm", "Göteborg", "Malmö"}
|
||||||
# A tätort's floor: "minst 200 invånare", docs/research/research-geo-se.md, Ortnamn.
|
# A tätort's floor: "minst 200 invånare", docs/research/research-geo-se.md, Lantmäteriet → Ortnamn.
|
||||||
UNMATCHED_POPULATION = 200
|
UNMATCHED_POPULATION = 200
|
||||||
|
|
||||||
|
|
||||||
@@ -135,8 +135,8 @@ class Nearest:
|
|||||||
|
|
||||||
|
|
||||||
def street_delivery(name, codes):
|
def street_delivery(name, codes):
|
||||||
"""The codes delivered to a street: the digit after the postort's own prefix is 0 or 1 for boxes and 8 for reply mail,
|
"""The codes delivered to a street: the digit after the postort's own prefix is 0 or 1 for boxes and 8 for reply mail
|
||||||
per docs/research/research-geo-se.md, postnummer Structure."""
|
outside ONE_POSITION's cities, per docs/research/research-geo-se.md, Postal codes → Structure."""
|
||||||
if name in ONE_POSITION:
|
if name in ONE_POSITION:
|
||||||
return [c for c in codes if c[1] != "0"]
|
return [c for c in codes if c[1] != "0"]
|
||||||
largest = collections.Counter(c[:3] for c in codes).most_common(1)[0][1]
|
largest = collections.Counter(c[:3] for c in codes).most_common(1)[0][1]
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ type Template struct {
|
|||||||
n node
|
n node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fake renders the template once, each {…} drawn afresh.
|
||||||
func (t *Template) Fake() string {
|
func (t *Template) Fake() string {
|
||||||
t.g.mu.Lock()
|
t.g.mu.Lock()
|
||||||
defer t.g.mu.Unlock()
|
defer t.g.mu.Unlock()
|
||||||
|
|||||||
+10
-9
@@ -62,11 +62,12 @@ func rendersInside(nodes []node, t *template) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// refuseSingleRead refuses b where it is read once, outside a repeat nested where it is bound, at a
|
// refuseSingleRead refuses b when its one read sits in b's own scope, not in a repeat nested inside
|
||||||
// spot the bound spelling can stand: that spelling draws the same without the name, {/word} for
|
// it, at a spot where the bound spelling could stand. That spelling draws the same without the
|
||||||
// {/word as w}{w}. A bound field stands in only where the reading template reaches the binder
|
// name: write {/word} for {/word as w}{w}. A bound field can stand in only where the reading
|
||||||
// through fields, and a calc operand reads neither a reference nor a path. Where the spelling would
|
// template reaches the binder through fields. A calc operand cannot read a reference or a path.
|
||||||
// be a CLI argument or tag of one reference alone, that entry point's own refusal names the bare path.
|
// Where the spelling would be a whole CLI argument or a whole struct tag, that entry point refuses
|
||||||
|
// it and names the bare path.
|
||||||
func (b *nameBinding) refuseSingleRead(uses []nameUse) error {
|
func (b *nameBinding) refuseSingleRead(uses []nameUse) error {
|
||||||
if len(uses) == 0 {
|
if len(uses) == 0 {
|
||||||
panic(invariant.Broken("name %q has no read at resolve, though its compile found one", b.name))
|
panic(invariant.Broken("name %q has no read at resolve, though its compile found one", b.name))
|
||||||
@@ -120,10 +121,10 @@ func calcReads(spelling string) bool {
|
|||||||
return err == nil && isVar && v.Name == spelling
|
return err == nil && isVar && v.Name == spelling
|
||||||
}
|
}
|
||||||
|
|
||||||
// refuseTwiceDrawn refuses read, a read of a name rendering n at key under its pick, where n renders
|
// refuseTwiceDrawn refuses read, a read of a name landing on n at key under the name's pick, where n
|
||||||
// a field twice that another read of the name addresses: the pick keeps one draw of the field, so
|
// renders a field twice and another read of the name addresses that field: the pick keeps one draw
|
||||||
// {n.w} beside {n} for a category {w}-{w} cannot say which it reads. addressed maps each level a
|
// of the field, so beside {n} for a category {w}-{w}, {n.w} cannot say which draw it reads.
|
||||||
// read of the name addresses to that read. It walks into every addressed level n renders.
|
// addressed maps each level a read of the name addresses to that read.
|
||||||
func refuseTwiceDrawn(addressed map[pickKey]string, read string, n node, key pickKey) error {
|
func refuseTwiceDrawn(addressed map[pickKey]string, read string, n node, key pickKey) error {
|
||||||
switch n := n.(type) {
|
switch n := n.(type) {
|
||||||
case *choice:
|
case *choice:
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ type Record struct {
|
|||||||
columns []Column
|
columns []Column
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Columns returns a copy of the record's columns, in name order.
|
||||||
func (r *Record) Columns() []Column {
|
func (r *Record) Columns() []Column {
|
||||||
return append([]Column(nil), r.columns...)
|
return append([]Column(nil), r.columns...)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -7,8 +7,8 @@ import (
|
|||||||
"github.com/larvit/fejkdata/internal/grammar"
|
"github.com/larvit/fejkdata/internal/grammar"
|
||||||
)
|
)
|
||||||
|
|
||||||
// resolvedRef is what a reference resolves to: the head its category is held
|
// resolvedRef is what a reference resolves to: the head its category is held under, a "/"
|
||||||
// under, its path from the root behind a "/", and the tail read into it.
|
// and then the category's path from the root, and the tail read into it.
|
||||||
type resolvedRef struct {
|
type resolvedRef struct {
|
||||||
head string
|
head string
|
||||||
tail []string
|
tail []string
|
||||||
|
|||||||
+2
-3
@@ -62,9 +62,8 @@ type resolvedNames struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resolveTemplates resolves ts in steps, each over every template before the next starts. The
|
// resolveTemplates resolves ts in steps, each over every template before the next starts. The
|
||||||
// references, the compiled format and the column read are kept on each template. The names'
|
// names' targets, keys and reads pass to later steps as arguments, and the bindings take their
|
||||||
// targets, keys and reads pass to later steps as arguments, and the bindings take their targets
|
// targets and keys only once every check has passed.
|
||||||
// and keys only once every check has passed.
|
|
||||||
func resolveTemplates(ts []templateSite, root map[string]node) error {
|
func resolveTemplates(ts []templateSite, root map[string]node) error {
|
||||||
for _, s := range ts {
|
for _, s := range ts {
|
||||||
refs, err := s.t.resolveRefs(s.folder, s.label, s.category, root)
|
refs, err := s.t.resolveRefs(s.folder, s.label, s.category, root)
|
||||||
|
|||||||
Reference in New Issue
Block a user