@heroiclands/package-build 25.6.0 → 25.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @heroiclands/package-build
2
2
 
3
+ ## 25.6.2
4
+
5
+ **Languages and scripts**
6
+
7
+ - Encoding documents can choose a mapping according to the letter before it, as well as the following letter and word position.
8
+
9
+ ## 25.6.1
10
+
11
+ **Languages and scripts**
12
+
13
+ - Scripts that allow diaeresis can read back the marks in split vowel groups when their writing keeps joined and separate vowels distinct.
14
+ - Language notes and spelling guides can declare pronunciation marks for rising or falling pitch with `kind: tone`.
15
+
3
16
  ## 25.6.0
4
17
 
5
18
  **Changes to act on**
package/docs/api.md CHANGED
@@ -2891,8 +2891,8 @@ expose their schema `key`.
2891
2891
  Encoding rules default to exact, uniquely decodable outputs. A note may state
2892
2892
  `rules.roundTrip: canonical` to permit aliases and empty code sequences;
2893
2893
  `decodeText` then returns the authored conventional reading without restoring
2894
- erased Roman characters. Contextual rules accept `before: vowel|consonant`
2895
- and `at: start|end|line-start`; supplied conditions combine with AND. Accent
2894
+ erased Roman characters. Contextual rules accept `after` (one exact NFC Unicode letter, `vowel` or
2895
+ `consonant`), `before: vowel|consonant` and `at: start|end|line-start`; supplied conditions combine with AND. `after` governs forward encoding only. Accent
2896
2896
  permission blocks accept explicit Boolean values. See [Encoding text](encoding-core.md).
2897
2897
 
2898
2898
  ### `engine.encodingLanguage`
@@ -53,15 +53,16 @@ second behaviour.
53
53
  | `case` | `{single-letter: preserve, consonant-group: lowercase-or-initial-uppercase, other-group-cases: forbidden}`; single letters retain authored case, and groups use lowercase or an initial capital. |
54
54
  | `stress` | `{modifier, position: after-stressed-vowel, printing: false, effect: stress-only, changes-sound: false, changes-length: false, vowel-group-position: first-vowel}`; `modifier` names a font code and acute mappings append it to the unchanged vowel. |
55
55
  | `vowel-groups` | `{reading: established, allow-splitting: false, unrecognized-adjacent-vowels: separate, groups: [...]}`; the explicit group list determines where an acute belongs on its first vowel. |
56
- | `diaeresis` | `{allowed: boolean}` permits or forbids explicitly mapped diaeresis characters. |
56
+ | `diaeresis` | `{allowed: boolean}`; false forbids diaeresis characters; true derives plain-vowel mappings and restores splits of distinctly mapped declared groups. |
57
57
  | `grave-accent` | `{allowed: boolean}` permits or forbids explicitly mapped grave-accent characters. |
58
- | `contextual-mappings` | A list of `{match, emit, before?, at?}`; following-letter or source-position conditions precede unconditional mappings. |
58
+ | `contextual-mappings` | A list of `{match, emit, after?, before?, at?}`; preceding-letter, following-letter or source-position conditions precede unconditional mappings. |
59
59
  | `y` | `{kind: consonant, sound: "y in yes", vowel-reading: false}`; y cannot also appear in `data.vowels`. |
60
60
 
61
61
  The accent blocks accept an explicit Boolean `allowed`. False forbids that
