@heroiclands/package-build 22.22.0 → 22.24.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 +46 -0
- package/README.md +1 -0
- package/bin/content-commands.mjs +51 -14
- package/ci/content-format-reference.mjs +1 -1
- package/content-config.mjs +80 -2
- package/docs/api.md +85 -72
- package/docs/authoring/assets.md +29 -0
- package/docs/authoring/dates-and-calendars.md +37 -1
- package/docs/authoring/links-and-markup.md +112 -31
- package/docs/commands.md +30 -29
- package/docs/configuration.md +92 -19
- package/docs/content-format.md +1 -1
- package/docs/guides/book.md +5 -4
- package/docs/guides/module-project.md +2 -2
- package/docs/guides/site.md +41 -0
- package/docs/project-setup.md +4 -4
- package/docs/reference/format-details.md +323 -60
- package/docs/reference/note-types.md +9 -9
- package/docs/reference/theme-pages.md +496 -0
- package/engine/anchors.mjs +16 -10
- package/engine/art-fields.mjs +118 -0
- package/engine/art-slots.mjs +9 -2
- package/engine/asset-index.mjs +160 -10
- package/engine/asset-replacement.mjs +93 -0
- package/engine/asset-types.mjs +240 -0
- package/engine/base-compiler.mjs +54 -2
- package/engine/bundles.mjs +13 -1
- package/engine/content-blocks.mjs +4 -4
- package/engine/content-embeds.mjs +19 -0
- package/engine/content-figures.mjs +468 -0
- package/engine/content-footnotes.mjs +10 -2
- package/engine/content-format.yaml +1 -1
- package/engine/content-images.mjs +126 -25
- package/engine/content-index.mjs +36 -10
- package/engine/field-reference.mjs +31 -10
- package/engine/field-spec.mjs +10 -8
- package/engine/foreign-catalog.mjs +145 -19
- package/engine/frontmatter-lint.mjs +73 -1
- package/engine/heading-attributes.mjs +31 -18
- package/engine/helpers.mjs +102 -33
- package/engine/infobox-registry.mjs +4 -1
- package/engine/infobox.mjs +47 -8
- package/engine/itinerary-scenes.mjs +4 -10
- package/engine/journals.mjs +264 -39
- package/engine/lore-events.mjs +197 -0
- package/engine/markdown-expressions.mjs +257 -7
- package/engine/note-dates.mjs +305 -12
- package/engine/note-vocabulary.mjs +11 -5
- package/engine/pathnames.mjs +36 -0
- package/engine/pdf-build.mjs +357 -34
- package/engine/pdf-images.mjs +64 -0
- package/engine/pdf-render.mjs +160 -36
- package/engine/scenes.mjs +16 -4
- package/engine/site-build.mjs +127 -13
- package/engine/site-config.mjs +19 -24
- package/engine/site-index.mjs +72 -1
- package/engine/site-preview.mjs +2 -0
- package/engine/system-block.mjs +44 -16
- package/hm3/actors.mjs +2 -2
- package/hugo-theme/data/banners.yaml +69 -0
- package/hugo-theme/layouts/404.html +85 -0
- package/hugo-theme/layouts/_default/baseof.html +64 -0
- package/hugo-theme/layouts/_default/list.html +139 -0
- package/hugo-theme/layouts/_default/single.html +4 -0
- package/hugo-theme/layouts/blog/list.html +54 -0
- package/hugo-theme/layouts/blog-post/single.html +36 -0
- package/hugo-theme/layouts/index.html +75 -0
- package/hugo-theme/layouts/partials/banner-url.html +117 -0
- package/hugo-theme/layouts/partials/cdn-url.html +36 -0
- package/hugo-theme/layouts/partials/draft-notice.html +41 -0
- package/hugo-theme/layouts/partials/draft-state.html +26 -0
- package/hugo-theme/layouts/partials/footer.html +29 -0
- package/hugo-theme/layouts/partials/header.html +35 -0
- package/hugo-theme/layouts/partials/hero-banner.html +86 -0
- package/hugo-theme/layouts/partials/holdings/entry.html +21 -0
- package/hugo-theme/layouts/partials/holdings/kind-groups.html +71 -0
- package/hugo-theme/layouts/partials/holdings.html +61 -0
- package/hugo-theme/layouts/partials/infobox/entry.html +15 -0
- package/hugo-theme/layouts/partials/infobox/items.html +26 -0
- package/hugo-theme/layouts/partials/infobox/section.html +56 -0
- package/hugo-theme/layouts/partials/infobox/value.html +43 -0
- package/hugo-theme/layouts/partials/infobox.html +57 -0
- package/hugo-theme/layouts/partials/page-body.html +154 -0
- package/hugo-theme/layouts/partials/place-map.html +9 -0
- package/hugo-theme/layouts/partials/related.html +121 -0
- package/hugo-theme/layouts/partials/search.html +84 -0
- package/hugo-theme/layouts/partials/site-url.html +32 -0
- package/hugo-theme/layouts/partials/tags.html +30 -0
- package/hugo-theme/layouts/partials/toc.html +28 -0
- package/hugo-theme/layouts/partials/warn-missing-banner.html +3 -0
- package/hugo-theme/layouts/shortcodes/cartouche.html +64 -0
- package/hugo-theme/layouts/shortcodes/exturl.html +12 -0
- package/hugo-theme/layouts/shortcodes/glyph.html +43 -0
- package/hugo-theme/layouts/shortcodes/pagelist.html +63 -0
- package/hugo-theme/static/css/sohl-icons.css +57 -0
- package/hugo-theme/static/css/style.css +2953 -0
- package/hugo-theme/static/fonts/game-icons-kb.woff2 +0 -0
- package/hugo-theme/static/img/banners/takheperu-hieroglyphs.svg +1 -0
- package/hugo-theme/static/img/cartouches/takheperu.svg +1 -0
- package/hugo-theme/theme.toml +11 -0
- package/manifest.mjs +30 -24
- package/package.json +2 -1
- package/packagebuild-metadata.jsonl +13 -13
- package/sohl/item-fields.mjs +4 -3
- package/types/content-config.d.mts +48 -1
- package/types/engine/anchors.d.mts +9 -4
- package/types/engine/art-fields.d.mts +64 -0
- package/types/engine/art-slots.d.mts +2 -1
- package/types/engine/asset-index.d.mts +43 -0
- package/types/engine/asset-replacement.d.mts +22 -0
- package/types/engine/asset-types.d.mts +18 -0
- package/types/engine/base-compiler.d.mts +0 -17
- package/types/engine/content-embeds.d.mts +16 -0
- package/types/engine/content-figures.d.mts +101 -0
- package/types/engine/content-footnotes.d.mts +7 -0
- package/types/engine/content-images.d.mts +78 -12
- package/types/engine/content-index.d.mts +8 -2
- package/types/engine/field-reference.d.mts +21 -0
- package/types/engine/field-spec.d.mts +20 -16
- package/types/engine/foreign-catalog.d.mts +39 -0
- package/types/engine/heading-attributes.d.mts +13 -8
- package/types/engine/helpers.d.mts +28 -10
- package/types/engine/infobox-registry.d.mts +4 -1
- package/types/engine/infobox.d.mts +6 -0
- package/types/engine/journals.d.mts +31 -9
- package/types/engine/lore-events.d.mts +14 -0
- package/types/engine/markdown-expressions.d.mts +23 -2
- package/types/engine/note-dates.d.mts +64 -1
- package/types/engine/pathnames.d.mts +26 -0
- package/types/engine/pdf-build.d.mts +28 -6
- package/types/engine/pdf-images.d.mts +52 -0
- package/types/engine/pdf-render.d.mts +12 -0
- package/types/engine/site-build.d.mts +14 -3
- package/types/engine/site-config.d.mts +9 -9
- package/types/engine/site-index.d.mts +54 -0
- package/types/engine/system-block.d.mts +26 -2
- package/types/hm3/actors.d.mts +18 -0
- package/types/manifest.d.mts +19 -23
- package/engine/content-captions.mjs +0 -230
- package/types/engine/content-captions.d.mts +0 -58
|
@@ -30,16 +30,28 @@ export function parseImageDirective(raw?: string): {
|
|
|
30
30
|
problems: string[];
|
|
31
31
|
};
|
|
32
32
|
/**
|
|
33
|
-
* The
|
|
33
|
+
* The class a picture's role names, or `""` for no role or one outside the
|
|
34
|
+
* closed set — the same silent-degrade rule every other unrecognised value
|
|
35
|
+
* here gets, since a role this far downstream has already been validated or
|
|
36
|
+
* dropped by the asset record that carries it.
|
|
34
37
|
*
|
|
35
|
-
* @param {
|
|
38
|
+
* @param {string} [role] - The role, from the resolved asset record.
|
|
39
|
+
* @returns {string} The class, or `""`.
|
|
40
|
+
*/
|
|
41
|
+
export function roleClass(role?: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* The classes a figure carries, from a parsed directive and its asset's role.
|
|
44
|
+
*
|
|
45
|
+
* @param {{classes?: string[], size?: string, float?: string, role?: string}} [directive] -
|
|
46
|
+
* As parsed, plus the role the resolved asset record carries, if any.
|
|
36
47
|
* @returns {string} A space-separated class list, always naming
|
|
37
48
|
* {@link IMAGE_FIGURE_CLASS} first.
|
|
38
49
|
*/
|
|
39
|
-
export function figureClasses({ classes, size, float }?: {
|
|
50
|
+
export function figureClasses({ classes, size, float, role }?: {
|
|
40
51
|
classes?: string[];
|
|
41
52
|
size?: string;
|
|
42
53
|
float?: string;
|
|
54
|
+
role?: string;
|
|
43
55
|
}): string;
|
|
44
56
|
/**
|
|
45
57
|
* Text going inside an HTML attribute or between tags.
|
|
@@ -55,28 +67,57 @@ export function escapeHtml(text: string): string;
|
|
|
55
67
|
* function, so the two cannot drift into styling the same directive through
|
|
56
68
|
* different class names.
|
|
57
69
|
*
|
|
70
|
+
* **No `<figcaption>` is emitted here.** A `:::figure` fence draws its own
|
|
71
|
+
* label and authored caption around whatever this returns; the alt text stays
|
|
72
|
+
* on the `img` element alone.
|
|
73
|
+
*
|
|
74
|
+
* **The role class and the `width`/`height` attributes are what a stylesheet
|
|
75
|
+
* elsewhere keys a role's size on.** This module states none — the measure a
|
|
76
|
+
* `portrait` fills on a page is a Hugo theme's or a Foundry system's own
|
|
77
|
+
* decision — and emits only what the resolved asset record states: a role
|
|
78
|
+
* class when the picture declares one, and the attributes whenever the
|
|
79
|
+
* picture resolved to an asset record at all, blank for a vector. The
|
|
80
|
+
* attributes reserve the picture's own layout space before it loads, which is
|
|
81
|
+
* what lets a page avoid reflowing as pictures load in.
|
|
82
|
+
*
|
|
58
83
|
* @param {object} image - The image.
|
|
59
84
|
* @param {string} image.src - The address, resolved for the surface.
|
|
60
|
-
* @param {string} [image.alt] - The alt text,
|
|
85
|
+
* @param {string} [image.alt] - The alt text, for a reader who cannot see the
|
|
86
|
+
* picture.
|
|
61
87
|
* @param {string[]} [image.classes] - Width classes, from the directive.
|
|
62
88
|
* @param {string} [image.size] - Named display size, from the directive.
|
|
63
89
|
* @param {string} [image.float] - The float position, from the directive.
|
|
90
|
+
* @param {string} [image.role] - The picture's declared role, from the
|
|
91
|
+
* resolved asset record.
|
|
92
|
+
* @param {number|""} [image.width] - The file's own pixel width, from the
|
|
93
|
+
* resolved asset record; `""` for a vector. Omitted entirely when the
|
|
94
|
+
* address resolved to no asset record at all.
|
|
95
|
+
* @param {number|""} [image.height] - As `width`.
|
|
64
96
|
* @returns {string} The figure, as one HTML block.
|
|
65
97
|
*/
|
|
66
|
-
export function imageFigureHtml({ src, alt, classes, size, float }: {
|
|
98
|
+
export function imageFigureHtml({ src, alt, classes, size, float, role, width, height, }: {
|
|
67
99
|
src: string;
|
|
68
100
|
alt?: string | undefined;
|
|
69
101
|
classes?: string[] | undefined;
|
|
70
102
|
size?: string | undefined;
|
|
71
103
|
float?: string | undefined;
|
|
104
|
+
role?: string | undefined;
|
|
105
|
+
width?: number | "" | undefined;
|
|
106
|
+
height?: number | "" | undefined;
|
|
72
107
|
}): string;
|
|
73
108
|
/**
|
|
74
109
|
* Whether a match sits alone in its own paragraph.
|
|
75
110
|
*
|
|
76
|
-
* "Alone" is the whole of a block: nothing else on its line, and a blank line
|
|
77
|
-
* or the end of the body either side of it. A
|
|
78
|
-
* disqualifies it for the same reason a word does —
|
|
79
|
-
* holds something the figure would have to be
|
|
111
|
+
* "Alone" is the whole of a block: nothing else on its line, and a blank line,
|
|
112
|
+
* a body-extension delimiter or the end of the body either side of it. A
|
|
113
|
+
* leading `>` or list marker disqualifies it for the same reason a word does —
|
|
114
|
+
* the paragraph it belongs to holds something the figure would have to be
|
|
115
|
+
* lifted out of.
|
|
116
|
+
*
|
|
117
|
+
* **A footnote reference trailing the match is not "other text."** `[^note]`
|
|
118
|
+
* annotates the picture rather than sitting beside it in prose, the same
|
|
119
|
+
* standing its own directive already has, so `[^note]` is
|
|
120
|
+
* still alone.
|
|
80
121
|
*
|
|
81
122
|
* @param {string} text - The body the match indexes into.
|
|
82
123
|
* @param {number} start - Where the match begins.
|
|
@@ -127,6 +168,9 @@ export function imageSourcesIn(body: string): string[];
|
|
|
127
168
|
* @param {object} [opts]
|
|
128
169
|
* @param {number} [opts.bodyLine=1] - The 1-based file line the body starts on.
|
|
129
170
|
* @param {number} [opts.bodyColumn=1] - The 1-based file column it starts at.
|
|
171
|
+
* @param {Array<{line: number, generated: boolean}>} [opts.lineMap] - From
|
|
172
|
+
* table expansion, mapping each line of `body` back to the line an author
|
|
173
|
+
* wrote, for a caller handing in a body whose tables already expanded.
|
|
130
174
|
* @param {object} [opts.config] - The resolved build configuration. Supplied,
|
|
131
175
|
* an address is also held to the one surface a pathname can be dead on
|
|
132
176
|
* without any other pass noticing — see the Foundry address below. Omitted,
|
|
@@ -136,9 +180,13 @@ export function imageSourcesIn(body: string): string[];
|
|
|
136
180
|
* severity: "error", message: string}>} One finding per defect, in source
|
|
137
181
|
* order.
|
|
138
182
|
*/
|
|
139
|
-
export function checkImages(body: string, file: string, { bodyLine, bodyColumn, config }?: {
|
|
183
|
+
export function checkImages(body: string, file: string, { bodyLine, bodyColumn, lineMap, config }?: {
|
|
140
184
|
bodyLine?: number | undefined;
|
|
141
185
|
bodyColumn?: number | undefined;
|
|
186
|
+
lineMap?: {
|
|
187
|
+
line: number;
|
|
188
|
+
generated: boolean;
|
|
189
|
+
}[] | undefined;
|
|
142
190
|
config?: object | undefined;
|
|
143
191
|
}): Array<{
|
|
144
192
|
file: string;
|
|
@@ -201,9 +249,18 @@ export function lintContentImages(contentBase: string, { skipDirectories, config
|
|
|
201
249
|
* @param {(src: string) => string} [resolveSrc] - Translates an authored
|
|
202
250
|
* pathname into the address this surface serves. The default is the identity,
|
|
203
251
|
* for a caller rendering the format rather than publishing it.
|
|
252
|
+
* @param {(src: string) => {type?: string, role?: string, width?: number|"", height?: number|""}|undefined}
|
|
253
|
+
* [lookupAsset] - What the resolved asset record says about the address, as
|
|
254
|
+
* authored — before `resolveSrc` translates it. The default answers nothing,
|
|
255
|
+
* which is what an address resolving to no asset record gets anyway.
|
|
204
256
|
* @returns {string} The same body, with each block image as a `<figure>`.
|
|
205
257
|
*/
|
|
206
|
-
export function renderImageFigures(body: string, resolveSrc?: (src: string) => string
|
|
258
|
+
export function renderImageFigures(body: string, resolveSrc?: (src: string) => string, lookupAsset?: (src: string) => {
|
|
259
|
+
type?: string;
|
|
260
|
+
role?: string;
|
|
261
|
+
width?: number | "";
|
|
262
|
+
height?: number | "";
|
|
263
|
+
} | undefined): string;
|
|
207
264
|
/**
|
|
208
265
|
* A markdown-it plugin that reads an image's directive and renders its figure.
|
|
209
266
|
*
|
|
@@ -226,9 +283,18 @@ export function renderImageFigures(body: string, resolveSrc?: (src: string) => s
|
|
|
226
283
|
* address into the one this surface serves. Foundry is handed the path inside
|
|
227
284
|
* the install; a renderer that resolves the address itself — the book stages
|
|
228
285
|
* its own copy — passes nothing and gets the address as authored.
|
|
286
|
+
* @param {(src: string) => {type?: string, role?: string, width?: number|"", height?: number|""}|undefined}
|
|
287
|
+
* [lookupAsset] - What the resolved asset record says about the address, as
|
|
288
|
+
* authored — before `resolveSrc` runs. The default answers nothing, which is
|
|
289
|
+
* what an address resolving to no asset record gets anyway.
|
|
229
290
|
* @returns {(md: object) => void} A markdown-it plugin.
|
|
230
291
|
*/
|
|
231
|
-
export function imagePlugin(resolveSrc?: (src: string) => string
|
|
292
|
+
export function imagePlugin(resolveSrc?: (src: string) => string, lookupAsset?: (src: string) => {
|
|
293
|
+
type?: string;
|
|
294
|
+
role?: string;
|
|
295
|
+
width?: number | "";
|
|
296
|
+
height?: number | "";
|
|
297
|
+
} | undefined): (md: object) => void;
|
|
232
298
|
/**
|
|
233
299
|
* The width classes an image may carry, and what each means to a renderer.
|
|
234
300
|
*
|
|
@@ -103,6 +103,10 @@ export function asciiAliases(aliases: unknown): Array<string>;
|
|
|
103
103
|
* entries are derived against.
|
|
104
104
|
* @param {object} [options.addressContext] - Address resolution context.
|
|
105
105
|
* @param {object} [options.dateContext] - Calendar conversion context.
|
|
106
|
+
* @param {(address: string) => string|undefined} [options.resolveRole] - From
|
|
107
|
+
* a picture's address to the role its asset declares, so a figure anchor's
|
|
108
|
+
* `name` reads `Map 1` rather than `Figure 1` where it is due — see
|
|
109
|
+
* {@link module:engine/content-figures.scanFigures}.
|
|
106
110
|
* @returns {Record<string, any>} The record, keys sorted at every depth. A
|
|
107
111
|
* **stub** — a note with an empty body, on a type an empty body suppresses —
|
|
108
112
|
* carries `address` and `anchors` as `null`: it publishes no page, so it
|
|
@@ -114,7 +118,7 @@ export function asciiAliases(aliases: unknown): Array<string>;
|
|
|
114
118
|
* otherwise be overwritten without a word. `file` and, where the file was
|
|
115
119
|
* read, `position` ride on the error.
|
|
116
120
|
*/
|
|
117
|
-
export function buildIndexRecord({ frontmatter, relPath, absPath, contentPackage, body, bodyLine, manifest, addressContext, dateContext, }: {
|
|
121
|
+
export function buildIndexRecord({ frontmatter, relPath, absPath, contentPackage, body, bodyLine, manifest, addressContext, dateContext, resolveRole, }: {
|
|
118
122
|
frontmatter: Record<string, any>;
|
|
119
123
|
relPath: string;
|
|
120
124
|
absPath?: string | undefined;
|
|
@@ -124,9 +128,10 @@ export function buildIndexRecord({ frontmatter, relPath, absPath, contentPackage
|
|
|
124
128
|
manifest?: object | undefined;
|
|
125
129
|
addressContext?: object | undefined;
|
|
126
130
|
dateContext?: object | undefined;
|
|
131
|
+
resolveRole?: ((address: string) => string | undefined) | undefined;
|
|
127
132
|
}): Record<string, any>;
|
|
128
133
|
/** Derive every index record belonging to one parsed note. */
|
|
129
|
-
export function indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absPath, contentPackage, manifest, addressContext, dateContext, }: {
|
|
134
|
+
export function indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absPath, contentPackage, manifest, addressContext, dateContext, resolveRole, }: {
|
|
130
135
|
frontmatter: any;
|
|
131
136
|
body: any;
|
|
132
137
|
bodyLine: any;
|
|
@@ -136,6 +141,7 @@ export function indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absP
|
|
|
136
141
|
manifest: any;
|
|
137
142
|
addressContext: any;
|
|
138
143
|
dateContext: any;
|
|
144
|
+
resolveRole: any;
|
|
139
145
|
}): object[];
|
|
140
146
|
/**
|
|
141
147
|
* Read a content tree into index records, in the order they will be written.
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one line explaining why a single field's shared top-level fallback is
|
|
3
|
+
* off.
|
|
4
|
+
*
|
|
5
|
+
* **The field's reason stands on its own** — a complete sentence, or more
|
|
6
|
+
* than one — rather than completing a clause the frame starts. A field that
|
|
7
|
+
* collides with a top-level spelling meaning something else can say so
|
|
8
|
+
* ("`weight` is the item's own, independent of the note's."); a field whose
|
|
9
|
+
* top-level spelling is refused outright by the closed vocabulary can say
|
|
10
|
+
* that instead, honestly, which "there it means …" cannot: a refused key
|
|
11
|
+
* carries no meaning to report.
|
|
12
|
+
*
|
|
13
|
+
* Exported so a guard can walk every field declaring `topLevelMeans` across
|
|
14
|
+
* every registry and check that each one composes into a grammatical
|
|
15
|
+
* sentence, without reimplementing the frame it is checking.
|
|
16
|
+
*
|
|
17
|
+
* @param {import("./field-spec.mjs").FieldSpec} field - A field declaring
|
|
18
|
+
* `topLevelMeans`.
|
|
19
|
+
* @returns {string} The composed markdown line.
|
|
20
|
+
*/
|
|
21
|
+
export function topLevelExemptionLine(field: import("./field-spec.mjs").FieldSpec): string;
|
|
1
22
|
/**
|
|
2
23
|
* Render the per-type item frontmatter reference.
|
|
3
24
|
*
|
|
@@ -213,19 +213,21 @@ export function runtimeOnlyFields(fields: readonly FieldSpec[]): FieldSpec[];
|
|
|
213
213
|
* retiring one — so a field can move into `data:` while the corpus catches
|
|
214
214
|
* up, instead of on a flag day across four repositories. A declaration that
|
|
215
215
|
* names one is mid-sweep by construction; see {@link readsLegacyKey}.
|
|
216
|
-
* @property {string} [topLevelMeans] - **
|
|
217
|
-
* name
|
|
218
|
-
*
|
|
219
|
-
*
|
|
216
|
+
* @property {string} [topLevelMeans] - **Why the note's top-level key of this
|
|
217
|
+
* name is not this field's source** — declared wherever that key's spelling
|
|
218
|
+
* means something else at the note level, or the closed top-level
|
|
219
|
+
* vocabulary refuses it outright, and stating either removes the shared
|
|
220
|
+
* top-level position from this field's resolution order.
|
|
220
221
|
*
|
|
221
222
|
* A field's `name` doubles as its identity and as the shared property it
|
|
222
223
|
* draws from, which is right wherever the two levels state the same quantity
|
|
223
224
|
* — `data.weight` is the weight, whoever reads it. It is wrong wherever a
|
|
224
|
-
* spelling collides across the two vocabularies
|
|
225
|
+
* spelling collides across the two vocabularies, or names a key the closed
|
|
226
|
+
* top-level vocabulary does not admit at all. An `affiliation` item's
|
|
225
227
|
* `system.title` is the style of address an office carries; a note's
|
|
226
|
-
* top-level `title` is
|
|
227
|
-
*
|
|
228
|
-
*
|
|
228
|
+
* top-level `title` is refused outright. Nothing relates them, and before
|
|
229
|
+
* this key one silently fed the other, stringifying an authored `title:
|
|
230
|
+
* null` into fifteen documents.
|
|
229
231
|
*
|
|
230
232
|
* **The value is the reason**, not a flag with a comment beside it. A boolean
|
|
231
233
|
* would record the decision and lose the case for it, and the next person
|
|
@@ -466,19 +468,21 @@ export type FieldSpec = {
|
|
|
466
468
|
*/
|
|
467
469
|
legacyKey?: string | undefined;
|
|
468
470
|
/**
|
|
469
|
-
* - **
|
|
470
|
-
* name
|
|
471
|
-
*
|
|
472
|
-
*
|
|
471
|
+
* - **Why the note's top-level key of this
|
|
472
|
+
* name is not this field's source** — declared wherever that key's spelling
|
|
473
|
+
* means something else at the note level, or the closed top-level
|
|
474
|
+
* vocabulary refuses it outright, and stating either removes the shared
|
|
475
|
+
* top-level position from this field's resolution order.
|
|
473
476
|
*
|
|
474
477
|
* A field's `name` doubles as its identity and as the shared property it
|
|
475
478
|
* draws from, which is right wherever the two levels state the same quantity
|
|
476
479
|
* — `data.weight` is the weight, whoever reads it. It is wrong wherever a
|
|
477
|
-
* spelling collides across the two vocabularies
|
|
480
|
+
* spelling collides across the two vocabularies, or names a key the closed
|
|
481
|
+
* top-level vocabulary does not admit at all. An `affiliation` item's
|
|
478
482
|
* `system.title` is the style of address an office carries; a note's
|
|
479
|
-
* top-level `title` is
|
|
480
|
-
*
|
|
481
|
-
*
|
|
483
|
+
* top-level `title` is refused outright. Nothing relates them, and before
|
|
484
|
+
* this key one silently fed the other, stringifying an authored `title:
|
|
485
|
+
* null` into fifteen documents.
|
|
482
486
|
*
|
|
483
487
|
* **The value is the reason**, not a flag with a comment beside it. A boolean
|
|
484
488
|
* would record the decision and lose the case for it, and the next person
|
|
@@ -11,6 +11,20 @@ export function itemCatalogRelationships(config: object): Array<{
|
|
|
11
11
|
kind: string;
|
|
12
12
|
verified: string | undefined;
|
|
13
13
|
}>;
|
|
14
|
+
/**
|
|
15
|
+
* Every declared relationship that opted into supplying its release archive
|
|
16
|
+
* for asset bytes alone, with no item catalogue built from it.
|
|
17
|
+
*
|
|
18
|
+
* @param {object} config - The resolved build configuration.
|
|
19
|
+
* @returns {Array<{id: string, manifest: string, kind: string, verified: string|undefined}>}
|
|
20
|
+
* The opted-in relationships, in declaration order.
|
|
21
|
+
*/
|
|
22
|
+
export function assetArchiveRelationships(config: object): Array<{
|
|
23
|
+
id: string;
|
|
24
|
+
manifest: string;
|
|
25
|
+
kind: string;
|
|
26
|
+
verified: string | undefined;
|
|
27
|
+
}>;
|
|
14
28
|
/**
|
|
15
29
|
* The cache directory for one dependency at one version.
|
|
16
30
|
*
|
|
@@ -95,6 +109,26 @@ export function fetchCatalog(config: object, rel: {
|
|
|
95
109
|
id: string;
|
|
96
110
|
manifest: string;
|
|
97
111
|
}): Promise<string>;
|
|
112
|
+
/**
|
|
113
|
+
* Fetch one dependency's release archive for its asset bytes alone, building
|
|
114
|
+
* no item catalogue from it.
|
|
115
|
+
*
|
|
116
|
+
* Idempotent: a complete cache for the resolved version is left alone. Where a
|
|
117
|
+
* relationship also declares `itemCatalog: true`, {@link fetchCatalog} already
|
|
118
|
+
* unpacked this same archive into this same cache directory, and
|
|
119
|
+
* {@link fetchAllCatalogs} does not call this function for it — the two never
|
|
120
|
+
* download the same bytes twice.
|
|
121
|
+
*
|
|
122
|
+
* @param {object} config - The resolved build configuration.
|
|
123
|
+
* @param {{id: string, manifest: string, verified?: string}} rel - The
|
|
124
|
+
* declared relationship.
|
|
125
|
+
* @returns {Promise<string>} The dependency's cache directory.
|
|
126
|
+
*/
|
|
127
|
+
export function fetchAssetArchive(config: object, rel: {
|
|
128
|
+
id: string;
|
|
129
|
+
manifest: string;
|
|
130
|
+
verified?: string;
|
|
131
|
+
}): Promise<string>;
|
|
98
132
|
/**
|
|
99
133
|
* Fill the cache from a locally built artifact rather than a release.
|
|
100
134
|
*
|
|
@@ -167,6 +201,11 @@ export function fetchAllMetadata(config: object): Promise<number>;
|
|
|
167
201
|
/**
|
|
168
202
|
* Fetch every opted-in dependency. The `deps fetch` command.
|
|
169
203
|
*
|
|
204
|
+
* A relationship declaring both `itemCatalog: true` and `assetArchive: true`
|
|
205
|
+
* is fetched once: {@link fetchCatalog} already unpacks the archive on its
|
|
206
|
+
* way to extracting the item catalogue, so this skips the archive-only fetch
|
|
207
|
+
* for any id {@link fetchCatalog} already handled.
|
|
208
|
+
*
|
|
170
209
|
* @param {object} config - The resolved build configuration.
|
|
171
210
|
* @returns {Promise<number>} How many dependencies were fetched.
|
|
172
211
|
*/
|
|
@@ -31,9 +31,9 @@ export function splitHeadingAttributes(heading: string): {
|
|
|
31
31
|
* A Foundry UUID addresses a page and nothing smaller, so a section a link can
|
|
32
32
|
* reach has to be one: a top-level heading starts a page, and so does any
|
|
33
33
|
* heading that names an anchor. {@link module:engine/journals.splitPages}
|
|
34
|
-
* decides *where* a page begins — a
|
|
35
|
-
*
|
|
36
|
-
*
|
|
34
|
+
* decides *where* a page begins — a heading inside a fence or a named block is
|
|
35
|
+
* its business — and asks this which headings are eligible, so no caller
|
|
36
|
+
* re-decides it.
|
|
37
37
|
*
|
|
38
38
|
* @param {{level: number, id: string}} heading - From
|
|
39
39
|
* {@link scanHeadingAttributes}, or any `{level, id}` pair.
|
|
@@ -86,7 +86,7 @@ export function headingAttributesPlugin(md: object): void;
|
|
|
86
86
|
* Parse one line as a heading, and say whether it starts a journal page.
|
|
87
87
|
*
|
|
88
88
|
* The single reading of that rule. {@link module:engine/journals.splitPages}
|
|
89
|
-
* builds its pages from it; `scanBlocks` and `
|
|
89
|
+
* builds its pages from it; `scanBlocks` and `scanFigures` refuse a heading
|
|
90
90
|
* that starts a page written where it cannot become one. All three ask this, so
|
|
91
91
|
* none of them can disagree about what a heading line means or about what starts
|
|
92
92
|
* a page — and the attribute block comes off here, so a class beside an anchor
|
|
@@ -115,15 +115,20 @@ export function parseHeadingLine(line: string): {
|
|
|
115
115
|
* builds the pages from this, and the passes that honour a class on a
|
|
116
116
|
* page-opening heading ask the same question of the same answer.
|
|
117
117
|
*
|
|
118
|
-
* A
|
|
119
|
-
* found by the
|
|
120
|
-
* dropped there.
|
|
118
|
+
* A figure fence also opens a page, which is `splitPages`' business: a fence is
|
|
119
|
+
* found by the figure pass, and the page it opens is named for its label.
|
|
121
120
|
*
|
|
122
121
|
* @param {string} source - A note's markdown body.
|
|
122
|
+
* @param {ReadonlySet<number>} [blockLines] - The 0-based lines sitting inside
|
|
123
|
+
* a named block, supplied by the caller. A named block is read by
|
|
124
|
+
* {@link module:engine/content-blocks.scanBlocks}, which knows every name in
|
|
125
|
+
* the registry, reads an opener's attribute block, and tracks nesting by
|
|
126
|
+
* depth — so the caller that already holds that answer passes it rather than
|
|
127
|
+
* a second reading of the same lines being kept here.
|
|
123
128
|
* @returns {Map<number, {level: number, line: number, text: string, id: string,
|
|
124
129
|
* classes: string[], values: Record<string, string>}>} Keyed by 0-based line.
|
|
125
130
|
*/
|
|
126
|
-
export function pageOpenings(source: string): Map<number, {
|
|
131
|
+
export function pageOpenings(source: string, blockLines?: ReadonlySet<number>): Map<number, {
|
|
127
132
|
level: number;
|
|
128
133
|
line: number;
|
|
129
134
|
text: string;
|
|
@@ -1,5 +1,21 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Render a note body with Foundry's named-block markup.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} body - The body, tables expanded and wikilinks resolved.
|
|
5
|
+
* @param {Array<{id: string, label: string}>} [figures] - Labels assigned by
|
|
6
|
+
* a note-wide scan, matched by id — see
|
|
7
|
+
* {@link module:engine/content-figures.renderFigureBlocks}.
|
|
8
|
+
* @param {Map<string, number>} [footnoteNumbers] - Shared across the note.
|
|
9
|
+
* @param {string} [docId] - Threaded into footnote anchors.
|
|
10
|
+
* @param {(address: string) => string|undefined} [resolveRole] - From a
|
|
11
|
+
* picture's address to the role its asset declares — see
|
|
12
|
+
* {@link module:engine/content-figures.scanFigures}.
|
|
13
|
+
* @returns {string} The rendered HTML.
|
|
14
|
+
*/
|
|
15
|
+
export function renderFoundryMarkdown(body: string, figures?: Array<{
|
|
16
|
+
id: string;
|
|
17
|
+
label: string;
|
|
18
|
+
}>, footnoteNumbers?: Map<string, number>, docId?: string, resolveRole?: (address: string) => string | undefined): string;
|
|
3
19
|
/**
|
|
4
20
|
* Parses a markdown file with YAML frontmatter.
|
|
5
21
|
*
|
|
@@ -206,16 +222,18 @@ export function makeFilename(name: string, id: string): string;
|
|
|
206
222
|
* the other.
|
|
207
223
|
*
|
|
208
224
|
* **`title` does not follow this rule**, and must not be made to. On a
|
|
209
|
-
* `type: affiliation` note `title` is
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
225
|
+
* `type: affiliation` note `title` is a declared item field with its own
|
|
226
|
+
* default (`""`, in `sohl/item-fields.mjs`), authored only inside the item's
|
|
227
|
+
* own `sohl` block — the closed top-level vocabulary has no `title` entry, so
|
|
228
|
+
* there is no shared key for this function's null-versus-blank distinction to
|
|
229
|
+
* apply to.
|
|
214
230
|
*
|
|
215
231
|
* **`banner:` does not follow it either, deliberately.** It is not a file
|
|
216
|
-
* inside a Foundry install: it reaches no compiled document and
|
|
217
|
-
*
|
|
218
|
-
*
|
|
232
|
+
* inside a Foundry install: it reaches no compiled document, and the site build
|
|
233
|
+
* resolves it through the website's own resolver before a page is written, so
|
|
234
|
+
* the theme receives a URL rather than an address. The book's section plates
|
|
235
|
+
* read a banner of their own, from the book plan's `presentation.page.banner`
|
|
236
|
+
* rather than from a note. See `docs/guides/site.md`.
|
|
219
237
|
*
|
|
220
238
|
* For items, the default is the art paired with the type's builder, reached
|
|
221
239
|
* through `itemArt()`, which runs the pathname back through this function so a
|
|
@@ -51,14 +51,17 @@ export function compilesSystemDocument(fm: object, map: object, router: object):
|
|
|
51
51
|
* @param {object} [options.router] - The pack router deciding which system
|
|
52
52
|
* compiles a document for this note. Defaults to the consuming repository's.
|
|
53
53
|
* @param {object} [options.dates] - Calendar conversion context.
|
|
54
|
+
* @param {string} [options.contentPackage] - This build's content package,
|
|
55
|
+
* the default a note box's short-form Address resolves against.
|
|
54
56
|
* @returns {object[]} The boxes, in the order every medium renders them.
|
|
55
57
|
* @throws {Error} When the built set disagrees with what the note's type maps
|
|
56
58
|
* to — see {@link module:engine/infobox.assertInfoboxSet}.
|
|
57
59
|
*/
|
|
58
|
-
export function noteInfoboxes(fm: object, { resolve, router, dates }?: {
|
|
60
|
+
export function noteInfoboxes(fm: object, { resolve, router, dates, contentPackage }?: {
|
|
59
61
|
resolve?: ((ref: unknown, hint?: object) => object | undefined) | undefined;
|
|
60
62
|
router?: object | undefined;
|
|
61
63
|
dates?: object | undefined;
|
|
64
|
+
contentPackage?: string | undefined;
|
|
62
65
|
}): object[];
|
|
63
66
|
/**
|
|
64
67
|
* Every system's infobox declaration, in the order a page shows them.
|
|
@@ -154,12 +154,15 @@ export function linkValue(ref: unknown, resolve: (ref: unknown, hint?: object) =
|
|
|
154
154
|
* @param {object} [options] - Options.
|
|
155
155
|
* @param {(ref: unknown) => object|undefined} [options.resolve] - Resolves a
|
|
156
156
|
* reference to `{name, url?, uuid?, address?}`.
|
|
157
|
+
* @param {string} [options.contentPackage] - This build's content package,
|
|
158
|
+
* the default a relation row's short-form Address resolves against.
|
|
157
159
|
* @param {object} [options.vocabulary] - The note vocabulary to read.
|
|
158
160
|
* @param {object} [options.presentation] - The overlay to read.
|
|
159
161
|
* @returns {object} The box.
|
|
160
162
|
*/
|
|
161
163
|
export function noteInfobox(fm: object, options?: {
|
|
162
164
|
resolve?: ((ref: unknown) => object | undefined) | undefined;
|
|
165
|
+
contentPackage?: string | undefined;
|
|
163
166
|
vocabulary?: object | undefined;
|
|
164
167
|
presentation?: object | undefined;
|
|
165
168
|
}): object;
|
|
@@ -268,6 +271,8 @@ export function systemRowsSection(fm: object, fields: readonly object[], { block
|
|
|
268
271
|
* Resolves one declared field against the note.
|
|
269
272
|
* @param {(ref: unknown) => object|undefined} [options.resolve] - Resolves a
|
|
270
273
|
* reference to `{name, url?, uuid?, address?}`.
|
|
274
|
+
* @param {string} [options.contentPackage] - This build's content package,
|
|
275
|
+
* the default a note box's short-form Address resolves against.
|
|
271
276
|
* @param {object} [options.vocabulary] - The note vocabulary to read.
|
|
272
277
|
* @returns {object[]} The boxes.
|
|
273
278
|
*/
|
|
@@ -277,6 +282,7 @@ export function buildInfoboxes(fm: object, options: {
|
|
|
277
282
|
compilesDocument: (fm: object, map: object) => boolean;
|
|
278
283
|
resolveField: (field: object, fm: object, opts: object) => object;
|
|
279
284
|
resolve?: ((ref: unknown) => object | undefined) | undefined;
|
|
285
|
+
contentPackage?: string | undefined;
|
|
280
286
|
vocabulary?: object | undefined;
|
|
281
287
|
}): object[];
|
|
282
288
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Splits a markdown body into pages by top-level H1 headings. Fenced
|
|
3
|
-
* code blocks are respected so `# foo` inside ``` blocks doesn't
|
|
4
|
-
* a split. Content before the first H1 (if non-empty) becomes a
|
|
5
|
-
* page. Each H1 yields a page whose name is the heading
|
|
3
|
+
* code blocks are respected so `# foo` inside ``` or ~~~ blocks doesn't
|
|
4
|
+
* trigger a split. Content before the first H1 (if non-empty) becomes a
|
|
5
|
+
* leading page. Each H1 yields a page whose name is the heading
|
|
6
6
|
* text (with any `{#anchor-id}` suffix stripped out and surfaced as
|
|
7
7
|
* `anchorSlug`). The classes the heading declares come along as `classes`, so
|
|
8
8
|
* a surface that honours one has it without reading the suffix again.
|
|
@@ -13,16 +13,26 @@
|
|
|
13
13
|
* calling that page "Introduction" would label the description as a preamble to
|
|
14
14
|
* nothing.
|
|
15
15
|
*
|
|
16
|
+
* A figure fence carries its own record along onto the page it starts, as
|
|
17
|
+
* `figure` — `null` for a page a heading started. {@link buildPages} reads it
|
|
18
|
+
* to build the `image` or `text` page a fence begins; nothing else sets it.
|
|
19
|
+
*
|
|
16
20
|
* @param {string} body - Markdown body to split.
|
|
17
21
|
* @param {string} [leadName] - Name of the page before the first heading.
|
|
22
|
+
* @param {(address: string) => string|undefined} [resolveRole] - From a
|
|
23
|
+
* picture's address to the role its asset declares, so a figure page's
|
|
24
|
+
* name reads `Map 1` rather than `Figure 1` where it is due — see
|
|
25
|
+
* {@link module:engine/content-figures.scanFigures}.
|
|
18
26
|
* @returns {Array<{name: string, anchorSlug: string|null, level: number,
|
|
19
|
-
* classes: string[], markdown: string}>} Pages in
|
|
27
|
+
* classes: string[], figure: object|null, markdown: string}>} Pages in
|
|
28
|
+
* document order.
|
|
20
29
|
*/
|
|
21
|
-
export function splitPages(body: string, leadName?: string): Array<{
|
|
30
|
+
export function splitPages(body: string, leadName?: string, resolveRole?: (address: string) => string | undefined): Array<{
|
|
22
31
|
name: string;
|
|
23
32
|
anchorSlug: string | null;
|
|
24
33
|
level: number;
|
|
25
34
|
classes: string[];
|
|
35
|
+
figure: object | null;
|
|
26
36
|
markdown: string;
|
|
27
37
|
}>;
|
|
28
38
|
/**
|
|
@@ -101,15 +111,22 @@ export function journalPageId(entryId: string, page: {
|
|
|
101
111
|
* @param {string} noteName - The note, for error messages.
|
|
102
112
|
* A page whose heading carries `.secret` is given to the GM alone, by the one
|
|
103
113
|
* ownership value Foundry reads as "nobody but a GM". Every other page states
|
|
104
|
-
* no ownership and inherits the journal's.
|
|
105
|
-
*
|
|
114
|
+
* no ownership and inherits the journal's. A figure-started page states none
|
|
115
|
+
* either: {@link scanFigures} validates a figure's classes against its own
|
|
116
|
+
* closed vocabulary, which carries no `.secret`.
|
|
117
|
+
*
|
|
118
|
+
* @param {Array<object>} figures - From {@link scanFigures}, numbered across
|
|
119
|
+
* the whole note. Read by a page a heading started; a page a figure started
|
|
120
|
+
* carries its own figure already, from {@link splitPages}.
|
|
121
|
+
* @param {(address: string) => string|undefined} [resolveRole] - See
|
|
122
|
+
* {@link splitPages}.
|
|
106
123
|
* @returns {Array<{_id: string, name: string, type: string,
|
|
107
124
|
* title: {show: boolean, level: number},
|
|
108
125
|
* text: {format: number, content: string}, _key: string,
|
|
109
126
|
* ownership?: {default: number}}>} The page documents, in order.
|
|
110
127
|
* @throws {Error} When the note has no content at all, or repeats an anchor.
|
|
111
128
|
*/
|
|
112
|
-
export function buildPages(rawPages: Array<object>, entryId: string, noteName: string,
|
|
129
|
+
export function buildPages(rawPages: Array<object>, entryId: string, noteName: string, figures: Array<object>, resolveRole?: (address: string) => string | undefined): Array<{
|
|
113
130
|
_id: string;
|
|
114
131
|
name: string;
|
|
115
132
|
type: string;
|
|
@@ -156,9 +173,13 @@ export function buildPages(rawPages: Array<object>, entryId: string, noteName: s
|
|
|
156
173
|
* module:engine/draft-notice}. It leads the first authored page,
|
|
157
174
|
* because a reader deciding whether to rely on the entry has to be told
|
|
158
175
|
* before they read it rather than after.
|
|
176
|
+
* @param {(address: string) => string|undefined} [params.resolveRole] - From
|
|
177
|
+
* a picture's address to the role its asset declares, so a figure page's
|
|
178
|
+
* name reads `Map 1` rather than `Figure 1` where it is due — see
|
|
179
|
+
* {@link module:engine/content-figures.scanFigures}.
|
|
159
180
|
* @returns {object} The JournalEntry document, keyed for the pack.
|
|
160
181
|
*/
|
|
161
|
-
export function buildJournalEntry({ id, name, markdown, leadName, folder, stats, infoboxes, notice, }: {
|
|
182
|
+
export function buildJournalEntry({ id, name, markdown, leadName, folder, stats, infoboxes, notice, resolveRole, }: {
|
|
162
183
|
id: string;
|
|
163
184
|
name: string;
|
|
164
185
|
markdown: string;
|
|
@@ -171,6 +192,7 @@ export function buildJournalEntry({ id, name, markdown, leadName, folder, stats,
|
|
|
171
192
|
html: string;
|
|
172
193
|
}[] | undefined;
|
|
173
194
|
notice?: string | undefined;
|
|
195
|
+
resolveRole?: ((address: string) => string | undefined) | undefined;
|
|
174
196
|
}): object;
|
|
175
197
|
/**
|
|
176
198
|
* Journals pack compiler.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate one `lore` note's `data.events`.
|
|
3
|
+
*
|
|
4
|
+
* Registered as the `events` field's own `check` in `note-vocabulary.mjs`, so
|
|
5
|
+
* it runs on every `lore` note regardless of `subType` — an occasion is not a
|
|
6
|
+
* calendar fact, and nothing here is scoped to `subType: calendar`.
|
|
7
|
+
*
|
|
8
|
+
* @param {object} note - The note, as the link index hands it over.
|
|
9
|
+
* @param {{index?: object}} [options]
|
|
10
|
+
* @returns {object[]} Findings, each positioned at the entry that earned it.
|
|
11
|
+
*/
|
|
12
|
+
export function checkLoreEvents(note: object, { index }?: {
|
|
13
|
+
index?: object;
|
|
14
|
+
}): object[];
|
|
@@ -3,12 +3,33 @@ export function sqlQueriesInMarkdown(body: any, fm?: {}): any[];
|
|
|
3
3
|
/**
|
|
4
4
|
* Expand scalar frontmatter references and registered functions in Markdown prose.
|
|
5
5
|
* @param {string} body
|
|
6
|
-
* @param {{fm?: object, dates?: object, sqlResults?: Map<string, object>,
|
|
6
|
+
* @param {{fm?: object, dates?: object, sqlResults?: Map<string, object>,
|
|
7
|
+
* figures?: {get: (id: string) => {label: string, caption: string,
|
|
8
|
+
* hasCaption: boolean}|undefined, note?: (address: string) =>
|
|
9
|
+
* {url: string|null, figures: Map<string, object>}|undefined,
|
|
10
|
+
* link?: Function}, file?: string, bodyLine?: number}} [options] -
|
|
11
|
+
* `figures` is the `ref` helper's own view of the corpus: `get` reads this
|
|
12
|
+
* note's `:::figure` fences by id, and `note` resolves another note's the
|
|
13
|
+
* way a wikilink would — omitted, a cross-note address is refused rather
|
|
14
|
+
* than looked up. `link` overrides how a resolved reference renders; the
|
|
15
|
+
* default is a Markdown link to the target's own anchor.
|
|
7
16
|
*/
|
|
8
|
-
export function renderMarkdownExpressions(body: string, { fm, dates, sqlResults, file, bodyLine }?: {
|
|
17
|
+
export function renderMarkdownExpressions(body: string, { fm, dates, sqlResults, figures, file, bodyLine }?: {
|
|
9
18
|
fm?: object;
|
|
10
19
|
dates?: object;
|
|
11
20
|
sqlResults?: Map<string, object>;
|
|
21
|
+
figures?: {
|
|
22
|
+
get: (id: string) => {
|
|
23
|
+
label: string;
|
|
24
|
+
caption: string;
|
|
25
|
+
hasCaption: boolean;
|
|
26
|
+
} | undefined;
|
|
27
|
+
note?: (address: string) => {
|
|
28
|
+
url: string | null;
|
|
29
|
+
figures: Map<string, object>;
|
|
30
|
+
} | undefined;
|
|
31
|
+
link?: Function;
|
|
32
|
+
};
|
|
12
33
|
file?: string;
|
|
13
34
|
bodyLine?: number;
|
|
14
35
|
}): {
|