@heroiclands/package-build 20.3.1 → 20.5.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 +351 -0
- package/CONTENT.md +322 -110
- package/README.md +21 -10
- package/bin/content-build.mjs +204 -92
- package/bin/package-build.mjs +48 -15
- package/config.mjs +6 -8
- package/content-config.mjs +518 -151
- package/docs/api.md +1352 -0
- package/docs/commands.md +1609 -0
- package/docs/configuration.md +1432 -0
- package/docs/content-format.md +73 -74
- package/docs/diagnostics.md +356 -0
- package/docs/getting-started.md +813 -0
- package/docs/project-setup.md +469 -0
- package/e2e.mjs +4 -4
- package/engine/actor-compiler.mjs +64 -61
- package/engine/address-charset.mjs +6 -6
- package/engine/address-diff.mjs +57 -52
- package/engine/anchored-sections.mjs +1 -1
- package/engine/anchors.mjs +1 -1
- package/engine/base-compiler.mjs +42 -38
- package/engine/bundle-notes.mjs +4 -4
- package/engine/bundles.mjs +17 -8
- package/engine/code-fences.mjs +3 -3
- package/engine/compendiums.mjs +8 -8
- package/engine/compile-corpus.mjs +4 -5
- package/engine/content-address.mjs +24 -24
- package/engine/content-charset.mjs +1 -1
- package/engine/content-format-check.mjs +24 -25
- package/engine/content-format.mjs +8 -8
- package/engine/content-html.mjs +202 -0
- package/engine/content-icons.mjs +196 -165
- package/engine/content-index.mjs +61 -40
- package/engine/content-links.mjs +74 -41
- package/engine/content-lint.mjs +64 -34
- package/engine/content-package.mjs +7 -9
- package/engine/content-slug.mjs +2 -2
- package/engine/content-tables.mjs +38 -34
- package/engine/content-tree.mjs +1 -1
- package/engine/derived-fields.mjs +174 -0
- package/engine/diagnostics.mjs +3 -4
- package/engine/document-subtypes.mjs +6 -7
- package/engine/field-reference.mjs +8 -8
- package/engine/field-spec.mjs +29 -30
- package/engine/folder-notes.mjs +18 -16
- package/engine/foreign-catalog.mjs +8 -9
- package/engine/foundry-entries.mjs +19 -20
- package/engine/frontmatter-lint.mjs +95 -103
- package/engine/frontmatter.mjs +11 -11
- package/engine/generate.mjs +44 -39
- package/engine/helpers.mjs +147 -84
- package/engine/homepage.mjs +20 -22
- package/engine/ids.mjs +15 -15
- package/engine/index-records.mjs +4 -4
- package/engine/index.mjs +26 -10
- package/engine/item-compiler.mjs +54 -29
- package/engine/item-docs.mjs +11 -13
- package/engine/item-registry.mjs +13 -13
- package/engine/journals.mjs +24 -15
- package/engine/macros.mjs +3 -3
- package/engine/map-notes.mjs +6 -6
- package/engine/metadata-index.mjs +5 -5
- package/engine/note-claims.mjs +51 -41
- package/engine/note-ids.mjs +5 -5
- package/engine/note-package.mjs +4 -4
- package/engine/note-renames.mjs +3 -3
- package/engine/note-schemas.mjs +3 -8
- package/engine/note-vocabulary.mjs +56 -54
- package/engine/pack-config.mjs +39 -25
- package/engine/pack-router.mjs +0 -0
- package/engine/pdf-build.mjs +464 -0
- package/engine/pdf-fonts.mjs +420 -0
- package/engine/pdf-render.mjs +798 -0
- package/engine/pdf-toc.mjs +525 -0
- package/engine/prose-config.mjs +9 -9
- package/engine/prose-lint.mjs +12 -13
- package/engine/region-events.mjs +2 -2
- package/engine/retired-fields.mjs +24 -22
- package/engine/runtime-only-fields.mjs +1 -1
- package/engine/scene-levels.mjs +1 -1
- package/engine/scenes.mjs +33 -25
- package/engine/schema-check.mjs +21 -21
- package/engine/schema-extract.mjs +1 -1
- package/engine/site-build.mjs +66 -50
- package/engine/site-index.mjs +17 -18
- package/engine/sql-tables.mjs +21 -13
- package/engine/subtype-registry.mjs +5 -4
- package/engine/system-block.mjs +18 -19
- package/engine/systems.mjs +2 -2
- package/engine/web-wikilinks.mjs +41 -38
- package/engine/wikilink-syntax.mjs +16 -16
- package/engine/wikilinks.mjs +40 -42
- package/hm3/actors.mjs +30 -22
- package/hm3/document-subtypes.mjs +5 -5
- package/hm3/index.mjs +2 -2
- package/hm3/item-builders.mjs +1 -1
- package/hm3/item-fields.mjs +3 -3
- package/hm3/items.mjs +28 -8
- package/hm3/template-priority.mjs +2 -2
- package/lang.mjs +3 -3
- package/manifest.mjs +17 -20
- package/package.json +1 -2
- package/release.mjs +66 -6
- package/sohl/actors.mjs +36 -28
- package/sohl/affiliation-standings.mjs +2 -2
- package/sohl/being-info.mjs +5 -5
- package/sohl/default-item-art.mjs +5 -5
- package/sohl/document-subtypes.mjs +5 -5
- package/sohl/index.mjs +3 -3
- package/sohl/item-builders.mjs +7 -7
- package/sohl/item-fields.mjs +8 -9
- package/sohl/items.mjs +28 -6
- package/sohl/kb-passes.mjs +5 -5
- package/sohl/note-schemas.mjs +12 -12
- package/sohl/skill-base.mjs +1 -1
- package/types/content-config.d.mts +91 -39
- package/types/e2e.d.mts +3 -3
- package/types/engine/actor-compiler.d.mts +45 -40
- package/types/engine/address-charset.d.mts +6 -6
- package/types/engine/address-diff.d.mts +60 -6
- package/types/engine/base-compiler.d.mts +27 -21
- package/types/engine/bundle-notes.d.mts +3 -3
- package/types/engine/bundles.d.mts +10 -1
- package/types/engine/code-fences.d.mts +3 -3
- package/types/engine/compendiums.d.mts +3 -3
- package/types/engine/compile-corpus.d.mts +1 -1
- package/types/engine/content-address.d.mts +20 -20
- package/types/engine/content-format-check.d.mts +6 -6
- package/types/engine/content-format.d.mts +2 -2
- package/types/engine/content-html.d.mts +78 -0
- package/types/engine/content-icons.d.mts +139 -92
- package/types/engine/content-index.d.mts +59 -15
- package/types/engine/content-links.d.mts +8 -8
- package/types/engine/content-lint.d.mts +8 -6
- package/types/engine/content-package.d.mts +6 -8
- package/types/engine/content-tables.d.mts +49 -18
- package/types/engine/derived-fields.d.mts +101 -0
- package/types/engine/diagnostics.d.mts +2 -2
- package/types/engine/document-subtypes.d.mts +3 -3
- package/types/engine/field-spec.d.mts +37 -39
- package/types/engine/folder-notes.d.mts +4 -5
- package/types/engine/foreign-catalog.d.mts +3 -3
- package/types/engine/foundry-entries.d.mts +6 -7
- package/types/engine/frontmatter-lint.d.mts +10 -9
- package/types/engine/frontmatter.d.mts +7 -7
- package/types/engine/generate.d.mts +7 -7
- package/types/engine/helpers.d.mts +128 -56
- package/types/engine/homepage.d.mts +16 -18
- package/types/engine/ids.d.mts +13 -13
- package/types/engine/index-records.d.mts +3 -3
- package/types/engine/index.d.mts +6 -0
- package/types/engine/item-compiler.d.mts +21 -5
- package/types/engine/item-docs.d.mts +2 -2
- package/types/engine/item-registry.d.mts +6 -6
- package/types/engine/journals.d.mts +12 -3
- package/types/engine/map-notes.d.mts +2 -2
- package/types/engine/metadata-index.d.mts +4 -4
- package/types/engine/note-claims.d.mts +30 -22
- package/types/engine/note-ids.d.mts +4 -4
- package/types/engine/note-package.d.mts +1 -1
- package/types/engine/note-renames.d.mts +3 -3
- package/types/engine/note-vocabulary.d.mts +31 -203
- package/types/engine/pack-config.d.mts +7 -7
- package/types/engine/pack-router.d.mts +1 -1
- package/types/engine/pdf-build.d.mts +42 -0
- package/types/engine/pdf-fonts.d.mts +30 -0
- package/types/engine/pdf-render.d.mts +144 -0
- package/types/engine/pdf-toc.d.mts +114 -0
- package/types/engine/prose-config.d.mts +9 -9
- package/types/engine/prose-lint.d.mts +3 -4
- package/types/engine/region-events.d.mts +2 -2
- package/types/engine/retired-fields.d.mts +10 -9
- package/types/engine/scenes.d.mts +10 -1
- package/types/engine/schema-check.d.mts +13 -13
- package/types/engine/site-build.d.mts +52 -25
- package/types/engine/site-index.d.mts +3 -4
- package/types/engine/sql-tables.d.mts +11 -5
- package/types/engine/subtype-registry.d.mts +3 -3
- package/types/engine/system-block.d.mts +3 -3
- package/types/engine/web-wikilinks.d.mts +7 -7
- package/types/engine/wikilink-syntax.d.mts +17 -17
- package/types/engine/wikilinks.d.mts +14 -14
- package/types/hm3/actors.d.mts +9 -1
- package/types/hm3/document-subtypes.d.mts +1 -1
- package/types/hm3/items.d.mts +9 -2
- package/types/hm3/template-priority.d.mts +1 -1
- package/types/manifest.d.mts +8 -8
- package/types/release.d.mts +15 -4
- package/types/sohl/actors.d.mts +12 -4
- package/types/sohl/affiliation-standings.d.mts +2 -2
- package/types/sohl/being-info.d.mts +2 -2
- package/types/sohl/document-subtypes.d.mts +1 -1
- package/types/sohl/items.d.mts +9 -2
- package/types/sohl/note-schemas.d.mts +1 -1
- package/MIGRATING.md +0 -608
|
@@ -24,7 +24,7 @@ export function declaredTags(type: string, groups?: object): readonly string[];
|
|
|
24
24
|
*/
|
|
25
25
|
export function hasTag(fm: object | null | undefined, tag: string): boolean;
|
|
26
26
|
/**
|
|
27
|
-
* Whether a note is tagged as an unfinished **draft
|
|
27
|
+
* Whether a note is tagged as an unfinished **draft**.
|
|
28
28
|
*
|
|
29
29
|
* The one reader of {@link DRAFT_TAG}, so both builds ask the same question of
|
|
30
30
|
* the same field. Presentation only: a draft note is in the packs, in the
|
|
@@ -38,10 +38,11 @@ export function isDraftNote(fm: object | null | undefined): boolean;
|
|
|
38
38
|
/**
|
|
39
39
|
* What a note carrying a subType outside the address charset is told.
|
|
40
40
|
*
|
|
41
|
-
* **Why the charset holds for a subType, which reaches no address.**
|
|
41
|
+
* **Why the charset holds for a subType, which reaches no address.** The rule
|
|
42
|
+
* said
|
|
42
43
|
* "the hyphen separates the segments of an address", and that was true of a
|
|
43
44
|
* subType when it shipped: `sectionOf` returned a `doc`'s subType, so the value
|
|
44
|
-
* was a URL path segment.
|
|
45
|
+
* was a URL path segment. Sections are retired and it is not one. The rule
|
|
45
46
|
* stays, on its own footing: a subType is a vocabulary term the whole toolchain
|
|
46
47
|
* keys on, and it is one closed set away from being an address segment again —
|
|
47
48
|
* so the reason to spell it in the address charset is that a charset holding
|
|
@@ -72,8 +73,8 @@ export function typeCharsetMessage(type: string): string;
|
|
|
72
73
|
*
|
|
73
74
|
* The message states the reason **per key**, as {@link typeCharsetMessage} and
|
|
74
75
|
* {@link subTypeCharsetMessage} do: a type is an address segment, and a subType
|
|
75
|
-
*
|
|
76
|
-
* would be half wrong
|
|
76
|
+
* is not one, since sections are retired, so a single claim covering both
|
|
77
|
+
* would be half wrong.
|
|
77
78
|
*
|
|
78
79
|
* @param {Readonly<Record<string, TypeVocabulary>>} vocabulary - The registry.
|
|
79
80
|
* @param {string} [where] - What declares it, for the message.
|
|
@@ -104,19 +105,21 @@ export function dataFields(type: string, vocabulary?: Readonly<Record<string, Ty
|
|
|
104
105
|
*/
|
|
105
106
|
export function subTypes(type: string, vocabulary?: Readonly<Record<string, TypeVocabulary>>): readonly string[] | null | undefined;
|
|
106
107
|
/**
|
|
107
|
-
*
|
|
108
|
-
* declares.
|
|
108
|
+
* The declared tag that marks a note as **unfinished**.
|
|
109
109
|
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* key will be called — and the disagreement is recorded on the field rather
|
|
114
|
-
* than resolved silently.
|
|
110
|
+
* Named once and referenced from the declaration below, because a second
|
|
111
|
+
* spelling is how the two come apart: rename the tag in `DECLARED_TAGS` and a
|
|
112
|
+
* private copy elsewhere keeps matching the old word, silently.
|
|
115
113
|
*
|
|
116
|
-
*
|
|
114
|
+
* It is a **presentation** fact and nothing more. A draft note compiles,
|
|
115
|
+
* validates, publishes and resolves like any other; only a link *into* it
|
|
116
|
+
* renders marked. What it emphatically is not is the retired `draft:` field,
|
|
117
|
+
* whose entire effect was to move a note from published to unresolvable — see
|
|
118
|
+
* {@link draftRetiredMessage}.
|
|
117
119
|
*/
|
|
120
|
+
export const DRAFT_TAG: "draft";
|
|
118
121
|
/**
|
|
119
|
-
* The tags that **classify** a note, grouped by what they classify
|
|
122
|
+
* The tags that **classify** a note, grouped by what they classify.
|
|
120
123
|
*
|
|
121
124
|
* `tags:` lives at the open top level and most tags belong there: a theme, a
|
|
122
125
|
* region, a working state is the author's own and this build has no opinion
|
|
@@ -141,20 +144,6 @@ export function subTypes(type: string, vocabulary?: Readonly<Record<string, Type
|
|
|
141
144
|
* fishing village is a `village` that is `fishing`, and the single-valued field
|
|
142
145
|
* this replaced had to spell it `Fishing Village` as a value of its own.
|
|
143
146
|
*/
|
|
144
|
-
/**
|
|
145
|
-
* The declared tag that marks a note as **unfinished** (#183).
|
|
146
|
-
*
|
|
147
|
-
* Named once and referenced from the declaration below, because a second
|
|
148
|
-
* spelling is how the two come apart: rename the tag in `DECLARED_TAGS` and a
|
|
149
|
-
* private copy elsewhere keeps matching the old word, silently.
|
|
150
|
-
*
|
|
151
|
-
* It is a **presentation** fact and nothing more. A draft note compiles,
|
|
152
|
-
* validates, publishes and resolves like any other; only a link *into* it
|
|
153
|
-
* renders marked. What it emphatically is not is the retired `draft:` field,
|
|
154
|
-
* whose entire effect was to move a note from published to unresolvable — see
|
|
155
|
-
* {@link draftRetiredMessage}.
|
|
156
|
-
*/
|
|
157
|
-
export const DRAFT_TAG: "draft";
|
|
158
147
|
export const DECLARED_TAGS: Readonly<{
|
|
159
148
|
/** What a place *is*. */
|
|
160
149
|
placeKind: Readonly<{
|
|
@@ -182,186 +171,25 @@ export const DECLARED_TAGS: Readonly<{
|
|
|
182
171
|
tags: readonly string[];
|
|
183
172
|
}>;
|
|
184
173
|
}>;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
affliction: Readonly<{
|
|
199
|
-
subTypes: readonly string[];
|
|
200
|
-
data: readonly DataFieldSpec[];
|
|
201
|
-
}>;
|
|
202
|
-
armorgear: Readonly<{
|
|
203
|
-
data: readonly DataFieldSpec[];
|
|
204
|
-
}>;
|
|
205
|
-
armorlocation: Readonly<{
|
|
206
|
-
subTypes: null;
|
|
207
|
-
data: readonly DataFieldSpec[];
|
|
208
|
-
}>;
|
|
209
|
-
attribute: Readonly<{
|
|
210
|
-
data: readonly DataFieldSpec[];
|
|
211
|
-
}>;
|
|
212
|
-
concoctiongear: Readonly<{
|
|
213
|
-
subTypes: readonly string[];
|
|
214
|
-
data: readonly (DataFieldSpec | Readonly<{
|
|
215
|
-
describe: "How many of the thing there are; one when unstated.";
|
|
216
|
-
shape: "number";
|
|
217
|
-
kind: "number";
|
|
218
|
-
name: "quantity";
|
|
219
|
-
}>)[];
|
|
220
|
-
}>;
|
|
221
|
-
containergear: Readonly<{
|
|
222
|
-
data: readonly DataFieldSpec[];
|
|
223
|
-
}>;
|
|
224
|
-
miscgear: Readonly<{
|
|
225
|
-
data: readonly (DataFieldSpec | Readonly<{
|
|
226
|
-
describe: "How many of the thing there are; one when unstated.";
|
|
227
|
-
shape: "number";
|
|
228
|
-
kind: "number";
|
|
229
|
-
name: "quantity";
|
|
230
|
-
}>)[];
|
|
231
|
-
}>;
|
|
232
|
-
mystery: Readonly<{
|
|
233
|
-
subTypes: readonly string[];
|
|
234
|
-
data: readonly DataFieldSpec[];
|
|
235
|
-
}>;
|
|
236
|
-
mysticalability: Readonly<{
|
|
237
|
-
subTypes: readonly string[];
|
|
238
|
-
data: readonly DataFieldSpec[];
|
|
239
|
-
}>;
|
|
240
|
-
projectilegear: Readonly<{
|
|
241
|
-
subTypes: readonly string[];
|
|
242
|
-
data: readonly (DataFieldSpec | Readonly<{
|
|
243
|
-
describe: "How many of the thing there are; one when unstated.";
|
|
244
|
-
shape: "number";
|
|
245
|
-
kind: "number";
|
|
246
|
-
name: "quantity";
|
|
247
|
-
}>)[];
|
|
248
|
-
}>;
|
|
249
|
-
skill: Readonly<{
|
|
250
|
-
subTypes: readonly string[];
|
|
251
|
-
data: readonly DataFieldSpec[];
|
|
252
|
-
}>;
|
|
253
|
-
trauma: Readonly<{
|
|
254
|
-
subTypes: readonly string[];
|
|
255
|
-
data: readonly DataFieldSpec[];
|
|
256
|
-
}>;
|
|
257
|
-
weapongear: Readonly<{
|
|
258
|
-
data: readonly DataFieldSpec[];
|
|
259
|
-
}>;
|
|
260
|
-
doc: Readonly<{
|
|
261
|
-
subTypes: readonly string[];
|
|
262
|
-
data: readonly never[];
|
|
263
|
-
}>;
|
|
264
|
-
macro: Readonly<{
|
|
265
|
-
data: readonly never[];
|
|
266
|
-
}>;
|
|
267
|
-
folder: Readonly<{
|
|
268
|
-
data: readonly ({
|
|
269
|
-
describe: string;
|
|
270
|
-
shape: "a wikilink, or a map of wikilinks keyed by pack";
|
|
271
|
-
kind: "scalar-or-map";
|
|
272
|
-
entryShape: "a wikilink";
|
|
273
|
-
keys: "pack";
|
|
274
|
-
name: string;
|
|
275
|
-
} | {
|
|
276
|
-
describe: string;
|
|
277
|
-
shape: "string";
|
|
278
|
-
kind: "string";
|
|
279
|
-
name: string;
|
|
280
|
-
})[];
|
|
281
|
-
}>;
|
|
282
|
-
bundle: Readonly<{
|
|
283
|
-
data: readonly {
|
|
284
|
-
describe: string;
|
|
285
|
-
shape: "list of wikilinks";
|
|
286
|
-
kind: "list";
|
|
287
|
-
name: string;
|
|
288
|
-
}[];
|
|
289
|
-
}>;
|
|
290
|
-
lore: Readonly<{
|
|
291
|
-
subTypes: readonly string[];
|
|
292
|
-
data: readonly never[];
|
|
293
|
-
}>;
|
|
294
|
-
place: Readonly<{
|
|
295
|
-
subTypes: readonly string[];
|
|
296
|
-
data: readonly ({
|
|
297
|
-
describe: string;
|
|
298
|
-
shape: "string";
|
|
299
|
-
kind: "string";
|
|
300
|
-
name: string;
|
|
301
|
-
} | {
|
|
302
|
-
describe: string;
|
|
303
|
-
shape: "list of wikilinks";
|
|
304
|
-
kind: "list";
|
|
305
|
-
name: string;
|
|
306
|
-
} | {
|
|
307
|
-
describe: string;
|
|
308
|
-
shape: "number";
|
|
309
|
-
kind: "number";
|
|
310
|
-
name: string;
|
|
311
|
-
})[];
|
|
312
|
-
}>;
|
|
313
|
-
scenario: Readonly<{
|
|
314
|
-
subTypes: readonly string[];
|
|
315
|
-
data: readonly ({
|
|
316
|
-
describe: string;
|
|
317
|
-
shape: "list of wikilinks";
|
|
318
|
-
kind: "list";
|
|
319
|
-
name: string;
|
|
320
|
-
} | {
|
|
321
|
-
describe: string;
|
|
322
|
-
shape: "string";
|
|
323
|
-
kind: "string";
|
|
324
|
-
name: string;
|
|
325
|
-
} | {
|
|
326
|
-
describe: string;
|
|
327
|
-
shape: "list";
|
|
328
|
-
kind: "list";
|
|
329
|
-
name: string;
|
|
330
|
-
})[];
|
|
331
|
-
}>;
|
|
332
|
-
homepage: Readonly<{
|
|
333
|
-
data: readonly never[];
|
|
334
|
-
}>;
|
|
335
|
-
map: Readonly<{
|
|
336
|
-
subTypes: readonly string[];
|
|
337
|
-
data: readonly ({
|
|
338
|
-
describe: string;
|
|
339
|
-
shape: "string";
|
|
340
|
-
kind: "string";
|
|
341
|
-
name: string;
|
|
342
|
-
} | {
|
|
343
|
-
describe: string;
|
|
344
|
-
shape: "list";
|
|
345
|
-
kind: "list";
|
|
346
|
-
name: string;
|
|
347
|
-
} | {
|
|
348
|
-
describe: string;
|
|
349
|
-
shape: "number";
|
|
350
|
-
kind: "number";
|
|
351
|
-
name: string;
|
|
352
|
-
} | {
|
|
353
|
-
describe: string;
|
|
354
|
-
shape: "as authored";
|
|
355
|
-
name: string;
|
|
356
|
-
})[];
|
|
357
|
-
}>;
|
|
358
|
-
}>;
|
|
174
|
+
/**
|
|
175
|
+
* Every note type this toolchain compiles, and the closed vocabulary it
|
|
176
|
+
* declares.
|
|
177
|
+
*
|
|
178
|
+
* Taken from the content-format specification, one `### type:` section per
|
|
179
|
+
* entry. Where the specification and the shape notes are authored in today
|
|
180
|
+
* disagree, the specification wins on the **name** — that is what a `data:`
|
|
181
|
+
* key will be called — and the disagreement is recorded on the field rather
|
|
182
|
+
* than resolved silently.
|
|
183
|
+
*
|
|
184
|
+
* @type {Readonly<Record<string, TypeVocabulary>>}
|
|
185
|
+
*/
|
|
186
|
+
export const NOTE_VOCABULARY: Readonly<Record<string, TypeVocabulary>>;
|
|
359
187
|
/**
|
|
360
188
|
* One `data:` key a note type may carry.
|
|
361
189
|
*
|
|
362
190
|
* A deliberate subset of {@link import ("./field-spec.mjs").FieldSpec}: no `to`,
|
|
363
191
|
* because nothing here builds anything yet. Reading `data.*` through into a
|
|
364
|
-
* document's `system` block is the passthrough slice
|
|
192
|
+
* document's `system` block is the passthrough slice, and claiming an
|
|
365
193
|
* emitted path this does not produce would be a lie in the one place a reader
|
|
366
194
|
* would trust it.
|
|
367
195
|
*/
|
|
@@ -20,7 +20,7 @@ export function findConfigFile(from: string): string | undefined;
|
|
|
20
20
|
*
|
|
21
21
|
* Kept separate from {@link loadPackConfig} because the *choice* is worth being
|
|
22
22
|
* able to ask about without loading anything: the two walks disagreeing is the
|
|
23
|
-
* observable form of
|
|
23
|
+
* observable form of that, and a caller that wants to report it — or a test
|
|
24
24
|
* that wants to describe it — should not have to reproduce the resolution and
|
|
25
25
|
* risk disagreeing with the loader about it. It performs I/O, and is named for
|
|
26
26
|
* it, like the {@link findConfigFile} it calls twice.
|
|
@@ -58,7 +58,7 @@ export function resolveConfigFile({ cwd, moduleDir }?: {
|
|
|
58
58
|
* worse than locating none — a reader would learn that some configuration
|
|
59
59
|
* errors carry a position and could not predict which — so the path rides on
|
|
60
60
|
* the error and every one of them is located here, at the boundary that knows
|
|
61
|
-
* which file was read
|
|
61
|
+
* which file was read.
|
|
62
62
|
*
|
|
63
63
|
* The message keeps its body and gains the `file:line:column: error: ` prefix
|
|
64
64
|
* every other finding in this build already uses, so nothing a reader has today
|
|
@@ -82,7 +82,7 @@ export function locateConfigError(err: unknown, configPath?: string): unknown;
|
|
|
82
82
|
* cannot write `import.meta.dirname`, and any absolute path it wrote instead
|
|
83
83
|
* would be one machine's — so authoring it is rejected rather than honoured.
|
|
84
84
|
* - **`itemBuilders`** is a *name* (`sohl`) — or a list of names, for a tree
|
|
85
|
-
* feeding more than one system
|
|
85
|
+
* feeding more than one system — resolved against the built-in
|
|
86
86
|
* registries. A registry's name is the system it belongs to. A registry of a
|
|
87
87
|
* consumer's own is code, and code goes in an `.mjs` configuration.
|
|
88
88
|
* - **`stats.systemVersion`** is derived from the adjacent `package.json` when
|
|
@@ -95,11 +95,11 @@ export function locateConfigError(err: unknown, configPath?: string): unknown;
|
|
|
95
95
|
*
|
|
96
96
|
* @param {unknown} data - The parsed configuration document.
|
|
97
97
|
* @param {string} configPath - Absolute path of the file it was parsed from.
|
|
98
|
-
* @returns {import("../config.mjs").ContentBuildConfig} The frozen configuration.
|
|
98
|
+
* @returns {import("../content-config.mjs").ContentBuildConfig} The frozen configuration.
|
|
99
99
|
* @throws {Error} When the document is not a mapping, declares `rootDir`, or
|
|
100
100
|
* names an item-builder registry this package does not ship.
|
|
101
101
|
*/
|
|
102
|
-
export function configFromData(data: unknown, configPath: string): import("../config.mjs").ContentBuildConfig;
|
|
102
|
+
export function configFromData(data: unknown, configPath: string): import("../content-config.mjs").ContentBuildConfig;
|
|
103
103
|
/**
|
|
104
104
|
* The consuming repository's resolved, frozen configuration.
|
|
105
105
|
*
|
|
@@ -108,12 +108,12 @@ export function configFromData(data: unknown, configPath: string): import("../co
|
|
|
108
108
|
* configuration (#2). The result is memoised, so calling it in a default
|
|
109
109
|
* parameter — the usual spelling here — costs one property read per call.
|
|
110
110
|
*
|
|
111
|
-
* @returns {import("../config.mjs").ContentBuildConfig} The frozen configuration.
|
|
111
|
+
* @returns {import("../content-config.mjs").ContentBuildConfig} The frozen configuration.
|
|
112
112
|
* @throws {Error} When no configuration file can be found, or the one named
|
|
113
113
|
* cannot be loaded. Absence is a defect, not a fallback: without it the
|
|
114
114
|
* compilers know neither what to compile nor where to put it.
|
|
115
115
|
*/
|
|
116
|
-
export function loadPackConfig(): import("../config.mjs").ContentBuildConfig;
|
|
116
|
+
export function loadPackConfig(): import("../content-config.mjs").ContentBuildConfig;
|
|
117
117
|
/**
|
|
118
118
|
* The file {@link loadPackConfig} resolved the configuration from.
|
|
119
119
|
*
|
|
@@ -48,7 +48,7 @@ export class PackRoutingError extends Error {
|
|
|
48
48
|
*
|
|
49
49
|
* Deliberately close to the retired `package:` and deliberately not the same
|
|
50
50
|
* word: `package:` said which *distribution* owned a note — now the
|
|
51
|
-
* repository's `contentPackage`, and no longer authorable
|
|
51
|
+
* repository's `contentPackage`, and no longer authorable — while `pack:`
|
|
52
52
|
* says which *compendium* receives its document.
|
|
53
53
|
*/
|
|
54
54
|
export const PACK_FIELD: "pack";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The file name a downloaded book identifies itself by.
|
|
3
|
+
*
|
|
4
|
+
* The zip and the manifest take their names from the manifest, so an asset's
|
|
5
|
+
* name and its advertised URL cannot disagree. A PDF has no advertised URL, so
|
|
6
|
+
* its name is a free choice — which is exactly why it is fixed here rather than
|
|
7
|
+
* left for each of six consumers to invent.
|
|
8
|
+
*
|
|
9
|
+
* @param {string} artifact - The package's artifact name.
|
|
10
|
+
* @param {string} version - The version being released.
|
|
11
|
+
* @returns {string} `<artifact>-<version>.pdf`, or `<artifact>.pdf` unversioned.
|
|
12
|
+
*/
|
|
13
|
+
export function pdfFileName(artifact: string, version: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Build the book.
|
|
16
|
+
*
|
|
17
|
+
* @param {object} [opts] - Options.
|
|
18
|
+
* @param {object} [opts.config] - A resolved configuration; loaded when absent.
|
|
19
|
+
* @param {string} [opts.out] - Where to write, overriding `pdf.out`.
|
|
20
|
+
* @param {string} [opts.version] - Stamped on the title page and the file name.
|
|
21
|
+
* @param {boolean} [opts.compile] - Whether to run Typst. False leaves the
|
|
22
|
+
* `.typ` source, which is what the unit tests read.
|
|
23
|
+
* @returns {Promise<object>} `{ built, reason, findings, typ, pdf, stats }`.
|
|
24
|
+
*/
|
|
25
|
+
export function buildPdf({ config, out, version, compile }?: {
|
|
26
|
+
config?: object | undefined;
|
|
27
|
+
out?: string | undefined;
|
|
28
|
+
version?: string | undefined;
|
|
29
|
+
compile?: boolean | undefined;
|
|
30
|
+
}): Promise<object>;
|
|
31
|
+
/**
|
|
32
|
+
* Run Typst over the emitted source.
|
|
33
|
+
*
|
|
34
|
+
* @param {string} typPath - The `.typ` file.
|
|
35
|
+
* @param {string} pdfPath - Where the PDF goes.
|
|
36
|
+
* @param {object} pdf - The resolved `pdf:` block.
|
|
37
|
+
* @returns {{ok: boolean, message: string}} What happened.
|
|
38
|
+
*/
|
|
39
|
+
export function compileTypst(typPath: string, pdfPath: string, pdf?: object): {
|
|
40
|
+
ok: boolean;
|
|
41
|
+
message: string;
|
|
42
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every glyph name a font carries, with the codepoint that reaches it.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} file - Path to a `.ttf`/`.otf`.
|
|
5
|
+
* @returns {Map<string, number>} Name → codepoint.
|
|
6
|
+
*/
|
|
7
|
+
export function glyphTable(file: string): Map<string, number>;
|
|
8
|
+
/**
|
|
9
|
+
* The family name a font file announces, for Typst's `text(font: …)`.
|
|
10
|
+
*
|
|
11
|
+
* Read from the `name` table rather than from the file name, because the file
|
|
12
|
+
* is what a consumer happened to call it and the family is what the font stack
|
|
13
|
+
* will match on.
|
|
14
|
+
*
|
|
15
|
+
* @param {string} file - Path to a `.ttf`/`.otf`.
|
|
16
|
+
* @returns {string} The family name, or "" when the table cannot be read.
|
|
17
|
+
*/
|
|
18
|
+
export function familyName(file: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Resolve every icon in a registry against the fonts a consumer named.
|
|
21
|
+
*
|
|
22
|
+
* @param {object} registry - The resolved `icons:` registry.
|
|
23
|
+
* @param {Record<string, string>} iconFonts - Family name → font file.
|
|
24
|
+
* @param {object[]} [findings] - Collected here rather than thrown.
|
|
25
|
+
* @returns {Map<string, {font: string, codepoint: number}>} Icon name → glyph.
|
|
26
|
+
*/
|
|
27
|
+
export function resolveIconGlyphs(registry: object, iconFonts?: Record<string, string>, findings?: object[]): Map<string, {
|
|
28
|
+
font: string;
|
|
29
|
+
codepoint: number;
|
|
30
|
+
}>;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escape literal text for Typst markup.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} text - Text as the author wrote it.
|
|
5
|
+
* @returns {string} The same text, inert.
|
|
6
|
+
*/
|
|
7
|
+
export function escapeTypst(text: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Escape a string going inside Typst string quotes, as a `#link` URL does.
|
|
10
|
+
*
|
|
11
|
+
* @param {string} text - The raw value.
|
|
12
|
+
* @returns {string} The same value, quotable.
|
|
13
|
+
*/
|
|
14
|
+
export function escapeTypstString(text: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* A Typst label, from a plan anchor.
|
|
17
|
+
*
|
|
18
|
+
* Typst labels admit a narrower charset than an anchor does, so anything else
|
|
19
|
+
* folds to a hyphen. The plan already guarantees anchors are unique, and a fold
|
|
20
|
+
* that merged two of them would silently give one destination two meanings —
|
|
21
|
+
* so the fold is injective by construction: only characters Typst rejects move,
|
|
22
|
+
* and they move to a character the slugifier never emits twice in a row.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} anchor - The plan's anchor.
|
|
25
|
+
* @returns {string} A Typst label name.
|
|
26
|
+
*/
|
|
27
|
+
export function labelFor(anchor: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* A markdown-it configured to parse, not to render.
|
|
30
|
+
*
|
|
31
|
+
* `html: false` is the load-bearing setting: raw HTML in a note has no route to
|
|
32
|
+
* Typst at all, which is why {@link module:engine/content-html} reports it. With
|
|
33
|
+
* HTML disabled markdown-it emits the tag as text, so it arrives in the book
|
|
34
|
+
* visibly wrong rather than invisibly missing.
|
|
35
|
+
*
|
|
36
|
+
* @param {object} [registry] - The icon registry.
|
|
37
|
+
* @returns {object} A markdown-it instance.
|
|
38
|
+
*/
|
|
39
|
+
export function createParser(registry?: object): object;
|
|
40
|
+
/**
|
|
41
|
+
* Render markdown as Typst content.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} markdown - The note's body, tables expanded and links resolved.
|
|
44
|
+
* @param {object} [opts] - Options.
|
|
45
|
+
* @param {object} [opts.md] - A parser from {@link createParser}, reused across
|
|
46
|
+
* a whole book rather than rebuilt for each of 2,500 notes.
|
|
47
|
+
* @param {object} [opts.registry] - The icon registry, when no parser is passed.
|
|
48
|
+
* @param {Map<string, string>} [opts.links] - Address slug → plan anchor.
|
|
49
|
+
* @param {Map<string, string>} [opts.glyphs] - Icon name → `{font, char}`.
|
|
50
|
+
* @param {number} [opts.headingOffset] - Added to every heading level, so a
|
|
51
|
+
* note's own `##` nests beneath the entry heading the book gave it.
|
|
52
|
+
* @param {string} [opts.anchorPrefix] - The entry's anchor, which namespaces
|
|
53
|
+
* every `{#slug}` the body declares.
|
|
54
|
+
* @returns {string} Typst markup.
|
|
55
|
+
*/
|
|
56
|
+
export function markdownToTypst(markdown: string, opts?: {
|
|
57
|
+
md?: object | undefined;
|
|
58
|
+
registry?: object | undefined;
|
|
59
|
+
links?: Map<string, string> | undefined;
|
|
60
|
+
glyphs?: Map<string, string> | undefined;
|
|
61
|
+
headingOffset?: number | undefined;
|
|
62
|
+
anchorPrefix?: string | undefined;
|
|
63
|
+
}): string;
|
|
64
|
+
/**
|
|
65
|
+
* The whole book, as one Typst document.
|
|
66
|
+
*
|
|
67
|
+
* **Pure, and that is the point.** Everything a reviewer of #316 has to check
|
|
68
|
+
* about structure — the outline's shape, the anchors, which links went inward,
|
|
69
|
+
* the order entries print in — is decided here from a plan and a map of bodies,
|
|
70
|
+
* with no filesystem and no compiler. {@link module:engine/pdf-build} supplies
|
|
71
|
+
* both and runs Typst over the result.
|
|
72
|
+
*
|
|
73
|
+
* ## Two outlines, and why they are not the same outline
|
|
74
|
+
*
|
|
75
|
+
* A roster of 2,500 entries wants every entry reachable from a viewer's
|
|
76
|
+
* sidebar, and emphatically does not want all 2,500 printed in the front
|
|
77
|
+
* matter: that is forty pages of contents before the book starts.
|
|
78
|
+
*
|
|
79
|
+
* Typst separates the two for us. **The PDF bookmark outline is built from
|
|
80
|
+
* every heading**, so each entry gets its own node at its own depth for free
|
|
81
|
+
* and the sidebar is the navigational interface the issue asks for.
|
|
82
|
+
* **`#outline()` prints only to `tocDepth`**, so the paper table of contents
|
|
83
|
+
* stays the sections. Both are page-numbered and both are links.
|
|
84
|
+
*
|
|
85
|
+
* ## Headings carry the structure, so nothing else has to
|
|
86
|
+
*
|
|
87
|
+
* Every section, every prose file and every entry is a real Typst heading at
|
|
88
|
+
* its plan depth. That single decision supplies the bookmarks, the printed
|
|
89
|
+
* contents, the running heads and the page breaks at once — where drawing
|
|
90
|
+
* titles as styled text would have meant building all four by hand and keeping
|
|
91
|
+
* them agreeing with each other.
|
|
92
|
+
*
|
|
93
|
+
* @param {object} opts - Options.
|
|
94
|
+
* @param {object} opts.plan - From {@link module:engine/pdf-toc.planDocument}.
|
|
95
|
+
* @param {Map<string, string>} opts.bodies - Anchor → the entry's rendered
|
|
96
|
+
* Typst body. An entry with no body prints its heading alone.
|
|
97
|
+
* @param {string} opts.title - The document's title.
|
|
98
|
+
* @param {string} [opts.subtitle] - Shown under it on the title page.
|
|
99
|
+
* @param {string[]} [opts.front] - Rendered Typst for each front-matter file.
|
|
100
|
+
* @param {object} [opts.fonts] - `{ serif, sans, mono }` family names.
|
|
101
|
+
* @param {number} [opts.tocDepth] - How deep the *printed* contents go.
|
|
102
|
+
* @param {string} [opts.version] - Stamped on the title page when given.
|
|
103
|
+
* @returns {string} A complete `.typ` document.
|
|
104
|
+
*/
|
|
105
|
+
export function renderBook({ plan, bodies, title, subtitle, front, fonts, tocDepth, version, }?: {
|
|
106
|
+
plan: object;
|
|
107
|
+
bodies: Map<string, string>;
|
|
108
|
+
title: string;
|
|
109
|
+
subtitle?: string | undefined;
|
|
110
|
+
front?: string[] | undefined;
|
|
111
|
+
fonts?: object | undefined;
|
|
112
|
+
tocDepth?: number | undefined;
|
|
113
|
+
version?: string | undefined;
|
|
114
|
+
}): string;
|
|
115
|
+
/**
|
|
116
|
+
* Point every internal link at a label the document actually declares.
|
|
117
|
+
*
|
|
118
|
+
* **Typst refuses to compile a reference to a label that is not there.** That
|
|
119
|
+
* makes one mistyped `[[note#appearance]]`, or an anchor written inside a code
|
|
120
|
+
* fence where no heading is emitted, fatal to a 1,200-page book — and fatal at
|
|
121
|
+
* the very end, after everything else has succeeded. A reference book cannot
|
|
122
|
+
* have that failure mode: the link is the least important thing on the page and
|
|
123
|
+
* would be taking the other two thousand entries down with it.
|
|
124
|
+
*
|
|
125
|
+
* So references are reconciled against declarations before the source is
|
|
126
|
+
* written. A link to a section that does not exist falls back to the **entry**
|
|
127
|
+
* that would have contained it, which is where a reader wants to end up anyway;
|
|
128
|
+
* a link with no entry to fall back to becomes plain text. Both are reported.
|
|
129
|
+
*
|
|
130
|
+
* A declaration is a label not preceded by `#link(` — the only two places a
|
|
131
|
+
* label appears are the heading that declares one and the link that uses one.
|
|
132
|
+
*
|
|
133
|
+
* @param {string} source - The assembled Typst document.
|
|
134
|
+
* @param {object[]} [findings] - Collected here rather than thrown.
|
|
135
|
+
* @returns {string} The same document, with no reference left dangling.
|
|
136
|
+
*/
|
|
137
|
+
export function resolveDanglingLabels(source: string, findings?: object[]): string;
|
|
138
|
+
/**
|
|
139
|
+
* Every icon name a body uses, so a build can resolve them once.
|
|
140
|
+
*
|
|
141
|
+
* @param {string} markdown - A note body.
|
|
142
|
+
* @returns {string[]} The names, in order of appearance, with repeats.
|
|
143
|
+
*/
|
|
144
|
+
export function iconNamesIn(markdown: string): string[];
|