diff --git a/README.md b/README.md index f242dc1..7b86cd5 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,10 @@ Each locale carries `address`, `color`, `company`, `date`, `email`, `first-name` `ip`, `last-name`, `person`, `phone`, `price`, `sentence`, `sex`, `time`, `url`, `username`, `version` and `word`, formatted per locale; `sv_SE` adds `personnummer` and `samordningsnummer`, `en_US` adds `ssn`, `itin` and `phone-exchange` (the three -digits after the area code). `misc` carries `car`, `coordinate`, `creditcard` +digits after the area code). `en_US.phone` draws its exchange from `en_US.phone-exchange`, +which draws evenly from the codes the North American Numbering Plan Administration (NANPA) +may assign: `200` to `999`, except `211`, `311` … `911`, `555`, `950`, `958`, `959` and +`976`. `misc` carries `car`, `coordinate`, `creditcard` (Luhn-valid), `currency` (ISO 4217), `datetime` (RFC 3339), `emoji`, `httpmethod`, `httpstatus`, `language` (ISO 639-1, with its 639-2/T code), `loglevel` (syslog severity), `mac`, `mimetype`, `objectid`, `port`, `protocol`, `territory` (ISO @@ -174,10 +177,6 @@ carry sub-fields — `misc.currency.symbol`, `misc.territory.alpha2`, `misc.territory[SE].capital` and `misc.currency[Euro].symbol` select a row; `car` and `useragent` carry no key or name, so they are drawn from rather than selected in. -`en_US.phone` draws its exchange from `en_US.phone-exchange`, which draws evenly from the -codes NANPA may assign: `200` to `999`, except `211`, `311` … `911`, `555`, `950`, `958`, -`959` and `976`. - Where a script under [`data-import/`](data-import) reads a source, the facts come from that source, and the script drops a row only by a rule it states; elsewhere a small hand-written set ships, and [`todo.md`](todo.md) carries the step that replaces it (goal 14). Copy @@ -264,9 +263,10 @@ one has no use for, and `sv_SE.title` has no `parent`, so it is selected as A `geo` folder holds one tree per country under its alpha-2 code: five [linked tables](#linked-tables) named alike, and an `address` record binding one locality and drawing its street and postal code inside it. The locale's `address` prints that -record, and each of its columns describes the address printed. Do not expect a check that a -Swedish street lies in its postort to pass: a street may sit under a neighbouring postort, -as the `street` row's counting rule explains. +record, and each of its columns describes the address printed. Do not assert that a Swedish +street lies in its postort: the import counts each road segment toward the shipped postort +owning the postal code whose centre point lies nearest, so a street may sit under a +neighbouring one. | Table | `geo.SE` | `geo.US` | Weight | |-------|----------|----------|--------| @@ -274,7 +274,7 @@ as the `street` row's counting rule explains. | `municipality` | kommun, by code or name | county, by FIPS code or name | population | | `locality` | postort, by name; [`geo-se.py`](data-import/geo-se.py)'s `localities` picks which ship | incorporated place of 25,000 people or more with a postal code of its own, by GEOID or name; Hawaii has none | tätort population, the kommun's where the postort names it, else 200; place population | | `postal-code` | postnummer with street delivery, by code | ZCTA, by code | one; address ranges | -| `street` | gatunamn, the ten with most road segments per postort, each segment counted toward the shipped postort whose postal code's centre point is nearest | street name, the ten with most address ranges per place | segments; address ranges | +| `street` | gatunamn, the ten with most road segments per postort | street name, the ten with most address ranges per place | segments; address ranges | `geo.SE.region[Skåne län].municipality` draws a kommun in Skåne, `geo.SE.locality[Lund].street` a street in Lund, and diff --git a/data-import/geo-se.py b/data-import/geo-se.py index 0f8ad88..449770e 100644 --- a/data-import/geo-se.py +++ b/data-import/geo-se.py @@ -136,9 +136,9 @@ class Nearest: def street_delivery(name, codes): """The codes delivered to a street. Outside ONE_POSITION's cities, the digit after the postort's own prefix is 0 or 1 - for boxes and 8 for reply mail, that prefix being three digits where one three-digit prefix starts at least half - the postort's codes, else two; inside them, a second digit 0 marks boxes. - Per docs/research/research-geo-se.md, Postal codes → Structure.""" + for boxes and 8 for reply mail; inside them, a second digit 0 marks boxes. + Per docs/research/research-geo-se.md, Postal codes → Structure. + The postort's own prefix is three digits where one three-digit prefix starts at least half its codes, else two.""" if name in ONE_POSITION: return [c for c in codes if c[1] != "0"] largest = collections.Counter(c[:3] for c in codes).most_common(1)[0][1] diff --git a/doc.go b/doc.go index 546176c..da3ab66 100644 --- a/doc.go +++ b/doc.go @@ -31,18 +31,18 @@ package fejkdata // and the value each path read: `drawMemo`. // - level — a prefix of a read's path, from where it starts to its leaf; a choice and the // variant drawn from it, or a table and its row, share one. `arm.levels` holds one pick -// key per level, and a step's `pathStep.at` indexes it. +// key per level. // - pick key — the key a memo keeps a level's draw under, the level's path of segments: -// `pickKey`, `levelKeys`. A read through a name keys from the node its binding starts at, -// as ""; a fresh read keys from its head, and `pickKey.under` moves its keys under the -// key of the level it renders in. -// - addressed key — a pick key some read of a name lands on or passes, from the name's own -// level: `addressedKeys`. A fresh read rendering in a pick is kept in it only where its -// first level is addressed: `renderEnv.keeps`, `readUnder`. -// In data/geo/SE/address.json, {l.street.name} reads through {.locality as l} at the -// levels "", "street" and "street.name", the last its key, and {l.name} adds "name". -// Where {p} renders a category whose format reads {first}, and {p.first} sits beside -// it, that fresh read's key "first", under {p}'s "", is addressed: both read one draw. +// `pickKey`, `levelKeys`. +// - addressed key — a pick key some read of a name lands on or passes, from the level the +// name's binding lands on onward: `addressedKeys`. A fresh read rendering in a pick is +// kept in it only where its first level is addressed: `renderEnv.keeps`, `readUnder`. +// In data/geo/SE/address.json, {.locality as l} binds l, and {l.street.name} passes the +// levels "", "street" and "street.name", the last its key. With {l.name} and +// {l.postal-code.code}, l's addressed keys are those three, "name", "postal-code" and +// "postal-code.code". Where p binds a category whose format reads {first}, and both {p} +// and {p.first} are read, the {first} that {p} renders has the key "first" under {p}'s +// key "". {p.first} addresses "first", so both read one draw. // - pin — fixing which row of a table one path, or one named pick, uses: // `pinSet`, `namedPick.pins`, `table.drawStep`. // - link — a table's tie to its parent table, each row to its parent row: diff --git a/namefence.go b/namefence.go index 8601acf..3b502d0 100644 --- a/namefence.go +++ b/namefence.go @@ -66,7 +66,7 @@ func rendersInside(nodes []node, t *template) bool { // it, at a spot where the bound spelling could stand. That spelling draws the same without the // name: write {/word} for {/word as w}{w}. A bound field can stand in only where the reading // template reaches the binder through fields. A single read as a calc operand stands where a calc -// could not read the spelling, a reference or a path: {/misc.coordinate.lat as lat}{calc(lat * 60)} +// could not read the spelling, a reference or a path. So {/misc.coordinate.lat as lat}{calc(lat * 60)} // stands, since {calc(/misc.coordinate.lat * 60)} does not compile. // Where the spelling would be a whole CLI argument or a whole struct tag, that entry point refuses // it and names the bare path. @@ -142,9 +142,9 @@ func refuseTwiceDrawn(addressed map[pickKey]string, read string, n node, key pic } // refuseTwiceDrawnIn is refuseTwiceDrawn over t's own reads of its fields; a reference or a read -// through a name draws apart from the pick. It steps into each read whose level a read of the -// name lands on or passes, at that read's key under key: beside {n.w.a}, it refuses {n} where -// n's format reads {w} and w's reads {a}-{a}, since "w" and "w.a" are addressed. +// through a name draws apart from the pick. It recurses into each read whose key under key is +// addressed: beside {n.w.a}, it refuses {n} where n's format reads {w} and w's reads {a}-{a}, +// since "w" and "w.a" are addressed. func refuseTwiceDrawnIn(addressed map[pickKey]string, read string, t *template, key pickKey) error { reads := map[string]int{} var into []arm