docs: sync core-parser spec and add unit normalisation
Bring core-parser.md in line with the resolved design in CONTEXT.md and ADRs 0004/0005, and promote a new decision to normalise ingredient/cookware units. - Full sync of the core-parser spec: diagnostics/total-function channel, container blocks (ListItemBlock, BlockquoteBlock), RawInline alongside RawBlock via position-slicing, the unified WikilinkNode/TransclusionNode shape as two typed nodes, and the minimal remark plugin set. - New ADR 0006: normalise ingredient/cookware units via a known-alias table with passthrough, case-insensitive, canonical-only; align Timer matching to case-insensitive too. - SPEC.md: units are normalised (new Units section, alias table); Timer table marked case-insensitive. - CONTEXT.md: add Unit Normalisation entry, resolve the open item. - fixtures/basic.md: add a blockquote (callout) carrying an annotation and a non-canonical unit so the integration test exercises containers and normalisation. - Expand the core test.todo checklists to cover the new behaviour (containers, raw fallbacks, diagnostics, unit normalisation, wikilink/transclusion variants); still pending, suite stays green.
This commit is contained in:
@@ -26,6 +26,7 @@ The quantity/unit split is **grammar-driven, not last-space-driven**: the parser
|
||||
If the brace content does not begin with a grammar-valid quantity (e.g. `@stock{a splash}`), the entire content is preserved as the quantity string and the unit is left empty — no annotation is dropped.
|
||||
The name is trimmed of surrounding whitespace (interior spaces preserved, so `@unsalted butter{}` stays `unsalted butter`), and the brace content is trimmed before grammar-matching.
|
||||
The unit is the whole remainder after the quantity, so multi-word units work: `@stock{200 fl oz}` → quantity `200`, unit `fl oz`.
|
||||
The unit is normalised: a unit matching a known alias is rewritten to its canonical abbreviation (case-insensitive, multi-word aware), and any unit not in the table is passed through verbatim. See the [[Unit Normalisation]] entry and ADR 0006.
|
||||
Valid name characters: any character except `{`, `}`, `@`, `$`, `~`.
|
||||
|
||||
## Cookware Annotation
|
||||
@@ -35,7 +36,7 @@ Syntax: `$name{}`, `$name{quantity}`, or `$name{quantity unit}`
|
||||
Same `{`-terminated name rule as Ingredient.
|
||||
The `{}` wrapper is mandatory.
|
||||
Quantity is optional; `$pan{}` is valid with no quantity.
|
||||
Quantity and unit follow the same rules as Ingredient: valid formats are integer, decimal, simple fraction, mixed number; unit is free-form; the split is grammar-driven, with non-numeric content preserved wholesale as the quantity string.
|
||||
Quantity and unit follow the same rules as Ingredient: valid formats are integer, decimal, simple fraction, mixed number; the split is grammar-driven, with non-numeric content preserved wholesale as the quantity string; and the unit is normalised via the same known-alias table (see [[Unit Normalisation]]).
|
||||
Valid name characters: any character except `{`, `}`, `@`, `$`, `~`.
|
||||
|
||||
## Timer Annotation
|
||||
@@ -50,9 +51,21 @@ In range form, the `-` separator follows the first quantity expression — since
|
||||
The range `-` must directly abut both numbers: `~10-15 mins` is a range, but `~10 - 15 mins` (spaces around `-`) is plain prose, not a timer.
|
||||
One or more spaces separate the number (or range) from the unit.
|
||||
The annotation terminates after the unit word — trailing prose is ignored. `~1 min more` parses as a timer of 1 min; "more" is plain text.
|
||||
The unit matches only as a complete word (followed by whitespace, punctuation, or end-of-input) and the longest known alias wins (`seconds` before `sec`); `~5 minsx` is not a timer because `minsx` is not a known unit.
|
||||
The unit matches only as a complete word (followed by whitespace, punctuation, or end-of-input), is matched case-insensitively, and the longest known alias wins (`seconds` before `sec`); `~5 minsx` is not a timer because `minsx` is not a known unit.
|
||||
Known unit set (aliases → canonical abbreviation): `sec`, `secs`, `second`, `seconds` → `s`; `min`, `mins`, `minute`, `minutes` → `min`; `hr`, `hrs`, `hour`, `hours` → `hr`.
|
||||
|
||||
## Unit Normalisation
|
||||
|
||||
The Parser normalises Ingredient and Cookware units to a canonical abbreviation from a fixed known-alias table.
|
||||
A unit whose text matches an alias is rewritten to its canonical form; any unit not in the table is passed through verbatim (original casing and spacing preserved).
|
||||
Lookup is **case-insensitive**, multi-word aliases (`fluid ounce`) match on the whole unit string, and only the canonical unit is retained — the author's original spelling is not kept.
|
||||
Single-letter cooking abbreviations (`t`, `T`, `c`) are excluded as ambiguous, and count/descriptive units (`clove`, `pinch`, `to taste`) have no canonical form and pass through unchanged.
|
||||
Timer units are normalised from their own known set (see [[Timer Annotation]]), also case-insensitively.
|
||||
|
||||
Canonical set (aliases → canonical): g, gram, grams → `g`; kg, kilogram, kilograms, kilo, kilos → `kg`; mg, milligram, milligrams → `mg`; oz, ounce, ounces → `oz`; lb, lbs, pound, pounds → `lb`; ml, milliliter, millilitre, milliliters, millilitres → `ml`; l, liter, litre, liters, litres → `l`; tsp, teaspoon, teaspoons → `tsp`; tbsp, tablespoon, tablespoons → `tbsp`; cup, cups → `cup`; fl oz, fluid ounce, fluid ounces → `fl oz`; pt, pint, pints → `pt`; qt, quart, quarts → `qt`; gal, gallon, gallons → `gal`.
|
||||
|
||||
The durable definition of this table lives in the core-parser spec and `SPEC.md`; ADR 0006 records the decision.
|
||||
|
||||
## Recipe File
|
||||
|
||||
A valid `.md` file that may contain any combination of Obsidian Flavored Markdown, YAML frontmatter, and Annotations.
|
||||
@@ -183,4 +196,7 @@ A raw node exposes only that `value` string; it carries no `kind`/type hint (tha
|
||||
|
||||
## Open / Unresolved
|
||||
|
||||
- **Unit normalisation** for Ingredient/Cookware — the parser should normalise known aliases to a canonical abbreviation (`grams` → `g`, `kilograms` → `kg`); exact alias table and canonical forms are TBD. This is a parser concern, not a format constraint. (Timer unit normalisation is already fully specified above.)
|
||||
- _(none currently)_
|
||||
|
||||
Resolved:
|
||||
- **Unit normalisation** for Ingredient/Cookware — resolved as a known-alias table with passthrough, case-insensitive, canonical-only. See [[Unit Normalisation]] and ADR 0006.
|
||||
|
||||
Reference in New Issue
Block a user