62
- accent; true permits it only where the character is accepted and mapped.
63
- Omitting the block also permits such explicit mappings. Neither choice invents
64
- an accent pronunciation or adds a character to the inventory.
62
+ accent. True on the grave accent permits it only where the character is
63
+ accepted and mapped; true on the diaeresis turns on the
64
+ [diaeresis rule](#the-diaeresis-by-rule). Omitting either block permits
65
+ explicit mappings alone, and no choice invents an accent pronunciation.
65
66
 
66
67
  `rules.roundTrip` is optional and defaults to `exact`. Exact mappings must be
67
68
  uniquely decodable across adjacent mappings and spaces; ambiguous outputs and
@@ -79,13 +80,28 @@ empty outputs or store invisible metadata to restore the original spelling.
79
80
  A language's authoritative vocabulary can recover fuller word spellings.
80
81
  Shared word spaces remain spaces in both modes.
81
82
 
82
- Contextual entries use `{match, emit, before?, at?}` and require at least one
83
- condition. `before` is `vowel` or `consonant`; `at` is `start`, `end` or
83
+ Contextual entries use `{match, emit, after?, before?, at?}` and require at least one
84
+ condition. `after` tests the immediately preceding Unicode scalar in the NFC
85
+ matching stream (including derived diaeresis-to-plain vowel projection). It is
86
+ `vowel`, `consonant`, or one literal NFC Unicode letter, compared exactly and
87
+ case-sensitively; astral letters are permitted. Category conditions require
88
+ `data.vowels`; a literal does not. Neither category matches a missing predecessor, punctuation or space. A literal
89
+ matches only that letter. `after` is a
90
+ positive condition, so refusing an unlisted predecessor requires authored
91
+ allowed alternatives with no unconditional fallback. For example,
92
+ `{match: k, after: a, emit: K_AFTER_A}` selects that font code after `a`.
93
+
94
+ `after` governs forward encoding only, like `at`; decoding does not validate a
95
+ preceding-source condition. Existing inverse `before` checks remain strict in
96
+ exact mode. Source validation permits spellings without mapping coverage for
97
+ authoritative native entries; `encodeText` refuses uncovered source text.
98
+
99
+ `before` is `vowel` or `consonant`; `at` is `start`, `end` or
84
100
  `line-start`. `start` and `end` refer to word boundaries. A consonant is a
85
101
  letter outside the declared `data.vowels`. Line start follows a newline or
86
102
  verse slash and permits preceding indentation carets. Multiple conditions
87
103
  combine with AND. Entries for the same source may use different conditions;
88
- repeating the same source and condition tuple is an error. Equal-length
104
+ repeating the same `(match, after, before, at)` tuple is an error. Equal-length
89
105
  contextual matches retain authored order.
90
106
 
91
107
  ```yaml
@@ -116,7 +132,8 @@ canonical round trips. Decoding keeps the shared space as a space.
116
132
  A contextual match cannot contain whitespace, literal markers or forbidden
117
133
  accents. Both modes enforce the same accepted characters, normalization,
118
134
  case, stress, accent and literal-control rules. The compiler does not infer
119
- linguistic vowel groups or silently add missing letter mappings.
135
+ linguistic vowel groups or silently add missing plain-letter mappings. The
136
+ [diaeresis rule](#the-diaeresis-by-rule) uses only explicitly declared groups.
120
137
 
121
138
  Lint checks every authored word, variant and registered name for a language
122
139
  with an encoding document, including unused entries. It also checks actual
@@ -147,6 +164,42 @@ text to the surrounding sentence. Names, literal codage and independent
147
164
  language children count as text. An explicit mapping can give a standard
148
165
  source its own font glyph. Other punctuation needs its own mapping.
149
166
 
167
+ ### The diaeresis by rule
168
+
169
+ A diaeresis splits a listed vowel group: _kau_ uses the group _au_, while
170
+ _kaü_ sounds its vowels apart. Adjacent vowels outside the declared groups
171
+ already sound separately and need no mark: _kae_ remains _kae_.
172
+
173
+ `diaeresis: {allowed: true}` accepts _ä_, _ë_, _ï_, _ö_ and _ü_, and their
174
+ capitals, using the corresponding plain vowel's mappings and contextual
175
+ rules. No extra mapping rows are needed. This applies only when the plain
176
+ vowel has a mapping of its own and no source explicitly names that diaeresis
177
+ vowel. Explicit mappings retain their authored spelling and glyphs. A derived
178
+ diaeresis blocks a row from joining the preceding vowel, while permitting
179
+ matching from the marked vowel onward. Source pieces and errors retain their
180
+ authored UTF-16 offsets, including decomposed input normalized to NFC.
181
+
182
+ Decoding retains the selected native mapping boundaries. A group written by
183
+ its own mapping stays together; separate mappings receive a diaeresis where
184
+ their letters would otherwise be joined by a declared group mapping. For
185
+ example, with `au: AU`, `a: A` and `u: U`, the AU glyph reads _au_ and the A
186
+ then U glyphs read _aü_. Groups use `rules.vowel-groups.groups`, longest first;
187
+ there is no default group list. Existing marks and the interiors of explicit
188
+ mappings retain their spelling. Literal `⟦…⟧` spans receive no derived marks.
189
+
190
+ The native writing must distinguish the group from its split. A group with
191
+ no mapping of its own, or one emitting the same sequence as its separate
192
+ vowels, cannot restore that distinction. The compiler still accepts such an
193
+ encoding and its bare vowel spelling. An exact encoding refuses a newly
194
+ derived split input when its native path cannot recover the mark. This also
195
+ applies when a particular context or an acute prevents the distinct group
196
+ mapping from matching. Canonical encodings retain their existing longest
197
+ complete native match and authored-alias preferences, so an ambiguous split
198
+ may return the conventional bare spelling. Standalone or non-group diaeresis
199
+ aliases remain accepted, but have no rule-derived mark to restore; this is
200
+ not a pronunciation validator. An encoding that omits the permission block
201
+ or forbids the diaeresis derives no aliases or marks.
202
+
150
203
  ## Conversion API
151
204
 
152
205
  The pure engine works in browsers and Node and opens no files. The caller
@@ -153,8 +153,14 @@ An encoding's output must decode unambiguously, including across adjacent
153
153
  mappings and spaces. The compiler refuses indistinguishable spellings rather
154
154
  than choosing a guessed reading. See [the executable rules](../encoding-core.md).
155
155
 
156
- Mappings match longest first; contextual before-vowel rules precede their
157
- unconditional alternatives. A case rule may allow lowercase and initial-capital
156
+ Mappings match longest first; contextual rules precede their unconditional
157
+ alternatives. A contextual mapping may use `after: vowel`, `after: consonant`
158
+ or one exact NFC letter such as `after: a` to test the preceding source letter.
159
+ It may combine this with `before` and `at`; all supplied conditions must hold.
160
+ The categories use `data.vowels`. These positive conditions need explicit
161
+ allowed alternatives to refuse a predecessor, with no unconditional fallback.
162
+ `after` governs encoding only; see [the executable rules](../encoding-core.md)
163
+ for normalization and decoding details. A case rule may allow lowercase and initial-capital
158
164
  groups while refusing other mixed or uppercase group spellings. Encoding keeps
159
165
  authored case and never rewrites a word's Roman spelling.
160
166
 
@@ -6314,7 +6314,7 @@ SoHL sets `system.quantity` to `1` for each compendium item.
6314
6314
  | `sounds.marks` | `{ mark, letters, kind, limit }[]` | The marks the language writes on its letters |
6315
6315
  | `sounds.marks[].mark` | `string`, required | The mark's name, as `acute` |
6316
6316
  | `sounds.marks[].letters` | `string[]`, required | The letters that carry it |
6317
- | `sounds.marks[].kind` | `stress`, `length`, `apart` or `quality`, required | What it says of its letter |
6317
+ | `sounds.marks[].kind` | `stress`, `length`, `apart`, `quality` or `tone`, required | What it says of its letter; `tone` marks a rising or falling pitch |
6318
6318
  | `sounds.marks[].limit` | `one` or `any`, required | How many a word may carry |
6319
6319
  | `sounds.skeleton` | `{ second, third?, between? }[]` | The vowel set between a root's second and third consonants |
6320
6320
  | `sounds.skeleton[].second` | `string[]` or `any`, required | The second consonants the row holds for; `any` for every other |
@@ -6970,7 +6970,7 @@ closed list where its values are words:
6970
6970
  - `joins`: what happens where a consonant or a vowel meets another (`C+C`,
6971
6971
  `V+C`, `V+V`): `merge`, `insert` the `letters` between, `drop` the first, or
6972
6972
  `double` the consonant, everywhere or `where` stated.
6973
- - `marks`: the marks written on letters, each saying `stress`, `length`, `apart` (the mark sets a vowel to be said apart from its neighbour, as a diaeresis does) or `quality` (the mark changes which vowel is said, as a grave writing the short vowel of _cat_ does), and
6973
+ - `marks`: the marks written on letters, each saying `stress`, `length`, `apart` (the mark sets a vowel to be said apart from its neighbour, as a diaeresis does), `quality` (the mark changes which vowel is said, as a grave writing the short vowel of _cat_ does) or `tone` (marks a rising or falling pitch), and
6974
6974
  whether a word carries `one` at most or `any`.
6975
6975
  - `skeleton`: the vowel set between a root's second and third consonants, by
6976
6976
  the second consonant and, where a row states `third`, the third; nothing
@@ -8319,72 +8319,73 @@ did not foresee. Holes found in play are fixed in the scenario itself.
8319
8319
  - settingguide: A culture's guide to the setting, which names its culture in `data.culture`. It orients a reader to a setting or region, bringing its places, peoples, institutions, and daily life into one usable frame with links to detailed notes.
8320
8320
  - post: A blog post, which states the day it was published in `data.date` and may name its writer in `data.author`. A site whose `site.feed` names a section lists its posts there, newest first, and feeds them as Atom.
8321
8321
 
8322
- | `data` property | Values | Description |
8323
- | ------------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
8324
- | `language` | a configured language alias | The configured language alias an encoding document writes. |
8325
- | `font` | an installed font slug | The encoding's installed font, which supplies all glyph codes. |
8326
- | `accepts` | a list of characters or ranges | Accepted Roman letters and additions to standard punctuation. |
8327
- | `vowels` | a string | The letters a contextual vowel match reads as vowels. |
8328
- | `mappings` | Roman strings to glyph codes | Roman source strings mapped to codes published by the selected font. |
8329
- | `rules` | the closed encoding rules vocabulary | Executable normalization, matching, case, stress, vowel groups, accents and contextual mappings. |
8330
- | `rules.normalization` | "NFC" | Required value: "NFC". |
8331
- | `rules.matching` | "longest-first" | Required value: "longest-first". |
8332
- | `rules.roundTrip` | a string | Exact by default; canonical permits aliases and empty code sequences and decodes an authored conventional spelling. |
8333
- | `rules.word-separators` | a list of nonempty NFC source sequences | Source word dividers written as shared spaces, after contextual alternatives; cannot also be ordinary mappings or replace shared punctuation. |
8334
- | `rules.case` | a map | Case handling for letters and consonant groups. |
8335
- | `rules.case.single-letter` | "preserve" | Required value: "preserve". |
8336
- | `rules.case.consonant-group` | "lowercase-or-initial-uppercase" | Required value: "lowercase-or-initial-uppercase". |
8337
- | `rules.case.other-group-cases` | "forbidden" | Required value: "forbidden". |
8338
- | `rules.stress` | a map | The font's nonprinting stress modifier after an acute vowel. |
8339
- | `rules.stress.modifier` | a string | The font code for U+E0114. |
8340
- | `rules.stress.position` | "after-stressed-vowel" | Required value: "after-stressed-vowel". |
8341
- | `rules.stress.printing` | false | Required value: false. |
8342
- | `rules.stress.effect` | "stress-only" | Required value: "stress-only". |
8343
- | `rules.stress.changes-sound` | false | Required value: false. |
8344
- | `rules.stress.changes-length` | false | Required value: false. |
8345
- | `rules.stress.vowel-group-position` | "first-vowel" | Required value: "first-vowel". |
8346
- | `rules.vowel-groups` | a map | Explicit recognized vowel groups and their acute placement. |
8347
- | `rules.vowel-groups.reading` | "established" | Required value: "established". |
8348
- | `rules.vowel-groups.allow-splitting` | false | Required value: false. |
8349
- | `rules.vowel-groups.unrecognized-adjacent-vowels` | "separate" | Required value: "separate". |
8350
- | `rules.vowel-groups.groups` | a list of vowel groups | The complete authored group inventory. |
8351
- | `rules.diaeresis` | a map | Whether diaeresis mappings are allowed. |
8352
- | `rules.diaeresis.allowed` | true or false | False forbids the accent; true permits explicitly mapped and accepted characters. |
8353
- | `rules.grave-accent` | a map | Whether grave-accent mappings are allowed. |
8354
- | `rules.grave-accent.allowed` | true or false | False forbids the accent; true permits explicitly mapped and accepted characters. |
8355
- | `rules.contextual-mappings` | a list of conditional mappings | Alternatives conditioned on the following letter or source position, applied before unconditional mappings. |
8356
- | `rules.contextual-mappings[].match` | a string | The source sequence. |
8357
- | `rules.contextual-mappings[].before` | a string | Match before a declared vowel or another letter. |
8358
- | `rules.contextual-mappings[].at` | a string | Match at word start, word end or line start. |
8359
- | `rules.contextual-mappings[].emit` | a glyph code or list of codes (empty only with canonical round trips) | The font codes written by this alternative. |
8360
- | `rules.y` | a map | The consonant reading of y. |
8361
- | `rules.y.kind` | "consonant" | Required value: "consonant". |
8362
- | `rules.y.sound` | "y in yes" | Required value: "y in yes". |
8363
- | `rules.y.vowel-reading` | false | Required value: false. |
8364
- | `culture` | `Address` | `settingguide` only, and required there: the culture the guide introduces, naming a lore note with `subType: culture` |
8365
- | `concepts` | list of `{ id, gloss, group }` | A core vocabulary's concept list, any subType. See [the core vocabulary](#the-core-vocabulary) |
8366
- | `date` | `YYYY-MM-DD` | `post` only, and required there: the day the post was published |
8367
- | `author` | string | `post` only: who wrote the post; a post naming none carries the site's byline, the first entry of `authors` |
8368
- | `concepts[].id` | string | Required: lowercase letters, digits and `-`, unique in the package |
8369
- | `concepts[].gloss` | string | Required: what the concept means, in brief |
8370
- | `concepts[].group` | string | Required: the group the report lists the concept under |
8371
- | `metres` | `{ name, beats, kind }[]` | The metres a verse div's `scan=` names; any subType. See [metres](#metres) |
8372
- | `metres[].name` | string | Required: what `scan=` names it by, lowercase letters, digits and `-`, unique in the package |
8373
- | `metres[].beats` | `integer`, required | The beats of one line, above zero |
8374
- | `metres[].kind` | `accentual` | Required: how the beats are counted |
8375
- | `sounds` | `{ letters?, marks? }` | A spelling guide's letters and marks, for every tongue of the setting; any subType. See [a spelling guide's sounds](#a-spelling-guides-sounds) |
8376
- | `sounds.letters` | `{ letters, kind, like?, place?, ipa?, tongue? }[]` | The letters, each row's keys as a language note's `sounds.letters` |
8377
- | `sounds.letters[].letters` | `string[]`, required | The letters or digraphs the row describes |
8378
- | `sounds.letters[].kind` | `string`, required | What kind of sound they write, as `consonant` or `vowel pair` |
8379
- | `sounds.letters[].like` | `string` | What they sound like |
8380
- | `sounds.letters[].place` | `string` | Where in the mouth they are made |
8381
- | `sounds.letters[].ipa` | `string` | The sounds they write, in the International Phonetic Alphabet |
8382
- | `sounds.letters[].tongue` | an Address, or a list of them | The language notes that write the letters; every tongue where absent |
8383
- | `sounds.marks` | `{ mark, letters, kind, limit }[]` | The marks written on the letters, each row's keys as a language note's `sounds.marks` |
8384
- | `sounds.marks[].mark` | `string`, required | The mark's name, as `acute` |
8385
- | `sounds.marks[].letters` | `string[]`, required | The letters that carry it |
8386
- | `sounds.marks[].kind` | `stress`, `length`, `apart` or `quality`, required | What it says of its letter |
8387
- | `sounds.marks[].limit` | `one` or `any`, required | How many a word may carry |
8322
+ | `data` property | Values | Description |
8323
+ | ------------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
8324
+ | `language` | a configured language alias | The configured language alias an encoding document writes. |
8325
+ | `font` | an installed font slug | The encoding's installed font, which supplies all glyph codes. |
8326
+ | `accepts` | a list of characters or ranges | Accepted Roman letters and additions to standard punctuation. |
8327
+ | `vowels` | a string | The letters a contextual vowel match reads as vowels. |
8328
+ | `mappings` | Roman strings to glyph codes | Roman source strings mapped to codes published by the selected font. |
8329
+ | `rules` | the closed encoding rules vocabulary | Executable normalization, matching, case, stress, vowel groups, accents and contextual mappings. |
8330
+ | `rules.normalization` | "NFC" | Required value: "NFC". |
8331
+ | `rules.matching` | "longest-first" | Required value: "longest-first". |
8332
+ | `rules.roundTrip` | a string | Exact by default; canonical permits aliases and empty code sequences and decodes an authored conventional spelling. |
8333
+ | `rules.word-separators` | a list of nonempty NFC source sequences | Source word dividers written as shared spaces, after contextual alternatives; cannot also be ordinary mappings or replace shared punctuation. |
8334
+ | `rules.case` | a map | Case handling for letters and consonant groups. |
8335
+ | `rules.case.single-letter` | "preserve" | Required value: "preserve". |
8336
+ | `rules.case.consonant-group` | "lowercase-or-initial-uppercase" | Required value: "lowercase-or-initial-uppercase". |
8337
+ | `rules.case.other-group-cases` | "forbidden" | Required value: "forbidden". |
8338
+ | `rules.stress` | a map | The font's nonprinting stress modifier after an acute vowel. |
8339
+ | `rules.stress.modifier` | a string | The font code for U+E0114. |
8340
+ | `rules.stress.position` | "after-stressed-vowel" | Required value: "after-stressed-vowel". |
8341
+ | `rules.stress.printing` | false | Required value: false. |
8342
+ | `rules.stress.effect` | "stress-only" | Required value: "stress-only". |
8343
+ | `rules.stress.changes-sound` | false | Required value: false. |
8344
+ | `rules.stress.changes-length` | false | Required value: false. |
8345
+ | `rules.stress.vowel-group-position` | "first-vowel" | Required value: "first-vowel". |
8346
+ | `rules.vowel-groups` | a map | Explicit recognized vowel groups and their acute placement. |
8347
+ | `rules.vowel-groups.reading` | "established" | Required value: "established". |
8348
+ | `rules.vowel-groups.allow-splitting` | false | Required value: false. |
8349
+ | `rules.vowel-groups.unrecognized-adjacent-vowels` | "separate" | Required value: "separate". |
8350
+ | `rules.vowel-groups.groups` | a list of vowel groups | The complete authored group inventory. |
8351
+ | `rules.diaeresis` | a map | Whether diaeresis vowels are allowed, and how they are written. |
8352
+ | `rules.diaeresis.allowed` | true or false | False forbids the diaeresis; true derives plain-vowel mappings and restores splits where a declared group's native mapping distinguishes joined and separate vowels. Exact conversion refuses an unrecoverable derived group split; canonical conversion keeps its conventional reading. |
8353
+ | `rules.grave-accent` | a map | Whether grave-accent mappings are allowed. |
8354
+ | `rules.grave-accent.allowed` | true or false | False forbids the accent; true permits explicitly mapped and accepted characters. |
8355
+ | `rules.contextual-mappings` | a list of conditional mappings | Alternatives conditioned on the preceding letter, following letter or source position, applied before unconditional mappings. |
8356
+ | `rules.contextual-mappings[].match` | a string | The source sequence. |
8357
+ | `rules.contextual-mappings[].after` | one NFC Unicode letter, vowel or consonant | Match after one exact NFC Unicode letter, a declared vowel or another letter. |
8358
+ | `rules.contextual-mappings[].before` | a string | Match before a declared vowel or another letter. |
8359
+ | `rules.contextual-mappings[].at` | a string | Match at word start, word end or line start. |
8360
+ | `rules.contextual-mappings[].emit` | a glyph code or list of codes (empty only with canonical round trips) | The font codes written by this alternative. |
8361
+ | `rules.y` | a map | The consonant reading of y. |
8362
+ | `rules.y.kind` | "consonant" | Required value: "consonant". |
8363
+ | `rules.y.sound` | "y in yes" | Required value: "y in yes". |
8364
+ | `rules.y.vowel-reading` | false | Required value: false. |
8365
+ | `culture` | `Address` | `settingguide` only, and required there: the culture the guide introduces, naming a lore note with `subType: culture` |
8366
+ | `concepts` | list of `{ id, gloss, group }` | A core vocabulary's concept list, any subType. See [the core vocabulary](#the-core-vocabulary) |
8367
+ | `date` | `YYYY-MM-DD` | `post` only, and required there: the day the post was published |
8368
+ | `author` | string | `post` only: who wrote the post; a post naming none carries the site's byline, the first entry of `authors` |
8369
+ | `concepts[].id` | string | Required: lowercase letters, digits and `-`, unique in the package |
8370
+ | `concepts[].gloss` | string | Required: what the concept means, in brief |
8371
+ | `concepts[].group` | string | Required: the group the report lists the concept under |
8372
+ | `metres` | `{ name, beats, kind }[]` | The metres a verse div's `scan=` names; any subType. See [metres](#metres) |
8373
+ | `metres[].name` | string | Required: what `scan=` names it by, lowercase letters, digits and `-`, unique in the package |
8374
+ | `metres[].beats` | `integer`, required | The beats of one line, above zero |
8375
+ | `metres[].kind` | `accentual` | Required: how the beats are counted |
8376
+ | `sounds` | `{ letters?, marks? }` | A spelling guide's letters and marks, for every tongue of the setting; any subType. See [a spelling guide's sounds](#a-spelling-guides-sounds) |
8377
+ | `sounds.letters` | `{ letters, kind, like?, place?, ipa?, tongue? }[]` | The letters, each row's keys as a language note's `sounds.letters` |
8378
+ | `sounds.letters[].letters` | `string[]`, required | The letters or digraphs the row describes |
8379
+ | `sounds.letters[].kind` | `string`, required | What kind of sound they write, as `consonant` or `vowel pair` |
8380
+ | `sounds.letters[].like` | `string` | What they sound like |
8381
+ | `sounds.letters[].place` | `string` | Where in the mouth they are made |
8382
+ | `sounds.letters[].ipa` | `string` | The sounds they write, in the International Phonetic Alphabet |
8383
+ | `sounds.letters[].tongue` | an Address, or a list of them | The language notes that write the letters; every tongue where absent |
8384
+ | `sounds.marks` | `{ mark, letters, kind, limit }[]` | The marks written on the letters, each row's keys as a language note's `sounds.marks` |
8385
+ | `sounds.marks[].mark` | `string`, required | The mark's name, as `acute` |
8386
+ | `sounds.marks[].letters` | `string[]`, required | The letters that carry it |
8387
+ | `sounds.marks[].kind` | `stress`, `length`, `apart`, `quality` or `tone`, required | What it says of its letter; `tone` marks a rising or falling pitch |
8388
+ | `sounds.marks[].limit` | `one` or `any`, required | How many a word may carry |
8388
8389
 
8389
8390
  A setting guide introduces one culture's view of the setting, so it names that
8390
8391
  culture, and a `doc` of any other `subType` has no culture of its own to name.