@heroiclands/package-build 23.12.8 → 23.13.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.
- package/CHANGELOG.md +48 -0
- package/README.md +1 -1
- package/assets/preview/gitea.ini +2 -2
- package/assets/styles/content-base.css +143 -23
- package/bin/content-commands.mjs +15 -4
- package/bin/package-build-preview.mjs +2 -2
- package/docs/api.md +18 -18
- package/docs/authoring/links-and-markup.md +156 -22
- package/docs/commands.md +22 -7
- package/docs/configuration.md +1 -1
- package/docs/content-format.md +3 -3
- package/docs/diagnostics.md +42 -0
- package/docs/reference/format-details.md +99 -22
- package/docs/reference/note-types.md +8 -1
- package/docs/reference/theme-pages.md +51 -0
- package/docs/source-preview.md +1 -1
- package/engine/anchors.mjs +2 -2
- package/engine/code-fences.mjs +3 -3
- package/engine/content-blocks.mjs +3 -3
- package/engine/content-figures.mjs +5 -5
- package/engine/content-index.mjs +1 -1
- package/engine/content-scripts.mjs +55 -21
- package/engine/content-spans.mjs +2 -2
- package/engine/content-verse.mjs +750 -0
- package/engine/dictionary-rows.mjs +15 -4
- package/engine/field-reference.mjs +4 -4
- package/engine/first-use.mjs +17 -27
- package/engine/key-case-collisions.mjs +136 -0
- package/engine/language-data.mjs +203 -6
- package/engine/language-terms.mjs +74 -5
- package/engine/map-lexicon.mjs +42 -23
- package/engine/names.mjs +36 -9
- package/engine/note-matter.mjs +66 -0
- package/engine/pdf-build.mjs +1 -0
- package/engine/pdf-render.mjs +107 -18
- package/engine/read-stdin.mjs +29 -0
- package/engine/run-rows.mjs +2 -2
- package/engine/run-words.mjs +4 -111
- package/engine/site-build.mjs +4 -4
- package/engine/site-preview.mjs +14 -14
- package/engine/sql-tables.mjs +20 -3
- package/engine/web-wikilinks.mjs +1 -1
- package/engine/word-forms.mjs +349 -0
- package/engine/word-terms.mjs +9 -0
- package/hugo-theme/static/css/style.css +92 -14
- package/package.json +2 -2
- package/types/engine/code-fences.d.mts +3 -3
- package/types/engine/content-scripts.d.mts +8 -4
- package/types/engine/content-verse.d.mts +240 -0
- package/types/engine/dictionary-rows.d.mts +10 -0
- package/types/engine/field-reference.d.mts +1 -1
- package/types/engine/key-case-collisions.d.mts +28 -0
- package/types/engine/language-data.d.mts +0 -2
- package/types/engine/map-lexicon.d.mts +19 -6
- package/types/engine/names.d.mts +34 -3
- package/types/engine/note-matter.d.mts +48 -0
- package/types/engine/read-stdin.d.mts +11 -0
- package/types/engine/run-rows.d.mts +2 -2
- package/types/engine/run-words.d.mts +0 -15
- package/types/engine/sql-tables.d.mts +4 -1
- package/types/engine/web-wikilinks.d.mts +1 -1
- package/types/engine/word-forms.d.mts +82 -0
- package/engine/content-poetry.mjs +0 -240
- package/types/engine/content-poetry.d.mts +0 -58
|
@@ -17,13 +17,13 @@ export function parseHeaderArgs(info: string): {
|
|
|
17
17
|
* @param {object} [options]
|
|
18
18
|
* @param {boolean} [options.spans=true] - Include inline code spans. Set false
|
|
19
19
|
* to consider only block-level code.
|
|
20
|
-
* @param {boolean} [options.
|
|
20
|
+
* @param {boolean} [options.verseAsProse=true] - Treat verse bodies as inline prose.
|
|
21
21
|
* @returns {Array<{start: number, end: number}>} Non-overlapping regions, in
|
|
22
22
|
* source order. `end` is exclusive.
|
|
23
23
|
*/
|
|
24
|
-
export function codeRegions(markdown: string | null | undefined, { spans,
|
|
24
|
+
export function codeRegions(markdown: string | null | undefined, { spans, verseAsProse }?: {
|
|
25
25
|
spans?: boolean | undefined;
|
|
26
|
-
|
|
26
|
+
verseAsProse?: boolean | undefined;
|
|
27
27
|
}): Array<{
|
|
28
28
|
start: number;
|
|
29
29
|
end: number;
|
|
@@ -14,7 +14,7 @@ export function runContext(config: {
|
|
|
14
14
|
rootDir?: string;
|
|
15
15
|
} | undefined, records?: Iterable<Record<string, any>>): RunContext;
|
|
16
16
|
/**
|
|
17
|
-
* Find the spans, divs and
|
|
17
|
+
* Find the spans, divs and verse fences marked with `lang=`, `font=` or
|
|
18
18
|
* `map=`, and every fault in their markup and their text.
|
|
19
19
|
*
|
|
20
20
|
* @param {string} source - Authored Markdown: a note body, or a whole file
|
|
@@ -44,8 +44,12 @@ export function scanRuns(source: string, ctx?: RunContext, syntax?: import("./co
|
|
|
44
44
|
};
|
|
45
45
|
/**
|
|
46
46
|
* Rewrite text marked with `lang=`, `font=` and `map=` into the plain span,
|
|
47
|
-
* div and
|
|
47
|
+
* div and verse grammar the rest of each chain renders, one line for one line.
|
|
48
48
|
*
|
|
49
|
+
* - **A verse in columns is expanded first** into one span per column entry
|
|
50
|
+
* per verse line, by {@link module:engine/content-verse.expandVerse}, so
|
|
51
|
+
* each entry is mapped and set as a span with its keys is. That is the one
|
|
52
|
+
* rewrite that changes the number of lines.
|
|
49
53
|
* - **The map, if any, is applied first.** Characters Markdown would read are
|
|
50
54
|
* then backslash-escaped, so they reach every later pass as characters.
|
|
51
55
|
* - **The construct carries** the language's tag as `lang`, the face's class
|
|
@@ -179,7 +183,7 @@ export type RunContext = {
|
|
|
179
183
|
wordBooks?: ReadonlyMap<string, import("./run-words.mjs").WordBook> | undefined;
|
|
180
184
|
};
|
|
181
185
|
/**
|
|
182
|
-
* One span, div or
|
|
186
|
+
* One span, div or verse fence carrying `lang=`, `font=` or `map=`. Its
|
|
183
187
|
* `lang`, `font` and `map` are the ones it is set with: its own, else the
|
|
184
188
|
* innermost div or fence around it that states one.
|
|
185
189
|
*/
|
|
@@ -187,7 +191,7 @@ export type Run = {
|
|
|
187
191
|
/**
|
|
188
192
|
* - Which construct.
|
|
189
193
|
*/
|
|
190
|
-
kind: "span" | "block" | "
|
|
194
|
+
kind: "span" | "block" | "verse";
|
|
191
195
|
/**
|
|
192
196
|
* - The language as written.
|
|
193
197
|
*/
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/** The authored verse lines, excluding stanza separators. */
|
|
2
|
+
export function verseLines(body: any): string[];
|
|
3
|
+
/**
|
|
4
|
+
* The least-indented verse is level zero. Every two additional leading spaces
|
|
5
|
+
* add one level; a leftover space is discarded and the level stops at eight.
|
|
6
|
+
* Blank lines divide stanzas rather than contributing to the baseline.
|
|
7
|
+
*/
|
|
8
|
+
export function verseStanzas(body: any): {
|
|
9
|
+
text: string;
|
|
10
|
+
level: number;
|
|
11
|
+
}[][];
|
|
12
|
+
/** A verse is inline Markdown even when it starts with block syntax. */
|
|
13
|
+
export function inlineVerse(text: any): string;
|
|
14
|
+
/**
|
|
15
|
+
* Keep stanzas as Markdown paragraphs and make every verse line a hard break.
|
|
16
|
+
* The surrounding renderer still sees the entire note, so links and footnote
|
|
17
|
+
* definitions remain in scope. The span carries the indent for each line.
|
|
18
|
+
*/
|
|
19
|
+
export function verseMarkdown(body: any, step?: number): string;
|
|
20
|
+
/**
|
|
21
|
+
* The number a line shows: `undefined` when the verse is not numbered, `""`
|
|
22
|
+
* when this line is not one of every `step`th.
|
|
23
|
+
*
|
|
24
|
+
* @param {number} line - The line's number, 1-based across the verse.
|
|
25
|
+
* @param {number} step - The verse's `numstep`.
|
|
26
|
+
* @returns {string|undefined} The number shown.
|
|
27
|
+
*/
|
|
28
|
+
export function lineNumber(line: number, step: number): string | undefined;
|
|
29
|
+
/** Read verse code fences; start/end are inclusive zero-based source lines.
|
|
30
|
+
* @param {string} source - Authored Markdown.
|
|
31
|
+
*/
|
|
32
|
+
export function scanVerse(source: string): {
|
|
33
|
+
blocks: {
|
|
34
|
+
end: number;
|
|
35
|
+
body: string;
|
|
36
|
+
start: number;
|
|
37
|
+
fence: string;
|
|
38
|
+
name: string;
|
|
39
|
+
attributes: {};
|
|
40
|
+
id: string;
|
|
41
|
+
classes: never[];
|
|
42
|
+
indent: string;
|
|
43
|
+
}[];
|
|
44
|
+
errors: {
|
|
45
|
+
line: number;
|
|
46
|
+
column: number;
|
|
47
|
+
message: string;
|
|
48
|
+
}[];
|
|
49
|
+
};
|
|
50
|
+
/** Whether a verse states a column. */
|
|
51
|
+
export function hasColumns(block: any): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* A column's stacked entries, each with its offset in the written value.
|
|
54
|
+
*
|
|
55
|
+
* @param {string} value - A `col1=` or `col2=` value.
|
|
56
|
+
* @returns {Array<{raw: string, offset: number, lang?: string, map?: string, font?: string, offsets: {lang: number, map?: number, font?: number}}>}
|
|
57
|
+
* Each entry; one whose `lang` is `undefined` is malformed.
|
|
58
|
+
*/
|
|
59
|
+
export function columnEntries(value: string): Array<{
|
|
60
|
+
raw: string;
|
|
61
|
+
offset: number;
|
|
62
|
+
lang?: string;
|
|
63
|
+
map?: string;
|
|
64
|
+
font?: string;
|
|
65
|
+
offsets: {
|
|
66
|
+
lang: number;
|
|
67
|
+
map?: number;
|
|
68
|
+
font?: number;
|
|
69
|
+
};
|
|
70
|
+
}>;
|
|
71
|
+
/**
|
|
72
|
+
* The columns of a verse, the left first, each entry located in the opening
|
|
73
|
+
* line.
|
|
74
|
+
*
|
|
75
|
+
* @param {object} block - A verse from {@link scanVerse}.
|
|
76
|
+
* @param {string} opening - Its opening line.
|
|
77
|
+
* @returns {Array<{key: string, entries: Array<ReturnType<typeof columnEntries>[number] & {column: number, columns: {lang: number, map?: number, font?: number}}>}>}
|
|
78
|
+
* 1-based columns.
|
|
79
|
+
*/
|
|
80
|
+
export function verseColumns(block: object, opening: string): Array<{
|
|
81
|
+
key: string;
|
|
82
|
+
entries: Array<ReturnType<typeof columnEntries>[number] & {
|
|
83
|
+
column: number;
|
|
84
|
+
columns: {
|
|
85
|
+
lang: number;
|
|
86
|
+
map?: number;
|
|
87
|
+
font?: number;
|
|
88
|
+
};
|
|
89
|
+
}>;
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* The verse lines of a verse in columns: each blank-line group of span lines
|
|
93
|
+
* is one verse line, and a line holding only `***` breaks the stanza.
|
|
94
|
+
*
|
|
95
|
+
* @param {object} block - A verse from {@link scanVerse}.
|
|
96
|
+
* @param {string[]} lines - The source, by line.
|
|
97
|
+
* @returns {Array<{stanzaBreak: true, line: number}|{stanzaBreak?: false, parts: Array<{line: number, column: number, text: string, textColumn: number, lang?: string, span: boolean, extra: boolean, indent: number}>}>}
|
|
98
|
+
* 0-based lines, 1-based columns.
|
|
99
|
+
*/
|
|
100
|
+
export function verseGroups(block: object, lines: string[]): Array<{
|
|
101
|
+
stanzaBreak: true;
|
|
102
|
+
line: number;
|
|
103
|
+
} | {
|
|
104
|
+
stanzaBreak?: false;
|
|
105
|
+
parts: Array<{
|
|
106
|
+
line: number;
|
|
107
|
+
column: number;
|
|
108
|
+
text: string;
|
|
109
|
+
textColumn: number;
|
|
110
|
+
lang?: string;
|
|
111
|
+
span: boolean;
|
|
112
|
+
extra: boolean;
|
|
113
|
+
indent: number;
|
|
114
|
+
}>;
|
|
115
|
+
}>;
|
|
116
|
+
/**
|
|
117
|
+
* Whether text runs right to left: its first letter is in a right-to-left
|
|
118
|
+
* block. A face's right-to-left code points sit in U+1E800–U+1EFFF.
|
|
119
|
+
*
|
|
120
|
+
* @param {string} text - Text, after any map.
|
|
121
|
+
* @returns {boolean} Whether it starts right to left.
|
|
122
|
+
*/
|
|
123
|
+
export function rightToLeft(text: string): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Where a line of {@link expandVerseOrigins}'s output came from.
|
|
126
|
+
*
|
|
127
|
+
* @typedef {object} VerseOrigin
|
|
128
|
+
* @property {number} line - The source line, 0-based.
|
|
129
|
+
* @property {number} [textColumn] - For an entry's line, the 1-based source
|
|
130
|
+
* column of its text's first character.
|
|
131
|
+
* @property {boolean} [span] - Whether the source line is a span, whose `[`
|
|
132
|
+
* sits before its text.
|
|
133
|
+
* @property {number} [textLength] - The length of the entry's text.
|
|
134
|
+
* @property {{line: number, columns: {lang: number, map?: number, font?: number}}} [entry] -
|
|
135
|
+
* Where the entry is written in the opening line.
|
|
136
|
+
*/
|
|
137
|
+
/**
|
|
138
|
+
* Write each verse line of a sound verse in columns as one span per column
|
|
139
|
+
* entry, the left column's entries first, each with the entry's language,
|
|
140
|
+
* mapping and font. Every target runs it before marked text is rewritten, so
|
|
141
|
+
* each entry is set exactly as a span with those keys is. The verse gains the
|
|
142
|
+
* class {@link COLUMNS_CLASS}; a verse already carrying it, a verse with a
|
|
143
|
+
* finding, and a verse without columns are left as written.
|
|
144
|
+
*
|
|
145
|
+
* @param {string} source - Markdown.
|
|
146
|
+
* @returns {{markdown: string, origins: VerseOrigin[]}} The Markdown, and
|
|
147
|
+
* where each of its lines came from.
|
|
148
|
+
*/
|
|
149
|
+
export function expandVerseOrigins(source: string): {
|
|
150
|
+
markdown: string;
|
|
151
|
+
origins: VerseOrigin[];
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* {@link expandVerseOrigins}'s Markdown alone.
|
|
155
|
+
*
|
|
156
|
+
* @param {string} source - Markdown.
|
|
157
|
+
* @returns {string} The Markdown with each verse in columns expanded.
|
|
158
|
+
*/
|
|
159
|
+
export function expandVerse(source: string): string;
|
|
160
|
+
/**
|
|
161
|
+
* Where a position in {@link expandVerseOrigins}'s output was written.
|
|
162
|
+
*
|
|
163
|
+
* A position in an entry's text is the same character of the source line; a
|
|
164
|
+
* position in its keys is the entry's part in the opening line that states
|
|
165
|
+
* the key it falls in.
|
|
166
|
+
*
|
|
167
|
+
* @param {{line: number, column: number}} at - 1-based, in the output.
|
|
168
|
+
* @param {string[]} expanded - The output, by line.
|
|
169
|
+
* @param {VerseOrigin[]} origins - From {@link expandVerseOrigins}.
|
|
170
|
+
* @returns {{line: number, column: number}} 1-based, in the source.
|
|
171
|
+
*/
|
|
172
|
+
export function sourcePosition(at: {
|
|
173
|
+
line: number;
|
|
174
|
+
column: number;
|
|
175
|
+
}, expanded: string[], origins: VerseOrigin[]): {
|
|
176
|
+
line: number;
|
|
177
|
+
column: number;
|
|
178
|
+
};
|
|
179
|
+
/** Replace verse fences with HTML wrappers whose body remains inline Markdown.
|
|
180
|
+
* @param {string} source - Authored Markdown.
|
|
181
|
+
*/
|
|
182
|
+
export function renderVerse(source: string): {
|
|
183
|
+
markdown: string;
|
|
184
|
+
errors: {
|
|
185
|
+
line: number;
|
|
186
|
+
column: number;
|
|
187
|
+
message: string;
|
|
188
|
+
}[];
|
|
189
|
+
};
|
|
190
|
+
/** The keys that set a verse in columns, the left first. */
|
|
191
|
+
export const COLUMN_KEYS: readonly string[];
|
|
192
|
+
/** The class the build gives a verse in columns once its lines are expanded. */
|
|
193
|
+
export const COLUMNS_CLASS: "verse-columns";
|
|
194
|
+
/**
|
|
195
|
+
* The keys a verse fence's attribute block takes. `lang`, `font` and `map`
|
|
196
|
+
* are read by `scanRuns` in content-scripts.mjs; `dir`, and on the site
|
|
197
|
+
* `data-pagefind-ignore`, are written by its rewrite of a fence set in one of
|
|
198
|
+
* the faces, and reach the element as they are written.
|
|
199
|
+
*/
|
|
200
|
+
export const VERSE_KEYS: readonly string[];
|
|
201
|
+
/**
|
|
202
|
+
* The line that breaks a stanza in a verse in columns, `***`, also as the
|
|
203
|
+
* rewrite of marked text escapes it.
|
|
204
|
+
*/
|
|
205
|
+
export const STANZA_BREAK: RegExp;
|
|
206
|
+
/**
|
|
207
|
+
* Where a line of {@link expandVerseOrigins}'s output came from.
|
|
208
|
+
*/
|
|
209
|
+
export type VerseOrigin = {
|
|
210
|
+
/**
|
|
211
|
+
* - The source line, 0-based.
|
|
212
|
+
*/
|
|
213
|
+
line: number;
|
|
214
|
+
/**
|
|
215
|
+
* - For an entry's line, the 1-based source
|
|
216
|
+
* column of its text's first character.
|
|
217
|
+
*/
|
|
218
|
+
textColumn?: number | undefined;
|
|
219
|
+
/**
|
|
220
|
+
* - Whether the source line is a span, whose `[`
|
|
221
|
+
* sits before its text.
|
|
222
|
+
*/
|
|
223
|
+
span?: boolean | undefined;
|
|
224
|
+
/**
|
|
225
|
+
* - The length of the entry's text.
|
|
226
|
+
*/
|
|
227
|
+
textLength?: number | undefined;
|
|
228
|
+
/**
|
|
229
|
+
* -
|
|
230
|
+
* Where the entry is written in the opening line.
|
|
231
|
+
*/
|
|
232
|
+
entry?: {
|
|
233
|
+
line: number;
|
|
234
|
+
columns: {
|
|
235
|
+
lang: number;
|
|
236
|
+
map?: number;
|
|
237
|
+
font?: number;
|
|
238
|
+
};
|
|
239
|
+
} | undefined;
|
|
240
|
+
};
|
|
@@ -13,6 +13,16 @@ export function pluralOf(word: {
|
|
|
13
13
|
class?: unknown;
|
|
14
14
|
plural?: unknown;
|
|
15
15
|
}, grammar: Record<string, any> | undefined): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* The plural a language's `data.grammar.plural` rule gives a form: the first
|
|
18
|
+
* literal ending replacement that fits, whatever the form's class.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} form - The form.
|
|
21
|
+
* @param {Record<string, any>|undefined} grammar - Its language's
|
|
22
|
+
* `data.grammar`.
|
|
23
|
+
* @returns {string|null} The plural, or `null` where no rule fits.
|
|
24
|
+
*/
|
|
25
|
+
export function pluralByRule(form: string, grammar: Record<string, any> | undefined): string | null;
|
|
16
26
|
/**
|
|
17
27
|
* The stable prose anchor of a word in one language's dictionary. The exact
|
|
18
28
|
* language and NFC form identify it, including case and accents.
|
|
@@ -84,7 +84,7 @@ export function shortcodeFromBasename(destination: string): string;
|
|
|
84
84
|
* {@link shortcodeFromBasename}.
|
|
85
85
|
* @param {Record<string, unknown>} [options.frontmatter] - The consumer's
|
|
86
86
|
* declared `docs.itemFields.frontmatter`.
|
|
87
|
-
* @returns {Record<string, unknown>} The envelope, ready for `
|
|
87
|
+
* @returns {Record<string, unknown>} The envelope, ready for `writeMatter`.
|
|
88
88
|
*/
|
|
89
89
|
export function itemFieldsEnvelope({ title, shortcode, frontmatter }: {
|
|
90
90
|
title: string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every key that two records, or one record, spell with different case at the
|
|
3
|
+
* same path.
|
|
4
|
+
*
|
|
5
|
+
* @param {object[]} records - Content-index records.
|
|
6
|
+
* @returns {Array<{key: string, other: string, record: object, otherRecord: object}>}
|
|
7
|
+
* One entry per spelling that collides with another, naming the record that
|
|
8
|
+
* uses it and a record that uses the other spelling.
|
|
9
|
+
*/
|
|
10
|
+
export function findKeyCaseCollisions(records: object[]): Array<{
|
|
11
|
+
key: string;
|
|
12
|
+
other: string;
|
|
13
|
+
record: object;
|
|
14
|
+
otherRecord: object;
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* The diagnostics for every case collision in the records, one per spelling,
|
|
18
|
+
* each naming the note and line of the spelling it collides with.
|
|
19
|
+
*
|
|
20
|
+
* @param {object[]} records - Content-index records.
|
|
21
|
+
* @param {object} [options]
|
|
22
|
+
* @param {string} [options.contentBase] - The directory the records' paths are
|
|
23
|
+
* relative to.
|
|
24
|
+
* @returns {string[]} Formatted `file:line:column: error: message` lines.
|
|
25
|
+
*/
|
|
26
|
+
export function keyCaseCollisionDiagnostics(records: object[], { contentBase }?: {
|
|
27
|
+
contentBase?: string | undefined;
|
|
28
|
+
}): string[];
|
|
@@ -20,5 +20,3 @@ export function checkLanguageData(note: object, { index, types }?: {
|
|
|
20
20
|
index?: object | undefined;
|
|
21
21
|
types?: readonly string[] | undefined;
|
|
22
22
|
}): object[];
|
|
23
|
-
/** How a foreign row that its tongue's register does not bear out is reported. */
|
|
24
|
-
export const FOREIGN_ROW_SEVERITY: "warning";
|
|
@@ -125,18 +125,21 @@ export function transliterate(ctx: object, keys: {
|
|
|
125
125
|
/**
|
|
126
126
|
* Every word of a language's lexicon with its native form under a map: the
|
|
127
127
|
* stated exception, else the rows' spelling, each exactly as the build gives
|
|
128
|
-
* it.
|
|
128
|
+
* it. With `derived`, the forms the language's rules derive follow the words,
|
|
129
|
+
* each case folded and naming the word it comes from in `from`, so the list
|
|
130
|
+
* is what the mapped-run word check accepts of the lexicon.
|
|
129
131
|
*
|
|
130
132
|
* @param {object} ctx - The run context.
|
|
131
|
-
* @param {{lang: string, map: string, font?: string}} keys -
|
|
132
|
-
* map and
|
|
133
|
-
* @returns {{entries: Array<{form: string, native: string, exception: boolean, class: string|null, gloss: string|null}>}|{problem: string, about: string}}
|
|
134
|
-
* The words in `data.words` order, or the problem.
|
|
133
|
+
* @param {{lang: string, map: string, font?: string, derived?: boolean}} keys -
|
|
134
|
+
* The language, the map, the face, and whether to list derived forms.
|
|
135
|
+
* @returns {{entries: Array<{form: string, native: string, exception: boolean, class: string|null, gloss: string|null, from?: string}>}|{problem: string, about: string}}
|
|
136
|
+
* The words in `data.words` order, then any derived forms, or the problem.
|
|
135
137
|
*/
|
|
136
|
-
export function lexiconEntries(ctx: object, { lang, map, font }: {
|
|
138
|
+
export function lexiconEntries(ctx: object, { lang, map, font, derived }: {
|
|
137
139
|
lang: string;
|
|
138
140
|
map: string;
|
|
139
141
|
font?: string;
|
|
142
|
+
derived?: boolean;
|
|
140
143
|
}): {
|
|
141
144
|
entries: Array<{
|
|
142
145
|
form: string;
|
|
@@ -144,6 +147,7 @@ export function lexiconEntries(ctx: object, { lang, map, font }: {
|
|
|
144
147
|
exception: boolean;
|
|
145
148
|
class: string | null;
|
|
146
149
|
gloss: string | null;
|
|
150
|
+
from?: string;
|
|
147
151
|
}>;
|
|
148
152
|
} | {
|
|
149
153
|
problem: string;
|
|
@@ -253,6 +257,15 @@ export type Lexicon = {
|
|
|
253
257
|
* forms by the word's form, NFC; the first word of a form keeps it.
|
|
254
258
|
*/
|
|
255
259
|
byForm: ReadonlyMap<string, readonly NativeForm[]>;
|
|
260
|
+
/**
|
|
261
|
+
* - The
|
|
262
|
+
* forms the language's rules derive from its words, folded, as the mapped-run
|
|
263
|
+
* word check accepts them (see {@link module :engine/word-forms.derivedForms}).
|
|
264
|
+
*/
|
|
265
|
+
derived: ReadonlyArray<{
|
|
266
|
+
form: string;
|
|
267
|
+
from: LexiconWord;
|
|
268
|
+
}>;
|
|
256
269
|
};
|
|
257
270
|
/**
|
|
258
271
|
* What a run, a passage or a listing is mapped by.
|
package/types/engine/names.d.mts
CHANGED
|
@@ -5,15 +5,24 @@
|
|
|
5
5
|
* @property {string} full - Declared full name.
|
|
6
6
|
* @property {true} indexed - The identity belongs to the indexed catalog.
|
|
7
7
|
* @property {boolean} [fullUse] - The label is a full-name form rather than an alias.
|
|
8
|
+
* @property {string} [type] - The note's type, absent on an ambiguous label identity.
|
|
9
|
+
* @property {string|null} [subType] - The note's subtype, or null.
|
|
8
10
|
* @property {NameMatch[]} [candidates] - Indexed identities sharing the label.
|
|
9
11
|
* @property {string} [destination] - Canonical Address used by a resolved link.
|
|
10
12
|
*/
|
|
11
13
|
/**
|
|
12
14
|
* The prepared name and declared-alias lookup.
|
|
13
15
|
* @typedef {object} NameCatalog
|
|
14
|
-
* @property {(label: string, preferred?: {key: string}) => NameMatch|undefined} recognize - Match a whole visible label.
|
|
16
|
+
* @property {(label: string, preferred?: {key: string}, kind?: NameKind) => NameMatch|undefined} recognize - Match a whole visible label, among notes of `kind` when it supplies a type.
|
|
15
17
|
* @property {(target: string) => NameMatch|undefined} resolve - Resolve an Address target without its anchor to its indexed identity.
|
|
16
18
|
*/
|
|
19
|
+
/**
|
|
20
|
+
* What a typed `.name` span says the named thing is. A null type matches any note;
|
|
21
|
+
* a type matches only notes of that type, and a subtype only notes of that subtype.
|
|
22
|
+
* @typedef {object} NameKind
|
|
23
|
+
* @property {string|null} type - Supplied type, or null.
|
|
24
|
+
* @property {string|null} subType - Supplied subtype, or null.
|
|
25
|
+
*/
|
|
17
26
|
/**
|
|
18
27
|
* One captured marked-name occurrence.
|
|
19
28
|
* @typedef {object} MarkedName
|
|
@@ -175,6 +184,14 @@ export type NameMatch = {
|
|
|
175
184
|
* - The label is a full-name form rather than an alias.
|
|
176
185
|
*/
|
|
177
186
|
fullUse?: boolean | undefined;
|
|
187
|
+
/**
|
|
188
|
+
* - The note's type, absent on an ambiguous label identity.
|
|
189
|
+
*/
|
|
190
|
+
type?: string | undefined;
|
|
191
|
+
/**
|
|
192
|
+
* - The note's subtype, or null.
|
|
193
|
+
*/
|
|
194
|
+
subType?: string | null | undefined;
|
|
178
195
|
/**
|
|
179
196
|
* - Indexed identities sharing the label.
|
|
180
197
|
*/
|
|
@@ -189,16 +206,30 @@ export type NameMatch = {
|
|
|
189
206
|
*/
|
|
190
207
|
export type NameCatalog = {
|
|
191
208
|
/**
|
|
192
|
-
* - Match a whole visible label.
|
|
209
|
+
* - Match a whole visible label, among notes of `kind` when it supplies a type.
|
|
193
210
|
*/
|
|
194
211
|
recognize: (label: string, preferred?: {
|
|
195
212
|
key: string;
|
|
196
|
-
}) => NameMatch | undefined;
|
|
213
|
+
}, kind?: NameKind) => NameMatch | undefined;
|
|
197
214
|
/**
|
|
198
215
|
* - Resolve an Address target without its anchor to its indexed identity.
|
|
199
216
|
*/
|
|
200
217
|
resolve: (target: string) => NameMatch | undefined;
|
|
201
218
|
};
|
|
219
|
+
/**
|
|
220
|
+
* What a typed `.name` span says the named thing is. A null type matches any note;
|
|
221
|
+
* a type matches only notes of that type, and a subtype only notes of that subtype.
|
|
222
|
+
*/
|
|
223
|
+
export type NameKind = {
|
|
224
|
+
/**
|
|
225
|
+
* - Supplied type, or null.
|
|
226
|
+
*/
|
|
227
|
+
type: string | null;
|
|
228
|
+
/**
|
|
229
|
+
* - Supplied subtype, or null.
|
|
230
|
+
*/
|
|
231
|
+
subType: string | null;
|
|
232
|
+
};
|
|
202
233
|
/**
|
|
203
234
|
* One captured marked-name occurrence.
|
|
204
235
|
*/
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A page split at its frontmatter.
|
|
3
|
+
*
|
|
4
|
+
* @typedef {object} NoteMatter
|
|
5
|
+
* @property {unknown} data - The parsed frontmatter; an empty map where the
|
|
6
|
+
* page has none or the block is empty.
|
|
7
|
+
* @property {string} content - The body after the closing fence and its line
|
|
8
|
+
* break, or the whole text where there is no frontmatter.
|
|
9
|
+
* @property {string} matter - The YAML source between the fences; empty where
|
|
10
|
+
* there is no frontmatter.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Split a page's frontmatter from its body and parse it.
|
|
14
|
+
*
|
|
15
|
+
* @param {string} source - The complete Markdown source.
|
|
16
|
+
* @returns {NoteMatter} The parsed frontmatter, the body and the YAML source.
|
|
17
|
+
* @throws {Error} The `yaml` parse error, where the frontmatter is not YAML.
|
|
18
|
+
*/
|
|
19
|
+
export function readMatter(source: string): NoteMatter;
|
|
20
|
+
/**
|
|
21
|
+
* A page with `data` as its frontmatter above `content`.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} content - The body.
|
|
24
|
+
* @param {Record<string, unknown>} data - The frontmatter.
|
|
25
|
+
* @returns {string} The fenced YAML, then the body closed on a line break; the
|
|
26
|
+
* body alone where `data` serializes to an empty map.
|
|
27
|
+
*/
|
|
28
|
+
export function writeMatter(content: string, data: Record<string, unknown>): string;
|
|
29
|
+
/**
|
|
30
|
+
* A page split at its frontmatter.
|
|
31
|
+
*/
|
|
32
|
+
export type NoteMatter = {
|
|
33
|
+
/**
|
|
34
|
+
* - The parsed frontmatter; an empty map where the
|
|
35
|
+
* page has none or the block is empty.
|
|
36
|
+
*/
|
|
37
|
+
data: unknown;
|
|
38
|
+
/**
|
|
39
|
+
* - The body after the closing fence and its line
|
|
40
|
+
* break, or the whole text where there is no frontmatter.
|
|
41
|
+
*/
|
|
42
|
+
content: string;
|
|
43
|
+
/**
|
|
44
|
+
* - The YAML source between the fences; empty where
|
|
45
|
+
* there is no frontmatter.
|
|
46
|
+
*/
|
|
47
|
+
matter: string;
|
|
48
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads standard input to its end as UTF-8 text.
|
|
3
|
+
*
|
|
4
|
+
* The stream is read asynchronously, so a pipe whose writer is slower than the
|
|
5
|
+
* reader, or a non-blocking descriptor, delivers the whole input instead of
|
|
6
|
+
* failing with `EAGAIN`.
|
|
7
|
+
*
|
|
8
|
+
* @param {NodeJS.ReadableStream} [stream] The stream to drain; standard input by default.
|
|
9
|
+
* @returns {Promise<string>} The complete input.
|
|
10
|
+
*/
|
|
11
|
+
export function readStdin(stream?: NodeJS.ReadableStream): Promise<string>;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* One run as an index record carries it.
|
|
3
3
|
*
|
|
4
4
|
* @typedef {object} RecordRun
|
|
5
|
-
* @property {"span"|"block"|"
|
|
5
|
+
* @property {"span"|"block"|"verse"} kind - The construct.
|
|
6
6
|
* @property {string|null} lang - The language it is set in, as written: its
|
|
7
7
|
* own `lang=`, else the one the div or fence around it states.
|
|
8
8
|
* @property {string|null} tag - The BCP 47 tag it resolves to, or null.
|
|
@@ -57,7 +57,7 @@ export type RecordRun = {
|
|
|
57
57
|
/**
|
|
58
58
|
* - The construct.
|
|
59
59
|
*/
|
|
60
|
-
kind: "span" | "block" | "
|
|
60
|
+
kind: "span" | "block" | "verse";
|
|
61
61
|
/**
|
|
62
62
|
* - The language it is set in, as written: its
|
|
63
63
|
* own `lang=`, else the one the div or fence around it states.
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A word as it is compared: NFC, lowercase, `’` read as `'`.
|
|
3
|
-
*
|
|
4
|
-
* @param {string} word - The word.
|
|
5
|
-
* @returns {string} Its folded form.
|
|
6
|
-
*/
|
|
7
|
-
export function foldWord(word: string): string;
|
|
8
|
-
/**
|
|
9
|
-
* The words a language note accepts of its own: its forms, and what its
|
|
10
|
-
* plural rows, verb pattern and replacing suffixes derive from them.
|
|
11
|
-
*
|
|
12
|
-
* @param {Record<string, any>} data - The language note's `data`.
|
|
13
|
-
* @returns {Set<string>} The words, folded.
|
|
14
|
-
*/
|
|
15
|
-
export function lexiconWords(data: Record<string, any>): Set<string>;
|
|
16
1
|
/**
|
|
17
2
|
* The words of every name a language note registers under a tongue other than
|
|
18
3
|
* `translation`.
|
|
@@ -65,10 +65,12 @@ export function findSqlBlocks(markdown: string): Array<{
|
|
|
65
65
|
* @param {object} [opts.addressContext] - Address resolution context.
|
|
66
66
|
* @param {"all"|"public"} [opts.audience] - Whether to exclude GM notes from
|
|
67
67
|
* local and dependency relations.
|
|
68
|
+
* @param {string} [opts.contentBase] - The directory the records' paths are
|
|
69
|
+
* relative to, so a refused key is reported at its file and line.
|
|
68
70
|
* @returns {Promise<{query: (sql: string) => Promise<object[]>,
|
|
69
71
|
* close: () => Promise<void>}>} The open database.
|
|
70
72
|
*/
|
|
71
|
-
export function openNotesDatabase(records: object[], { dir, dependencies, addressContext, audience }?: {
|
|
73
|
+
export function openNotesDatabase(records: object[], { dir, dependencies, addressContext, audience, contentBase }?: {
|
|
72
74
|
dir?: string | undefined;
|
|
73
75
|
dependencies?: {
|
|
74
76
|
id: string;
|
|
@@ -76,6 +78,7 @@ export function openNotesDatabase(records: object[], { dir, dependencies, addres
|
|
|
76
78
|
}[] | undefined;
|
|
77
79
|
addressContext?: object | undefined;
|
|
78
80
|
audience?: "all" | "public" | undefined;
|
|
81
|
+
contentBase?: string | undefined;
|
|
79
82
|
}): Promise<{
|
|
80
83
|
query: (sql: string) => Promise<object[]>;
|
|
81
84
|
close: () => Promise<void>;
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* Values are read from the *parsed* frontmatter, so a `[[` inside a YAML comment
|
|
20
20
|
* is not a hit, and every hit can be named by the path a reader would look at.
|
|
21
21
|
*
|
|
22
|
-
* @param {unknown} fm - Parsed frontmatter, as `
|
|
22
|
+
* @param {unknown} fm - Parsed frontmatter, as `readMatter` returns it.
|
|
23
23
|
* @returns {Array<{path: string, link: string}>} In reading order; `path` is the
|
|
24
24
|
* dotted key path of the offending value (`government.summary`, `aliases.1`).
|
|
25
25
|
*/
|