@heroiclands/package-build 25.2.1 → 25.4.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 +26 -0
- package/README.md +1 -1
- package/assets/styles/content-base.css +97 -116
- package/docs/api.md +30 -6
- package/docs/authoring/links-and-markup.md +214 -126
- package/docs/commands.md +2 -2
- package/docs/content-format.md +31 -6
- package/docs/diagnostics.md +27 -27
- package/docs/guides/writing-in-invented-scripts.md +89 -83
- package/docs/reference/format-details.md +6 -7
- package/docs/reference/note-types.md +15 -15
- package/docs/reference/theme-pages.md +38 -57
- package/engine/anchors.mjs +14 -0
- package/engine/code-fences.mjs +15 -6
- package/engine/content-blocks.mjs +7 -4
- package/engine/content-figures.mjs +19 -5
- package/engine/content-footnotes.mjs +60 -1
- package/engine/content-index.mjs +1 -1
- package/engine/content-render.mjs +66 -48
- package/engine/content-scripts.mjs +357 -101
- package/engine/content-spans.mjs +76 -10
- package/engine/content-verse.mjs +687 -358
- package/engine/first-use.mjs +43 -12
- package/engine/heading-attributes.mjs +2 -1
- package/engine/journals.mjs +8 -1
- package/engine/markdown-blocks.mjs +3 -2
- package/engine/markup-validation.mjs +17 -0
- package/engine/name-markup.mjs +1 -0
- package/engine/note-vocabulary.mjs +2 -2
- package/engine/pdf-render.mjs +89 -130
- package/engine/prose-lint.mjs +14 -2
- package/engine/roman-verse.mjs +68 -57
- package/engine/run-rows.mjs +1 -1
- package/engine/sql-tables.mjs +1 -1
- package/engine/verse-format.mjs +77 -0
- package/engine/verse-metre.mjs +49 -47
- package/engine/verse-regions.mjs +181 -0
- package/engine/wikilink-pattern.mjs +31 -0
- package/engine/wikilink-syntax.mjs +2 -16
- package/package.json +1 -1
- package/site-theme/static/css/style.css +68 -96
- package/types/engine/code-fences.d.mts +1 -3
- package/types/engine/content-blocks.d.mts +3 -1
- package/types/engine/content-footnotes.d.mts +23 -0
- package/types/engine/content-scripts.d.mts +12 -7
- package/types/engine/content-spans.d.mts +3 -1
- package/types/engine/content-verse.d.mts +263 -82
- package/types/engine/name-markup.d.mts +5 -0
- package/types/engine/roman-verse.d.mts +7 -6
- package/types/engine/verse-format.d.mts +9 -0
- package/types/engine/verse-metre.d.mts +4 -4
- package/types/engine/verse-regions.d.mts +78 -0
- package/types/engine/wikilink-pattern.d.mts +17 -0
- package/types/engine/wikilink-syntax.d.mts +1 -41
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/** The authored verse lines, excluding blank lines and stanza separators. */
|
|
2
|
-
export function verseLines(body: any): string[];
|
|
3
1
|
/**
|
|
4
2
|
* Read one verse line. Marker offsets are zero-based in the authored line;
|
|
5
3
|
* textColumn is the one-based column of its first non-space character.
|
|
@@ -12,103 +10,286 @@ export function verseLine(line: any): {
|
|
|
12
10
|
markerLength: number;
|
|
13
11
|
textColumn: number;
|
|
14
12
|
};
|
|
13
|
+
/** A verse is inline Markdown even when it starts with block syntax. */
|
|
14
|
+
export function inlineVerse(text: any): string;
|
|
15
|
+
/**
|
|
16
|
+
* Whether text runs right to left: its first letter is in a right-to-left
|
|
17
|
+
* block. A face's right-to-left code points sit in U+1E800–U+1EFFF.
|
|
18
|
+
*
|
|
19
|
+
* @param {string} text - Text, after any map.
|
|
20
|
+
* @returns {boolean} Whether it starts right to left.
|
|
21
|
+
*/
|
|
22
|
+
export function rightToLeft(text: string): boolean;
|
|
23
|
+
/** Read verse divs; start/end are inclusive zero-based source lines.
|
|
24
|
+
* @param {string} source - Authored Markdown.
|
|
25
|
+
* @param {object} [options] - Whole-page validation choices.
|
|
26
|
+
* @param {boolean} [options.checkWorks] - Whether to validate page-local versions.
|
|
27
|
+
* @returns {{blocks: VerseBlock[], errors: VerseDiagnostic[]}} Located divs and findings.
|
|
28
|
+
*/
|
|
29
|
+
export function scanVerse(source: string, { checkWorks }?: {
|
|
30
|
+
checkWorks?: boolean | undefined;
|
|
31
|
+
}): {
|
|
32
|
+
blocks: VerseBlock[];
|
|
33
|
+
errors: VerseDiagnostic[];
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Parse logical verse lines, stanzas and cantos without losing authored offsets.
|
|
37
|
+
* Offsets are UTF-16 positions relative to body. Delimiters and indentation are
|
|
38
|
+
* layout ranges; source newlines inside a logical line contribute one space.
|
|
39
|
+
* @param {string} body - Authored verse body.
|
|
40
|
+
* @param {{inline?: boolean, footnotes?: ReadonlySet<string>}} [options] - Inline quotations have no cantos; footnotes are same-note definition labels.
|
|
41
|
+
* @returns {VerseModel} The shared structure with offsets relative to the body.
|
|
42
|
+
*/
|
|
43
|
+
export function parseVerse(body: string, { inline, footnotes }?: {
|
|
44
|
+
inline?: boolean;
|
|
45
|
+
footnotes?: ReadonlySet<string>;
|
|
46
|
+
}): VerseModel;
|
|
15
47
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
48
|
+
* Validate a quoted verse span using its original source coordinates.
|
|
49
|
+
* @param {{start: number, text: string, attrs: Array<[string,string]>}} span - Authored span.
|
|
50
|
+
* @param {string} source - Complete Markdown source.
|
|
51
|
+
* @returns {VerseDiagnostic[]} Located inline-only findings.
|
|
18
52
|
*/
|
|
53
|
+
export function inlineVerseFindings(span: {
|
|
54
|
+
start: number;
|
|
55
|
+
text: string;
|
|
56
|
+
attrs: Array<[string, string]>;
|
|
57
|
+
}, source: string): VerseDiagnostic[];
|
|
58
|
+
/** Logical line text for consumers that do not need source locations. */
|
|
59
|
+
export function verseLines(body: any): string[];
|
|
60
|
+
/** Paragraph groups with separate canto gaps. */
|
|
19
61
|
export function verseStanzas(body: any): {
|
|
20
62
|
text: string;
|
|
21
63
|
level: number;
|
|
22
64
|
}[][];
|
|
23
|
-
/** A verse is inline Markdown even when it starts with block syntax. */
|
|
24
|
-
export function inlineVerse(text: any): string;
|
|
25
65
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* definitions remain in scope. The span carries the indent for each line.
|
|
66
|
+
* Compare the stanza counts of each version of a page-local work.
|
|
67
|
+
* @param {VerseBlock[]} blocks - Divs belonging to one page.
|
|
68
|
+
* @returns {VerseDiagnostic[]} Findings at affected opening divs.
|
|
30
69
|
*/
|
|
31
|
-
export function
|
|
70
|
+
export function workShapeFindings(blocks: VerseBlock[]): VerseDiagnostic[];
|
|
32
71
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* @param {
|
|
37
|
-
* @param {
|
|
38
|
-
* @
|
|
72
|
+
* Render a shared verse structure while preserving surrounding inline Markdown.
|
|
73
|
+
* @param {string} body - Authored verse body.
|
|
74
|
+
* @param {object} [options] - Shared structure and display choices.
|
|
75
|
+
* @param {boolean} [options.labelled] - Whether each stanza carries its label.
|
|
76
|
+
* @param {VerseModel} [options.model] - Parsed structure; defaults to parsing the body.
|
|
77
|
+
* @param {VersePresentation} [options.presentation] - Native-cell font and language.
|
|
78
|
+
* @param {boolean} [options.inline] - Whether wrappers must remain inline-safe.
|
|
79
|
+
* @returns {string} Markdown with verse layout wrappers.
|
|
39
80
|
*/
|
|
40
|
-
export function
|
|
41
|
-
|
|
42
|
-
|
|
81
|
+
export function verseMarkdown(body: string, { labelled, model, presentation, inline }?: {
|
|
82
|
+
labelled?: boolean | undefined;
|
|
83
|
+
model?: VerseModel | undefined;
|
|
84
|
+
presentation?: VersePresentation | undefined;
|
|
85
|
+
inline?: boolean | undefined;
|
|
86
|
+
}): string;
|
|
87
|
+
/**
|
|
88
|
+
* Replace verse divs with wrappers whose bodies remain inline Markdown.
|
|
89
|
+
* @param {string} source - Markdown containing verse divs.
|
|
90
|
+
* @param {object} [options] - Encoded display models.
|
|
91
|
+
* @param {Map<string, VersePresentation>} [options.verses] - Presentations keyed by rewritten body.
|
|
43
92
|
*/
|
|
44
|
-
export function
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
fence: string;
|
|
50
|
-
name: string;
|
|
51
|
-
attributes: {};
|
|
52
|
-
id: string;
|
|
53
|
-
classes: never[];
|
|
54
|
-
indent: string;
|
|
55
|
-
}[];
|
|
56
|
-
errors: any[];
|
|
93
|
+
export function renderVerse(source: string, { verses }?: {
|
|
94
|
+
verses?: Map<string, VersePresentation> | undefined;
|
|
95
|
+
}): {
|
|
96
|
+
markdown: string;
|
|
97
|
+
errors: VerseDiagnostic[];
|
|
57
98
|
};
|
|
58
|
-
/** The number of verse columns; an omitted or invalid count uses the ordinary layout. */
|
|
59
|
-
export function verseColumnCount(block: any): number;
|
|
60
|
-
/** Whether a verse uses the numbered multi-column protocol. */
|
|
61
|
-
export function hasColumns(block: any): boolean;
|
|
62
99
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* @param {object} block - A verse from scanVerse.
|
|
68
|
-
* @param {string[]} lines - The complete source, by line.
|
|
69
|
-
* @returns {Array<{stanzaBreak: true, line: number}|{stanzaBreak?: false, parts: Array<{column: number, line: number, sourceColumn: number, textColumn: number, text: string, indent: number, markerStart: number, markerLength: number, prefixLength: number}>}>}
|
|
100
|
+
* Render quoted verse with inline-safe wrappers and shared logical structure.
|
|
101
|
+
* @param {string} source - Markdown after block verse rendering.
|
|
102
|
+
* @returns {string} Markdown retaining surrounding prose.
|
|
70
103
|
*/
|
|
71
|
-
export function
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
column: number;
|
|
78
|
-
line: number;
|
|
79
|
-
sourceColumn: number;
|
|
80
|
-
textColumn: number;
|
|
81
|
-
text: string;
|
|
82
|
-
indent: number;
|
|
83
|
-
markerStart: number;
|
|
84
|
-
markerLength: number;
|
|
85
|
-
prefixLength: number;
|
|
86
|
-
}>;
|
|
87
|
-
}>;
|
|
104
|
+
export function renderVerseQuotes(source: string): string;
|
|
105
|
+
/** The authored attributes of a verse div. */
|
|
106
|
+
export const VERSE_KEYS: readonly string[];
|
|
107
|
+
/** A canto separator, including the escaped form produced by a native run. */
|
|
108
|
+
export const STANZA_BREAK: RegExp;
|
|
109
|
+
export function stanzaSeparator(group: any): boolean;
|
|
88
110
|
/**
|
|
89
|
-
*
|
|
90
|
-
* block. A face's right-to-left code points sit in U+1E800–U+1EFFF.
|
|
91
|
-
*
|
|
92
|
-
* @param {string} text - Text, after any map.
|
|
93
|
-
* @returns {boolean} Whether it starts right to left.
|
|
111
|
+
* A logical line with its authored UTF-16 coordinates.
|
|
94
112
|
*/
|
|
95
|
-
export
|
|
96
|
-
/**
|
|
97
|
-
|
|
113
|
+
export type VerseLine = {
|
|
114
|
+
/**
|
|
115
|
+
* - Inline Markdown in this presentation.
|
|
116
|
+
*/
|
|
117
|
+
text: string;
|
|
118
|
+
/**
|
|
119
|
+
* - Leading-period indentation depth.
|
|
120
|
+
*/
|
|
121
|
+
level: number;
|
|
122
|
+
/**
|
|
123
|
+
* - First authored offset, including indentation.
|
|
124
|
+
*/
|
|
125
|
+
from: number;
|
|
126
|
+
/**
|
|
127
|
+
* - Offset at the line ending.
|
|
128
|
+
*/
|
|
129
|
+
to: number;
|
|
130
|
+
/**
|
|
131
|
+
* - Source offset for each UTF-16 text unit.
|
|
132
|
+
*/
|
|
133
|
+
offsets: number[];
|
|
134
|
+
/**
|
|
135
|
+
* - Roman text paired with an encoded line.
|
|
136
|
+
*/
|
|
137
|
+
romanText?: string | undefined;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* A stanza's logical lines and authored bounds.
|
|
98
141
|
*/
|
|
99
|
-
export
|
|
100
|
-
|
|
101
|
-
|
|
142
|
+
export type VerseStanza = {
|
|
143
|
+
/**
|
|
144
|
+
* - Lines in reading order.
|
|
145
|
+
*/
|
|
146
|
+
lines: VerseLine[];
|
|
147
|
+
/**
|
|
148
|
+
* - First authored offset.
|
|
149
|
+
*/
|
|
150
|
+
from: number;
|
|
151
|
+
/**
|
|
152
|
+
* - Offset at the stanza ending.
|
|
153
|
+
*/
|
|
154
|
+
to: number;
|
|
155
|
+
};
|
|
156
|
+
export type VerseTextGroup = VerseStanza & {
|
|
157
|
+
canto: number;
|
|
158
|
+
stanza: number;
|
|
159
|
+
label: string;
|
|
160
|
+
cantoBreak?: false;
|
|
161
|
+
};
|
|
162
|
+
export type VerseCantoBreak = {
|
|
163
|
+
cantoBreak: true;
|
|
164
|
+
from: number;
|
|
165
|
+
to: number;
|
|
166
|
+
text?: string;
|
|
167
|
+
id?: string;
|
|
168
|
+
title?: string;
|
|
169
|
+
};
|
|
170
|
+
export type VerseBoundary = {
|
|
171
|
+
kind: "line" | "stanza" | "canto";
|
|
172
|
+
sourceOffset: number;
|
|
173
|
+
};
|
|
174
|
+
export type VerseFinding = {
|
|
175
|
+
offset: number;
|
|
176
|
+
message: string;
|
|
102
177
|
};
|
|
103
|
-
export function stanzaSeparator(group: any): boolean;
|
|
104
|
-
/** The layout class the build gives a verse whose cols count exceeds one. */
|
|
105
|
-
export const COLUMNS_CLASS: "verse-columns";
|
|
106
178
|
/**
|
|
107
|
-
*
|
|
108
|
-
* are read by `scanRuns` in content-scripts.mjs; `dir`, and on the site
|
|
109
|
-
* `data-pagefind-ignore`, are written by its rewrite of a fence set in one of
|
|
110
|
-
* the faces, and reach the element as they are written.
|
|
179
|
+
* Shared authored verse structure and source locations.
|
|
111
180
|
*/
|
|
112
|
-
export
|
|
113
|
-
/**
|
|
114
|
-
|
|
181
|
+
export type VerseModel = {
|
|
182
|
+
/**
|
|
183
|
+
* - Cantos in reading order.
|
|
184
|
+
*/
|
|
185
|
+
cantos: Array<{
|
|
186
|
+
stanzas: VerseStanza[];
|
|
187
|
+
}>;
|
|
188
|
+
/**
|
|
189
|
+
* - Stanzas and canto breaks.
|
|
190
|
+
*/
|
|
191
|
+
groups: Array<VerseTextGroup | VerseCantoBreak>;
|
|
192
|
+
/**
|
|
193
|
+
* - Explicit authored boundaries.
|
|
194
|
+
*/
|
|
195
|
+
boundaries: VerseBoundary[];
|
|
196
|
+
/**
|
|
197
|
+
* - Source ranges omitted from encoded letters.
|
|
198
|
+
*/
|
|
199
|
+
layout: Array<[number, number]>;
|
|
200
|
+
/**
|
|
201
|
+
* - Findings relative to the verse body.
|
|
202
|
+
*/
|
|
203
|
+
errors: VerseFinding[];
|
|
204
|
+
/**
|
|
205
|
+
* - Defined references without substantive verse text.
|
|
206
|
+
*/
|
|
207
|
+
notes: VerseLine[];
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* An authored verse div with its parsed logical structure.
|
|
211
|
+
*/
|
|
212
|
+
export type VerseBlock = {
|
|
213
|
+
/**
|
|
214
|
+
* - Opening div's zero-based source line.
|
|
215
|
+
*/
|
|
216
|
+
start: number;
|
|
217
|
+
/**
|
|
218
|
+
* - Closing div's zero-based source line.
|
|
219
|
+
*/
|
|
220
|
+
end: number;
|
|
221
|
+
/**
|
|
222
|
+
* - Complete div first offset.
|
|
223
|
+
*/
|
|
224
|
+
from: number;
|
|
225
|
+
/**
|
|
226
|
+
* - Offset past complete div.
|
|
227
|
+
*/
|
|
228
|
+
to: number;
|
|
229
|
+
/**
|
|
230
|
+
* - First body offset.
|
|
231
|
+
*/
|
|
232
|
+
bodyStart: number;
|
|
233
|
+
/**
|
|
234
|
+
* - Offset past body text.
|
|
235
|
+
*/
|
|
236
|
+
bodyEnd: number;
|
|
237
|
+
/**
|
|
238
|
+
* - Whether the closing delimiter exists.
|
|
239
|
+
*/
|
|
240
|
+
closed: boolean;
|
|
241
|
+
/**
|
|
242
|
+
* - Attribute syntax findings.
|
|
243
|
+
*/
|
|
244
|
+
problems: string[];
|
|
245
|
+
/**
|
|
246
|
+
* - Region name.
|
|
247
|
+
*/
|
|
248
|
+
name: "verse";
|
|
249
|
+
/**
|
|
250
|
+
* - Authored attribute values.
|
|
251
|
+
*/
|
|
252
|
+
attributes: Record<string, string>;
|
|
253
|
+
/**
|
|
254
|
+
* - Authored anchor, or the empty string.
|
|
255
|
+
*/
|
|
256
|
+
id: string;
|
|
257
|
+
/**
|
|
258
|
+
* - Authored presentation classes.
|
|
259
|
+
*/
|
|
260
|
+
classes: string[];
|
|
261
|
+
/**
|
|
262
|
+
* - Opening div's leading spaces.
|
|
263
|
+
*/
|
|
264
|
+
indent: string;
|
|
265
|
+
/**
|
|
266
|
+
* - Authored verse body.
|
|
267
|
+
*/
|
|
268
|
+
body: string;
|
|
269
|
+
/**
|
|
270
|
+
* - Logical structure relative to the body.
|
|
271
|
+
*/
|
|
272
|
+
model: VerseModel;
|
|
273
|
+
};
|
|
274
|
+
export type VerseDiagnostic = {
|
|
275
|
+
line: number;
|
|
276
|
+
column: number;
|
|
277
|
+
message: string;
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* An encoded verse's shared display model and native-cell presentation.
|
|
281
|
+
*/
|
|
282
|
+
export type VersePresentation = {
|
|
283
|
+
/**
|
|
284
|
+
* - Logical structure with paired line text.
|
|
285
|
+
*/
|
|
286
|
+
model: VerseModel;
|
|
287
|
+
/**
|
|
288
|
+
* - Native script and font classes.
|
|
289
|
+
*/
|
|
290
|
+
classes: string[];
|
|
291
|
+
/**
|
|
292
|
+
* - Native language, direction and search attributes.
|
|
293
|
+
*/
|
|
294
|
+
attributes: Record<string, string>;
|
|
295
|
+
};
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
* @property {string} visible - Visible text from the actual parsed children.
|
|
27
27
|
* @property {ReadonlyArray<readonly [string, string]>} attrs - Retained permitted HTML attributes.
|
|
28
28
|
* @property {Record<string, SpanAttributePosition>} attributePositions - Authored key/value sites by retained attribute name.
|
|
29
|
+
* @property {ReturnType<typeof import("./content-verse.mjs").parseVerse>} [verseModel] - Logical model of an inline verse quotation.
|
|
29
30
|
*/
|
|
30
31
|
/**
|
|
31
32
|
* One located span-grammar or refused-attribute finding.
|
|
@@ -139,6 +140,10 @@ export type ContentSpan = {
|
|
|
139
140
|
* - Authored key/value sites by retained attribute name.
|
|
140
141
|
*/
|
|
141
142
|
attributePositions: Record<string, SpanAttributePosition>;
|
|
143
|
+
/**
|
|
144
|
+
* - Logical model of an inline verse quotation.
|
|
145
|
+
*/
|
|
146
|
+
verseModel?: import("./content-verse.mjs").VerseModel | undefined;
|
|
142
147
|
};
|
|
143
148
|
/**
|
|
144
149
|
* One located span-grammar or refused-attribute finding.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* The caller writes the boundaries through its selected encoding.
|
|
2
|
+
* Project verse text with explicit authored line, stanza and canto boundaries.
|
|
3
|
+
* Source newlines within a logical line are whitespace. Delimiters and visual
|
|
4
|
+
* indentation do not reach the encoder as letters.
|
|
6
5
|
* @param {string} source - Complete authored source.
|
|
7
|
-
* @param {Parameters<typeof plainRomanRun>[1] & {
|
|
6
|
+
* @param {Parameters<typeof plainRomanRun>[1] & {model?: ReturnType<typeof parseVerse>, modelOffset?: number}} [options] - Run bounds, spans and layout projection.
|
|
8
7
|
* @returns {ReturnType<typeof plainRomanRun> & {boundaries: Array<{kind: "line"|"stanza"|"canto", at: number, sourceOffset: number}>, errors: Array<{offset: number, message: string}>}} Visible text, positions and structural events.
|
|
9
8
|
*/
|
|
10
9
|
export function plainRomanVerse(source: string, options?: Parameters<typeof plainRomanRun>[1] & {
|
|
11
|
-
|
|
10
|
+
model?: ReturnType<typeof parseVerse>;
|
|
11
|
+
modelOffset?: number;
|
|
12
12
|
}): ReturnType<typeof plainRomanRun> & {
|
|
13
13
|
boundaries: Array<{
|
|
14
14
|
kind: "line" | "stanza" | "canto";
|
|
@@ -21,3 +21,4 @@ export function plainRomanVerse(source: string, options?: Parameters<typeof plai
|
|
|
21
21
|
}>;
|
|
22
22
|
};
|
|
23
23
|
import { plainRomanRun } from "./roman-run.mjs";
|
|
24
|
+
import { parseVerse } from "./content-verse.mjs";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replace verse markup with opaque placeholders and restore its original bytes.
|
|
3
|
+
* @param {string} source - Complete Markdown source.
|
|
4
|
+
* @returns {{markdown: string, restore: (formatted: string) => string}} Protected source and exact restoration.
|
|
5
|
+
*/
|
|
6
|
+
export function protectVerseSource(source: string): {
|
|
7
|
+
markdown: string;
|
|
8
|
+
restore: (formatted: string) => string;
|
|
9
|
+
};
|
|
@@ -60,7 +60,7 @@ export function lineBeats(text: string, book: MetreBook): {
|
|
|
60
60
|
* The warning for a line that cannot have its metre's beats.
|
|
61
61
|
*
|
|
62
62
|
* @param {{min: number, max: number}} beats - The line's beats.
|
|
63
|
-
* @param {import("./metre-declaration.mjs").Metre} metre - The
|
|
63
|
+
* @param {import("./metre-declaration.mjs").Metre} metre - The div's metre.
|
|
64
64
|
* @returns {string} The message.
|
|
65
65
|
*/
|
|
66
66
|
export function metreMessage({ min, max }: {
|
|
@@ -68,13 +68,13 @@ export function metreMessage({ min, max }: {
|
|
|
68
68
|
max: number;
|
|
69
69
|
}, metre: import("./metre-declaration.mjs").Metre): string;
|
|
70
70
|
/**
|
|
71
|
-
* Check the verse
|
|
71
|
+
* Check the verse divs that state `scan=`.
|
|
72
72
|
*
|
|
73
73
|
* @param {ReadonlyArray<{start: number, end: number, indent: string, attributes: Record<string, string>, classes: string[]}>} blocks -
|
|
74
|
-
* The
|
|
74
|
+
* The divs, from {@link module:engine/content-verse.scanVerse}.
|
|
75
75
|
* @param {string[]} lines - The source's lines.
|
|
76
76
|
* @param {{languages?: Readonly<Record<string, {tag: string}>>, metres?: ReadonlyMap<string, import("./metre-declaration.mjs").Metre>, metreBooks?: ReadonlyMap<string, MetreBook>, lexicons?: ReadonlyMap<string, unknown>, attributeColumns: (line: string, key: string) => {key: number, value: number}}} ctx -
|
|
77
|
-
* The metres and books, and how the
|
|
77
|
+
* The metres and books, and how the div says its columns and where its
|
|
78
78
|
* keys sit.
|
|
79
79
|
* @returns {{errors: object[], warnings: object[]}} The findings at 1-based
|
|
80
80
|
* positions.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install the opaque verse-div block rule. Tokens carry raw source regions.
|
|
3
|
+
* @param {import("markdown-it")} md - Markdown parser.
|
|
4
|
+
*/
|
|
5
|
+
export function verseDivPlugin(md: typeof import("markdown-it")): void;
|
|
6
|
+
/**
|
|
7
|
+
* Locate complete raw verse divs while leaving literal examples untouched.
|
|
8
|
+
* @param {string} source - Authored Markdown.
|
|
9
|
+
* @returns {VerseRegion[]} Regions in source order, including unclosed divs.
|
|
10
|
+
*/
|
|
11
|
+
export function verseRegions(source: string): VerseRegion[];
|
|
12
|
+
/**
|
|
13
|
+
* Source ranges belonging to inline syntax rather than visible verse text.
|
|
14
|
+
* @param {string} source - Inline Markdown.
|
|
15
|
+
* @returns {Array<[number,number]>} Protected UTF-16 ranges.
|
|
16
|
+
*/
|
|
17
|
+
export function inlineSyntaxRanges(source: string): Array<[number, number]>;
|
|
18
|
+
/**
|
|
19
|
+
* A raw verse div, opaque to ordinary Markdown block syntax.
|
|
20
|
+
*/
|
|
21
|
+
export type VerseRegion = {
|
|
22
|
+
/**
|
|
23
|
+
* - Opening line, zero based.
|
|
24
|
+
*/
|
|
25
|
+
start: number;
|
|
26
|
+
/**
|
|
27
|
+
* - Closing line, zero based and inclusive.
|
|
28
|
+
*/
|
|
29
|
+
end: number;
|
|
30
|
+
/**
|
|
31
|
+
* - First offset of the complete region.
|
|
32
|
+
*/
|
|
33
|
+
from: number;
|
|
34
|
+
/**
|
|
35
|
+
* - Offset past the complete region.
|
|
36
|
+
*/
|
|
37
|
+
to: number;
|
|
38
|
+
/**
|
|
39
|
+
* - First body offset.
|
|
40
|
+
*/
|
|
41
|
+
bodyStart: number;
|
|
42
|
+
/**
|
|
43
|
+
* - Offset past body text, excluding its final newline.
|
|
44
|
+
*/
|
|
45
|
+
bodyEnd: number;
|
|
46
|
+
/**
|
|
47
|
+
* - Authored body bytes.
|
|
48
|
+
*/
|
|
49
|
+
body: string;
|
|
50
|
+
/**
|
|
51
|
+
* - Authored values.
|
|
52
|
+
*/
|
|
53
|
+
attributes: Record<string, string>;
|
|
54
|
+
/**
|
|
55
|
+
* - Anchor or empty string.
|
|
56
|
+
*/
|
|
57
|
+
id: string;
|
|
58
|
+
/**
|
|
59
|
+
* - Authored classes including verse.
|
|
60
|
+
*/
|
|
61
|
+
classes: string[];
|
|
62
|
+
/**
|
|
63
|
+
* - Opening indentation.
|
|
64
|
+
*/
|
|
65
|
+
indent: string;
|
|
66
|
+
/**
|
|
67
|
+
* - Region kind.
|
|
68
|
+
*/
|
|
69
|
+
name: "verse";
|
|
70
|
+
/**
|
|
71
|
+
* - Whether a closing delimiter is present.
|
|
72
|
+
*/
|
|
73
|
+
closed: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* - Attribute syntax findings.
|
|
76
|
+
*/
|
|
77
|
+
problems: string[];
|
|
78
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The dependency-free lexical wikilink pattern. @module */
|
|
2
|
+
/**
|
|
3
|
+
* A wikilink, as authored.
|
|
4
|
+
*
|
|
5
|
+
* **Newlines are excluded deliberately.** A link is written on one line; an
|
|
6
|
+
* unclosed `[[` is a typo, and the alternative is letting it swallow arbitrary
|
|
7
|
+
* prose in search of a closer. Erring towards "not a link" leaves the author's
|
|
8
|
+
* text as written, which is the safe direction for a rewriter.
|
|
9
|
+
*
|
|
10
|
+
* **A leading `!` makes it an embed, not a link**, and the lookbehind is what
|
|
11
|
+
* keeps every reader from seeing one as the other. Stated here rather than in
|
|
12
|
+
* each reader for the reason the rest of this module exists: the checker, the
|
|
13
|
+
* resolver and the embed reader all match on this pattern, and a copy of the
|
|
14
|
+
* exclusion in each is a place for it to be forgotten. An embed's
|
|
15
|
+
* own grammar is {@link module:engine/content-embeds}.
|
|
16
|
+
*/
|
|
17
|
+
export const WIKILINK: RegExp;
|
|
@@ -206,47 +206,7 @@ export function secretDestination(destination: object, anchor?: string): boolean
|
|
|
206
206
|
* @returns {string} Inline spoiler or visible reference.
|
|
207
207
|
*/
|
|
208
208
|
export function presentWikilink(reference: string, parsed: object, destination: object): string;
|
|
209
|
-
|
|
210
|
-
* What a `[[…]]` **is**, before anything decides where it points.
|
|
211
|
-
*
|
|
212
|
-
* One authored link is written three ways — a Foundry `@UUID` content link for
|
|
213
|
-
* the packs, a URL for the web, a cross-reference for the book — and those
|
|
214
|
-
* forms are the *only* thing that legitimately differs. The syntax is the
|
|
215
|
-
* author's, and it is the same syntax whichever build is reading it.
|
|
216
|
-
*
|
|
217
|
-
* So the parse lives here, once, and two readers take it: the link checker
|
|
218
|
-
* (`content-links.mjs`) and the resolver (`wikilinks.mjs`). Each receives the
|
|
219
|
-
* parts and decides only what it is for: which document the address names.
|
|
220
|
-
*
|
|
221
|
-
* The one rule about a link's *shape* also lives here — **a link carries a
|
|
222
|
-
* label** ({@link unlabelledLinkMessage}) — because every build states it
|
|
223
|
-
* through one message and the author reads the same words whichever ran
|
|
224
|
-
* first.
|
|
225
|
-
*
|
|
226
|
-
* For the same reason, so does the **vocabulary of link findings**
|
|
227
|
-
* ({@link LINK_FINDING_REASONS}) and the message each one reports through
|
|
228
|
-
* ({@link linkFindingMessage}). Every build reads one authored link; an author
|
|
229
|
-
* meets whichever ran first, and a consumer switching on a `reason` should not
|
|
230
|
-
* be switching on which build produced it.
|
|
231
|
-
*
|
|
232
|
-
* @module
|
|
233
|
-
*/
|
|
234
|
-
/**
|
|
235
|
-
* A wikilink, as authored.
|
|
236
|
-
*
|
|
237
|
-
* **Newlines are excluded deliberately.** A link is written on one line; an
|
|
238
|
-
* unclosed `[[` is a typo, and the alternative is letting it swallow arbitrary
|
|
239
|
-
* prose in search of a closer. Erring towards "not a link" leaves the author's
|
|
240
|
-
* text as written, which is the safe direction for a rewriter.
|
|
241
|
-
*
|
|
242
|
-
* **A leading `!` makes it an embed, not a link**, and the lookbehind is what
|
|
243
|
-
* keeps every reader from seeing one as the other. Stated here rather than in
|
|
244
|
-
* each reader for the reason the rest of this module exists: the checker, the
|
|
245
|
-
* resolver and the embed reader all match on this pattern, and a copy of the
|
|
246
|
-
* exclusion in each is a place for it to be forgotten. An embed's
|
|
247
|
-
* own grammar is {@link module:engine/content-embeds}.
|
|
248
|
-
*/
|
|
249
|
-
export const WIKILINK: RegExp;
|
|
209
|
+
export { WIKILINK } from "./wikilink-pattern.mjs";
|
|
250
210
|
/**
|
|
251
211
|
* Every way a link can fail, named once for every reader of a link.
|
|
252
212
|
*
|