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 27 additions and 16 deletions
Showing only changes of commit 0dfa615b54 - Show all commits
+3 -1
View File
@@ -16,6 +16,8 @@ import (
const (
maxLen = 1 << 20
maxDecimals = 1024
// shortestDecimals prints the fewest digits that read back as the same float64.
shortestDecimals = -1
)
// builtins is the registry of {name(args)} functions. Derivations read the digits
@@ -100,7 +102,7 @@ func chars(alphabet string) func([]string) callFn {
const hexDigits = "0123456789abcdef"
// formatFloat prints v to dp decimals, -1 for the shortest form, and a zero unsigned.
// formatFloat prints v to dp decimals, or shortestDecimals, and a zero unsigned.
func formatFloat(v float64, dp int) string {
s := strconv.FormatFloat(v, 'f', dp, 64)
if strings.HasPrefix(s, "-") && strings.Trim(s, "-0.") == "" {
+3 -3
View File
@@ -187,7 +187,7 @@ func neverNumeric(n node) (text string, never bool) {
// calcPrep parses the expression and decimals once, at compile time, and places each
// operand name at the position expand will read it into. checkCalc proved both args
// valid, so no step here can fail; dp -1 prints the minimal form.
// valid, so no step here can fail.
func calcPrep(args []string) callFn {
expr, err := parseCalc(args[0])
if err != nil { // a nil AST would be a nil dereference per render, with no message
@@ -204,12 +204,12 @@ func calcPrep(args []string) callFn {
}
}
// calcDecimals is a calc's decimals count, or -1 for the shortest form.
// calcDecimals is a calc's decimals count, or shortestDecimals where it names none.
func calcDecimals(args []string) int {
if len(args) == 2 {
return atoi(args[1])
}
return -1
return shortestDecimals
}
// indexVars replaces each operand name with its position in the values expand reads.
+7 -3
View File
@@ -125,10 +125,14 @@ type builtin struct {
// operands names the fields the call reads, which expand renders for it; nil
// for a builtin that reads none.
operands func(args []string) []string
// proveNumber proves what a call prints, token its body: the bounds of its number and the
// datatype of its text, prints or one inside it; nil for a builtin whose text is no number.
// proveNumber bounds the number a call's text reads as, token its body, and says which
// datatypes that text is not; set it where every render reads as a finite number, which
// makes the call a calc operand, and leave it nil otherwise.
proveNumber func(token string, prints DataType, args []string) proven
prints DataType
// prints is the datatype every render's text is, which a typed column holds the call to:
// DataTypeString where it reads as a number but no column should type it, as digits'
// leading zeros; unset where proveNumber is nil.
prints DataType
}
// funcCall splits a "{token}" body shaped name(args) into its parts; ok is false
-2
View File
@@ -26,8 +26,6 @@ least modify.
This round, in order:
- Name `printedNumber`'s `dp` cases, and say on `builtin` what `prints` and
`proveNumber` a new builtin sets: the extender copied `digits` by analogy.
- Rename the names that mislead: `table.pinnedRow` is the row node, not a pinned row;
`table.category` is a bare name beside the dotted `category` of `resolveLink`;
`checkRenders` renders nothing; `fieldAlternation` is a plain `{name}` too; and
+14 -7
View File
@@ -261,16 +261,23 @@ func bounded(lo, hi float64, integral bool) proven {
func magnitude(v proven) float64 { return math.Max(math.Abs(v.lo), math.Abs(v.hi)) }
// printedNumber is what a token printing v to dp decimals holds: an integer when whole
// and within int64, else a number.
// printedNumber is what a token printing v to dp decimals holds.
func printedNumber(token string, v proven, dp int) proven {
if dp >= 0 {
half, _ := strconv.ParseFloat("5e-"+strconv.Itoa(dp+1), 64)
v = proven{lo: v.lo - half, hi: v.hi + half, nonZero: math.Max(0, v.nonZero-half), integral: v.integral || dp == 0}
}
if dp != 0 && !(dp < 0 && v.integral) {
if dp == shortestDecimals {
if v.integral { // a whole value prints with no point
return printedInteger(token, v)
}
return printing(token, DataTypeNumber, v)
}
half, _ := strconv.ParseFloat("5e-"+strconv.Itoa(dp+1), 64)
v = proven{lo: v.lo - half, hi: v.hi + half, nonZero: math.Max(0, v.nonZero-half), integral: v.integral || dp == 0}
if dp == 0 {
return printedInteger(token, v)
}
return printing(token, DataTypeNumber, v)
}
func printedInteger(token string, v proven) proven {
v = printing(token, DataTypeInteger, v)
if !(magnitude(v) < math.MaxInt64) {
v.not[DataTypeInteger] = fmt.Sprintf("{%s} is not proven within int64", token)