@heroiclands/package-build 23.13.0 → 24.0.1

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.
Files changed (236) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +2 -1
  3. package/assets/preview/gitea.ini +12 -7
  4. package/assets/styles/content-base.css +150 -1
  5. package/bin/content-commands.mjs +356 -210
  6. package/bin/package-build.mjs +3 -2
  7. package/ci/check-banners.mjs +7 -7
  8. package/config.mjs +21 -6
  9. package/content-config.mjs +199 -80
  10. package/docs/api.md +93 -72
  11. package/docs/authoring/links-and-markup.md +316 -78
  12. package/docs/commands.md +248 -80
  13. package/docs/configuration.md +210 -102
  14. package/docs/content-format.md +2 -2
  15. package/docs/diagnostics.md +2 -2
  16. package/docs/getting-started.md +1 -1
  17. package/docs/guides/icons.md +1 -1
  18. package/docs/guides/module-project.md +5 -8
  19. package/docs/guides/release-and-deploy.md +2 -2
  20. package/docs/guides/site.md +155 -23
  21. package/docs/guides/system-project.md +1 -1
  22. package/docs/guides/writing-in-invented-scripts.md +1247 -0
  23. package/docs/index.md +1 -0
  24. package/docs/project-setup.md +28 -30
  25. package/docs/reference/format-details.md +589 -308
  26. package/docs/reference/note-types.md +40 -10
  27. package/docs/reference/theme-pages.md +127 -108
  28. package/docs/source-preview.md +15 -1
  29. package/engine/asset-shipping.mjs +22 -10
  30. package/engine/base-compiler.mjs +62 -104
  31. package/engine/changelog-lint.mjs +1 -1
  32. package/engine/content-address.mjs +1 -1
  33. package/engine/content-alerts.mjs +8 -4
  34. package/engine/content-blocks.mjs +26 -11
  35. package/engine/content-embeds.mjs +1 -1
  36. package/engine/content-expand.mjs +376 -0
  37. package/engine/content-figures.mjs +13 -6
  38. package/engine/content-format.yaml +8 -0
  39. package/engine/content-glyphs.mjs +213 -0
  40. package/engine/content-images.mjs +6 -7
  41. package/engine/content-links.mjs +3 -3
  42. package/engine/content-lint.mjs +1 -1
  43. package/engine/content-render.mjs +453 -0
  44. package/engine/content-scripts.mjs +326 -27
  45. package/engine/content-spans.mjs +4 -1
  46. package/engine/content-styles.mjs +91 -0
  47. package/engine/content-symbols.mjs +186 -0
  48. package/engine/content-verse.mjs +6 -18
  49. package/engine/core-report.mjs +169 -0
  50. package/engine/core-vocabulary.mjs +208 -0
  51. package/engine/dictionary-html.mjs +119 -0
  52. package/engine/field-reference.mjs +1 -1
  53. package/engine/frontmatter-lint.mjs +1 -1
  54. package/engine/heading-attributes.mjs +89 -0
  55. package/engine/helpers.mjs +61 -101
  56. package/engine/homepage.mjs +17 -29
  57. package/engine/html-minify.mjs +70 -0
  58. package/engine/index.mjs +8 -5
  59. package/engine/language-rows.mjs +8 -2
  60. package/engine/language-terms.mjs +115 -14
  61. package/engine/language-words.mjs +12 -0
  62. package/engine/logographic.mjs +255 -0
  63. package/engine/map-lexicon.mjs +221 -25
  64. package/engine/map-places.mjs +5 -4
  65. package/engine/markdown-expressions.mjs +0 -2
  66. package/engine/markdownlint-run.mjs +9 -3
  67. package/engine/markup-validation.mjs +21 -0
  68. package/engine/metre-declaration.mjs +134 -0
  69. package/engine/note-matter.mjs +2 -2
  70. package/engine/note-vocabulary.mjs +187 -3
  71. package/engine/pdf-build.mjs +68 -133
  72. package/engine/pdf-render.mjs +102 -44
  73. package/engine/post-fields.mjs +157 -0
  74. package/engine/preview-index.mjs +130 -0
  75. package/engine/preview-source.mjs +450 -0
  76. package/engine/project-init.mjs +5 -12
  77. package/engine/prose-config.mjs +3 -3
  78. package/engine/run-words.mjs +3 -2
  79. package/engine/script-emphasis-terms.mjs +38 -0
  80. package/engine/script-emphasis.mjs +295 -0
  81. package/engine/script-font-delivery.mjs +4 -4
  82. package/engine/site-build.mjs +265 -313
  83. package/engine/site-config.mjs +26 -238
  84. package/engine/site-files.mjs +175 -0
  85. package/engine/site-index.mjs +9 -4
  86. package/engine/site-preview.mjs +50 -523
  87. package/engine/site-reach.mjs +213 -0
  88. package/engine/site-render.mjs +668 -0
  89. package/engine/site-root.mjs +90 -39
  90. package/engine/site-search.mjs +161 -0
  91. package/engine/site-serve.mjs +274 -0
  92. package/engine/site-theme-banner.mjs +154 -0
  93. package/engine/site-theme-urls.mjs +125 -0
  94. package/engine/site-theme.mjs +939 -0
  95. package/engine/sql-tables.mjs +9 -6
  96. package/engine/text-maps.mjs +57 -10
  97. package/engine/typographer.mjs +248 -0
  98. package/engine/verse-metre.mjs +357 -0
  99. package/engine/wikilink-syntax.mjs +29 -47
  100. package/engine/wikilinks.mjs +758 -279
  101. package/engine/word-forms.mjs +39 -24
  102. package/engine/word-rows.mjs +12 -2
  103. package/engine/word-terms.mjs +29 -4
  104. package/manifest.mjs +3 -4
  105. package/package.json +10 -7
  106. package/{hugo-theme → site-theme}/data/banners.yaml +6 -10
  107. package/site-theme/layouts/base.hbs +31 -0
  108. package/site-theme/layouts/blog-list.hbs +30 -0
  109. package/site-theme/layouts/blog-post.hbs +40 -0
  110. package/site-theme/layouts/home.hbs +35 -0
  111. package/site-theme/layouts/list.hbs +20 -0
  112. package/site-theme/layouts/not-found.hbs +31 -0
  113. package/site-theme/layouts/page.hbs +7 -0
  114. package/site-theme/partials/copy-buttons.hbs +37 -0
  115. package/site-theme/partials/draft-notice.hbs +5 -0
  116. package/site-theme/partials/exturl.hbs +2 -0
  117. package/{hugo-theme/layouts/partials/footer.html → site-theme/partials/footer.hbs} +10 -7
  118. package/site-theme/partials/header.hbs +44 -0
  119. package/site-theme/partials/hero-banner.hbs +11 -0
  120. package/site-theme/partials/infobox-entry.hbs +2 -0
  121. package/site-theme/partials/infobox-section.hbs +31 -0
  122. package/site-theme/partials/infobox-value.hbs +2 -0
  123. package/site-theme/partials/infobox.hbs +18 -0
  124. package/site-theme/partials/list-members.hbs +9 -0
  125. package/site-theme/partials/nav-links.hbs +5 -0
  126. package/site-theme/partials/page-body.hbs +48 -0
  127. package/site-theme/partials/page-list.hbs +14 -0
  128. package/site-theme/partials/related.hbs +24 -0
  129. package/site-theme/partials/search-meta.hbs +6 -0
  130. package/site-theme/partials/search-names.hbs +2 -0
  131. package/site-theme/partials/search.hbs +52 -0
  132. package/site-theme/partials/tags.hbs +4 -0
  133. package/site-theme/partials/toc.hbs +7 -0
  134. package/{hugo-theme → site-theme}/static/css/style.css +14 -0
  135. package/stage.mjs +1 -2
  136. package/types/config.d.mts +8 -4
  137. package/types/content-config.d.mts +15 -15
  138. package/types/engine/asset-shipping.d.mts +5 -2
  139. package/types/engine/base-compiler.d.mts +20 -2
  140. package/types/engine/content-address.d.mts +1 -1
  141. package/types/engine/content-alerts.d.mts +8 -2
  142. package/types/engine/content-blocks.d.mts +11 -4
  143. package/types/engine/content-expand.d.mts +288 -0
  144. package/types/engine/content-figures.d.mts +11 -3
  145. package/types/engine/content-glyphs.d.mts +85 -0
  146. package/types/engine/content-images.d.mts +6 -7
  147. package/types/engine/content-links.d.mts +1 -1
  148. package/types/engine/content-render.d.mts +199 -0
  149. package/types/engine/content-scripts.d.mts +62 -0
  150. package/types/engine/content-spans.d.mts +1 -1
  151. package/types/engine/content-styles.d.mts +33 -0
  152. package/types/engine/content-symbols.d.mts +35 -0
  153. package/types/engine/core-report.d.mts +45 -0
  154. package/types/engine/core-vocabulary.d.mts +53 -0
  155. package/types/engine/dictionary-html.d.mts +8 -0
  156. package/types/engine/field-reference.d.mts +1 -1
  157. package/types/engine/heading-attributes.d.mts +20 -0
  158. package/types/engine/helpers.d.mts +3 -10
  159. package/types/engine/homepage.d.mts +11 -24
  160. package/types/engine/html-minify.d.mts +9 -0
  161. package/types/engine/index.d.mts +2 -1
  162. package/types/engine/language-terms.d.mts +24 -2
  163. package/types/engine/logographic.d.mts +45 -0
  164. package/types/engine/map-lexicon.d.mts +48 -8
  165. package/types/engine/map-places.d.mts +8 -0
  166. package/types/engine/markdown-expressions.d.mts +0 -2
  167. package/types/engine/metre-declaration.d.mts +39 -0
  168. package/types/engine/pdf-render.d.mts +6 -2
  169. package/types/engine/post-fields.d.mts +44 -0
  170. package/types/engine/preview-index.d.mts +72 -0
  171. package/types/engine/preview-source.d.mts +51 -0
  172. package/types/engine/script-emphasis-terms.d.mts +21 -0
  173. package/types/engine/script-emphasis.d.mts +84 -0
  174. package/types/engine/script-font-delivery.d.mts +4 -4
  175. package/types/engine/site-build.d.mts +71 -113
  176. package/types/engine/site-config.d.mts +14 -134
  177. package/types/engine/site-files.d.mts +73 -0
  178. package/types/engine/site-index.d.mts +11 -3
  179. package/types/engine/site-preview.d.mts +15 -19
  180. package/types/engine/site-reach.d.mts +76 -0
  181. package/types/engine/site-render.d.mts +173 -0
  182. package/types/engine/site-root.d.mts +14 -4
  183. package/types/engine/site-search.d.mts +54 -0
  184. package/types/engine/site-serve.d.mts +44 -0
  185. package/types/engine/site-theme-banner.d.mts +51 -0
  186. package/types/engine/site-theme-urls.d.mts +60 -0
  187. package/types/engine/site-theme.d.mts +127 -0
  188. package/types/engine/text-maps.d.mts +17 -3
  189. package/types/engine/typographer.d.mts +11 -0
  190. package/types/engine/verse-metre.d.mts +131 -0
  191. package/types/engine/wikilink-syntax.d.mts +30 -48
  192. package/types/engine/wikilinks.d.mts +330 -14
  193. package/types/engine/word-forms.d.mts +3 -2
  194. package/types/manifest.d.mts +3 -4
  195. package/types/stage.d.mts +1 -2
  196. package/types/vendor/markdownlint.d.mts +8 -0
  197. package/vendor/markdownlint.mjs +20388 -0
  198. package/engine/web-wikilinks.mjs +0 -594
  199. package/hugo-theme/layouts/404.html +0 -85
  200. package/hugo-theme/layouts/_default/baseof.html +0 -67
  201. package/hugo-theme/layouts/_default/list.html +0 -139
  202. package/hugo-theme/layouts/_default/single.html +0 -4
  203. package/hugo-theme/layouts/blog/list.html +0 -54
  204. package/hugo-theme/layouts/blog-post/single.html +0 -36
  205. package/hugo-theme/layouts/index.html +0 -75
  206. package/hugo-theme/layouts/partials/banner-url.html +0 -141
  207. package/hugo-theme/layouts/partials/cdn-url.html +0 -36
  208. package/hugo-theme/layouts/partials/dictionary-lists.html +0 -58
  209. package/hugo-theme/layouts/partials/draft-notice.html +0 -41
  210. package/hugo-theme/layouts/partials/draft-state.html +0 -26
  211. package/hugo-theme/layouts/partials/header.html +0 -35
  212. package/hugo-theme/layouts/partials/hero-banner.html +0 -85
  213. package/hugo-theme/layouts/partials/infobox/entry.html +0 -18
  214. package/hugo-theme/layouts/partials/infobox/items.html +0 -26
  215. package/hugo-theme/layouts/partials/infobox/section.html +0 -56
  216. package/hugo-theme/layouts/partials/infobox/value.html +0 -43
  217. package/hugo-theme/layouts/partials/infobox.html +0 -57
  218. package/hugo-theme/layouts/partials/page-body.html +0 -152
  219. package/hugo-theme/layouts/partials/related.html +0 -138
  220. package/hugo-theme/layouts/partials/search.html +0 -84
  221. package/hugo-theme/layouts/partials/site-url.html +0 -32
  222. package/hugo-theme/layouts/partials/tags.html +0 -30
  223. package/hugo-theme/layouts/partials/toc.html +0 -28
  224. package/hugo-theme/layouts/partials/warn-missing-banner.html +0 -3
  225. package/hugo-theme/layouts/shortcodes/cartouche.html +0 -64
  226. package/hugo-theme/layouts/shortcodes/exturl.html +0 -12
  227. package/hugo-theme/layouts/shortcodes/glyph.html +0 -43
  228. package/hugo-theme/layouts/shortcodes/pagelist.html +0 -63
  229. package/hugo-theme/theme.toml +0 -11
  230. package/types/engine/web-wikilinks.d.mts +0 -107
  231. /package/{hugo-theme → site-theme}/data/banner-kinds.yaml +0 -0
  232. /package/{hugo-theme → site-theme}/static/css/sohl-icons.css +0 -0
  233. /package/{hugo-theme → site-theme}/static/fonts/game-icons-kb.woff2 +0 -0
  234. /package/{hugo-theme → site-theme}/static/img/banners/takheperu-hieroglyphs.svg +0 -0
  235. /package/{hugo-theme → site-theme}/static/img/cartouches/takheperu.svg +0 -0
  236. /package/{hugo-theme → site-theme}/static/js/inline-spoilers.js +0 -0
