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
4 changed files with 21 additions and 12 deletions
Showing only changes of commit 57bd06c16f - Show all commits
+4 -1
View File
@@ -459,6 +459,9 @@ func parseInput(raw string) (input, error) {
if trimmed == "" {
return input{}, fmt.Errorf("stdin holds no template: %s", pipeHint)
}
if trimmed == "null" {
return input{}, fmt.Errorf("stdin holds only null, as jq prints for a missing key: %s", pipeHint)
}
text := raw
if json.Valid([]byte(trimmed)) {
text = trimmed
@@ -511,7 +514,7 @@ func hasEmptySegment(path string) bool {
switch {
case seg != "":
stepUp = false
case stepUp && !last, !stepUp && last:
case stepUp != last:
return true
default:
stepUp = !stepUp
+5 -5
View File
@@ -102,7 +102,7 @@ template per run.
2026-10-07, Lilleman auf Larv. Serves goal 9.6: a CLI carrying your own modules is a few
lines of Go and works just like `fejkdata`, so `fejkdata`'s own CLI is such a CLI and
imports nothing under `internal/`. It copies one reading the API does not export yet,
the lone reference: `isPath` and `withoutSelectors` in `cmd/fejkdata`, pinned to the
the lone reference: `isPath`, `hasEmptySegment` and `withoutSelectors` in `cmd/fejkdata`, pinned to the
grammar by a test, until `todo.md` item 129 moves that reading into the library.
## A template that does not compile is misuse (exit 2), including a reference that resolves to nothing, save a lone reference under the CLI's `--format` until item 129
@@ -119,8 +119,8 @@ until item 129: it reads a path, and only the data is absent.
Padding is where the two readings disagree: a format string renders it, JSON drops it. A
template that parses as JSON is its JSON, so its padding is dropped, as `encoding/json`
drops it. Goal 5.7 refuses only a spelling that suggests a mistake, and padding around
JSON suggests none.
drops it. Goal 5.7: only an obvious mistake fails to load, and padding around JSON is
none.
## A JSON string stays a template even where its bare text renders alike
@@ -640,8 +640,8 @@ Table section teaches it.
2026-09-18, Lilleman auf Larv. Serves goal 5.6.
A layout may carry the comma that separates arguments,
`'January 2, 2006'`, and a bare `2006-01-02` reads like a third date, so a bare layout is
refused naming the quoted one. The layout is Go's reference time because the
`'January 2, 2006'`, a bare `2006-01-02` reads like a third date, and a double-quoted one
could be quotes printed in the output, so each is refused naming the single-quoted one. The layout is Go's reference time because the
library renders with it and a Go caller already knows it; its names are English, and a
locale's own month and weekday names are data.
+6 -5
View File
@@ -118,12 +118,13 @@ const (
// compileAt compiles a node drawn against no other: no choice's item, or a one-item choice's.
// A weight there does nothing, bar the default 1 written out.
func compileAt(v any, pos position) (node, error) {
w, err := weightOf(v)
if err != nil {
return nil, err
if o, isObject := v.(map[string]any); isObject {
if w, isNumber := o["weight"].(float64); isNumber && w != 1 {
return nil, fmt.Errorf(`weight %v skews a draw between items, and nothing here is drawn against this one; drop "weight"`, w)
}
}
if w != 1 {
return nil, fmt.Errorf(`weight %v skews a draw between items, and nothing here is drawn against this one; drop "weight"`, w)
if _, err := weightOf(v); err != nil {
return nil, err
}
return compileItem(v, pos)
}
+6 -1
View File
@@ -6,7 +6,7 @@
`Bar = 9`
`Next ID = 161`
`Next ID = 162`
| Goal | W |
|---|---|
@@ -123,6 +123,7 @@
| 79 | 0.2.0 | decision | **Beside a `--data-path`, load in `New` the user's categories, the shipped ones they override or read, and the shipped ones whose reads reach an overridden one; load the rest on first reach.** | 6 | 6 | 7 | 8 | 13 | 12.9 |
| 27 | 0.2.0 | | **Merge `en_US.ip` and `sv_SE.ip`, today byte-identical, into one `misc.ip`.** | 3 | 2 | 4 | 6 | 8 | 12.3 |
| 107 | 0.2.0 | decision | **Move the template engine into `internal/`, leaving the root the public API and its options.** | 6 | 9 | 3 | 8 | 3.2, 3.4 | 12.2 |
| 161 | 0.2.0 | | **Refuse an identifier that starts or ends with whitespace, so `{ x as p}` loads as `{x as p}` or every field can be bound to a name.** | 2 | 2 | 2 | 6 | 5.6, 4.1 | 11.7 |
| 112 | 0.2.0 | | **Check a calc's field operands where its template resolves, beside its name operands, once item 36 reports every mistake at once.** | 2 | 2 | 1 | 6 | 3.2 | 10.3 |
| 108 | 0.2.0 | defect | **Name item 26 in the decision "No builtin reads the clock, so a date is bounded by days, never by an age", as the item that ends its conflict with goal 4.** | 1 | 1 | 1 | 4 | 3.4 | 8.0 |
| 38 | 0.3.0 | defect | **Compare `calcParser.binary`'s operator as a rune.** | 1 | 1 | 3 | 6 | 6 | 13.8 |
@@ -465,6 +466,10 @@ The decision "With only the shipped set, a category loads on the first call reac
The engine returns column values and the root builds `Record`. Revises the decision "The template engine stays the root package until item 107; what reads no engine type, a table's rows included, sits in `internal/`", and, if the vocabulary moves, "The vocabulary sits below `doc.go`'s package clause, not in the package doc".
### 161. Refuse an identifier that starts or ends with whitespace, so `{ x as p}` loads as `{x as p}` or every field can be bound to a name.
`grammar/identifier.go` allows a field named ` x`, and `{ x}` reads it, but `checkBind` in `format.go` refuses every padded binding, so no spelling binds that field to a name (goal 4.1), and the refusal names one meaning only (goal 5.6). The goals audit of the narrowed goal 5.7 found it.
### 112. Check a calc's field operands where its template resolves, beside its name operands, once item 36 reports every mistake at once.
Needs item 36. `checkCalcFields` runs at compile and `checkCalcNames` in `resolveTemplates`, two passes over one rule. Moving the field check there before item 36 would change which of two mistakes in two category files a load reports, since every category compiles before any resolves.