@heroiclands/package-build 24.1.1 → 25.1.0

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 (107) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +1 -0
  3. package/bin/content-commands.mjs +30 -96
  4. package/bin/encoding-commands.mjs +146 -0
  5. package/bin/package-build.mjs +35 -24
  6. package/config.mjs +25 -0
  7. package/convert.mjs +182 -0
  8. package/docs/api.md +154 -11
  9. package/docs/authoring/links-and-markup.md +260 -473
  10. package/docs/commands.md +118 -119
  11. package/docs/configuration.md +31 -13
  12. package/docs/content-format.md +11 -4
  13. package/docs/diagnostics.md +43 -16
  14. package/docs/encoding-core.md +135 -0
  15. package/docs/guides/book.md +2 -2
  16. package/docs/guides/module-project.md +23 -1
  17. package/docs/guides/site.md +2 -2
  18. package/docs/guides/writing-in-invented-scripts.md +453 -569
  19. package/docs/reference/format-details.md +290 -380
  20. package/docs/reference/note-types.md +80 -62
  21. package/docs/source-preview.md +8 -0
  22. package/e2e.mjs +1 -1
  23. package/engine/base-compiler.mjs +27 -9
  24. package/engine/content-charset.mjs +21 -1
  25. package/engine/content-format.yaml +7 -2
  26. package/engine/content-index.mjs +6 -2
  27. package/engine/content-links.mjs +1 -0
  28. package/engine/content-scripts.mjs +658 -423
  29. package/engine/content-scroll.mjs +4 -4
  30. package/engine/content-spans.mjs +40 -9
  31. package/engine/content-verse.mjs +1 -1
  32. package/engine/converter-data.mjs +70 -0
  33. package/engine/dictionary-rows.mjs +2 -34
  34. package/engine/encoding-integrity.mjs +94 -0
  35. package/engine/encoding-language.mjs +506 -0
  36. package/engine/encoding-lexicon.mjs +699 -0
  37. package/engine/encoding-notes.mjs +186 -0
  38. package/engine/encoding-standard.mjs +42 -0
  39. package/engine/encoding-template.mjs +313 -0
  40. package/engine/encoding-terms.mjs +141 -0
  41. package/engine/encoding.mjs +946 -0
  42. package/engine/extension-attributes.mjs +2 -0
  43. package/engine/helpers.mjs +1 -1
  44. package/engine/index.mjs +10 -0
  45. package/engine/language-data.mjs +4 -1
  46. package/engine/language-terms.mjs +23 -12
  47. package/engine/{logographic.mjs → language-writings.mjs} +29 -38
  48. package/engine/markup-validation.mjs +1 -1
  49. package/engine/note-vocabulary.mjs +4 -158
  50. package/engine/pdf-render.mjs +31 -3
  51. package/engine/roman-characters.mjs +232 -0
  52. package/engine/roman-run.mjs +149 -0
  53. package/engine/roman-verse.mjs +95 -0
  54. package/engine/run-rows.mjs +29 -31
  55. package/engine/run-words.mjs +2 -2
  56. package/engine/script-emphasis-terms.mjs +3 -0
  57. package/engine/script-emphasis.mjs +3 -10
  58. package/engine/script-font-delivery.mjs +9 -12
  59. package/engine/script-fonts.mjs +2 -1
  60. package/engine/site-build.mjs +14 -5
  61. package/engine/site-preview.mjs +12 -2
  62. package/engine/sql-tables.mjs +36 -31
  63. package/engine/verse-metre.mjs +1 -1
  64. package/engine/word-forms.mjs +1 -1
  65. package/engine/word-inflections.mjs +48 -0
  66. package/engine/word-rows.mjs +1 -1
  67. package/engine/word-terms.mjs +16 -17
  68. package/package.json +11 -5
  69. package/types/config.d.mts +5 -0
  70. package/types/convert.d.mts +44 -0
  71. package/types/e2e.d.mts +1 -1
  72. package/types/engine/base-compiler.d.mts +4 -2
  73. package/types/engine/content-charset.d.mts +8 -0
  74. package/types/engine/content-index.d.mts +4 -1
  75. package/types/engine/content-scripts.d.mts +108 -42
  76. package/types/engine/converter-data.d.mts +11 -0
  77. package/types/engine/dictionary-rows.d.mts +1 -25
  78. package/types/engine/encoding-integrity.d.mts +14 -0
  79. package/types/engine/encoding-language.d.mts +36 -0
  80. package/types/engine/encoding-lexicon.d.mts +259 -0
  81. package/types/engine/encoding-notes.d.mts +39 -0
  82. package/types/engine/encoding-standard.d.mts +11 -0
  83. package/types/engine/encoding-template.d.mts +43 -0
  84. package/types/engine/encoding-terms.d.mts +105 -0
  85. package/types/engine/encoding.d.mts +155 -0
  86. package/types/engine/helpers.d.mts +1 -1
  87. package/types/engine/index.d.mts +5 -0
  88. package/types/engine/language-terms.d.mts +1 -1
  89. package/types/engine/{logographic.d.mts → language-writings.d.mts} +6 -6
  90. package/types/engine/markup-validation.d.mts +1 -1
  91. package/types/engine/pdf-render.d.mts +1 -1
  92. package/types/engine/roman-characters.d.mts +45 -0
  93. package/types/engine/roman-run.d.mts +101 -0
  94. package/types/engine/roman-verse.d.mts +23 -0
  95. package/types/engine/run-rows.d.mts +13 -20
  96. package/types/engine/script-emphasis-terms.d.mts +2 -0
  97. package/types/engine/script-emphasis.d.mts +1 -1
  98. package/types/engine/script-font-delivery.d.mts +2 -3
  99. package/types/engine/script-fonts.d.mts +5 -0
  100. package/types/engine/site-preview.d.mts +1 -1
  101. package/types/engine/word-inflections.d.mts +25 -0
  102. package/engine/map-lexicon.mjs +0 -1034
  103. package/engine/text-maps.mjs +0 -654
  104. package/engine/written-in.mjs +0 -204
  105. package/types/engine/map-lexicon.d.mts +0 -330
  106. package/types/engine/text-maps.d.mts +0 -189
  107. package/types/engine/written-in.d.mts +0 -76