@@ -492,8 +492,7 @@ The event fell on {{dateformat "vrcal" "300.25"}}.
492
492
  The comparison helpers `gt`, `gte`, `lt`, and `lte` take two numbers; `eq`
493
493
  compares two values. `and`, `or`, and `not` combine Boolean results. Nested
494
494
  helpers use Handlebars parentheses. These expressions are replaced on web,
495
- Foundry, and book pages. Code spans and fences remain literal, as do Hugo
496
- shortcodes such as `{{< glyph slug="bes" >}}`. Prefix `\{{` to show an
495
+ Foundry, and book pages. Code spans and fences remain literal. Prefix `\{{` to show an
497
496
  expression literally in prose. A missing property, unresolved
498
497
  calendar, or invalid date produces a located build error.
499
498
 
@@ -2015,7 +2014,8 @@ generic families are not checked. `input`, `layout` and `encoding` in
2015
2014
  Text marked with `font=` or `map=`, or with a declared language, is plain: a
2016
2015
  span or a verse holds no emphasis, link, image, footnote, wikilink, code or
2017
2016
  HTML, and no span but a marked one inside a div or a fence; a div holds
2018
- paragraphs and line breaks only. The text is read as written, so `[`, `]`, `"`,
2017
+ paragraphs and line breaks only. Text set in a face takes `*…*` and `**…**`,
2018
+ set by its [emphasis convention](#script-notes-and-emphasis). The text is read as written, so `[`, `]`, `"`,
2019
2019
  `<<`, `>>`, `!` and `@#$%^&` are characters, and a bracket pair is markup only
2020
2020
  when `(`, `{` or a second `[` makes it a link, a span or a wikilink. Text marked
2021
2021
  with a real language's tag alone keeps its Markdown. See
@@ -2054,12 +2054,13 @@ data:
2054
2054
  - { from: y, to: "\U000F0246", before: consonant }
2055
2055
  ```
2056
2056
 
2057
- | Key | Shape | Meaning |
2058
- | -------- | ---------------------------------------------------- | ------------------------------------------------------------------------------- |
2059
- | `name` | string, required | What `map=` names it by: lowercase letters, digits and `-`, unique in the index |
2060
- | `vowels` | string | The characters `before: vowel` reads as vowels |
2061
- | `fonts` | list of `{ font, rows? }`, required, at least one | The faces the map is drawn in, by slug, each with any rows of its own |
2062
- | `rows` | list of `[from, to]` or `{ from, to, before?, at? }` | The shared rewrites, in authored order |
2057
+ | Key | Shape | Meaning |
2058
+ | ------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------- |
2059
+ | `name` | string, required | What `map=` names it by: lowercase letters, digits and `-`, unique in the index |
2060
+ | `logographic` | `true` | The script writes meanings; see [a logographic map](#a-logographic-map) |
2061
+ | `vowels` | string | The characters `before: vowel` reads as vowels |
2062
+ | `fonts` | list of `{ font, rows? }`, required, at least one | The faces the map is drawn in, by slug, each with any rows of its own |
2063
+ | `rows` | list of `[from, to]` or `{ from, to, before?, at? }` | The shared rewrites, in authored order |
2063
2064
 
2064
2065
  **A face's own rows come first.** A run in a face tries that face's `rows`,
2065
2066
  the longest match among them, and only where none matches the shared `rows`; a
@@ -2116,6 +2117,8 @@ The map's own check reports the rest, each at its key:
2116
2117
 
2117
2118
  > `` `data.map.fonts[0].font` is `mono`, a generic family; a map lists the faces it is drawn in ``
2118
2119
 
2120
+ > `` `data.map.rows[2]` matches `z`, a letter, and the rows of a logographic map write only the text between words ``
2121
+
2119
2122
  The lint checks the listed faces against the installed `@heroiclands/fonts`,
2120
2123
  each at the entry or the row at fault. Every listed face draws every code point
2121
2124
  its own rows write, every code point the shared rows it can reach write (a
@@ -2230,6 +2233,203 @@ every word with its native form, through the same code as the build: see
2230
2233
  [`transliterate`](../commands.md#package-build-transliterate-map-text) and
2231
2234
  [`lexicon`](../commands.md#package-build-lexicon-language).
2232
2235
 
2236
+ #### Metres
2237
+
2238
+ A verse fence that states `scan=` is counted against a metre declared in a
2239
+ `doc` note's `data.metres`, each entry `{ name, beats, kind }`. `name` is
2240
+ lowercase letters, digits and `-`, unique in the package, and a name declared
2241
+ twice is an error at the second. `beats` is a whole number above zero. `kind` is
2242
+ `accentual`: a beat falls on a stressed syllable, and no syllable's length is
2243
+ counted.
2244
+
2245
+ The fence states `lang=` with a language whose `note` names a language note
2246
+ stating `data.sounds.stress` (see [a language's register, sounds and
2247
+ history](#a-languages-register-sounds-and-history)). A word has one beat on its
2248
+ stressed syllable when it has two or more syllables; a one-syllable word has a
2249
+ beat when the `class` base of its lexicon entry is `n`, `v`, `adj`, `num` or
2250
+ `name`, and none when it is any other base; a one-syllable word the lexicon
2251
+ does not hold is counted as a content word; a word whose entries differ in
2252
+ class is a beat that may be left out; and a word of four or more syllables
2253
+ whose stress is not on its first may take a second beat there. A line scans when
2254
+ its count can be the metre's.
2255
+
2256
+ | Finding | Severity |
2257
+ | ----------------------------------------------------------------------------------------------- | -------- |
2258
+ | A line whose beats cannot be the metre's, at the line | warning |
2259
+ | A `scan=` no `data.metres` entry names, at the value | error |
2260
+ | A `scan=` on a fence with no `lang=`, at the key | error |
2261
+ | A `scan=` on a fence whose language states no stress rule or names no language note, at `lang=` | error |
2262
+ | A `scan=` on a verse in columns, at the key | error |
2263
+
2264
+ > ``this line has 4 beats (5 with secondary beats); the metre `hexameter` has 6``
2265
+
2266
+ The count is an author-side check. The rendered fence carries `data-scan` with
2267
+ the metre's name and nothing a reader sees.
2268
+
2269
+ #### A logographic map
2270
+
2271
+ A map stating `logographic: true` writes meanings, so its rows spell no word.
2272
+ Every word of a run under it is written from the run language's lexicon, and
2273
+ the rows write only the text between words: whitespace, points and any other
2274
+ text holding no letter. A word holds at least one letter; a run of digits is
2275
+ text between words. A word is matched case folded, NFC, with `’` read as `'`,
2276
+ and written by the first of these that gives a writing:
2277
+
2278
+ 1. **The entries of its form.** Each entry whose `form`, folded, is the word,
2279
+ and failing that each whose folded `form` with its joining hyphens taken
2280
+ off is the word (`Gar-` for `gar`). An entry is written by its own `native`
2281
+ for the map, the one for the run's face where it states one, else the one
2282
+ for no face; else by its `built` pieces' writings joined in order.
2283
+ 2. **A derived form.** A noun's plural (its own `plural`, else the
2284
+ `data.grammar.plural` rule) and a verb's present form for one person of
2285
+ `data.grammar.verbs.persons` are written by the stem's entry's writing,
2286
+ followed by the `text` of the `data.grammar.native` entry for that ending.
2287
+ Other derived forms (a replacing suffix, an agreeing form, a participle)
2288
+ have no writing of their own here; they are coined as words, or written in
2289
+ signs.
2290
+ 3. **Its hyphenated parts.** A word holding a hyphen or an en dash that the
2291
+ steps above do not write is written by each part in turn, each by steps 1
2292
+ and 2; the hyphen writes nothing.
2293
+
2294
+ A `built` piece is a word of the lexicon written exactly as the piece, else an
2295
+ affix of `data.affixes` whose `form` or `front` is the piece, else either one
2296
+ with joining hyphens taken off; a word piece is written by its own `native` or
2297
+ its own pieces, recursively, and an affix by its own `native`. A piece that
2298
+ reaches a word already being resolved has no writing.
2299
+
2300
+ **Ambiguity.** Where a step matches more than one entry and their writings are
2301
+ not all one text, or one has a writing and another none, the word has no
2302
+ writing and is an error naming every entry's gloss. A part matched that way
2303
+ makes the word ambiguous the same way, naming the part.
2304
+
2305
+ | Key | Shape | Meaning |
2306
+ | ------------------------------ | ------------------------------------------------------- | ------------------------------------------------------- |
2307
+ | `data.affixes[].native` | list of `{ map, font?, text }` | The affix's writing, for a `built` piece naming it |
2308
+ | `data.grammar.native` | list of `{ ending, map, font?, text }` | The signs a derived form takes after its stem's writing |
2309
+ | `data.grammar.native[].ending` | `plural`, `I`, `you`, `heShe`, `we`, `youAll` or `they` | The ending written |
2310
+ | `data.grammar.native[].text` | string, required, may be empty | The ending's signs; empty writes the stem alone |
2311
+
2312
+ ```yaml
2313
+ affixes:
2314
+ - form: "-unet"
2315
+ gloss: "a thing made of"
2316
+ native:
2317
+ - { map: zethu, text: "\U0001EBC7" }
2318
+ grammar:
2319
+ plural:
2320
+ - { ending: "", becomes: "im" }
2321
+ verbs:
2322
+ persons: { I: en, you: et, heShe: "", we: enu, youAll: etu, they: ar }
2323
+ native:
2324
+ - { ending: plural, map: zethu, text: "\U0001EBE1" }
2325
+ - { ending: I, map: zethu, text: "\U0001EBDF" }
2326
+ ```
2327
+
2328
+ A word with no writing, an ambiguous word, and a word in a run with no lexicon
2329
+ to write it from are each an error at the word, once per run:
2330
+
2331
+ > `` `zamlu` has no `zethu` writing in the `khel` lexicon, and its parts do not give one; state one, or write the word directly in signs ``
2332
+
2333
+ > `` `nelgir` stands for 2 words of the `khel` lexicon that the map `zethu` writes differently, “a god” and “god”; write the word directly in signs, choosing by its sense in `package-build lexicon khel --map zethu` ``
2334
+
2335
+ > `` `Gar-nelgir` is written from its part `nelgir`, which stands for 2 words of the `khel` lexicon that the map `zethu` writes differently, “a god” and “god”; write the word directly in signs, choosing by its sense in `package-build lexicon khel --map zethu` ``
2336
+
2337
+ > `` `halzi` has no `zethu` writing: the map `zethu` is logographic, and the run names no `lang=` whose lexicon writes it; mark the run with its language, or write the word directly in signs ``
2338
+
2339
+ > `` `halzi` has no `zethu` writing: the map `zethu` is logographic, and `tant` has no lexicon (`languages.tant.note`) to write it from; write the word directly in signs ``
2340
+
2341
+ Signs typed in the run hold no letter, so they are no word and pass through as
2342
+ typed. The face-coverage check reads the writings as it reads native forms; a
2343
+ word with no writing is reported by its own finding alone. The lexicon check
2344
+ and the register check apply to the run as to any mapped run.
2345
+
2346
+ Under a logographic map a word's `native` is its writing and is not compared
2347
+ with the rows. An affix's `native` and `data.grammar.native` are read only by
2348
+ a logographic map, so an entry naming any other map is an error, as is an
2349
+ ending of a person where the pattern states no `persons`. The checks of a
2350
+ word's `native` (an unknown map, a face the map is not for, a second entry, an
2351
+ undrawn code point) apply to both, a second entry being one for the same
2352
+ ending, map and face:
2353
+
2354
+ > `` `data.affixes[0].native[0]` names the map `roman`, which is not logographic; an affix is written by a native form only under a logographic map ``
2355
+
2356
+ > `` `data.grammar.native[0]` names the map `roman`, which is not logographic; an ending is written by a native form only under a logographic map ``
2357
+
2358
+ > `` `data.grammar.native[2]` states a second native form of the ending `plural` for the map `zethu`; the first is `data.grammar.native[1]` ``
2359
+
2360
+ > `` `data.grammar.native[3]` writes the ending `they`, and `data.grammar.verbs` states no `persons` ``
2361
+
2362
+ Affix and ending writings are not rows of the `natives` relation, which holds
2363
+ the words' native forms; `package-build lexicon` resolves them.
2364
+
2365
+ #### Script notes and emphasis
2366
+
2367
+ A `skill` note of `subType: script` states the faces its script is written in
2368
+ and how the script marks a stressed word, in `data.script`:
2369
+
2370
+ ```yaml
2371
+ data:
2372
+ script:
2373
+ fonts: [qalezu-hand]
2374
+ emphasis: overline
2375
+ strongEmphasis: rubric
2376
+ ```
2377
+
2378
+ - **`fonts`** lists installed faces by the slug `font=` names them by, at least
2379
+ one. A face belongs to one script.
2380
+ - **`emphasis`** is `rubric` or `overline`, and sets both `*…*` and `**…**`
2381
+ (or `_…_` and `__…__`) inside a run in one of the faces.
2382
+ - **`strongEmphasis`**, optional, is `rubric` or `overline`, and sets `**…**`
2383
+ alone.
2384
+
2385
+ A `skill` note of `subType: language` may state `data.emphasis`: `words`,
2386
+ `rubric` or `overline`. It overrides the script's convention in every run of the
2387
+ language. `words` means the language marks emphasis with a word, so `*…*` or
2388
+ `**…**` in a run of the language is an error at the emphasis.
2389
+
2390
+ Inside a run in a face, `_…_` is emphasis equal to `*…*`, and `__…__` equal to
2391
+ `**…**`; Markdown reads them as the same emphasis, and a formatter writes the
2392
+ underscore form. A strikethrough is an error.
2393
+
2394
+ A run's convention is its `lang=` language's `data.emphasis`, read through
2395
+ [`languages.<name>.note`](../configuration.md#languages); else the
2396
+ `data.script` of the script note listing its face; else none. Each convention
2397
+ renders as:
2398
+
2399
+ | Convention | Site and Foundry | Book |
2400
+ | ---------- | ---------------------------------------------------------------- | ----------------------------- |
2401
+ | `rubric` | `<em class="emph-rubric">` or `<strong class="emph-rubric">` | `#text(fill: book-rubric)[…]` |
2402
+ | `overline` | `<em class="emph-overline">` or `<strong class="emph-overline">` | `#overline[…]` |
2403
+ | none | `<em>` or `<strong>`, no class | the text alone |
2404
+
2405
+ Inside a face's run, the element keeps the face's Regular: `font-synthesis:
2406
+ none`, with no slant and no added weight. The two classes and the rubric's
2407
+ colour are described in [the theme](theme-pages.md#emphasis-in-a-script).
2408
+
2409
+ Each of these is an error at the key or the entry at fault:
2410
+
2411
+ > `` `data.script.emphasis` should be `rubric` or `overline`, but reads "rubrik". Did you mean "rubric"? ``
2412
+
2413
+ > `` `data.script` states a script's faces and emphasis, and this note's `subType` is not `script` ``
2414
+
2415
+ > `` `data.emphasis` states how a language marks emphasis, and this note's `subType` is not `language` ``
2416
+
2417
+ > `` `data.script.fonts` is empty; a script lists each face it is written in ``
2418
+
2419
+ > `` `data.script.fonts[0]` is `serif`, a generic family; a script lists the faces it is written in ``
2420
+
2421
+ > `` `data.script.fonts[1]` lists the font `semaron-kuriale` a second time; the first is `data.script.fonts[0]` ``
2422
+
2423
+ > `` `data.script.fonts[0]` is `semaron-kuriale`, which Skills/Scripts/Semaron_Carved.md also lists; a face belongs to one script ``
2424
+
2425
+ > `` `qalezu-hnad` is not a font: `data.script.fonts[1]` names an installed face; did you mean `qalezu-hand`? ``
2426
+
2427
+ In a run:
2428
+
2429
+ > ``text marked `lang=prv font=semaron-kuriale map=semaron` takes emphasis only as `*…*`, `_…_`, `**…**` or `__…__` ``
2430
+
2431
+ > `` `vyl` marks emphasis with a word, not a mark; write the word ``
2432
+
2233
2433
  ### Assets are types
2234
2434
 
2235
2435
  `icon`, `image` and `audio` are types in the type vocabulary, and an address
@@ -3349,7 +3549,7 @@ for the keys.
3349
3549
  | `letters` | `data.sounds.letters` | `letters` (a list), `kind`, `like`, `place`, `tongue` (a list, `NULL` for every tongue) |
3350
3550
  | `edges` | `data.sounds.edges` | `edge`, `sounds` (a list: `[any]` for every sound, empty for none) |
3351
3551
  | `clusters` | `data.sounds.clusters` | No `position`: `max`, one row per language stating it |
3352
- | `stress` | `data.sounds.stress` | No `position`: `stress`, one row per language stating it |
3552
+ | `stress` | `data.sounds.stress` | No `position`: `two`, `longer` and `mark` (`NULL` where unstated), one row per language stating it |
3353
3553
  | `finals` | `data.sounds.finals` | `final`, `like` |
3354
3554
  | `syllables` | `data.sounds.syllables` | No `position`, one row per language stating it: `onsets`, `codas`, `finals`, `doubled`, `vowelPairs`, `neverInitial` and `signature` (lists, `any` a list of one), `initialVowel` and `finalVowel` (`true` or `false`), and the harmony as `harmony_back`, `harmony_front`, `harmony_neutral`, `harmony_neutralAs` and `harmony_partners` (a list of `{ vowel, partner }`) |
3355
3555
  | `joining` | `data.sounds.joining` | `first` and `second` (lists), `written`, `example` |
@@ -5881,242 +6081,261 @@ SoHL sets `system.quantity` to `1` for each compendium item.
5881
6081
  - combat
5882
6082
  - combattechnique
5883
6083
 
5884
- | `data` property | Values | Description |
5885
- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
5886
- | `templatePriority` | `number` | Template priority, _null_ = not a template |
5887
- | `masteryLevel` | `number` | HM3 mastery level |
5888
- | `parentSkill` | `Address` | Parent skill this skill specializes |
5889
- | `names` | `{ pattern, given, <name>... }` | `language` only: how its speakers are named, for `package-build npc new` — see [name lists](#name-lists) |
5890
- | `names.pattern` | `string`, `string[]` or map of `gender` words to either, required | Placeholders such as `{given}`, `{given.male}` and `{clan}`, each naming a list, with literal text around them; a list states several forms, a map each gender's forms |
5891
- | `names.given` | map of `gender` words to lists of names, required | Given names by gender; `female` and `male` are required |
5892
- | `names.given.<name>` | `string[]` | The given names of one gender |
5893
- | `names.<name>` | `string[]` | A list the placeholder of the same name draws from |
5894
- | `family` | `Address` | `language` only: the parent language, naming a skill note with `subType: language`; this language reads the parent's words as its own — see [a language's words](#a-languages-words) |
5895
- | `abbreviation` | `string` | `language` only: the tag a dictionary prints for it, as `Prov.`; its full name where unstated — see [dictionaries and glossaries](#dictionaries-and-glossaries) |
5896
- | `grammar` | `{ plural?, verbs?, agreement?, participles? }` | Optional noun plurals, one verb pattern, agreement and participles; supplied shapes only are checked |
5897
- | `grammar.plural` | `{ ending, becomes }[]` | Literal suffix replacements in authored order; the first match wins |
5898
- | `grammar.plural[].ending` | `string`, required, may be empty | Bare suffix to replace; empty matches every noun |
5899
- | `grammar.plural[].becomes` | `string`, required, may be empty | Bare replacement; empty deletes the matching suffix |
5900
- | `grammar.verbs` | `{ invariant: true }` or `{ persons: { I, you, heShe, we, youAll, they }, replaces? }` | One regular present pattern, printed once at the dictionary head |
5901
- | `grammar.verbs.invariant` | `true` | Verbs do not change; excludes `persons` |
5902
- | `grammar.verbs.persons` | a map of all six ending strings | Each ending is added to the citation form, or replaces its closing `replaces`; excludes `invariant` |
5903
- | `grammar.verbs.persons.I` | `string`, required, may be empty | Ending for I |
5904
- | `grammar.verbs.persons.you` | `string`, required, may be empty | Ending for you |
5905
- | `grammar.verbs.persons.heShe` | `string`, required, may be empty | Ending for he/she |
5906
- | `grammar.verbs.persons.we` | `string`, required, may be empty | Ending for we |
5907
- | `grammar.verbs.persons.youAll` | `string`, required, may be empty | Ending for you all |
5908
- | `grammar.verbs.persons.they` | `string`, required, may be empty | Ending for they |
5909
- | `grammar.verbs.replaces` | `string`, nonempty | Closing letters each ending takes the place of; a citation form closing otherwise takes the ending whole. With `persons` only |
5910
- | `grammar.agreement` | `{ classes, endings }` | Adjectives, pronouns or any other named classes agree by swapping among `endings`; see [optional noun and verb forms](#optional-noun-and-verb-forms) |
5911
- | `grammar.agreement.classes` | `string[]`, required, at least one | Word class bases from the [master word classes](#word-classes), each once |
5912
- | `grammar.agreement.endings` | `string[]`, required, at least two | The singular endings, one per gender; the `plural` rule gives each one's plural |
5913
- | `grammar.participles` | `{ root, affixes }` | Participle suffixes on the verb root; see [optional noun and verb forms](#optional-noun-and-verb-forms) |
5914
- | `grammar.participles.root` | `string[]`, required, at least one, nonempty | Infinitive endings a citation form drops to give the root; the longest that fits wins |
5915
- | `grammar.participles.affixes` | `string[]`, required, at least one | Suffixes of `affixes`, by `form`, each attaching to the root as its `replaces` says |
5916
- | `classModifiers` | `string[]` | `language` only: the word class modifiers the language uses, each from the [master word classes](#word-classes); empty when unstated |
5917
- | `fields` | `{ name, holds }[]` | `language` only: the fields its words are grouped under |
5918
- | `fields[].name` | `string`, required | The field's name, which a word's `field` names |
5919
- | `fields[].holds` | `string`, required | What the field holds |
5920
- | `words` | `{ form, class, field, gloss, … }[]` | `language` only: its words in authored order; its automatic dictionary sorts them alphabetically — see [a language's words](#a-languages-words) |
5921
- | `words[].form` | `string`, required | The word as cited, bare: no backticks |
5922
- | `words[].variants` | `string[]` | Its other forms, as a short form beside a long one; a marked use of one cites the word |
5923
- | `words[].name_sort` | `string` | Its sort key; the form when unstated |
5924
- | `words[].class` | `string`, required | A class from the master word classes, base first: `n I f` |
5925
- | `words[].plural` | `string` | Optional explicit noun plural; the dictionary uses it before the language rule |
5926
- | `words[].field` | `string`, required | One of the note's `fields` names |
5927
- | `words[].gloss` | `string` or `string[]`, required | The meaning, in brief; a list states one sense per entry, which a dictionary numbers |
5928
- | `words[].source` | `{ kind, language?, form? }` | Where the word comes from |
5929
- | `words[].source.kind` | `inherited`, `borrowed`, `kept`, `worn`, `coined`, `substrate` or `island`, required | How the word came into the language |
5930
- | `words[].source.language` | `Address` | The language a `borrowed` word came from, naming a skill note with `subType: language`; required for `borrowed` |
5931
- | `words[].source.form` | `string` | The form the word had in its source, bare |
5932
- | `words[].built` | `string[]` | The pieces the word is built from, in order, as the note's words and affixes write them; absent for a root word |
5933
- | `words[].note` | `string` | What a source says of the word beyond its pieces, as a cognate it is read with |
5934
- | `words[].pronunciation` | `string` | A respelling, as `sol-MEH-reh`: letters, apostrophes and hyphens, at most one syllable in capitals |
5935
- | `words[].tones` | `string` | A tone pattern, as `LHL` |
5936
- | `words[].root` | `string` | A consonantal skeleton, as `d-l-k` |
5937
- | `words[].frame` | `string` | The frame a root is set in, named in `sounds.frames` of the language or an ancestor |
5938
- | `words[].native` | `{ map, font?, text }[]` | The word's native form under a map, stated only where the rows spell it differently — see [a map reads the dictionary first](#a-map-reads-the-dictionary-first) |
5939
- | `words[].native[].map` | `string` | Required: the `data.map.name` the form is written for |
5940
- | `words[].native[].font` | `string` | The one face the form is for, one the map lists; unstated, every face it lists |
5941
- | `words[].native[].text` | `string` | Required: the word as the script writes it |
5942
- | `affixes` | `{ form?, zero?, kind?, given?, where?, gloss, attaches?, examples?, barredAfter?, tones? }[]` | `language` only: the affixes a word's `built` pieces may name; each states a `form` or `zero: true` |
5943
- | `affixes[].form` | `string` | The affix as a `built` piece names it, as `-rith`; absent on a zero affix |
5944
- | `affixes[].zero` | `boolean` | The affix is written as nothing, as a case with no ending; it states no `form`, prints as `∅`, and no `built` piece names it |
5945
- | `affixes[].kind` | `case`, `derivation`, `tense`, `aspect`, `mood`, `voice`, `name` or `lineage` | What it makes: a case, a derived word, a verb's tense, aspect, mood or voice, a given name's ending or a lineage name's ending |
5946
- | `affixes[].given` | `man`, `woman` or `either` | Who a given name closing on it belongs to; only on an affix of kind `name` |
5947
- | `affixes[].where` | `string` | Where this form stands, for an affix written two ways, as `before a stop`; everywhere where absent |
5948
- | `affixes[].gloss` | `string`, required | What it means |
5949
- | `affixes[].attaches` | `string` | How it attaches, as `replaces a closing vowel` |
5950
- | `affixes[].examples` | `string[]` | The names it is read from |
5951
- | `affixes[].barredAfter` | `string[]` | The sounds a stem may not close on to take the affix, as `[n]` |
5952
- | `affixes[].tones` | `string` | The tone pattern it carries, as `L` |
5953
- | `affixes[].replaces` | `string` | What it takes the place of at the close of the stem: `vowel` for any closing vowel, or the letters, as `a`; added to the whole stem where absent |
5954
- | `affixes[].attachesTo` | `string[]` | The word classes it attaches to, by their base, as `[n, adj]`; every class where absent |
5955
- | `affixes[].lengthens` | `boolean` | Whether the stem's last vowel lengthens before it; `false` where unstated, and never beside `replaces` |
5956
- | `affixes[].front` | `string` | Its form after front vowels, where the language keeps vowel harmony, as `-ür` |
5957
- | `tongues` | `{ tag, meaning, language? }[]` | `language` only: the tags a register row's `tongue` names — see [a language's register, sounds and history](#a-languages-register-sounds-and-history) |
5958
- | `tongues[].tag` | `string`, required | Lowercase letters and digits, as `dunhari`, or a tag closing on `:<tongue>`, as `exonym:<tongue>`, which declares `exonym:vylari` and every tag like it |
5959
- | `tongues[].meaning` | `string`, required | What a name of this tongue is |
5960
- | `tongues[].language` | `Address` | The language note the tag names, where it is one |
5961
- | `register` | `{ name, tongue?, kind?, built?, why? }[]` | `language` only: every name the setting gives in the language's reach; the notes carrying each are derived |
5962
- | `register[].name` | `string`, required | The name, as the setting writes it |
5963
- | `register[].tongue` | `string` | A tag `tongues` declares, or `translation`; a row states a `tongue`, a `kind`, or both |
5964
- | `register[].kind` | `byname`, `given` or `place` | What kind of name it is, in a language that sorts its names by kind |
5965
- | `register[].built` | `string[]` | The pieces the name is built from, as a word's `built` writes them |
5966
- | `register[].gloss` | `string` | What the name means, where the pages give its sense |
5967
- | `register[].why` | `string` | Why the name stands outside the pattern the language's names are built by |
5968
- | `retired` | `{ form, instead?, why }[]` | `language` only: the forms the setting does not write |
5969
- | `retired[].form` | `string`, required | The form the setting does not write |
5970
- | `retired[].instead` | `string` or `string[]` | What is written in its place; absent where nothing is |
5971
- | `retired[].why` | `string`, required | Why the setting does not write it |
5972
- | `scope` | `{ folders?, cultures?, lore?, parents?, addresses?, paths?, types?, skip? }` | `language` only: the notes the register covers |
5973
- | `scope.folders` | `Address[]` | Every note whose `packFolder` is one of these folders |
5974
- | `scope.cultures` | `Address[]` | Every note whose `culture` is one of these cultures |
5975
- | `scope.lore` | `Address[]` | Every note whose `lore` names one of these notes |
5976
- | `scope.parents` | `Address[]` | Every note whose `parents` names one of these notes |
5977
- | `scope.addresses` | `Address[]` | These notes themselves |
5978
- | `scope.paths` | `string[]` | Every note whose file sits below one of these content paths, as `Regions/Aelwyth/` |
5979
- | `scope.types` | `string[]` | The note types covered; a note of another type is out of scope whatever else catches it |
5980
- | `scope.skip` | `Address[]` | Notes out of scope whatever else catches them |
5981
- | `sounds` | `{ letters?, edges?, clusters?, stress?, finals?, syllables?, joining?, joins?, marks?, skeleton?, frames?, readPast? }` | `language` only: the letters it writes and the rules its words keep |
5982
- | `sounds.letters` | `{ letters, kind, like?, place?, tongue? }[]` | The letters and the sounds they stand for |
5983
- | `sounds.letters[].letters` | `string[]`, required | The letters or digraphs the row describes |
5984
- | `sounds.letters[].kind` | `string`, required | What kind of sound they write, as `consonant` or `long vowel` |
5985
- | `sounds.letters[].like` | `string` | What they sound like; absent where the row states only their kind and place |
5986
- | `sounds.letters[].place` | `string` | Where in the mouth they are made, as `lips` or `tongue-tip` |
5987
- | `sounds.letters[].tongue` | `string` or `string[]` | The tongues that write them, as tags `tongues` declares; every one where absent |
5988
- | `sounds.edges` | `{ edge, sounds }[]` | The sounds that may stand at each edge of a word, one entry per edge |
5989
- | `sounds.edges[].edge` | `openConsonant`, `openCluster`, `closeConsonant`, `closeCluster`, `innerCluster`, `vowelPair`, `glide` or `syllabic`, required | Which edge the sounds stand at |
5990
- | `sounds.edges[].sounds` | `string[]` or `any`, required | The sounds; `any` for every one, an empty list for none |
5991
- | `sounds.clusters` | `{ max, groups? }` | How many consonants may stand together |
5992
- | `sounds.clusters.max` | `integer`, required | The most consonants that stand together inside a word |
5993
- | `sounds.clusters.groups` | `{ what, clusters, use }[]` | The clusters that may stand inside a word, in groups; a language stating them states no `innerCluster` edge |
5994
- | `sounds.clusters.groups[].what` | `string`, required | What the group's clusters are made of, as `a nasal and a fricative` |
5995
- | `sounds.clusters.groups[].clusters` | `string[]`, required | The clusters, as written; no cluster stands in two groups |
5996
- | `sounds.clusters.groups[].use` | `common` or `sparing`, required | How often the group's clusters stand inside a word |
5997
- | `sounds.stress` | `first syllable`, `penultimate or final`, `by weight` or `as marked` | Where a word's stress falls |
5998
- | `sounds.finals` | `{ final, like }[]` | The syllable finals, for a language whose syllables are parsed by them |
5999
- | `sounds.finals[].final` | `string`, required | The final, as `ang` |
6000
- | `sounds.finals[].like` | `string`, required | What it sounds like |
6001
- | `sounds.syllables` | map of syllable rules | What a syllable and a word may open and close on |
6002
- | `sounds.syllables.onsets` | `single` | What a syllable opens on: a single consonant |
6003
- | `sounds.syllables.codas` | `string[]` or `any` | The consonants that may close a syllable |
6004
- | `sounds.syllables.finals` | `string[]` or `any` | The consonants that may close a word |
6005
- | `sounds.syllables.doubled` | `string[]` | The doubled consonants a word may hold; none where empty |
6006
- | `sounds.syllables.vowelPairs` | `string[]` | The vowels that may stand together; none where empty |
6007
- | `sounds.syllables.initialVowel` | `boolean` | Whether a word may open on a vowel |
6008
- | `sounds.syllables.finalVowel` | `boolean` | Whether a word may close on a vowel; `true` where unstated |
6009
- | `sounds.syllables.neverInitial` | `string[]` | The letters that never open a word |
6010
- | `sounds.syllables.signature` | `string[]` | The letters that mark a word as the language's own |
6011
- | `sounds.syllables.harmony` | `{ back, front, neutral?, neutralAs?, partners? }` | The vowel harmony a word keeps |
6012
- | `sounds.syllables.harmony.back` | `string[]`, required | The back vowels |
6013
- | `sounds.syllables.harmony.front` | `string[]`, required | The front vowels |
6014
- | `sounds.syllables.harmony.neutral` | `string[]` | The vowels of neither set |
6015
- | `sounds.syllables.harmony.neutralAs` | `back` or `front` | The set a word of neutral vowels alone counts as |
6016
- | `sounds.syllables.harmony.partners` | map of vowels to front vowels | The front vowel each vowel turns to in an affix's front form, keyed by the vowel |
6017
- | `sounds.syllables.harmony.partners.<name>` | `string` | One vowel's partner, one of the harmony's `front` vowels; the key is a vowel of the harmony |
6018
- | `sounds.joining` | `{ first, second, written, example? }[]` | How two parts are written where the first closes and the second opens on the given sounds |
6019
- | `sounds.joining[].first` | `string[]`, required | The sounds the first part closes on |
6020
- | `sounds.joining[].second` | `string[]`, required | The sounds the second part opens on |
6021
- | `sounds.joining[].written` | `string`, required | What is written where they meet, as `â`; a join closing on `+`, as `y+`, keeps both and sets it between |
6022
- | `sounds.joining[].example` | `string` | A word joined so |
6023
- | `sounds.joins` | `{ meeting, rule, letters?, where? }[]` | What happens where two parts of a word meet, one entry per meeting |
6024
- | `sounds.joins[].meeting` | `C+C`, `V+C` or `V+V`, required | Which sounds meet: a consonant or a vowel closing the first part, then opening the second |
6025
- | `sounds.joins[].rule` | `merge`, `insert`, `drop` or `double`, required | What happens: one is written, `letters` are set between, the first is lost, or the consonant is doubled |
6026
- | `sounds.joins[].letters` | `string[]` | The letters `insert` sets between or `double` doubles |
6027
- | `sounds.joins[].where` | `string` | Where it holds, as `between stems`; everywhere where absent |
6028
- | `sounds.marks` | `{ mark, letters, kind, limit }[]` | The marks the language writes on its letters |
6029
- | `sounds.marks[].mark` | `string`, required | The mark's name, as `acute` |
6030
- | `sounds.marks[].letters` | `string[]`, required | The letters that carry it |
6031
- | `sounds.marks[].kind` | `stress` or `length`, required | What it says of its letter |
6032
- | `sounds.marks[].limit` | `one` or `any`, required | How many a word may carry |
6033
- | `sounds.skeleton` | `{ second, between? }[]` | The vowel set between a root's second and third consonants |
6034
- | `sounds.skeleton[].second` | `string[]` or `any`, required | The second consonants the row holds for; `any` for every other |
6035
- | `sounds.skeleton[].between` | `string` | The vowel set between; nothing where absent or empty |
6036
- | `sounds.frames` | `{ frame, shape, class, makes, examples? }[]` | The patterns a root is set in |
6037
- | `sounds.frames[].frame` | `string`, required | The frame's name, which a word's `frame` names |
6038
- | `sounds.frames[].shape` | `string`, required | The pattern, the root's consonants numbered, as `K1aK2K3` |
6039
- | `sounds.frames[].class` | `string[]`, required | The classes of word it makes, each a base of the [master word classes](#word-classes) |
6040
- | `sounds.frames[].makes` | `string`, required | What it makes of a root |
6041
- | `sounds.frames[].examples` | map of roots to forms | The form a root takes in the frame, keyed by the root |
6042
- | `sounds.frames[].examples.<name>` | `string` | One root's form, bare |
6043
- | `sounds.readPast` | `{ written, readAs?, what }[]` | Marks and spellings a word is read through before the sound rules hold it |
6044
- | `sounds.readPast[].written` | `string`, required | The mark or spelling the pages write |
6045
- | `sounds.readPast[].readAs` | `string` | What the word is read with in its place; absent where it is read as nothing |
6046
- | `sounds.readPast[].what` | `string`, required | What the mark or spelling is |
6047
- | `sounds.mutations` | `{ mutation, sound, becomes, example? }[]` | The sounds a word changes where a named mutation holds, one entry per sound |
6048
- | `sounds.mutations[].mutation` | `string`, required | The mutation's name, as `wearing`; its rows share it |
6049
- | `sounds.mutations[].sound` | `string`, required | The sound where the mutation does not hold, as `p`; once per mutation |
6050
- | `sounds.mutations[].becomes` | `string`, required | What it becomes where the mutation holds, as `v` |
6051
- | `sounds.mutations[].example` | `string` | A word that shows it |
6052
- | `soundChanges` | `{ name, from?, to?, steps }[]` | `language` only: named sets of ordered changes, each making one tongue's words from another's |
6053
- | `soundChanges[].name` | `string`, required | The set's name, which no other set of the note shares |
6054
- | `soundChanges[].from` | `Address` | The language note whose words the steps start from |
6055
- | `soundChanges[].to` | `Address` | The language note whose words the steps make |
6056
- | `soundChanges[].takes` | `string` | The form of the older word the steps start from, as `accusative`; its citation form where absent |
6057
- | `soundChanges[].steps` | `{ step, change, where? }[]`, required | The steps, in the order they apply |
6058
- | `soundChanges[].steps[].step` | `string`, required | The step's label, as `A1` or `"1"`; no label stands twice in a set |
6059
- | `soundChanges[].steps[].change` | `string`, required | The change in arrow notation, as `` `ph` > `f`; `kh` > `h` ``, or the operation it names in words |
6060
- | `soundChanges[].steps[].where` | `string` | Where it holds, as `word end`; everywhere where absent |
6061
- | `elements` | `{ form, variants?, position?, kind?, sense, examples?, word?, joining? }[]` | `language` only: the elements its names are built from |
6062
- | `elements[].form` | `string`, required | The element, as `arn-` |
6063
- | `elements[].variants` | `string[]` | The element's other forms, as `aldr-` beside `ald-` |
6064
- | `elements[].position` | `opening`, `closing`, `either` or `link` | Where in a name it stands |
6065
- | `elements[].kind` | `byname`, `given` or `place` | The kind of name it builds, in a language that keeps one set of elements per kind; every kind where absent |
6066
- | `elements[].sense` | `string`, required | What it means |
6067
- | `elements[].examples` | `string[]` | The names it is read from |
6068
- | `elements[].word` | `string` | The word it is the stem of, a form of `words` of the language or an ancestor |
6069
- | `elements[].joining` | `string` | The element's joining form, as `-borgar`, when it qualifies another word |
6070
- | `roots` | `{ root, sense, field? }[]` | `language` only: the consonantal roots its words are set from |
6071
- | `roots[].root` | `string`, required | The root, as `d-l-k` |
6072
- | `roots[].sense` | `string`, required | What it means |
6073
- | `roots[].field` | `string` | The field it belongs to, as `stone` |
6074
- | `cognates` | `{ forms, proto?, gloss }[]` | `language` only: sets of forms one older word takes in several languages, stated on the eldest |
6075
- | `cognates[].forms` | map of language Addresses to forms, required | The form the set takes in each language, keyed by the language note |
6076
- | `cognates[].forms.<name>` | `string` | One language's form, bare |
6077
- | `cognates[].gloss` | `string`, required | What the forms mean |
6078
- | `cognates[].proto` | `string` | The reconstructed form the set descends from, in no attested language; printed with an asterisk |
6079
- | `callingNames` | `{ closings, minSyllables }` | `language` only: the short name a long given name is called by |
6080
- | `callingNames.closings` | `{ form?, doubled?, usual }[]`, required | What a calling name closes on |
6081
- | `callingNames.closings[].form` | `string` | The ending, as `-u`; a row states `form` or `doubled`, never both |
6082
- | `callingNames.closings[].doubled` | `boolean` | The calling name doubles the first syllable instead of taking an ending |
6083
- | `callingNames.closings[].usual` | `man`, `woman` or `either`, required | Whose name it usually makes |
6084
- | `callingNames.minSyllables` | `integer`, required | The fewest syllables a given name has that the pages give a calling name |
6085
- | `older` | `{ form, gloss?, layer? }[]` | `language` only: the words and names older than its rules, which no sound or name rule holds |
6086
- | `older[].form` | `string`, required | The form as the setting writes it; no form stands twice |
6087
- | `older[].gloss` | `string` | What it means |
6088
- | `older[].layer` | `string` | The historical layer it belongs to, as `Primordial` |
6089
- | `negation` | `{ particle, mutation? }` | `language` only: how a verb is negated |
6090
- | `negation.particle` | `string`, required | The particle that stands before the verb, a form of `words` of the language or an ancestor |
6091
- | `negation.mutation` | `string` | The mutation the negated verb takes, named in `sounds.mutations` |
6092
- | `naming` | `{ shapes?, edges?, draws?, heldFrom?, nearName? }` | `language` only: the shapes, edges and sources its names keep beyond its words' rules |
6093
- | `naming.shapes` | `{ of, syllables?, perVowel? }[]` | How long each class of name runs |
6094
- | `naming.shapes[].of` | `name`, `given`, `clan`, `bound` or `compound`, required | The class of name; once per class |
6095
- | `naming.shapes[].syllables` | `{ min, max }` | How many syllables a name of the class runs to |
6096
- | `naming.shapes[].syllables.min` | `integer`, required | The fewest |
6097
- | `naming.shapes[].syllables.max` | `integer`, required | The most; never below `min` |
6098
- | `naming.shapes[].perVowel` | `{ min, max }` | How many consonants a name of the class carries to each vowel; a shape states this, `syllables`, or both |
6099
- | `naming.shapes[].perVowel.min` | `number`, required | The fewest |
6100
- | `naming.shapes[].perVowel.max` | `number`, required | The most; never below `min` |
6101
- | `naming.edges` | `{ edge, sounds, vowel?, of? }[]` | The sounds a name may open and close on, where names keep edges ordinary words do not |
6102
- | `naming.edges[].edge` | an `edge` of `sounds.edges`, required | Which edge of a name the sounds stand at; once per class of name |
6103
- | `naming.edges[].sounds` | `string[]` or `any`, required | The sounds; `any` for every one, an empty list for none |
6104
- | `naming.edges[].vowel` | `boolean` | Whether a vowel may stand at the edge too; `false` where unstated |
6105
- | `naming.edges[].of` | `name`, `given`, `clan`, `bound` or `compound` | The class of name the edge holds for; `name`, every name, where absent |
6106
- | `naming.draws` | `{ kind, elements }[]` | The element kinds each kind of name is built from |
6107
- | `naming.draws[].kind` | `byname`, `given` or `place`, required | The kind of name; once per kind |
6108
- | `naming.draws[].elements` | list of `byname`, `given` or `place`, required | The element kinds, as `elements[].kind` states them |
6109
- | `naming.heldFrom` | `{ source, takes, clip?, joining?, elements? }[]` | What a place name takes first, by what the place is held from |
6110
- | `naming.heldFrom[].source` | `string`, required | What the place is held from, as `a founder` |
6111
- | `naming.heldFrom[].takes` | `stem`, `godName`, `givenName` or `element`, required | What stands first: a name-stem in any grade, a god's name, a founder's given name, or one of `elements` |
6112
- | `naming.heldFrom[].clip` | `first` | How the name is clipped: to its first element; whole where absent. A name row only |
6113
- | `naming.heldFrom[].joining` | `string[]` | The joining endings, one of which stands at the seam after the name. A name row only |
6114
- | `naming.heldFrom[].elements` | `string[]` | The elements that may stand first; required on, and only on, a row that takes an `element` |
6115
- | `naming.nearName` | `{ minSyllables, examples? }` | The near name a long given name carries |
6116
- | `naming.nearName.minSyllables` | `integer`, required | The fewest syllables a given name has that carries a near name |
6117
- | `naming.nearName.examples` | `{ near, given }[]` | Worked near names |
6118
- | `naming.nearName.examples[].near` | `string`, required | The near name |
6119
- | `naming.nearName.examples[].given` | `string`, required | The given name it is the near name of |
6084
+ | `data` property | Values | Description |
6085
+ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
6086
+ | `templatePriority` | `number` | Template priority, _null_ = not a template |
6087
+ | `masteryLevel` | `number` | HM3 mastery level |
6088
+ | `parentSkill` | `Address` | Parent skill this skill specializes |
6089
+ | `names` | `{ pattern, given, <name>... }` | `language` only: how its speakers are named, for `package-build npc new` — see [name lists](#name-lists) |
6090
+ | `names.pattern` | `string`, `string[]` or map of `gender` words to either, required | Placeholders such as `{given}`, `{given.male}` and `{clan}`, each naming a list, with literal text around them; a list states several forms, a map each gender's forms |
6091
+ | `names.given` | map of `gender` words to lists of names, required | Given names by gender; `female` and `male` are required |
6092
+ | `names.given.<name>` | `string[]` | The given names of one gender |
6093
+ | `names.<name>` | `string[]` | A list the placeholder of the same name draws from |
6094
+ | `family` | `Address` | `language` only: the parent language, naming a skill note with `subType: language`; this language reads the parent's words as its own — see [a language's words](#a-languages-words) |
6095
+ | `abbreviation` | `string` | `language` only: the tag a dictionary prints for it, as `Prov.`; its full name where unstated — see [dictionaries and glossaries](#dictionaries-and-glossaries) |
6096
+ | `core` | `boolean` | `language` only: `true` where the language must cover the [core vocabulary](#the-core-vocabulary) |
6097
+ | `grammar` | `{ plural?, verbs?, agreement?, participles? }` | Optional noun plurals, one verb pattern, agreement and participles; supplied shapes only are checked |
6098
+ | `grammar.plural` | `{ ending, becomes }[]` | Literal suffix replacements in authored order; the first match wins |
6099
+ | `grammar.plural[].ending` | `string`, required, may be empty | Bare suffix to replace; empty matches every noun |
6100
+ | `grammar.plural[].becomes` | `string`, required, may be empty | Bare replacement; empty deletes the matching suffix |
6101
+ | `grammar.verbs` | `{ invariant: true }` or `{ persons: { I, you, heShe, we, youAll, they }, replaces? }` | One regular present pattern, printed once at the dictionary head |
6102
+ | `grammar.verbs.invariant` | `true` | Verbs do not change; excludes `persons` |
6103
+ | `grammar.verbs.persons` | a map of all six ending strings | Each ending is added to the citation form, or replaces its closing `replaces`; excludes `invariant` |
6104
+ | `grammar.verbs.persons.I` | `string`, required, may be empty | Ending for I |
6105
+ | `grammar.verbs.persons.you` | `string`, required, may be empty | Ending for you |
6106
+ | `grammar.verbs.persons.heShe` | `string`, required, may be empty | Ending for he/she |
6107
+ | `grammar.verbs.persons.we` | `string`, required, may be empty | Ending for we |
6108
+ | `grammar.verbs.persons.youAll` | `string`, required, may be empty | Ending for you all |
6109
+ | `grammar.verbs.persons.they` | `string`, required, may be empty | Ending for they |
6110
+ | `grammar.verbs.replaces` | `string`, nonempty | Closing letters each ending takes the place of; a citation form closing otherwise takes the ending whole. With `persons` only |
6111
+ | `grammar.agreement` | `{ classes, endings }` | Adjectives, pronouns or any other named classes agree by swapping among `endings`; see [optional noun and verb forms](#optional-noun-and-verb-forms) |
6112
+ | `grammar.agreement.classes` | `string[]`, required, at least one | Word class bases from the [master word classes](#word-classes), each once |
6113
+ | `grammar.agreement.endings` | `string[]`, required, at least two | The singular endings, one per gender; the `plural` rule gives each one's plural |
6114
+ | `grammar.participles` | `{ root, affixes }` | Participle suffixes on the verb root; see [optional noun and verb forms](#optional-noun-and-verb-forms) |
6115
+ | `grammar.participles.root` | `string[]`, required, at least one, nonempty | Infinitive endings a citation form drops to give the root; the longest that fits wins |
6116
+ | `grammar.participles.affixes` | `string[]`, required, at least one | Suffixes of `affixes`, by `form`, each attaching to the root as its `replaces` says |
6117
+ | `classModifiers` | `string[]` | `language` only: the word class modifiers the language uses, each from the [master word classes](#word-classes); empty when unstated |
6118
+ | `fields` | `{ name, holds }[]` | `language` only: the fields its words are grouped under |
6119
+ | `fields[].name` | `string`, required | The field's name, which a word's `field` names |
6120
+ | `fields[].holds` | `string`, required | What the field holds |
6121
+ | `words` | `{ form, class, field, gloss, … }[]` | `language` only: its words in authored order; its automatic dictionary sorts them alphabetically — see [a language's words](#a-languages-words) |
6122
+ | `words[].form` | `string`, required | The word as cited, bare: no backticks |
6123
+ | `words[].variants` | `string[]` | Its other forms, as a short form beside a long one; a marked use of one cites the word, and a mapped run accepts it |
6124
+ | `words[].name_sort` | `string` | Its sort key; the form when unstated |
6125
+ | `words[].class` | `string`, required | A class from the master word classes, base first: `n I f` |
6126
+ | `words[].plural` | `string` | Optional explicit noun plural; the dictionary uses it before the language rule |
6127
+ | `words[].field` | `string`, required | One of the note's `fields` names |
6128
+ | `words[].gloss` | `string` or `string[]`, required | The meaning, in brief; a list states one sense per entry, which a dictionary numbers |
6129
+ | `words[].concept` | `string` or `string[]` | The core concepts the word serves, each an `id` of a [`data.concepts`](#the-core-vocabulary) list; one id, or a list for a word that serves several |
6130
+ | `words[].source` | `{ kind, language?, form? }` | Where the word comes from |
6131
+ | `words[].source.kind` | `inherited`, `borrowed`, `kept`, `worn`, `coined`, `substrate` or `island`, required | How the word came into the language |
6132
+ | `words[].source.language` | `Address` | The language a `borrowed` word came from, naming a skill note with `subType: language`; required for `borrowed` |
6133
+ | `words[].source.form` | `string` | The form the word had in its source, bare |
6134
+ | `words[].built` | `string[]` | The pieces the word is built from, in order, as the note's words and affixes write them; absent for a root word |
6135
+ | `words[].note` | `string` | What a source says of the word beyond its pieces, as a cognate it is read with |
6136
+ | `words[].pronunciation` | `string` | A respelling, as `sol-MEH-reh`: letters, apostrophes and hyphens, at most one syllable in capitals |
6137
+ | `words[].tones` | `string` | A tone pattern, as `LHL` |
6138
+ | `words[].root` | `string` | A consonantal skeleton, as `d-l-k` |
6139
+ | `words[].frame` | `string` | The frame a root is set in, named in `sounds.frames` of the language or an ancestor |
6140
+ | `words[].native` | `{ map, font?, text }[]` | The word's native form under a map, stated only where the rows spell it differently — see [a map reads the dictionary first](#a-map-reads-the-dictionary-first) |
6141
+ | `words[].native[].map` | `string` | Required: the `data.map.name` the form is written for |
6142
+ | `words[].native[].font` | `string` | The one face the form is for, one the map lists; unstated, every face it lists |
6143
+ | `words[].native[].text` | `string` | Required: the word as the script writes it |
6144
+ | `affixes` | `{ form?, zero?, kind?, given?, where?, gloss, attaches?, examples?, barredAfter?, tones? }[]` | `language` only: the affixes a word's `built` pieces may name; each states a `form` or `zero: true` |
6145
+ | `affixes[].form` | `string` | The affix as a `built` piece names it, as `-rith`; absent on a zero affix |
6146
+ | `affixes[].zero` | `boolean` | The affix is written as nothing, as a case with no ending; it states no `form`, prints as `∅`, and no `built` piece names it |
6147
+ | `affixes[].kind` | `case`, `derivation`, `tense`, `aspect`, `mood`, `voice`, `name` or `lineage` | What it makes: a case, a derived word, a verb's tense, aspect, mood or voice, a given name's ending or a lineage name's ending |
6148
+ | `affixes[].given` | `man`, `woman` or `either` | Who a given name closing on it belongs to; only on an affix of kind `name` |
6149
+ | `affixes[].where` | `string` | Where this form stands, for an affix written two ways, as `before a stop`; everywhere where absent |
6150
+ | `affixes[].gloss` | `string`, required | What it means |
6151
+ | `affixes[].attaches` | `string` | How it attaches, as `replaces a closing vowel` |
6152
+ | `affixes[].examples` | `string[]` | The names it is read from |
6153
+ | `affixes[].barredAfter` | `string[]` | The sounds a stem may not close on to take the affix, as `[n]` |
6154
+ | `affixes[].tones` | `string` | The tone pattern it carries, as `L` |
6155
+ | `affixes[].replaces` | `string` | What it takes the place of at the close of the stem: `vowel` for any closing vowel, or the letters, as `a`; added to the whole stem where absent |
6156
+ | `affixes[].attachesTo` | `string[]` | The word classes it attaches to, by their base, as `[n, adj]`; every class where absent |
6157
+ | `affixes[].lengthens` | `boolean` | Whether the stem's last vowel lengthens before it; `false` where unstated, and never beside `replaces` |
6158
+ | `affixes[].front` | `string` | Its form after front vowels, where the language keeps vowel harmony, as `-ür` |
6159
+ | `tongues` | `{ tag, meaning, language? }[]` | `language` only: the tags a register row's `tongue` names — see [a language's register, sounds and history](#a-languages-register-sounds-and-history) |
6160
+ | `tongues[].tag` | `string`, required | Lowercase letters and digits, as `dunhari`, or a tag closing on `:<tongue>`, as `exonym:<tongue>`, which declares `exonym:vylari` and every tag like it |
6161
+ | `tongues[].meaning` | `string`, required | What a name of this tongue is |
6162
+ | `tongues[].language` | `Address` | The language note the tag names, where it is one |
6163
+ | `register` | `{ name, tongue?, kind?, built?, why? }[]` | `language` only: every name the setting gives in the language's reach; the notes carrying each are derived |
6164
+ | `register[].name` | `string`, required | The name, as the setting writes it |
6165
+ | `register[].tongue` | `string` | A tag `tongues` declares, or `translation`; a row states a `tongue`, a `kind`, or both |
6166
+ | `register[].kind` | `byname`, `given` or `place` | What kind of name it is, in a language that sorts its names by kind |
6167
+ | `register[].built` | `string[]` | The pieces the name is built from, as a word's `built` writes them |
6168
+ | `register[].gloss` | `string` | What the name means, where the pages give its sense |
6169
+ | `register[].why` | `string` | Why the name stands outside the pattern the language's names are built by |
6170
+ | `retired` | `{ form, instead?, why }[]` | `language` only: the forms the setting does not write |
6171
+ | `retired[].form` | `string`, required | The form the setting does not write |
6172
+ | `retired[].instead` | `string` or `string[]` | What is written in its place; absent where nothing is |
6173
+ | `retired[].why` | `string`, required | Why the setting does not write it |
6174
+ | `scope` | `{ folders?, cultures?, lore?, parents?, addresses?, paths?, types?, skip? }` | `language` only: the notes the register covers |
6175
+ | `scope.folders` | `Address[]` | Every note whose `packFolder` is one of these folders |
6176
+ | `scope.cultures` | `Address[]` | Every note whose `culture` is one of these cultures |
6177
+ | `scope.lore` | `Address[]` | Every note whose `lore` names one of these notes |
6178
+ | `scope.parents` | `Address[]` | Every note whose `parents` names one of these notes |
6179
+ | `scope.addresses` | `Address[]` | These notes themselves |
6180
+ | `scope.paths` | `string[]` | Every note whose file sits below one of these content paths, as `Regions/Aelwyth/` |
6181
+ | `scope.types` | `string[]` | The note types covered; a note of another type is out of scope whatever else catches it |
6182
+ | `scope.skip` | `Address[]` | Notes out of scope whatever else catches them |
6183
+ | `sounds` | `{ letters?, edges?, clusters?, stress?, finals?, syllables?, joining?, joins?, marks?, skeleton?, frames?, readPast? }` | `language` only: the letters it writes and the rules its words keep |
6184
+ | `sounds.letters` | `{ letters, kind, like?, place?, tongue? }[]` | The letters and the sounds they stand for |
6185
+ | `sounds.letters[].letters` | `string[]`, required | The letters or digraphs the row describes |
6186
+ | `sounds.letters[].kind` | `string`, required | What kind of sound they write, as `consonant` or `long vowel` |
6187
+ | `sounds.letters[].like` | `string` | What they sound like; absent where the row states only their kind and place |
6188
+ | `sounds.letters[].place` | `string` | Where in the mouth they are made, as `lips` or `tongue-tip` |
6189
+ | `sounds.letters[].tongue` | `string` or `string[]` | The tongues that write them, as tags `tongues` declares; every one where absent |
6190
+ | `sounds.edges` | `{ edge, sounds }[]` | The sounds that may stand at each edge of a word, one entry per edge |
6191
+ | `sounds.edges[].edge` | `openConsonant`, `openCluster`, `closeConsonant`, `closeCluster`, `innerCluster`, `vowelPair`, `glide` or `syllabic`, required | Which edge the sounds stand at |
6192
+ | `sounds.edges[].sounds` | `string[]` or `any`, required | The sounds; `any` for every one, an empty list for none |
6193
+ | `sounds.clusters` | `{ max, groups? }` | How many consonants may stand together |
6194
+ | `sounds.clusters.max` | `integer`, required | The most consonants that stand together inside a word |
6195
+ | `sounds.clusters.groups` | `{ what, clusters, use }[]` | The clusters that may stand inside a word, in groups; a language stating them states no `innerCluster` edge |
6196
+ | `sounds.clusters.groups[].what` | `string`, required | What the group's clusters are made of, as `a nasal and a fricative` |
6197
+ | `sounds.clusters.groups[].clusters` | `string[]`, required | The clusters, as written; no cluster stands in two groups |
6198
+ | `sounds.clusters.groups[].use` | `common` or `sparing`, required | How often the group's clusters stand inside a word |
6199
+ | `sounds.stress` | `{ two, longer, mark? }` | Where a word's stress falls, as a rule a program reads |
6200
+ | `sounds.stress.two` | `first` or `last`, required | The stressed syllable of a word of two syllables |
6201
+ | `sounds.stress.longer` | `antepenultimate`, `penultimate` or `final`, required | The stressed syllable of a word of three or more, counted from its end |
6202
+ | `sounds.stress.mark` | `acute`, `grave` or `circumflex` | The diacritic that marks a stress the rule would not choose; it moves the stress to the syllable it sits on |
6203
+ | `sounds.finals` | `{ final, like }[]` | The syllable finals, for a language whose syllables are parsed by them |
6204
+ | `sounds.finals[].final` | `string`, required | The final, as `ang` |
6205
+ | `sounds.finals[].like` | `string`, required | What it sounds like |
6206
+ | `sounds.syllables` | map of syllable rules | What a syllable and a word may open and close on |
6207
+ | `sounds.syllables.onsets` | `single` | What a syllable opens on: a single consonant |
6208
+ | `sounds.syllables.codas` | `string[]` or `any` | The consonants that may close a syllable |
6209
+ | `sounds.syllables.finals` | `string[]` or `any` | The consonants that may close a word |
6210
+ | `sounds.syllables.doubled` | `string[]` | The doubled consonants a word may hold; none where empty |
6211
+ | `sounds.syllables.vowelPairs` | `string[]` | The vowels that may stand together; none where empty |
6212
+ | `sounds.syllables.initialVowel` | `boolean` | Whether a word may open on a vowel |
6213
+ | `sounds.syllables.finalVowel` | `boolean` | Whether a word may close on a vowel; `true` where unstated |
6214
+ | `sounds.syllables.neverInitial` | `string[]` | The letters that never open a word |
6215
+ | `sounds.syllables.signature` | `string[]` | The letters that mark a word as the language's own |
6216
+ | `sounds.syllables.harmony` | `{ back, front, neutral?, neutralAs?, partners? }` | The vowel harmony a word keeps |
6217
+ | `sounds.syllables.harmony.back` | `string[]`, required | The back vowels |
6218
+ | `sounds.syllables.harmony.front` | `string[]`, required | The front vowels |
6219
+ | `sounds.syllables.harmony.neutral` | `string[]` | The vowels of neither set |
6220
+ | `sounds.syllables.harmony.neutralAs` | `back` or `front` | The set a word of neutral vowels alone counts as |
6221
+ | `sounds.syllables.harmony.partners` | map of vowels to front vowels | The front vowel each vowel turns to in an affix's front form, keyed by the vowel |
6222
+ | `sounds.syllables.harmony.partners.<name>` | `string` | One vowel's partner, one of the harmony's `front` vowels; the key is a vowel of the harmony |
6223
+ | `sounds.joining` | `{ first, second, written, example? }[]` | How two parts are written where the first closes and the second opens on the given sounds |
6224
+ | `sounds.joining[].first` | `string[]`, required | The sounds the first part closes on |
6225
+ | `sounds.joining[].second` | `string[]`, required | The sounds the second part opens on |
6226
+ | `sounds.joining[].written` | `string`, required | What is written where they meet, as `â`; a join closing on `+`, as `y+`, keeps both and sets it between |
6227
+ | `sounds.joining[].example` | `string` | A word joined so |
6228
+ | `sounds.joins` | `{ meeting, rule, letters?, where? }[]` | What happens where two parts of a word meet, one entry per meeting |
6229
+ | `sounds.joins[].meeting` | `C+C`, `V+C` or `V+V`, required | Which sounds meet: a consonant or a vowel closing the first part, then opening the second |
6230
+ | `sounds.joins[].rule` | `merge`, `insert`, `drop` or `double`, required | What happens: one is written, `letters` are set between, the first is lost, or the consonant is doubled |
6231
+ | `sounds.joins[].letters` | `string[]` | The letters `insert` sets between or `double` doubles |
6232
+ | `sounds.joins[].where` | `string` | Where it holds, as `between stems`; everywhere where absent |
6233
+ | `sounds.marks` | `{ mark, letters, kind, limit }[]` | The marks the language writes on its letters |
6234
+ | `sounds.marks[].mark` | `string`, required | The mark's name, as `acute` |
6235
+ | `sounds.marks[].letters` | `string[]`, required | The letters that carry it |
6236
+ | `sounds.marks[].kind` | `stress` or `length`, required | What it says of its letter |
6237
+ | `sounds.marks[].limit` | `one` or `any`, required | How many a word may carry |
6238
+ | `sounds.skeleton` | `{ second, between? }[]` | The vowel set between a root's second and third consonants |
6239
+ | `sounds.skeleton[].second` | `string[]` or `any`, required | The second consonants the row holds for; `any` for every other |
6240
+ | `sounds.skeleton[].between` | `string` | The vowel set between; nothing where absent or empty |
6241
+ | `sounds.frames` | `{ frame, shape, class, makes, examples? }[]` | The patterns a root is set in |
6242
+ | `sounds.frames[].frame` | `string`, required | The frame's name, which a word's `frame` names |
6243
+ | `sounds.frames[].shape` | `string`, required | The pattern, the root's consonants numbered, as `K1aK2K3` |
6244
+ | `sounds.frames[].class` | `string[]`, required | The classes of word it makes, each a base of the [master word classes](#word-classes) |
6245
+ | `sounds.frames[].makes` | `string`, required | What it makes of a root |
6246
+ | `sounds.frames[].examples` | map of roots to forms | The form a root takes in the frame, keyed by the root |
6247
+ | `sounds.frames[].examples.<name>` | `string` | One root's form, bare |
6248
+ | `sounds.readPast` | `{ written, readAs?, what }[]` | Marks and spellings a word is read through before the sound rules hold it |
6249
+ | `sounds.readPast[].written` | `string`, required | The mark or spelling the pages write |
6250
+ | `sounds.readPast[].readAs` | `string` | What the word is read with in its place; absent where it is read as nothing |
6251
+ | `sounds.readPast[].what` | `string`, required | What the mark or spelling is |
6252
+ | `sounds.mutations` | `{ mutation, sound, becomes, example? }[]` | The sounds a word changes where a named mutation holds, one entry per sound |
6253
+ | `sounds.mutations[].mutation` | `string`, required | The mutation's name, as `wearing`; its rows share it |
6254
+ | `sounds.mutations[].sound` | `string`, required | The sound where the mutation does not hold, as `p`; once per mutation |
6255
+ | `sounds.mutations[].becomes` | `string`, required | What it becomes where the mutation holds, as `v` |
6256
+ | `sounds.mutations[].example` | `string` | A word that shows it |
6257
+ | `soundChanges` | `{ name, from?, to?, steps }[]` | `language` only: named sets of ordered changes, each making one tongue's words from another's |
6258
+ | `soundChanges[].name` | `string`, required | The set's name, which no other set of the note shares |
6259
+ | `soundChanges[].from` | `Address` | The language note whose words the steps start from |
6260
+ | `soundChanges[].to` | `Address` | The language note whose words the steps make |
6261
+ | `soundChanges[].takes` | `string` | The form of the older word the steps start from, as `accusative`; its citation form where absent |
6262
+ | `soundChanges[].steps` | `{ step, change, where? }[]`, required | The steps, in the order they apply |
6263
+ | `soundChanges[].steps[].step` | `string`, required | The step's label, as `A1` or `"1"`; no label stands twice in a set |
6264
+ | `soundChanges[].steps[].change` | `string`, required | The change in arrow notation, as `` `ph` > `f`; `kh` > `h` ``, or the operation it names in words |
6265
+ | `soundChanges[].steps[].where` | `string` | Where it holds, as `word end`; everywhere where absent |
6266
+ | `elements` | `{ form, variants?, position?, kind?, sense, examples?, word?, joining? }[]` | `language` only: the elements its names are built from |
6267
+ | `elements[].form` | `string`, required | The element, as `arn-` |
6268
+ | `elements[].variants` | `string[]` | The element's other forms, as `aldr-` beside `ald-` |
6269
+ | `elements[].position` | `opening`, `closing`, `either` or `link` | Where in a name it stands |
6270
+ | `elements[].kind` | `byname`, `given` or `place` | The kind of name it builds, in a language that keeps one set of elements per kind; every kind where absent |
6271
+ | `elements[].sense` | `string`, required | What it means |
6272
+ | `elements[].examples` | `string[]` | The names it is read from |
6273
+ | `elements[].word` | `string` | The word it is the stem of, a form of `words` of the language or an ancestor |
6274
+ | `elements[].joining` | `string` | The element's joining form, as `-borgar`, when it qualifies another word |
6275
+ | `roots` | `{ root, sense, field? }[]` | `language` only: the consonantal roots its words are set from |
6276
+ | `roots[].root` | `string`, required | The root, as `d-l-k` |
6277
+ | `roots[].sense` | `string`, required | What it means |
6278
+ | `roots[].field` | `string` | The field it belongs to, as `stone` |
6279
+ | `cognates` | `{ forms, proto?, gloss }[]` | `language` only: sets of forms one older word takes in several languages, stated on the eldest |
6280
+ | `cognates[].forms` | map of language Addresses to forms, required | The form the set takes in each language, keyed by the language note |
6281
+ | `cognates[].forms.<name>` | `string` | One language's form, bare |
6282
+ | `cognates[].gloss` | `string`, required | What the forms mean |
6283
+ | `cognates[].proto` | `string` | The reconstructed form the set descends from, in no attested language; printed with an asterisk |
6284
+ | `callingNames` | `{ closings, minSyllables }` | `language` only: the short name a long given name is called by |
6285
+ | `callingNames.closings` | `{ form?, doubled?, usual }[]`, required | What a calling name closes on |
6286
+ | `callingNames.closings[].form` | `string` | The ending, as `-u`; a row states `form` or `doubled`, never both |
6287
+ | `callingNames.closings[].doubled` | `boolean` | The calling name doubles the first syllable instead of taking an ending |
6288
+ | `callingNames.closings[].usual` | `man`, `woman` or `either`, required | Whose name it usually makes |
6289
+ | `callingNames.minSyllables` | `integer`, required | The fewest syllables a given name has that the pages give a calling name |
6290
+ | `older` | `{ form, gloss?, layer? }[]` | `language` only: the words and names older than its rules, which no sound or name rule holds |
6291
+ | `older[].form` | `string`, required | The form as the setting writes it; no form stands twice |
6292
+ | `older[].gloss` | `string` | What it means |
6293
+ | `older[].layer` | `string` | The historical layer it belongs to, as `Primordial` |
6294
+ | `negation` | `{ particle, mutation? }` | `language` only: how a verb is negated |
6295
+ | `negation.particle` | `string`, required | The particle that stands before the verb, a form of `words` of the language or an ancestor |
6296
+ | `negation.mutation` | `string` | The mutation the negated verb takes, named in `sounds.mutations` |
6297
+ | `naming` | `{ shapes?, edges?, draws?, heldFrom?, nearName? }` | `language` only: the shapes, edges and sources its names keep beyond its words' rules |
6298
+ | `naming.shapes` | `{ of, syllables?, perVowel? }[]` | How long each class of name runs |
6299
+ | `naming.shapes[].of` | `name`, `given`, `clan`, `bound` or `compound`, required | The class of name; once per class |
6300
+ | `naming.shapes[].syllables` | `{ min, max }` | How many syllables a name of the class runs to |
6301
+ | `naming.shapes[].syllables.min` | `integer`, required | The fewest |
6302
+ | `naming.shapes[].syllables.max` | `integer`, required | The most; never below `min` |
6303
+ | `naming.shapes[].perVowel` | `{ min, max }` | How many consonants a name of the class carries to each vowel; a shape states this, `syllables`, or both |
6304
+ | `naming.shapes[].perVowel.min` | `number`, required | The fewest |
6305
+ | `naming.shapes[].perVowel.max` | `number`, required | The most; never below `min` |
6306
+ | `naming.edges` | `{ edge, sounds, vowel?, of? }[]` | The sounds a name may open and close on, where names keep edges ordinary words do not |
6307
+ | `naming.edges[].edge` | an `edge` of `sounds.edges`, required | Which edge of a name the sounds stand at; once per class of name |
6308
+ | `naming.edges[].sounds` | `string[]` or `any`, required | The sounds; `any` for every one, an empty list for none |
6309
+ | `naming.edges[].vowel` | `boolean` | Whether a vowel may stand at the edge too; `false` where unstated |
6310
+ | `naming.edges[].of` | `name`, `given`, `clan`, `bound` or `compound` | The class of name the edge holds for; `name`, every name, where absent |
6311
+ | `naming.draws` | `{ kind, elements }[]` | The element kinds each kind of name is built from |
6312
+ | `naming.draws[].kind` | `byname`, `given` or `place`, required | The kind of name; once per kind |
6313
+ | `naming.draws[].elements` | list of `byname`, `given` or `place`, required | The element kinds, as `elements[].kind` states them |
6314
+ | `naming.heldFrom` | `{ source, takes, clip?, joining?, elements? }[]` | What a place name takes first, by what the place is held from |
6315
+ | `naming.heldFrom[].source` | `string`, required | What the place is held from, as `a founder` |
6316
+ | `naming.heldFrom[].takes` | `stem`, `godName`, `givenName` or `element`, required | What stands first: a name-stem in any grade, a god's name, a founder's given name, or one of `elements` |
6317
+ | `naming.heldFrom[].clip` | `first` | How the name is clipped: to its first element; whole where absent. A name row only |
6318
+ | `naming.heldFrom[].joining` | `string[]` | The joining endings, one of which stands at the seam after the name. A name row only |
6319
+ | `naming.heldFrom[].elements` | `string[]` | The elements that may stand first; required on, and only on, a row that takes an `element` |
6320
+ | `naming.nearName` | `{ minSyllables, examples? }` | The near name a long given name carries |
6321
+ | `naming.nearName.minSyllables` | `integer`, required | The fewest syllables a given name has that carries a near name |
6322
+ | `naming.nearName.examples` | `{ near, given }[]` | Worked near names |
6323
+ | `naming.nearName.examples[].near` | `string`, required | The near name |
6324
+ | `naming.nearName.examples[].given` | `string`, required | The given name it is the near name of |
6325
+ | `grammar.native` | `{ ending, map, font?, text }[]` | Under a logographic map, the signs a derived form takes after its stem's writing — see [a logographic map](#a-logographic-map) |
6326
+ | `grammar.native[].ending` | `plural`, `I`, `you`, `heShe`, `we`, `youAll` or `they`, required | The ending written; a person only where `verbs.persons` is stated |
6327
+ | `grammar.native[].map` | `string`, required | The `data.map.name` of a logographic map |
6328
+ | `grammar.native[].font` | `string` | The one face the writing is for, one the map lists; unstated, every face it lists |
6329
+ | `grammar.native[].text` | `string`, required, may be empty | The ending's signs; empty writes the stem alone |
6330
+ | `affixes[].native` | `{ map, font?, text }[]` | The affix's writing under a logographic map, for a `built` piece naming it |
6331
+ | `affixes[].native[].map` | `string`, required | The `data.map.name` of a logographic map |
6332
+ | `affixes[].native[].font` | `string` | The one face the writing is for, one the map lists; unstated, every face it lists |
6333
+ | `affixes[].native[].text` | `string`, required | The affix as the script writes it |
6334
+ | `emphasis` | `words`, `rubric` or `overline` | `language` only: how the language marks a stressed word, over its script's; `words` makes `*…*` and `**…**` in its runs an error — see [script notes and emphasis](#script-notes-and-emphasis) |
6335
+ | `script` | `{ fonts, emphasis, strongEmphasis? }` | `script` only: the faces the script is written in and how it marks emphasis — see [script notes and emphasis](#script-notes-and-emphasis) |
6336
+ | `script.fonts` | `string[]`, required | Installed faces by the slug `font=` names them by; a face belongs to one script |
6337
+ | `script.emphasis` | `rubric` or `overline`, required | Sets `*…*` and `**…**` in a run in one of its faces |
6338
+ | `script.strongEmphasis` | `rubric` or `overline` | Sets `**…**` instead of `emphasis` |
6120
6339
 
6121
6340
  #### A language's words
6122
6341
 
@@ -6391,6 +6610,51 @@ ORDER BY position
6391
6610
  ```
6392
6611
  ````
6393
6612
 
6613
+ #### The core vocabulary
6614
+
6615
+ A setting can state the concepts every one of its languages has a word for, and
6616
+ measure each language against them from data. Three keys carry it:
6617
+
6618
+ | Key | On | Meaning |
6619
+ | ---------------------- | --------------- | -------------------------------------------------------------------------------------- |
6620
+ | `data.concepts` | a `doc` note | The concept list: `{ id, gloss, group }` entries, in the order the report lists them |
6621
+ | `data.core` | a language note | `true` where the language must cover the list; the report lists these languages |
6622
+ | `data.words[].concept` | a word | The id of the concept the word serves, or a list of ids for a word that serves several |
6623
+
6624
+ ```yaml
6625
+ ---
6626
+ shortcode: coreconcepts
6627
+ name: { full: Core concepts }
6628
+ type: doc
6629
+ subType: reference
6630
+ data:
6631
+ concepts:
6632
+ - { id: see-verb, gloss: to see, group: senses }
6633
+ - { id: smell-noun, gloss: "a smell; a scent", group: senses }
6634
+ - { id: knee, gloss: the knee, group: body }
6635
+ ---
6636
+ ```
6637
+
6638
+ The lint holds each to what it means, each finding located at the key at fault:
6639
+
6640
+ - a concept's `id` is lowercase letters, digits and `-`, stated once in its list
6641
+ and by one note of the package;
6642
+ - a concept's `gloss` and `group` are not blank;
6643
+ - `data.core` is stated on a language note only;
6644
+ - a word's `concept` names entries of a concept list, each once. An id no list
6645
+ declares is an error at the id, with the nearest declared id offered when one
6646
+ is near: `` `smel-noun` is not a core concept; did you mean `smell-noun`? ``.
6647
+ Where no note states `data.concepts`, every id is unknown, and the message
6648
+ says so.
6649
+
6650
+ A language reads the words of its `data.family` chain as its own, so a parent's
6651
+ tagged word covers the daughter's concept. `data.core` is not inherited: each
6652
+ language that must cover the list states it.
6653
+
6654
+ `package-build core` is the report. A concept no word serves is never a lint
6655
+ finding; the report lists it so the language can be filled in. See
6656
+ [`package-build core`](../commands.md#package-build-core).
6657
+
6394
6658
  #### A language's register, sounds and history
6395
6659
 
6396
6660
  A language note states in frontmatter every fact a check reads about its
@@ -6431,7 +6695,7 @@ data:
6431
6695
  - { edge: closeCluster, sounds: [nd, rd] }
6432
6696
  - { edge: vowelPair, sounds: [ai, au, ei] }
6433
6697
  clusters: { max: 2 }
6434
- stress: penultimate or final
6698
+ stress: { two: first, longer: penultimate, mark: acute }
6435
6699
  syllables:
6436
6700
  onsets: single
6437
6701
  codas: [b, d, k, sh]
@@ -6580,8 +6844,14 @@ rules hold it, each with what it is read as, or nothing.
6580
6844
  The rest of `sounds` states what a language's own rules read, each from a
6581
6845
  closed list where its values are words:
6582
6846
 
6583
- - `stress`: `first syllable`, `penultimate or final`, `by weight` or
6584
- `as marked`.
6847
+ - `stress`: the rule a program reads, `{ two, longer, mark? }`. `two` is the
6848
+ stressed syllable of a word of two syllables, `first` or `last`; `longer` is
6849
+ the stressed syllable of a word of three or more, counted from its end,
6850
+ `antepenultimate`, `penultimate` or `final`; `mark` is the diacritic, `acute`,
6851
+ `grave` or `circumflex`, that marks a stress the rule would not choose and
6852
+ moves it to the syllable it sits on. Syllables are vowel groups, a pair listed
6853
+ in `syllables.vowelPairs` counting as one. A verse fence's `scan=` counts
6854
+ beats by this rule; see [metres](#metres).
6585
6855
  - `finals`: the syllable finals, each with what it sounds like, for a language
6586
6856
  whose syllables are parsed by them.
6587
6857
  - `syllables`: what a syllable opens on (`single`, a single consonant), the
@@ -6692,44 +6962,44 @@ that keeps vowel harmony gives an affix's form after front vowels in `front`.
6692
6962
 
6693
6963
  Each finding is located at the key at fault:
6694
6964
 
6695
- | Finding | Severity |
6696
- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
6697
- | Any of these keys on a skill of another subType, at the key | error |
6698
- | An unknown, missing or wrongly shaped key in an entry | error |
6699
- | A value outside its closed list — an `edge`, an element `position` or `kind`, a register `kind`, `stress`, a join's `meeting` or `rule`, a mark's `kind` or `limit`, `onsets`, `neutralAs`, a closing's `usual`, a cluster group's `use`, an affix's `kind` or `given`, a naming class `of`, a draw's `kind` or `elements`, a held-from `takes` or `clip` — at the value | error |
6700
- | A `sounds` word other than `any`, at the value | error |
6701
- | A tongue tag that is not lowercase letters and digits, at the tag | error |
6702
- | A tongue tag stated twice, at the second | error |
6703
- | A register or letter tongue `tongues` does not declare, at the tag | error |
6704
- | An edge stated twice, at the second | error |
6705
- | A sound stated twice in one mutation, at the second | error |
6706
- | A cluster stated in two groups, at the second | error |
6707
- | An `innerCluster` edge beside `clusters.groups`, at the edge | error |
6708
- | A vowel partner keyed by no vowel of the harmony, at the key, or naming no `front` vowel, at the value | error |
6709
- | A form stated twice in `older`, at the second | error |
6710
- | A negation `mutation` that `sounds.mutations` does not name, at the value | error |
6711
- | A negation `particle` or an element `word` that is no word of the language or an ancestor, at the value | error |
6712
- | An affix's `given` where its `kind` is not `name`, at the key | error |
6713
- | An affix with `zero: true` beside a `form`, at `zero`, or with neither, at the entry | error |
6714
- | A naming shape stated twice for one class of name, at the second | error |
6715
- | A naming shape with neither `syllables` nor `perVowel`, at the entry | error |
6716
- | A naming range whose `min` is above its `max`, at the range | error |
6717
- | A naming edge stated twice for one class of name, at the second | error |
6718
- | A kind of name whose draws are stated twice, at the second | error |
6719
- | A held-from row that takes an `element` and names no `elements`, at the row | error |
6720
- | `elements` on a held-from row that takes no element, or `clip` or `joining` on one that takes no name, at the key | error |
6721
- | A `scope` Address that does not resolve, or a type that is no note type | error |
6722
- | A tongue `language` or a cognate form's language that is no language note | error |
6723
- | A register row with neither a `tongue` nor a `kind`, at the row | error |
6724
- | A register row tagged `other:<tongue>` or `exonym:<tongue>` whose tongue no `data.tongues` entry links to one language note, at the tongue | error |
6725
- | A register row tagged `other:<tongue>` or `exonym:<tongue>` whose name the tongue's own register does not list under that tongue, at the name | error |
6726
- | A sound-change set's name stated twice, at the second | error |
6727
- | A step label stated twice in one set, at the second | error |
6728
- | A set's `from` or `to` that is no language note, at the value | error |
6729
- | A frame class that is no word class base, at the class | error |
6730
- | An affix's `attachesTo` that names no class, at the key, or a class that is no word class base or one named twice, at the class | error |
6731
- | An affix stating both `replaces` and `lengthens: true`, at `lengthens` | error |
6732
- | A calling-name closing with both or neither of `form` and `doubled` | error |
6965
+ | Finding | Severity |
6966
+ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
6967
+ | Any of these keys on a skill of another subType, at the key | error |
6968
+ | An unknown, missing or wrongly shaped key in an entry | error |
6969
+ | A value outside its closed list — an `edge`, an element `position` or `kind`, a register `kind`, a stress rule's `two`, `longer` or `mark`, a join's `meeting` or `rule`, a mark's `kind` or `limit`, `onsets`, `neutralAs`, a closing's `usual`, a cluster group's `use`, an affix's `kind` or `given`, a naming class `of`, a draw's `kind` or `elements`, a held-from `takes` or `clip` — at the value | error |
6970
+ | A `sounds` word other than `any`, at the value | error |
6971
+ | A tongue tag that is not lowercase letters and digits, at the tag | error |
6972
+ | A tongue tag stated twice, at the second | error |
6973
+ | A register or letter tongue `tongues` does not declare, at the tag | error |
6974
+ | An edge stated twice, at the second | error |
6975
+ | A sound stated twice in one mutation, at the second | error |
6976
+ | A cluster stated in two groups, at the second | error |
6977
+ | An `innerCluster` edge beside `clusters.groups`, at the edge | error |
6978
+ | A vowel partner keyed by no vowel of the harmony, at the key, or naming no `front` vowel, at the value | error |
6979
+ | A form stated twice in `older`, at the second | error |
6980
+ | A negation `mutation` that `sounds.mutations` does not name, at the value | error |
6981
+ | A negation `particle` or an element `word` that is no word of the language or an ancestor, at the value | error |
6982
+ | An affix's `given` where its `kind` is not `name`, at the key | error |
6983
+ | An affix with `zero: true` beside a `form`, at `zero`, or with neither, at the entry | error |
6984
+ | A naming shape stated twice for one class of name, at the second | error |
6985
+ | A naming shape with neither `syllables` nor `perVowel`, at the entry | error |
6986
+ | A naming range whose `min` is above its `max`, at the range | error |
6987
+ | A naming edge stated twice for one class of name, at the second | error |
6988
+ | A kind of name whose draws are stated twice, at the second | error |
6989
+ | A held-from row that takes an `element` and names no `elements`, at the row | error |
6990
+ | `elements` on a held-from row that takes no element, or `clip` or `joining` on one that takes no name, at the key | error |
6991
+ | A `scope` Address that does not resolve, or a type that is no note type | error |
6992
+ | A tongue `language` or a cognate form's language that is no language note | error |
6993
+ | A register row with neither a `tongue` nor a `kind`, at the row | error |
6994
+ | A register row tagged `other:<tongue>` or `exonym:<tongue>` whose tongue no `data.tongues` entry links to one language note, at the tongue | error |
6995
+ | A register row tagged `other:<tongue>` or `exonym:<tongue>` whose name the tongue's own register does not list under that tongue, at the name | error |
6996
+ | A sound-change set's name stated twice, at the second | error |
6997
+ | A step label stated twice in one set, at the second | error |
6998
+ | A set's `from` or `to` that is no language note, at the value | error |
6999
+ | A frame class that is no word class base, at the class | error |
7000
+ | An affix's `attachesTo` that names no class, at the key, or a class that is no word class base or one named twice, at the class | error |
7001
+ | An affix stating both `replaces` and `lengthens: true`, at `lengthens` | error |
7002
+ | A calling-name closing with both or neither of `form` and `doubled` | error |
6733
7003
 
6734
7004
  A fence sets each table back from its relation:
6735
7005
 
@@ -7918,25 +8188,37 @@ Content prepared to be played — a situation with its cast, places, and possibl
7918
8188
  - howto: A task with an outcome, written as the steps that reach it.
7919
8189
  - concept: An explanation of how something works and why it is shaped that way, read to understand rather than to follow.
7920
8190
  - 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.
7921
-
7922
- | `data` property | Values | Description |
7923
- | --------------------------- | ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
7924
- | `culture` | `Address` | `settingguide` only, and required there: the culture the guide introduces, naming a lore note with `subType: culture` |
7925
- | `map` | `{ name, vowels?, fonts, rows }` | A mapping, which text marked `map=` with its `name` is rewritten by; any subType. See [mapping notes](#mapping-notes) |
7926
- | `map.name` | string | Required: what `map=` names it by, lowercase letters, digits and `-`, unique in the index |
7927
- | `map.vowels` | string | The characters `before: vowel` reads as vowels |
7928
- | `map.rows` | list of `[from, to]` or `{ from, to, before?, at? }` | Required: the rewrites, in authored order |
7929
- | `map.rows[].from` | string of one or more characters | Required in a map row: the characters it matches |
7930
- | `map.rows[].to` | string, which may be empty | Required in a map row: what it writes in their place |
7931
- | `map.rows[].before` | `vowel \| consonant` | What must follow the match |
7932
- | `map.rows[].at` | `start \| end` | Where the match must sit |
7933
- | `map.fonts` | list of `{ font, rows? }` | Required, at least one: the faces the map is drawn in |
7934
- | `map.fonts[].font` | an installed face's slug | Required: the face, as `font=` names it; not `mono`, `serif` or `sans` |
7935
- | `map.fonts[].rows` | list of `[from, to]` or `{ from, to, before?, at? }` | Rows for this face alone, tried before the shared `rows` |
7936
- | `map.fonts[].rows[].from` | string of one or more characters | Required in a map row: the characters it matches |
7937
- | `map.fonts[].rows[].to` | string, which may be empty | Required in a map row: what it writes in their place |
7938
- | `map.fonts[].rows[].before` | `vowel \| consonant` | What must follow the match |
7939
- | `map.fonts[].rows[].at` | `start \| end` | Where the match must sit |
8191
+ - 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.
8192
+
8193
+ | `data` property | Values | Description |
8194
+ | --------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
8195
+ | `culture` | `Address` | `settingguide` only, and required there: the culture the guide introduces, naming a lore note with `subType: culture` |
8196
+ | `concepts` | list of `{ id, gloss, group }` | A core vocabulary's concept list, any subType. See [the core vocabulary](#the-core-vocabulary) |
8197
+ | `date` | `YYYY-MM-DD` | `post` only, and required there: the day the post was published |
8198
+ | `author` | string | `post` only: who wrote the post; a post naming none carries the site's byline, the first entry of `authors` |
8199
+ | `concepts[].id` | string | Required: lowercase letters, digits and `-`, unique in the package |
8200
+ | `concepts[].gloss` | string | Required: what the concept means, in brief |
8201
+ | `concepts[].group` | string | Required: the group the report lists the concept under |
8202
+ | `map` | `{ name, vowels?, fonts, rows }` | A mapping, which text marked `map=` with its `name` is rewritten by; any subType. See [mapping notes](#mapping-notes) |
8203
+ | `map.name` | string | Required: what `map=` names it by, lowercase letters, digits and `-`, unique in the index |
8204
+ | `map.vowels` | string | The characters `before: vowel` reads as vowels |
8205
+ | `map.rows` | list of `[from, to]` or `{ from, to, before?, at? }` | Required: the rewrites, in authored order |
8206
+ | `map.rows[].from` | string of one or more characters | Required in a map row: the characters it matches |
8207
+ | `map.rows[].to` | string, which may be empty | Required in a map row: what it writes in their place |
8208
+ | `map.rows[].before` | `vowel \| consonant` | What must follow the match |
8209
+ | `map.rows[].at` | `start \| end` | Where the match must sit |
8210
+ | `map.fonts` | list of `{ font, rows? }` | Required, at least one: the faces the map is drawn in |
8211
+ | `map.fonts[].font` | an installed face's slug | Required: the face, as `font=` names it; not `mono`, `serif` or `sans` |
8212
+ | `map.fonts[].rows` | list of `[from, to]` or `{ from, to, before?, at? }` | Rows for this face alone, tried before the shared `rows` |
8213
+ | `map.fonts[].rows[].from` | string of one or more characters | Required in a map row: the characters it matches |
8214
+ | `map.fonts[].rows[].to` | string, which may be empty | Required in a map row: what it writes in their place |
8215
+ | `map.fonts[].rows[].before` | `vowel \| consonant` | What must follow the match |
8216
+ | `map.fonts[].rows[].at` | `start \| end` | Where the match must sit |
8217
+ | `metres` | `{ name, beats, kind }[]` | The metres a verse fence's `scan=` names; any subType. See [metres](#metres) |
8218
+ | `metres[].name` | string | Required: what `scan=` names it by, lowercase letters, digits and `-`, unique in the package |
8219
+ | `metres[].beats` | `integer`, required | The beats of one line, above zero |
8220
+ | `metres[].kind` | `accentual` | Required: how the beats are counted |
8221
+ | `map.logographic` | `true` | The script writes meanings: a run's words are written by the lexicon alone, and the rows write only the text between them |
7940
8222
 
7941
8223
  A setting guide introduces one culture's view of the setting, so it names that
7942
8224
  culture, and a `doc` of any other `subType` has no culture of its own to name.
@@ -7988,8 +8270,7 @@ site is its homepage and its pages, and nothing is generated between them.
7988
8270
 
7989
8271
  There is no landing page and no section. A section appears in **no address**: a
7990
8272
  page publishes at `/<package>/<type>-<shortcode>/`, which names no directory. A
7991
- section is what Hugo calls a content directory, and the note format does not
7992
- carry one.
8273
+ section is a content directory, and the note format does not carry one.
7993
8274
 
7994
8275
  So a `doc`'s `subType` is a **genre** and nothing else, closed to the values
7995
8276
  above.