@heroiclands/package-build 20.4.0 → 20.6.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 +288 -0
- package/CONTENT.md +213 -20
- package/README.md +19 -1
- package/bin/content-build.mjs +135 -32
- package/bin/package-build.mjs +46 -13
- package/content-config.mjs +345 -101
- package/docs/api.md +1352 -0
- package/docs/commands.md +1609 -0
- package/docs/configuration.md +1432 -0
- package/docs/content-format.md +16 -6
- package/docs/diagnostics.md +356 -0
- package/docs/getting-started.md +813 -0
- package/docs/project-setup.md +469 -0
- package/engine/actor-compiler.mjs +30 -27
- package/engine/address-diff.mjs +45 -41
- package/engine/base-compiler.mjs +6 -0
- package/engine/bundles.mjs +9 -0
- package/engine/content-address.mjs +9 -9
- package/engine/content-index.mjs +44 -23
- package/engine/content-links.mjs +44 -11
- package/engine/content-lint.mjs +44 -10
- package/engine/content-tables.mjs +32 -27
- package/engine/folder-notes.mjs +4 -2
- package/engine/frontmatter-lint.mjs +35 -38
- package/engine/generate.mjs +5 -0
- package/engine/helpers.mjs +86 -32
- package/engine/index.mjs +12 -2
- package/engine/journals.mjs +9 -0
- package/engine/note-claims.mjs +18 -10
- package/engine/note-schemas.mjs +0 -5
- package/engine/note-vocabulary.mjs +32 -31
- package/engine/pack-config.mjs +26 -12
- 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 +876 -0
- package/engine/pdf-toc.mjs +525 -0
- package/engine/scenes.mjs +14 -5
- package/engine/schema-check.mjs +1 -1
- package/engine/site-build.mjs +21 -3
- package/engine/web-wikilinks.mjs +6 -3
- package/engine/wikilinks.mjs +2 -4
- package/hm3/actors.mjs +8 -0
- package/hm3/items.mjs +8 -0
- package/package.json +1 -1
- package/release.mjs +63 -3
- package/sohl/actors.mjs +8 -0
- package/sohl/items.mjs +8 -0
- package/sohl/note-schemas.mjs +5 -5
- package/types/content-config.d.mts +66 -15
- package/types/engine/actor-compiler.d.mts +34 -30
- package/types/engine/address-diff.d.mts +57 -3
- package/types/engine/base-compiler.d.mts +10 -2
- package/types/engine/bundles.d.mts +9 -0
- package/types/engine/content-address.d.mts +9 -9
- package/types/engine/content-index.d.mts +57 -13
- package/types/engine/content-lint.d.mts +6 -4
- package/types/engine/content-tables.d.mts +49 -18
- package/types/engine/frontmatter-lint.d.mts +3 -2
- package/types/engine/helpers.d.mts +105 -31
- package/types/engine/index.d.mts +4 -0
- package/types/engine/journals.d.mts +9 -0
- package/types/engine/note-claims.d.mts +17 -10
- package/types/engine/note-vocabulary.d.mts +23 -196
- package/types/engine/pack-config.d.mts +4 -4
- 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 +156 -0
- package/types/engine/pdf-toc.d.mts +114 -0
- package/types/engine/scenes.d.mts +10 -1
- package/types/engine/schema-check.d.mts +2 -2
- package/types/engine/site-build.d.mts +34 -6
- package/types/engine/wikilinks.d.mts +2 -3
- package/types/hm3/actors.d.mts +8 -0
- package/types/hm3/items.d.mts +8 -0
- package/types/release.d.mts +15 -4
- package/types/sohl/actors.d.mts +10 -2
- package/types/sohl/items.d.mts +8 -0
|
@@ -46,7 +46,8 @@ export function lintContentTree(contentBase: string, { skipDirectories, contentP
|
|
|
46
46
|
keys: number;
|
|
47
47
|
};
|
|
48
48
|
/**
|
|
49
|
-
* The shape every `shortcode` must match: ASCII letters and digits
|
|
49
|
+
* The shape every `shortcode` must match: lowercase ASCII letters and digits
|
|
50
|
+
* only.
|
|
50
51
|
*
|
|
51
52
|
* This is {@link ADDRESS_SEGMENT_PATTERN}, not a second copy of it. A shortcode
|
|
52
53
|
* is the last segment of a canonical address, and the rule it is held to is the
|
|
@@ -54,9 +55,10 @@ export function lintContentTree(contentBase: string, { skipDirectories, contentP
|
|
|
54
55
|
* free to drift apart. The name survives because this is where the rule
|
|
55
56
|
* is applied to a note.
|
|
56
57
|
*
|
|
57
|
-
* Case is
|
|
58
|
-
*
|
|
59
|
-
*
|
|
58
|
+
* Case is held to that rule with no exception: two shortcodes differing only
|
|
59
|
+
* in case are two names nobody can tell apart, and `canonicalKey` lowercases
|
|
60
|
+
* every address it builds regardless, so a mixed-case shortcode addresses the
|
|
61
|
+
* same document as its lowercase spelling.
|
|
60
62
|
*
|
|
61
63
|
* A consuming system's *runtime* keeps its own copy of this pattern — it cannot
|
|
62
64
|
* import a build-time dependency into shipped code — and is expected to pin the
|
|
@@ -73,34 +73,65 @@ export function selectRows(spec: object, docs: Array<ContentTableDoc>, self?: Co
|
|
|
73
73
|
* @returns {string} The markdown table (no trailing newline).
|
|
74
74
|
*/
|
|
75
75
|
export function renderContentTable(spec: object, rows: Array<ContentTableDoc>, linkable: (doc: ContentTableDoc) => boolean, self?: ContentTableDoc): string;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Expand every fenced `dataview` and `sql` block in a markdown body.
|
|
78
|
+
*
|
|
79
|
+
* A block that cannot be honoured — malformed or unsupported — is left in the
|
|
80
|
+
* body verbatim and reported in `errors`, so the failure is visible in the
|
|
81
|
+
* output as well as on the console. Every other code fence, and every code
|
|
82
|
+
* span, is left alone (that is how the syntax is documented).
|
|
83
|
+
*
|
|
84
|
+
* A query that selects **no** note is an error unless the fence says
|
|
85
|
+
* `allow-empty`, which states that an empty table is the intended result.
|
|
86
|
+
*
|
|
87
|
+
* @param {string} markdown - The note body, frontmatter already stripped.
|
|
88
|
+
* @param {object} ctx
|
|
89
|
+
* @param {Array<ContentTableDoc>} ctx.docs - The searchable universe: every
|
|
90
|
+
* content note the caller considers in scope.
|
|
91
|
+
* @param {(doc: ContentTableDoc) => boolean} [ctx.linkable] - Whether a note can
|
|
92
|
+
* be linked to from a cell; defaults to never.
|
|
93
|
+
* @param {string} [ctx.source] - The note being expanded, for error reports.
|
|
94
|
+
* @param {ContentTableDoc} [ctx.self] - The note being expanded, as a searchable
|
|
95
|
+
* doc: what a query's `this` reads.
|
|
96
|
+
* @param {object[]} [ctx.sqlTables] - This note's prepared `sql` results, in
|
|
97
|
+
* document order, from
|
|
98
|
+
* {@link module:engine/sql-tables.prepareSqlTables}. An `sql` directive with
|
|
99
|
+
* no prepared result is an error: nothing here runs a query.
|
|
100
|
+
* @returns {{markdown: string, errors: Array<{source: string, directive: string,
|
|
101
|
+
* reason: string, line: number, column?: number}>,
|
|
102
|
+
* warnings: Array<{source: string, line: number, column: number,
|
|
103
|
+
* reason: string}>, lineMap: Array<{line: number, generated: boolean}>}}
|
|
104
|
+
* `lineMap` is parallel to the emitted lines and says which authored line
|
|
105
|
+
* each came from, so a diagnostic about the expanded body can name an
|
|
106
|
+
* authored position. An `errors` entry carries the 0-based line of the
|
|
107
|
+
* directive that failed, for the same reason. `warnings` holds one entry per
|
|
108
|
+
* `dataview` directive the body still authors.
|
|
109
|
+
*/
|
|
110
|
+
export function expandContentTables(markdown: string, { docs, linkable, source, self, sqlTables, }?: {
|
|
111
|
+
docs: Array<ContentTableDoc>;
|
|
112
|
+
linkable?: ((doc: ContentTableDoc) => boolean) | undefined;
|
|
79
113
|
source?: string | undefined;
|
|
80
|
-
self?: undefined;
|
|
81
|
-
sqlTables?: undefined;
|
|
114
|
+
self?: ContentTableDoc | undefined;
|
|
115
|
+
sqlTables?: object[] | undefined;
|
|
82
116
|
}): {
|
|
83
117
|
markdown: string;
|
|
84
|
-
errors:
|
|
85
|
-
source: string;
|
|
86
|
-
directive: string;
|
|
87
|
-
reason: any;
|
|
88
|
-
line: number;
|
|
89
|
-
column: number;
|
|
90
|
-
} | {
|
|
118
|
+
errors: Array<{
|
|
91
119
|
source: string;
|
|
92
120
|
directive: string;
|
|
93
|
-
reason:
|
|
121
|
+
reason: string;
|
|
94
122
|
line: number;
|
|
95
|
-
column?:
|
|
96
|
-
}
|
|
97
|
-
warnings: {
|
|
123
|
+
column?: number;
|
|
124
|
+
}>;
|
|
125
|
+
warnings: Array<{
|
|
98
126
|
source: string;
|
|
99
127
|
line: number;
|
|
100
128
|
column: number;
|
|
101
129
|
reason: string;
|
|
102
|
-
}
|
|
103
|
-
lineMap:
|
|
130
|
+
}>;
|
|
131
|
+
lineMap: Array<{
|
|
132
|
+
line: number;
|
|
133
|
+
generated: boolean;
|
|
134
|
+
}>;
|
|
104
135
|
};
|
|
105
136
|
/**
|
|
106
137
|
* One content note as a content build hands it to the expander: its parsed
|
|
@@ -112,8 +112,9 @@ export function matchesKind(value: unknown, kind: string): boolean;
|
|
|
112
112
|
* @param {object} note - A note from the link index (`{fm, file, raw, type}`).
|
|
113
113
|
* @param {object} opts
|
|
114
114
|
* @param {Record<string, readonly object[]>} opts.schemas - Type → declaration.
|
|
115
|
-
* @param {object} [opts.index] - The link index, for the reference check
|
|
116
|
-
* absence skips that check rather than
|
|
115
|
+
* @param {object} [opts.index] - The link index, for the reference check, which
|
|
116
|
+
* runs through its `referenceHit`. Its absence skips that check rather than
|
|
117
|
+
* reporting every reference as dead.
|
|
117
118
|
* @param {Record<string, object>} [opts.vocabulary] - Type → the closed regions
|
|
118
119
|
* it declares, as `engine/note-vocabulary.mjs` states them. Supplied
|
|
119
120
|
* by the caller for the same reason `schemas` is: this module validates a
|
|
@@ -23,24 +23,6 @@ export function parseMarkdownFile(filePath: any): {
|
|
|
23
23
|
bodyLine: number;
|
|
24
24
|
bodyColumn: number;
|
|
25
25
|
};
|
|
26
|
-
/**
|
|
27
|
-
* Recursively yields every `.md` file under `rootDir`, parsed.
|
|
28
|
-
* Yields `{ frontmatter, body, description, file, absPath, bodyLine,
|
|
29
|
-
* bodyColumn }` for each match — the last two from
|
|
30
|
-
* {@link parseMarkdownFile}, so a caller can report a position inside the
|
|
31
|
-
* body as a position in the file.
|
|
32
|
-
* Silently skips directories that don't exist.
|
|
33
|
-
*
|
|
34
|
-
* Directory names in `skipDirectories` are ignored wherever they appear. The
|
|
35
|
-
* walk itself knows nothing about what they mean: `Templates/` is an Obsidian
|
|
36
|
-
* templater convention this repository's vault happens to use, not a property
|
|
37
|
-
* of a content tree, so it is configured rather than hard-coded.
|
|
38
|
-
*
|
|
39
|
-
* @param {string} rootDir - Root of the tree to walk.
|
|
40
|
-
* @param {object} [opts]
|
|
41
|
-
* @param {readonly string[]} [opts.skipDirectories] - Directory names to ignore.
|
|
42
|
-
* Defaults to the configured list.
|
|
43
|
-
*/
|
|
44
26
|
/**
|
|
45
27
|
* Refuse a corpus read whose scope its caller did not state.
|
|
46
28
|
*
|
|
@@ -78,8 +60,35 @@ export function assertStatedScope(skipDirectories: readonly string[] | undefined
|
|
|
78
60
|
* @returns {void}
|
|
79
61
|
*/
|
|
80
62
|
export function assertSuppliedCorpus(records: readonly object[] | undefined, who: string): void;
|
|
81
|
-
|
|
82
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Recursively yields every `.md` file under `rootDir`, parsed.
|
|
65
|
+
*
|
|
66
|
+
* Yields `{ frontmatter, body, description, file, absPath, bodyLine,
|
|
67
|
+
* bodyColumn }` for each match — the last from {@link parseMarkdownFile}, so a
|
|
68
|
+
* caller can report a position inside the body as a position in the file. A
|
|
69
|
+
* root that does not exist yields nothing, and a directory that cannot be read
|
|
70
|
+
* is warned about and skipped.
|
|
71
|
+
*
|
|
72
|
+
* Directory names in `skipDirectories` are ignored wherever they appear. The
|
|
73
|
+
* walk itself knows nothing about what they mean: `Templates/` is an Obsidian
|
|
74
|
+
* templater convention this repository's vault happens to use, not a property
|
|
75
|
+
* of a content tree, so it is stated by the caller rather than hard-coded.
|
|
76
|
+
*
|
|
77
|
+
* @param {string} rootDir - Root of the tree to walk.
|
|
78
|
+
* @param {object} opts
|
|
79
|
+
* @param {readonly string[]} opts.skipDirectories - Directory names to ignore.
|
|
80
|
+
* Required: the scope is the caller's to state, so two passes cannot
|
|
81
|
+
* disagree about which files are the corpus.
|
|
82
|
+
* @yields {{frontmatter: object|null, body: string, description: string,
|
|
83
|
+
* file: string, absPath: string, bodyLine?: number, bodyColumn?: number}}
|
|
84
|
+
* One entry per `.md` file found.
|
|
85
|
+
* @throws {Error} When `skipDirectories` is not stated — see
|
|
86
|
+
* {@link assertStatedScope}.
|
|
87
|
+
*/
|
|
88
|
+
export function walkMarkdownTree(rootDir: string, { skipDirectories }?: {
|
|
89
|
+
skipDirectories: readonly string[];
|
|
90
|
+
}): Generator<{
|
|
91
|
+
file: string & NonSharedBuffer;
|
|
83
92
|
absPath: string;
|
|
84
93
|
frontmatter: null;
|
|
85
94
|
body: string;
|
|
@@ -87,7 +96,7 @@ export function walkMarkdownTree(rootDir: any, { skipDirectories }?: {}): Genera
|
|
|
87
96
|
bodyLine?: undefined;
|
|
88
97
|
bodyColumn?: undefined;
|
|
89
98
|
} | {
|
|
90
|
-
file: string;
|
|
99
|
+
file: string & NonSharedBuffer;
|
|
91
100
|
absPath: string;
|
|
92
101
|
frontmatter: any;
|
|
93
102
|
body: string;
|
|
@@ -240,14 +249,22 @@ export function makeFilename(name: any, id: any): string;
|
|
|
240
249
|
* `itemArt()`, which runs the path back through this function so a registry
|
|
241
250
|
* entry and a note's `img:` are spelled the same way (#7).
|
|
242
251
|
*
|
|
252
|
+
* **A package with no asset root cannot answer at all.** `assetRoot` is derived
|
|
253
|
+
* from the package kind, and a `documentation` package has none: Foundry serves
|
|
254
|
+
* no files for it. Only a compiling pass reaches here, and a documentation
|
|
255
|
+
* package runs none, so a path arriving with no root to put it under is a pass
|
|
256
|
+
* running where it should not — reported as that, rather than emitted as
|
|
257
|
+
* `null/icons/relic.svg` into a document nobody would check.
|
|
258
|
+
*
|
|
243
259
|
* @param {string | null | undefined} raw - content-relative path from frontmatter.
|
|
244
|
-
* @param {{assetRoot: string}} [config] - The resolved build configuration.
|
|
260
|
+
* @param {{assetRoot: string|null}} [config] - The resolved build configuration.
|
|
245
261
|
* Defaults to this repository's.
|
|
246
262
|
* @returns {string | null} the Foundry-relative path; `""` for a deliberate
|
|
247
263
|
* blank, and `null` when the note names no art at all.
|
|
264
|
+
* @throws {Error} When the configuration has no asset root.
|
|
248
265
|
*/
|
|
249
266
|
export function resolveImg(raw: string | null | undefined, config?: {
|
|
250
|
-
assetRoot: string;
|
|
267
|
+
assetRoot: string | null;
|
|
251
268
|
}): string | null;
|
|
252
269
|
/**
|
|
253
270
|
* Resolves the display name from frontmatter, preferring `name.full`,
|
|
@@ -368,9 +385,23 @@ export function defaultStats(): object;
|
|
|
368
385
|
* @param {object} [router] - The pack router. Supplied by the calling pass so
|
|
369
386
|
* the index and the compile agree about where each note landed; defaults to
|
|
370
387
|
* this repository's own.
|
|
388
|
+
* @param {object} [opts]
|
|
389
|
+
* @param {readonly string[]} [opts.skipDirectories] - Part of the options bag
|
|
390
|
+
* every corpus reader takes; the scope is already settled by `records`.
|
|
391
|
+
* @param {object} [opts.config] - The resolved build configuration; loaded when
|
|
392
|
+
* omitted.
|
|
393
|
+
* @param {readonly object[]} [opts.records] - The corpus, derived once per
|
|
394
|
+
* compile and handed in. Required: see {@link assertSuppliedCorpus}.
|
|
395
|
+
* @param {object[]} [opts.problems] - Part of the same options bag; the notes
|
|
396
|
+
* the index cannot record are collected where the corpus is derived.
|
|
371
397
|
* @returns {{byShortcode: Map, types: Set}} From `buildWikilinkIndex`.
|
|
372
398
|
*/
|
|
373
|
-
export function buildContentLinkIndex(contentBase: string, router?: object, { skipDirectories, config, records, problems }?: {
|
|
399
|
+
export function buildContentLinkIndex(contentBase: string, router?: object, { skipDirectories, config, records, problems }?: {
|
|
400
|
+
skipDirectories?: readonly string[] | undefined;
|
|
401
|
+
config?: object | undefined;
|
|
402
|
+
records?: readonly object[] | undefined;
|
|
403
|
+
problems?: object[] | undefined;
|
|
404
|
+
}): {
|
|
374
405
|
byShortcode: Map<any, any>;
|
|
375
406
|
types: Set<any>;
|
|
376
407
|
};
|
|
@@ -386,18 +417,42 @@ export function buildContentLinkIndex(contentBase: string, router?: object, { sk
|
|
|
386
417
|
* inventing a position.
|
|
387
418
|
*
|
|
388
419
|
* @param {string} body - The note's markdown body, tables already expanded.
|
|
389
|
-
* @param {object} ctx
|
|
390
|
-
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
420
|
+
* @param {object} ctx
|
|
421
|
+
* @param {string} ctx.type - The source note's content type.
|
|
422
|
+
* @param {string} ctx.id - The source note's document id.
|
|
423
|
+
* @param {string} ctx.pack - The pack the note's own document lands in, which
|
|
424
|
+
* addresses a `[[#slug]]` self-link: its target is the source note itself, so
|
|
425
|
+
* it has no index entry.
|
|
426
|
+
* @param {string} ctx.docPack - The pack the note's documentation journal lands
|
|
427
|
+
* in, addressing a self-link the same way.
|
|
428
|
+
* @param {object} ctx.index - The address index every link resolves through.
|
|
429
|
+
* @param {string} ctx.name - The note, for the message.
|
|
430
|
+
* @param {string} [ctx.file] - The note's file, so a report names it.
|
|
431
|
+
* @param {number} [ctx.bodyLine] - 1-based file line of the body's first line.
|
|
432
|
+
* @param {number} [ctx.bodyColumn] - 1-based file column of the same character.
|
|
433
|
+
* @param {Array<{line: number, generated: boolean}>} [ctx.lineMap] - Which
|
|
434
|
+
* authored line each body line came from, from {@link expandNoteTables}.
|
|
394
435
|
* @returns {{markdown: string, unresolved: Array<object>}}
|
|
395
436
|
* @throws {Error} On any link that does not resolve — an unlabelled one, a
|
|
396
437
|
* target that is not an address, or an address nothing publishes. The error
|
|
397
438
|
* carries `file` and `position`, so a caller reports it in the same form
|
|
398
439
|
* rather than re-deriving one.
|
|
399
440
|
*/
|
|
400
|
-
export function convertNoteWikilinks(body: string, { type, id, pack, docPack, index, name, file, bodyLine, bodyColumn, lineMap }:
|
|
441
|
+
export function convertNoteWikilinks(body: string, { type, id, pack, docPack, index, name, file, bodyLine, bodyColumn, lineMap }: {
|
|
442
|
+
type: string;
|
|
443
|
+
id: string;
|
|
444
|
+
pack: string;
|
|
445
|
+
docPack: string;
|
|
446
|
+
index: object;
|
|
447
|
+
name: string;
|
|
448
|
+
file?: string | undefined;
|
|
449
|
+
bodyLine?: number | undefined;
|
|
450
|
+
bodyColumn?: number | undefined;
|
|
451
|
+
lineMap?: {
|
|
452
|
+
line: number;
|
|
453
|
+
generated: boolean;
|
|
454
|
+
}[] | undefined;
|
|
455
|
+
}): {
|
|
401
456
|
markdown: string;
|
|
402
457
|
unresolved: Array<object>;
|
|
403
458
|
};
|
|
@@ -407,10 +462,24 @@ export function convertNoteWikilinks(body: string, { type, id, pack, docPack, in
|
|
|
407
462
|
* a table that leaves rows tied still emits identically on every build.
|
|
408
463
|
*
|
|
409
464
|
* @param {string} contentBase - Root of the content tree.
|
|
465
|
+
* @param {object} [opts]
|
|
466
|
+
* @param {readonly string[]} [opts.skipDirectories] - Part of the options bag
|
|
467
|
+
* every corpus reader takes; the scope is already settled by `records`.
|
|
468
|
+
* @param {object} [opts.config] - The resolved build configuration; loaded when
|
|
469
|
+
* omitted.
|
|
470
|
+
* @param {readonly object[]} [opts.records] - The corpus, derived once per
|
|
471
|
+
* compile and handed in. Required: see {@link assertSuppliedCorpus}.
|
|
472
|
+
* @param {object[]} [opts.problems] - Part of the same options bag; the notes
|
|
473
|
+
* the walk cannot read are collected where the corpus is derived.
|
|
410
474
|
* @returns {Array<{fm: object, path: string, tld: string, folder: string,
|
|
411
475
|
* absPath: string}>}
|
|
412
476
|
*/
|
|
413
|
-
export function collectContentDocs(contentBase: string, { skipDirectories, config, records, problems }?: {
|
|
477
|
+
export function collectContentDocs(contentBase: string, { skipDirectories, config, records, problems }?: {
|
|
478
|
+
skipDirectories?: readonly string[] | undefined;
|
|
479
|
+
config?: object | undefined;
|
|
480
|
+
records?: readonly object[] | undefined;
|
|
481
|
+
problems?: object[] | undefined;
|
|
482
|
+
}): Array<{
|
|
414
483
|
fm: object;
|
|
415
484
|
path: string;
|
|
416
485
|
tld: string;
|
|
@@ -434,6 +503,10 @@ export function collectContentDocs(contentBase: string, { skipDirectories, confi
|
|
|
434
503
|
* query's `this` reads. Its entry in `docs` supplies the path as well.
|
|
435
504
|
* @param {number} [ctx.bodyLine] - 1-based file line of the body's first line,
|
|
436
505
|
* so a failing directive can be reported at its position in the file.
|
|
506
|
+
* @param {object[]} [ctx.sqlTables] - This note's prepared `sql` results, in
|
|
507
|
+
* document order, from
|
|
508
|
+
* {@link module:engine/sql-tables.prepareSqlTables}. An `sql` directive with
|
|
509
|
+
* no prepared result fails the note: nothing here runs a query.
|
|
437
510
|
* @returns {{markdown: string, lineMap: Array<{line: number,
|
|
438
511
|
* generated: boolean}>}} The body with every table expanded, and where each
|
|
439
512
|
* emitted line came from — which is what lets a diagnostic about the
|
|
@@ -447,6 +520,7 @@ export function expandNoteTables(body: string, { docs, name, fm, bodyLine, sqlTa
|
|
|
447
520
|
name: string;
|
|
448
521
|
fm?: object | undefined;
|
|
449
522
|
bodyLine?: number | undefined;
|
|
523
|
+
sqlTables?: object[] | undefined;
|
|
450
524
|
}): {
|
|
451
525
|
markdown: string;
|
|
452
526
|
lineMap: Array<{
|
package/types/engine/index.d.mts
CHANGED
|
@@ -39,6 +39,10 @@ export * as itemDocs from "./item-docs.mjs";
|
|
|
39
39
|
export * as wikilinks from "./wikilinks.mjs";
|
|
40
40
|
export * as wikilinkSyntax from "./wikilink-syntax.mjs";
|
|
41
41
|
export * as siteIndex from "./site-index.mjs";
|
|
42
|
+
export * as pdfToc from "./pdf-toc.mjs";
|
|
43
|
+
export * as pdfRender from "./pdf-render.mjs";
|
|
44
|
+
export * as pdfFonts from "./pdf-fonts.mjs";
|
|
45
|
+
export * as pdfBuild from "./pdf-build.mjs";
|
|
42
46
|
export * as baseCompiler from "./base-compiler.mjs";
|
|
43
47
|
export * as journals from "./journals.mjs";
|
|
44
48
|
export * as macros from "./macros.mjs";
|
|
@@ -147,6 +147,15 @@ export function buildJournalEntry({ id, name, markdown, leadName, folder, flags,
|
|
|
147
147
|
flags?: object | undefined;
|
|
148
148
|
stats?: object | undefined;
|
|
149
149
|
}): object;
|
|
150
|
+
/**
|
|
151
|
+
* Journals pack compiler.
|
|
152
|
+
*
|
|
153
|
+
* Walks the content tree and compiles every `type: doc` note, and every note of
|
|
154
|
+
* a doc-carrying type, into one JournalEntry document: the body split into
|
|
155
|
+
* pages on its top-level H1 headings, each rendered to HTML. A doc-carrying
|
|
156
|
+
* note's entry is that document's documentation, filed in the document's own
|
|
157
|
+
* folder.
|
|
158
|
+
*/
|
|
150
159
|
export class Journals extends BasePackCompiler {
|
|
151
160
|
/**
|
|
152
161
|
* How many of the compiled entries were documentation for a document
|
|
@@ -7,10 +7,7 @@
|
|
|
7
7
|
* pack from appearing to answer for any note.
|
|
8
8
|
*
|
|
9
9
|
* @param {string} docType - The Foundry document type a pack holds.
|
|
10
|
-
* @param {ClaimSources} [sources] - What to answer from.
|
|
11
|
-
* @param {object} [opts] - Options.
|
|
12
|
-
* @param {readonly object[]} [opts.records] - The corpus, derived once by the
|
|
13
|
-
* compile and handed in — required, for the reason above. Defaults to the
|
|
10
|
+
* @param {ClaimSources} [sources] - What to answer from. Defaults to the
|
|
14
11
|
* configured registries and the systems this toolchain ships.
|
|
15
12
|
* @returns {ReadonlySet<string>} The note types such a pass would claim.
|
|
16
13
|
*/
|
|
@@ -88,9 +85,6 @@ export function documentClassesFor(type: string, sources?: ClaimSources, { hasPr
|
|
|
88
85
|
* @param {object} [config] - The resolved build configuration. Defaults to this
|
|
89
86
|
* repository's.
|
|
90
87
|
* @param {ClaimSources} [sources] - What to answer from.
|
|
91
|
-
* @param {object} [opts] - Options.
|
|
92
|
-
* @param {readonly object[]} [opts.records] - The corpus, derived once by the
|
|
93
|
-
* compile and handed in — required, for the reason above.
|
|
94
88
|
* @returns {ReadonlySet<string>} The claimed note types.
|
|
95
89
|
*/
|
|
96
90
|
export function claimedNoteTypes(config?: object, sources?: ClaimSources): ReadonlySet<string>;
|
|
@@ -104,9 +98,6 @@ export function claimedNoteTypes(config?: object, sources?: ClaimSources): Reado
|
|
|
104
98
|
* declare on top.
|
|
105
99
|
*
|
|
106
100
|
* @param {ClaimSources} [sources] - What to answer from.
|
|
107
|
-
* @param {object} [opts] - Options.
|
|
108
|
-
* @param {readonly object[]} [opts.records] - The corpus, derived once by the
|
|
109
|
-
* compile and handed in — required, for the reason above.
|
|
110
101
|
* @returns {ReadonlySet<string>} The vocabulary.
|
|
111
102
|
*/
|
|
112
103
|
export function noteTypeVocabulary(sources?: ClaimSources): ReadonlySet<string>;
|
|
@@ -150,6 +141,22 @@ export function unclaimedNoteFindings(config?: object, sources?: ClaimSources, {
|
|
|
150
141
|
* @type {ReadonlySet<string>}
|
|
151
142
|
*/
|
|
152
143
|
export const NEVER_PACKED_TYPES: ReadonlySet<string>;
|
|
144
|
+
/**
|
|
145
|
+
* The whole note vocabulary of a package that compiles no Foundry documents.
|
|
146
|
+
*
|
|
147
|
+
* Every other type in the vocabulary exists to *become* a document: a `skill` is
|
|
148
|
+
* an Item, a `being` an Actor, a `place` a JournalEntry, a `folder` the Folder
|
|
149
|
+
* they are filed under. In a `documentation` package none of them has a
|
|
150
|
+
* destination, so a note carrying one would be authored, validated, walked and
|
|
151
|
+
* then published as a page of something that was meant to be a compendium
|
|
152
|
+
* entry — the plausible-looking result that reads as success.
|
|
153
|
+
*
|
|
154
|
+
* `doc` is prose whose single document *is* the prose, and `homepage` is the
|
|
155
|
+
* authored front page every package publishes. Both are already pages first.
|
|
156
|
+
*
|
|
157
|
+
* @type {ReadonlySet<string>}
|
|
158
|
+
*/
|
|
159
|
+
export const DOCUMENTATION_NOTE_TYPES: ReadonlySet<string>;
|
|
153
160
|
/**
|
|
154
161
|
* Content types the specification states and this toolchain does not yet
|
|
155
162
|
* compile.
|
|
@@ -105,17 +105,19 @@ export function dataFields(type: string, vocabulary?: Readonly<Record<string, Ty
|
|
|
105
105
|
*/
|
|
106
106
|
export function subTypes(type: string, vocabulary?: Readonly<Record<string, TypeVocabulary>>): readonly string[] | null | undefined;
|
|
107
107
|
/**
|
|
108
|
-
*
|
|
109
|
-
* declares.
|
|
108
|
+
* The declared tag that marks a note as **unfinished**.
|
|
110
109
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* key will be called — and the disagreement is recorded on the field rather
|
|
115
|
-
* 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.
|
|
116
113
|
*
|
|
117
|
-
*
|
|
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}.
|
|
118
119
|
*/
|
|
120
|
+
export const DRAFT_TAG: "draft";
|
|
119
121
|
/**
|
|
120
122
|
* The tags that **classify** a note, grouped by what they classify.
|
|
121
123
|
*
|
|
@@ -142,20 +144,6 @@ export function subTypes(type: string, vocabulary?: Readonly<Record<string, Type
|
|
|
142
144
|
* fishing village is a `village` that is `fishing`, and the single-valued field
|
|
143
145
|
* this replaced had to spell it `Fishing Village` as a value of its own.
|
|
144
146
|
*/
|
|
145
|
-
/**
|
|
146
|
-
* The declared tag that marks a note as **unfinished**.
|
|
147
|
-
*
|
|
148
|
-
* Named once and referenced from the declaration below, because a second
|
|
149
|
-
* spelling is how the two come apart: rename the tag in `DECLARED_TAGS` and a
|
|
150
|
-
* private copy elsewhere keeps matching the old word, silently.
|
|
151
|
-
*
|
|
152
|
-
* It is a **presentation** fact and nothing more. A draft note compiles,
|
|
153
|
-
* validates, publishes and resolves like any other; only a link *into* it
|
|
154
|
-
* renders marked. What it emphatically is not is the retired `draft:` field,
|
|
155
|
-
* whose entire effect was to move a note from published to unresolvable — see
|
|
156
|
-
* {@link draftRetiredMessage}.
|
|
157
|
-
*/
|
|
158
|
-
export const DRAFT_TAG: "draft";
|
|
159
147
|
export const DECLARED_TAGS: Readonly<{
|
|
160
148
|
/** What a place *is*. */
|
|
161
149
|
placeKind: Readonly<{
|
|
@@ -183,180 +171,19 @@ export const DECLARED_TAGS: Readonly<{
|
|
|
183
171
|
tags: readonly string[];
|
|
184
172
|
}>;
|
|
185
173
|
}>;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
affliction: Readonly<{
|
|
200
|
-
subTypes: readonly string[];
|
|
201
|
-
data: readonly DataFieldSpec[];
|
|
202
|
-
}>;
|
|
203
|
-
armorgear: Readonly<{
|
|
204
|
-
data: readonly DataFieldSpec[];
|
|
205
|
-
}>;
|
|
206
|
-
armorlocation: Readonly<{
|
|
207
|
-
subTypes: null;
|
|
208
|
-
data: readonly DataFieldSpec[];
|
|
209
|
-
}>;
|
|
210
|
-
attribute: Readonly<{
|
|
211
|
-
data: readonly DataFieldSpec[];
|
|
212
|
-
}>;
|
|
213
|
-
concoctiongear: Readonly<{
|
|
214
|
-
subTypes: readonly string[];
|
|
215
|
-
data: readonly (DataFieldSpec | Readonly<{
|
|
216
|
-
describe: "How many of the thing there are; one when unstated.";
|
|
217
|
-
shape: "number";
|
|
218
|
-
kind: "number";
|
|
219
|
-
name: "quantity";
|
|
220
|
-
}>)[];
|
|
221
|
-
}>;
|
|
222
|
-
containergear: Readonly<{
|
|
223
|
-
data: readonly DataFieldSpec[];
|
|
224
|
-
}>;
|
|
225
|
-
miscgear: Readonly<{
|
|
226
|
-
data: readonly (DataFieldSpec | Readonly<{
|
|
227
|
-
describe: "How many of the thing there are; one when unstated.";
|
|
228
|
-
shape: "number";
|
|
229
|
-
kind: "number";
|
|
230
|
-
name: "quantity";
|
|
231
|
-
}>)[];
|
|
232
|
-
}>;
|
|
233
|
-
mystery: Readonly<{
|
|
234
|
-
subTypes: readonly string[];
|
|
235
|
-
data: readonly DataFieldSpec[];
|
|
236
|
-
}>;
|
|
237
|
-
mysticalability: Readonly<{
|
|
238
|
-
subTypes: readonly string[];
|
|
239
|
-
data: readonly DataFieldSpec[];
|
|
240
|
-
}>;
|
|
241
|
-
projectilegear: Readonly<{
|
|
242
|
-
subTypes: readonly string[];
|
|
243
|
-
data: readonly (DataFieldSpec | Readonly<{
|
|
244
|
-
describe: "How many of the thing there are; one when unstated.";
|
|
245
|
-
shape: "number";
|
|
246
|
-
kind: "number";
|
|
247
|
-
name: "quantity";
|
|
248
|
-
}>)[];
|
|
249
|
-
}>;
|
|
250
|
-
skill: Readonly<{
|
|
251
|
-
subTypes: readonly string[];
|
|
252
|
-
data: readonly DataFieldSpec[];
|
|
253
|
-
}>;
|
|
254
|
-
trauma: Readonly<{
|
|
255
|
-
subTypes: readonly string[];
|
|
256
|
-
data: readonly DataFieldSpec[];
|
|
257
|
-
}>;
|
|
258
|
-
weapongear: Readonly<{
|
|
259
|
-
data: readonly DataFieldSpec[];
|
|
260
|
-
}>;
|
|
261
|
-
doc: Readonly<{
|
|
262
|
-
subTypes: readonly string[];
|
|
263
|
-
data: readonly never[];
|
|
264
|
-
}>;
|
|
265
|
-
macro: Readonly<{
|
|
266
|
-
data: readonly never[];
|
|
267
|
-
}>;
|
|
268
|
-
folder: Readonly<{
|
|
269
|
-
data: readonly ({
|
|
270
|
-
describe: string;
|
|
271
|
-
shape: "a wikilink, or a map of wikilinks keyed by pack";
|
|
272
|
-
kind: "scalar-or-map";
|
|
273
|
-
entryShape: "a wikilink";
|
|
274
|
-
keys: "pack";
|
|
275
|
-
name: string;
|
|
276
|
-
} | {
|
|
277
|
-
describe: string;
|
|
278
|
-
shape: "string";
|
|
279
|
-
kind: "string";
|
|
280
|
-
name: string;
|
|
281
|
-
})[];
|
|
282
|
-
}>;
|
|
283
|
-
bundle: Readonly<{
|
|
284
|
-
data: readonly {
|
|
285
|
-
describe: string;
|
|
286
|
-
shape: "list of wikilinks";
|
|
287
|
-
kind: "list";
|
|
288
|
-
name: string;
|
|
289
|
-
}[];
|
|
290
|
-
}>;
|
|
291
|
-
lore: Readonly<{
|
|
292
|
-
subTypes: readonly string[];
|
|
293
|
-
data: readonly never[];
|
|
294
|
-
}>;
|
|
295
|
-
place: Readonly<{
|
|
296
|
-
subTypes: readonly string[];
|
|
297
|
-
data: readonly ({
|
|
298
|
-
describe: string;
|
|
299
|
-
shape: "string";
|
|
300
|
-
kind: "string";
|
|
301
|
-
name: string;
|
|
302
|
-
} | {
|
|
303
|
-
describe: string;
|
|
304
|
-
shape: "list of wikilinks";
|
|
305
|
-
kind: "list";
|
|
306
|
-
name: string;
|
|
307
|
-
} | {
|
|
308
|
-
describe: string;
|
|
309
|
-
shape: "number";
|
|
310
|
-
kind: "number";
|
|
311
|
-
name: string;
|
|
312
|
-
})[];
|
|
313
|
-
}>;
|
|
314
|
-
scenario: Readonly<{
|
|
315
|
-
subTypes: readonly string[];
|
|
316
|
-
data: readonly ({
|
|
317
|
-
describe: string;
|
|
318
|
-
shape: "list of wikilinks";
|
|
319
|
-
kind: "list";
|
|
320
|
-
name: string;
|
|
321
|
-
} | {
|
|
322
|
-
describe: string;
|
|
323
|
-
shape: "string";
|
|
324
|
-
kind: "string";
|
|
325
|
-
name: string;
|
|
326
|
-
} | {
|
|
327
|
-
describe: string;
|
|
328
|
-
shape: "list";
|
|
329
|
-
kind: "list";
|
|
330
|
-
name: string;
|
|
331
|
-
})[];
|
|
332
|
-
}>;
|
|
333
|
-
homepage: Readonly<{
|
|
334
|
-
data: readonly never[];
|
|
335
|
-
}>;
|
|
336
|
-
map: Readonly<{
|
|
337
|
-
subTypes: readonly string[];
|
|
338
|
-
data: readonly ({
|
|
339
|
-
describe: string;
|
|
340
|
-
shape: "string";
|
|
341
|
-
kind: "string";
|
|
342
|
-
name: string;
|
|
343
|
-
} | {
|
|
344
|
-
describe: string;
|
|
345
|
-
shape: "list";
|
|
346
|
-
kind: "list";
|
|
347
|
-
name: string;
|
|
348
|
-
} | {
|
|
349
|
-
describe: string;
|
|
350
|
-
shape: "number";
|
|
351
|
-
kind: "number";
|
|
352
|
-
name: string;
|
|
353
|
-
} | {
|
|
354
|
-
describe: string;
|
|
355
|
-
shape: "as authored";
|
|
356
|
-
name: string;
|
|
357
|
-
})[];
|
|
358
|
-
}>;
|
|
359
|
-
}>;
|
|
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>>;
|
|
360
187
|
/**
|
|
361
188
|
* One `data:` key a note type may carry.
|
|
362
189
|
*
|