@@ -1,204 +0,0 @@
1
- /*
2
- * This file is part of the Song of Heroic Lands (SoHL) system for Foundry VTT.
3
- * Copyright (c) 2024-2026 Tom Rodriguez ("Toasty") — <toasty@heroiclands.org>
4
- *
5
- * This work is licensed under the GNU General Public License v3.0 (GPLv3).
6
- * You may copy, modify, and distribute it under the terms of that license.
7
- *
8
- * For full terms, see the LICENSE.md file in the project root or visit:
9
- * https://www.gnu.org/licenses/gpl-3.0.html
10
- *
11
- * SPDX-License-Identifier: GPL-3.0-or-later
12
- */
13
-
14
- /**
15
- * **The script a language is written in.** A language note — a `skill` of
16
- * `subType: language` — names the map and the face its text is written in:
17
- *
18
- * ```yaml
19
- * data:
20
- * writtenIn: { map: semaron, font: semaron-kuriale }
21
- * ```
22
- *
23
- * These are native-presentation defaults, not an effect of identifying a
24
- * language. A rendering run requests them with its own `.nativefont` class
25
- * and explicit `lang=`; plain `[Zaron tholmeza]{lang=vyl}` stays Roman.
26
- * The renderer fills the map and font independently, honoring explicit
27
- * overrides and reporting an incompatible pair rather than silently omitting
28
- * a default. A nested marked run makes its own presentation choice.
29
- *
30
- * The low-level `fromWrittenIn` helper also serves explicit conversion
31
- * commands. It returns compatible default suggestions to those callers;
32
- * rendering opt-in and its required-font diagnostics belong to the run reader.
33
- *
34
- * @module
35
- */
36
-
37
- import { positionOfFrontmatterPath } from "./diagnostics.mjs";
38
- import { nearest } from "./near-miss.mjs";
39
- import { compileMap } from "./text-maps.mjs";
40
- import { LANGUAGE_SUBTYPE } from "./word-terms.mjs";
41
-
42
- /** The `data` key a language note names its script in. */
43
- export const WRITTEN_IN_KEY = "writtenIn";
44
-
45
- /**
46
- * A language's script.
47
- *
48
- * @typedef {object} WrittenIn
49
- * @property {string} map - The `data.map.name` of the mapping note.
50
- * @property {string} font - The slug of the face, one the map is drawn in.
51
- */
52
-
53
- /** Whether a value is a plain map. */
54
- const isMap = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
55
-
56
- /**
57
- * Whether a map is drawn in a face: it lists the face, or lists none.
58
- *
59
- * @param {import("./text-maps.mjs").TextMap} map - The map.
60
- * @param {string} font - The face's slug.
61
- * @returns {boolean} Whether the map may set text in it.
62
- */
63
- export function drawnIn(map, font) {
64
- return !map.fonts.size || map.fonts.has(font);
65
- }
66
-
67
- /** A list of names as prose: `a`, `a` and `b`, `a`, `b` and `c`. */
68
- function said(names) {
69
- const quoted = names.map((name) => `\`${name}\``);
70
- return quoted.length < 2 ?
71
- quoted.join("")
72
- : `${quoted.slice(0, -1).join(", ")} and ${quoted.at(-1)}`;
73
- }
74
-
75
- /**
76
- * The script each configured language's note names, where the map is known
77
- * and is drawn in the face. A default that names an unknown map or a face its
78
- * map is not drawn in is the note's finding, and fills no run.
79
- *
80
- * @param {ReadonlyMap<string, Record<string, any>>} byName - Each configured
81
- * language's note record, by language name, from
82
- * {@link module:engine/map-lexicon.languageRecordsByName}.
83
- * @param {ReadonlyMap<string, import("./text-maps.mjs").TextMap>} maps - The
84
- * maps by name.
85
- * @returns {Map<string, WrittenIn>} The scripts, by language name.
86
- */
87
- export function writtenInOf(byName, maps) {
88
- const out = new Map();
89
- for (const [name, record] of byName ?? []) {
90
- const value = record?.data?.[WRITTEN_IN_KEY];
91
- if (!isMap(value) || typeof value.map !== "string" || typeof value.font !== "string")
92
- continue;
93
- const map = maps?.get(value.map);
94
- if (!map || !drawnIn(map, value.font)) continue;
95
- out.set(name, Object.freeze({ map: value.map, font: value.font }));
96
- }
97
- return out;
98
- }
99
-
100
- /**
101
- * The keys a run takes from its language's script: each of `map` and `font`
102
- * the run does not state, where it agrees with the one the run does.
103
- *
104
- * @param {{lang?: string, map?: string, font?: string}} keys - The run's keys,
105
- * its own and those it inherits.
106
- * @param {ReadonlyMap<string, WrittenIn>|undefined} scripts - Each language's
107
- * script, from {@link writtenInOf}.
108
- * @param {ReadonlyMap<string, import("./text-maps.mjs").TextMap>|undefined} maps -
109
- * The maps by name.
110
- * @returns {{map?: string, font?: string}} What the run takes; empty when it
111
- * takes nothing.
112
- */
113
- export function fromWrittenIn(keys, scripts, maps) {
114
- if (keys.lang === undefined || (keys.map !== undefined && keys.font !== undefined)) return {};
115
- const script = scripts?.get(keys.lang);
116
- if (!script) return {};
117
- if (keys.map === undefined && keys.font === undefined) return { ...script };
118
- if (keys.map === undefined) {
119
- const map = maps?.get(script.map);
120
- return map && drawnIn(map, /** @type {string} */ (keys.font)) ? { map: script.map } : {};
121
- }
122
- const map = maps?.get(keys.map);
123
- return map && drawnIn(map, script.font) ? { font: script.font } : {};
124
- }
125
-
126
- /** The maps each lint index's notes declare, read once. */
127
- const declaredMaps = new WeakMap();
128
-
129
- /**
130
- * Each map the index's notes declare, by name; the first note to declare a
131
- * name keeps it.
132
- *
133
- * @param {{notes?: Iterable<{fm?: Record<string, any>}>}} index - The lint index.
134
- * @returns {Map<string, import("./text-maps.mjs").TextMap>} The maps.
135
- */
136
- function mapsIn(index) {
137
- const known = declaredMaps.get(index);
138
- if (known) return known;
139
- const maps = new Map();
140
- for (const note of index.notes ?? []) {
141
- const map = compileMap(note?.fm?.data?.map);
142
- if (map && !maps.has(map.name)) maps.set(map.name, map);
143
- }
144
- declaredMaps.set(index, maps);
145
- return maps;
146
- }
147
-
148
- /**
149
- * Check a note's `data.writtenIn`: that the note is a language, that `map`
150
- * names a map a mapping note declares, and that the map is drawn in `font`.
151
- * The data-key check owns the keys and their kinds.
152
- *
153
- * @param {{file: string, raw?: string, fm?: Record<string, any>}} note - The note.
154
- * @param {{index?: {notes?: Iterable<object>}}} [context] - The lint index;
155
- * without one, only the note's `subType` is checked.
156
- * @returns {object[]} The findings, each at its key or value.
157
- */
158
- export function checkWrittenIn(note, { index } = {}) {
159
- const value = note?.fm?.data?.[WRITTEN_IN_KEY];
160
- if (value === undefined || value === null) return [];
161
- const raw = note.raw ?? "";
162
- /**
163
- * @param {Array<string|number>} keyPath - Where the fault is.
164
- * @param {string} message - What is wrong.
165
- * @param {boolean} [key] - Locate the key rather than its value.
166
- */
167
- const finding = (keyPath, message, key = false) => ({
168
- file: note.file,
169
- ...positionOfFrontmatterPath(raw, ["data", WRITTEN_IN_KEY, ...keyPath], { key }),
170
- severity: "error",
171
- message,
172
- });
173
- if (String(note.fm?.subType ?? "").toLowerCase() !== LANGUAGE_SUBTYPE)
174
- return [
175
- finding(
176
- [],
177
- `\`data.${WRITTEN_IN_KEY}\` names the script a language is written in, and this ` +
178
- `note's \`subType\` is not \`${LANGUAGE_SUBTYPE}\``,
179
- true,
180
- ),
181
- ];
182
- if (!index || !isMap(value) || typeof value.map !== "string") return [];
183
- const maps = mapsIn(index);
184
- const map = maps.get(value.map);
185
- if (!map) {
186
- const near = nearest(value.map, [...maps.keys()]);
187
- return [
188
- finding(
189
- ["map"],
190
- `\`data.${WRITTEN_IN_KEY}.map\` is \`${value.map}\`, which no mapping note's ` +
191
- "`data.map.name` declares" +
192
- (near ? `; did you mean \`${near}\`?` : ""),
193
- ),
194
- ];
195
- }
196
- if (typeof value.font !== "string" || drawnIn(map, value.font)) return [];
197
- return [
198
- finding(
199
- ["font"],
200
- `\`data.${WRITTEN_IN_KEY}.font\` is \`${value.font}\`, which the map \`${map.name}\` ` +
201
- `is not drawn in; it is drawn in ${said([...map.fonts.keys()])}`,
202
- ),
203
- ];
204
- }
@@ -1,330 +0,0 @@
1
- /**
2
- * Each configured language's lexicon, read from the language note its `note`
3
- * names and its family chain. The nearest exact NFC form supplies the whole
4
- * word; grammar, registers and other settings remain the daughter's own.
5
- * A language with no `note`, or one naming no language note, has none.
6
- *
7
- * @param {Iterable<Record<string, any>>|undefined} records - Index records.
8
- * @param {{languages?: Readonly<Record<string, {tag: string, note?: string}>>, contentPackage?: string}} config -
9
- * The resolved configuration.
10
- * @returns {Map<string, Lexicon>} The lexicons by language name.
11
- */
12
- export function lexiconsFromRecords(records: Iterable<Record<string, any>> | undefined, config?: {
13
- languages?: Readonly<Record<string, {
14
- tag: string;
15
- note?: string;
16
- }>>;
17
- contentPackage?: string;
18
- }): Map<string, Lexicon>;
19
- /**
20
- * The language note each configured language's `note` names, by language
21
- * name. A language with no `note`, or one naming no language note, is absent.
22
- *
23
- * @param {Iterable<Record<string, any>>|undefined} records - Index records.
24
- * @param {{languages?: Readonly<Record<string, {tag: string, note?: string}>>, contentPackage?: string}} config -
25
- * The resolved configuration.
26
- * @returns {Map<string, Record<string, any>>} The records.
27
- */
28
- export function languageRecordsByName(records: Iterable<Record<string, any>> | undefined, { languages, contentPackage }?: {
29
- languages?: Readonly<Record<string, {
30
- tag: string;
31
- note?: string;
32
- }>>;
33
- contentPackage?: string;
34
- }): Map<string, Record<string, any>>;
35
- /**
36
- * Each `languages.<name>.note` that names no language note, at its key.
37
- *
38
- * @param {{languages?: Readonly<Record<string, {tag: string, note?: string}>>, contentPackage?: string, configFile?: string, configText?: string}} config -
39
- * The resolved configuration, and where it was read from.
40
- * @param {Iterable<Record<string, any>>} records - Index records.
41
- * @returns {object[]} The findings.
42
- */
43
- export function languageNoteFindings(config: {
44
- languages?: Readonly<Record<string, {
45
- tag: string;
46
- note?: string;
47
- }>>;
48
- contentPackage?: string;
49
- configFile?: string;
50
- configText?: string;
51
- }, records: Iterable<Record<string, any>>): object[];
52
- /**
53
- * A lookup of a word's native form under one map in one face: the form stated
54
- * for the face, else the one stated for no face.
55
- *
56
- * @param {Lexicon|undefined} lexicon - The lexicon.
57
- * @param {string} map - The map's name.
58
- * @param {string|undefined} font - The face.
59
- * @returns {((word: string) => string|undefined)|undefined} The lookup, or
60
- * `undefined` with no lexicon.
61
- */
62
- export function nativeLookup(lexicon: Lexicon | undefined, map: string, font: string | undefined): ((word: string) => string | undefined) | undefined;
63
- /**
64
- * What a run, a passage or a listing is mapped by.
65
- *
66
- * @typedef {object} Mapping
67
- * @property {import("./text-maps.mjs").TextMap} map - The map.
68
- * @property {string|undefined} font - The face, whose own rows come first.
69
- * @property {((word: string) => string|undefined)|undefined} native - The
70
- * language's native forms under the map in the face, for a map that spells
71
- * by its rows.
72
- * @property {((word: string) => import("./logographic.mjs").Writing)|undefined} writing -
73
- * Each word's writing, for a logographic map.
74
- */
75
- /**
76
- * The one path from a map, a face and a language to what rewrites the text.
77
- *
78
- * @param {{maps?: ReadonlyMap<string, import("./text-maps.mjs").TextMap>, lexicons?: ReadonlyMap<string, Lexicon>}} ctx -
79
- * The run context.
80
- * @param {{map: string, font?: string, lang?: string}} keys - The map, the face
81
- * and the language.
82
- * @returns {Mapping|undefined} The mapping, or `undefined` for an unknown map.
83
- */
84
- export function mappingFor(ctx: {
85
- maps?: ReadonlyMap<string, import("./text-maps.mjs").TextMap>;
86
- lexicons?: ReadonlyMap<string, Lexicon>;
87
- }, { map, font, lang }: {
88
- map: string;
89
- font?: string;
90
- lang?: string;
91
- }): Mapping | undefined;
92
- /**
93
- * Why a face is not one a map is for, or `undefined` where it is.
94
- *
95
- * @param {import("./text-maps.mjs").TextMap} map - The map.
96
- * @param {string} font - The face's slug.
97
- * @returns {string|undefined} The problem.
98
- */
99
- export function fontProblem(map: import("./text-maps.mjs").TextMap, font: string): string | undefined;
100
- /**
101
- * What is wrong with a capitalised word whose native form the rows cannot
102
- * capitalise.
103
- *
104
- * @param {string} word - The word as written.
105
- * @param {string} lower - The lowercase form the lexicon states.
106
- * @param {string|undefined} lang - The language.
107
- * @param {string} map - The map's name.
108
- * @returns {string} The message.
109
- */
110
- export function uncapitalisedMessage(word: string, lower: string, lang: string | undefined, map: string): string;
111
- /**
112
- * What is wrong with a word a logographic map gives no writing.
113
- *
114
- * @param {string} word - The word as written.
115
- * @param {object} unwritten - Why it has none, as
116
- * {@link module:engine/logographic.writingsOf} says.
117
- * @param {string|undefined} lang - The run's language.
118
- * @param {string} map - The map's name.
119
- * @returns {string} The message.
120
- */
121
- export function unwrittenMessage(word: string, unwritten: object, lang: string | undefined, map: string): string;
122
- /**
123
- * Map a passage exactly as the build maps a run with the same keys.
124
- *
125
- * @param {object} ctx - The run context.
126
- * @param {{map: string, font?: string, lang?: string}} keys - The map, the face
127
- * and the language.
128
- * @param {string} text - The passage, with no escapes.
129
- * @returns {{text: string}|{problem: string, about: string}} The mapped text, or the problem.
130
- */
131
- export function transliterate(ctx: object, keys: {
132
- map: string;
133
- font?: string;
134
- lang?: string;
135
- }, text: string): {
136
- text: string;
137
- } | {
138
- problem: string;
139
- about: string;
140
- };
141
- /**
142
- * Every word of a language's lexicon with its native form under a map: the
143
- * stated exception, else the rows' spelling, each exactly as the build gives
144
- * it. With `derived`, the forms the language's rules derive follow the words,
145
- * each case folded and naming the word it comes from in `from`, so the list
146
- * is what the mapped-run word check accepts of the lexicon.
147
- *
148
- * Under a logographic map an entry carries `source` in place of `exception`:
149
- * `own` for a writing it states, `parts` for one its parts give, and `none`,
150
- * with an empty `native`, where it has none. A word whose form a run cannot
151
- * write, because the form stands for entries written differently, or a part
152
- * does, also carries `ambiguous: true`; its `native` is still its own
153
- * writing, the signs a run writes directly for that sense.
154
- *
155
- * @param {object} ctx - The run context.
156
- * @param {{lang: string, map?: string, font?: string, derived?: boolean}} keys -
157
- * The language, the map, the face, and whether to list derived forms. A map
158
- * or a face left out is the one the language's `data.writtenIn` names.
159
- * @returns {{entries: Array<{form: string, native: string, exception?: boolean, source?: "own"|"parts"|"none", ambiguous?: true, class: string|null, gloss: string|null, from?: string}>}|{problem: string, about: string}}
160
- * The words in `data.words` order, then any derived forms, or the problem.
161
- */
162
- export function lexiconEntries(ctx: object, { lang, map, font, derived }: {
163
- lang: string;
164
- map?: string;
165
- font?: string;
166
- derived?: boolean;
167
- }): {
168
- entries: Array<{
169
- form: string;
170
- native: string;
171
- exception?: boolean;
172
- source?: "own" | "parts" | "none";
173
- ambiguous?: true;
174
- class: string | null;
175
- gloss: string | null;
176
- from?: string;
177
- }>;
178
- } | {
179
- problem: string;
180
- about: string;
181
- };
182
- /**
183
- * Check a mapping note's `fonts` against the installed faces: an unknown face
184
- * and a face listed twice, at the entry, and each code point a listed face
185
- * lacks, at the row that writes it.
186
- *
187
- * @param {{file: string, raw?: string, fm?: Record<string, any>}} note - The note.
188
- * @param {{faces?: ReadonlyMap<string, import("./script-fonts.mjs").Face>, maps?: ReadonlyMap<string, import("./text-maps.mjs").TextMap>}} ctx -
189
- * The run context.
190
- * @returns {object[]} The findings.
191
- */
192
- export function checkMapFonts(note: {
193
- file: string;
194
- raw?: string;
195
- fm?: Record<string, any>;
196
- }, ctx: {
197
- faces?: ReadonlyMap<string, import("./script-fonts.mjs").Face>;
198
- maps?: ReadonlyMap<string, import("./text-maps.mjs").TextMap>;
199
- }): object[];
200
- /**
201
- * Check a language note's native forms against the maps and faces: a word's
202
- * `native`, an affix's, and the endings' in `data.grammar.native`. Each is
203
- * checked for an unknown map, a face the map is not for, a second form for one
204
- * map and face (and one ending), and a code point a face it applies in does
205
- * not draw. A word's form under a map that spells by its rows is also checked
206
- * for stating what the rows already give; under a logographic map the rows
207
- * spell no word, so that check does not apply. An affix's and an ending's
208
- * writings mean something only under a logographic map, and an ending of a
209
- * person is written only where `data.grammar.verbs` states `persons`. The
210
- * shape of each entry is the data-key check's.
211
- *
212
- * @param {{file: string, raw?: string, fm?: Record<string, any>}} note - The note.
213
- * @param {{faces?: ReadonlyMap<string, import("./script-fonts.mjs").Face>, maps?: ReadonlyMap<string, import("./text-maps.mjs").TextMap>}} ctx -
214
- * The run context.
215
- * @returns {object[]} The findings.
216
- */
217
- export function checkLexiconNatives(note: {
218
- file: string;
219
- raw?: string;
220
- fm?: Record<string, any>;
221
- }, ctx: {
222
- faces?: ReadonlyMap<string, import("./script-fonts.mjs").Face>;
223
- maps?: ReadonlyMap<string, import("./text-maps.mjs").TextMap>;
224
- }): object[];
225
- /**
226
- * One row per native form of a language note's word, for the `natives`
227
- * relation: a text is a value of a row, never a struct key, so forms that
228
- * differ only in case stay apart.
229
- *
230
- * @param {Iterable<Record<string, any>>} records - Index records.
231
- * @returns {Array<Record<string, string|number|null>>} The rows; `word` is the
232
- * word's 0-based place in `data.words`, `native` the form's in its `native`.
233
- */
234
- export function nativeRows(records: Iterable<Record<string, any>>): Array<Record<string, string | number | null>>;
235
- /** Every column of the `natives` relation, in order. */
236
- export const NATIVE_COLUMNS: readonly string[];
237
- /**
238
- * One native form, read.
239
- */
240
- export type NativeForm = {
241
- /**
242
- * - The map it is written for.
243
- */
244
- map: string;
245
- /**
246
- * - The one face it is for.
247
- */
248
- font: string | undefined;
249
- /**
250
- * - The word in the script.
251
- */
252
- text: string;
253
- };
254
- /**
255
- * One word of a lexicon.
256
- */
257
- export type LexiconWord = {
258
- /**
259
- * - The word as cited.
260
- */
261
- form: string;
262
- /**
263
- * - Its class.
264
- */
265
- class: string | null;
266
- /**
267
- * - Its senses, joined by `; `.
268
- */
269
- gloss: string | null;
270
- /**
271
- * - Its native forms.
272
- */
273
- natives: readonly NativeForm[];
274
- };
275
- /**
276
- * A language's lexicon.
277
- */
278
- export type Lexicon = {
279
- /**
280
- * - The language's configured name.
281
- */
282
- language: string;
283
- /**
284
- * - Its words, in `data.words` order.
285
- */
286
- words: readonly LexiconWord[];
287
- /**
288
- * - The native
289
- * forms by the word's form, NFC; the first word of a form keeps it.
290
- */
291
- byForm: ReadonlyMap<string, readonly NativeForm[]>;
292
- /**
293
- * - The
294
- * forms the language's rules derive from its words, folded, as the mapped-run
295
- * word check accepts them (see {@link module :engine/word-forms.derivedForms}).
296
- */
297
- derived: ReadonlyArray<{
298
- form: string;
299
- from: LexiconWord;
300
- }>;
301
- /**
302
- * - The language note's `data`, which a
303
- * logographic map writes words from.
304
- */
305
- data: Record<string, any>;
306
- };
307
- /**
308
- * What a run, a passage or a listing is mapped by.
309
- */
310
- export type Mapping = {
311
- /**
312
- * - The map.
313
- */
314
- map: import("./text-maps.mjs").TextMap;
315
- /**
316
- * - The face, whose own rows come first.
317
- */
318
- font: string | undefined;
319
- /**
320
- * - The
321
- * language's native forms under the map in the face, for a map that spells
322
- * by its rows.
323
- */
324
- native: ((word: string) => string | undefined) | undefined;
325
- /**
326
- * -
327
- * Each word's writing, for a logographic map.
328
- */
329
- writing: ((word: string) => import("./logographic.mjs").Writing) | undefined;
330
- };