@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
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
{"address":{"canonical":"packagebuild-none-image-afflictionbnr"},"asset":{"ai":
|
|
2
|
-
{"address":{"canonical":"packagebuild-none-image-armorclothingbnr"},"asset":{"ai":
|
|
3
|
-
{"address":{"canonical":"packagebuild-none-image-attributebnr"},"asset":{"ai":
|
|
4
|
-
{"address":{"canonical":"packagebuild-none-image-containerbnr"},"asset":{"ai":
|
|
5
|
-
{"address":{"canonical":"packagebuild-none-image-devdocsbnr"},"asset":{"ai":
|
|
6
|
-
{"address":{"canonical":"packagebuild-none-image-miscgearbnr"},"asset":{"ai":
|
|
7
|
-
{"address":{"canonical":"packagebuild-none-image-mysticalabilitybnr"},"asset":{"ai":
|
|
8
|
-
{"address":{"canonical":"packagebuild-none-image-projectilebnr"},"asset":{"ai":
|
|
9
|
-
{"address":{"canonical":"packagebuild-none-image-rulesbnr"},"asset":{"ai":
|
|
10
|
-
{"address":{"canonical":"packagebuild-none-image-skillbnr"},"asset":{"ai":
|
|
11
|
-
{"address":{"canonical":"packagebuild-none-image-traumabnr"},"asset":{"ai":
|
|
12
|
-
{"address":{"canonical":"packagebuild-none-image-userguidebnr"},"asset":{"ai":
|
|
13
|
-
{"address":{"canonical":"packagebuild-none-image-weapongearbnr"},"asset":{"ai":
|
|
1
|
+
{"address":{"canonical":"packagebuild-none-image-afflictionbnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/afflictionbnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"afflictionbnr","type":"image"}
|
|
2
|
+
{"address":{"canonical":"packagebuild-none-image-armorclothingbnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/armorclothingbnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"armorclothingbnr","type":"image"}
|
|
3
|
+
{"address":{"canonical":"packagebuild-none-image-attributebnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/attributebnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"attributebnr","type":"image"}
|
|
4
|
+
{"address":{"canonical":"packagebuild-none-image-containerbnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/containerbnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"containerbnr","type":"image"}
|
|
5
|
+
{"address":{"canonical":"packagebuild-none-image-devdocsbnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/devdocsbnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"devdocsbnr","type":"image"}
|
|
6
|
+
{"address":{"canonical":"packagebuild-none-image-miscgearbnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/miscgearbnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"miscgearbnr","type":"image"}
|
|
7
|
+
{"address":{"canonical":"packagebuild-none-image-mysticalabilitybnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/mysticalabilitybnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"mysticalabilitybnr","type":"image"}
|
|
8
|
+
{"address":{"canonical":"packagebuild-none-image-projectilebnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/projectilebnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"projectilebnr","type":"image"}
|
|
9
|
+
{"address":{"canonical":"packagebuild-none-image-rulesbnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/rulesbnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"rulesbnr","type":"image"}
|
|
10
|
+
{"address":{"canonical":"packagebuild-none-image-skillbnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/skillbnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"skillbnr","type":"image"}
|
|
11
|
+
{"address":{"canonical":"packagebuild-none-image-traumabnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/traumabnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"traumabnr","type":"image"}
|
|
12
|
+
{"address":{"canonical":"packagebuild-none-image-userguidebnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/userguidebnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"userguidebnr","type":"image"}
|
|
13
|
+
{"address":{"canonical":"packagebuild-none-image-weapongearbnr"},"asset":{"ai":false,"attribution":"Tom Rodriguez","height":768,"license":"CC-BY-SA-4.0","notes":"","path":"images/banners/weapongearbnr.webp","role":"","source":"","width":1792},"package":"packagebuild","shortcode":"weapongearbnr","type":"image"}
|
package/sohl/item-fields.mjs
CHANGED
|
@@ -391,9 +391,10 @@ export const ITEM_FIELDS = Object.freeze({
|
|
|
391
391
|
...STRING,
|
|
392
392
|
default: "",
|
|
393
393
|
topLevelMeans:
|
|
394
|
-
"
|
|
395
|
-
"
|
|
396
|
-
"
|
|
394
|
+
"A top-level `title` is refused outright, since an office's " +
|
|
395
|
+
"style of address belongs to the membership that holds the " +
|
|
396
|
+
"office and nothing outside the item supplies it. Author it " +
|
|
397
|
+
"at `sohl.system.title` on the item, or at the " +
|
|
397
398
|
"`system.title` of the entry in a being's `sohl.items`.",
|
|
398
399
|
describe: "The style of address the office carries.",
|
|
399
400
|
},
|
|
@@ -126,6 +126,16 @@ export const RETIRED_ADDRESS_KEYS: Readonly<Record<string, string>>;
|
|
|
126
126
|
export const DEFAULT_ADDRESS_SCHEME: Readonly<{
|
|
127
127
|
prefix: "";
|
|
128
128
|
}>;
|
|
129
|
+
/**
|
|
130
|
+
* Every key a declared relationship may carry.
|
|
131
|
+
*
|
|
132
|
+
* Read by the manifest writer as well as by the configuration check: the keys
|
|
133
|
+
* Foundry's own relationship schema does not name are the build's own, and the
|
|
134
|
+
* published manifest carries none of them.
|
|
135
|
+
*
|
|
136
|
+
* @type {readonly string[]}
|
|
137
|
+
*/
|
|
138
|
+
export const RELATIONSHIP_KEYS: readonly string[];
|
|
129
139
|
/**
|
|
130
140
|
* How the loader hands {@link defineConfig} the system version it resolved.
|
|
131
141
|
*
|
|
@@ -274,7 +284,8 @@ export type PathsInput = {
|
|
|
274
284
|
unpack?: string | undefined;
|
|
275
285
|
/**
|
|
276
286
|
* Where a dependency declaring
|
|
277
|
-
* `itemCatalog: true`
|
|
287
|
+
* `itemCatalog: true` or
|
|
288
|
+
* `assetArchive: true` is unpacked.
|
|
278
289
|
* Inbound, and fetched rather than
|
|
279
290
|
* committed.
|
|
280
291
|
*/
|
|
@@ -438,6 +449,21 @@ export type RelationshipSpec = {
|
|
|
438
449
|
* `_stats.systemVersion` is stamped from.
|
|
439
450
|
*/
|
|
440
451
|
compatibility?: CompatibilitySpec | undefined;
|
|
452
|
+
/**
|
|
453
|
+
* Whether `deps fetch` unpacks this
|
|
454
|
+
* dependency's release archive and extracts
|
|
455
|
+
* its Item packs, so the actors pass can
|
|
456
|
+
* resolve embedded items this repository
|
|
457
|
+
* does not hold. Needs a `manifest`.
|
|
458
|
+
*/
|
|
459
|
+
itemCatalog?: boolean | undefined;
|
|
460
|
+
/**
|
|
461
|
+
* Whether `deps fetch` unpacks this
|
|
462
|
+
* dependency's release archive for its
|
|
463
|
+
* asset bytes alone, building no item
|
|
464
|
+
* catalogue from it. Needs a `manifest`.
|
|
465
|
+
*/
|
|
466
|
+
assetArchive?: boolean | undefined;
|
|
441
467
|
/**
|
|
442
468
|
* Whether `deps fetch` fetches this
|
|
443
469
|
* dependency's content index. Default
|
|
@@ -449,6 +475,16 @@ export type RelationshipSpec = {
|
|
|
449
475
|
* index.
|
|
450
476
|
*/
|
|
451
477
|
contentIndex?: boolean | undefined;
|
|
478
|
+
/**
|
|
479
|
+
* Whether this dependency's asset
|
|
480
|
+
* tree answers this package's own asset
|
|
481
|
+
* addresses ahead of its local record.
|
|
482
|
+
* Default `false`. Refuses `contentIndex:
|
|
483
|
+
* false` on the same entry, since a
|
|
484
|
+
* replacement with no fetched index to
|
|
485
|
+
* check against resolves nothing.
|
|
486
|
+
*/
|
|
487
|
+
assetReplacement?: boolean | undefined;
|
|
452
488
|
};
|
|
453
489
|
/**
|
|
454
490
|
* How a generated documentation page is framed in the repository publishing it.
|
|
@@ -628,6 +664,12 @@ export type ContentBuildConfigInput = {
|
|
|
628
664
|
* `Templates`). Default `[]`.
|
|
629
665
|
*/
|
|
630
666
|
skipDirectories?: string[] | undefined;
|
|
667
|
+
/**
|
|
668
|
+
* Whether `lint` refuses an asset
|
|
669
|
+
* record of this package carrying
|
|
670
|
+
* `ai: true`. Default `false`.
|
|
671
|
+
*/
|
|
672
|
+
forbidGeneratedArt?: boolean | undefined;
|
|
631
673
|
/**
|
|
632
674
|
* Reserved for
|
|
633
675
|
* `@heroiclands/package-build`, which
|
|
@@ -764,6 +806,11 @@ export type ContentBuildConfig = {
|
|
|
764
806
|
*/
|
|
765
807
|
docEntryTypes: ReadonlySet<string>;
|
|
766
808
|
skipDirectories: readonly string[];
|
|
809
|
+
/**
|
|
810
|
+
* Whether `lint` refuses an asset
|
|
811
|
+
* record of this package carrying `ai: true`.
|
|
812
|
+
*/
|
|
813
|
+
forbidGeneratedArt: boolean;
|
|
767
814
|
/**
|
|
768
815
|
* The
|
|
769
816
|
* fonts this package ships and the names it
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `{#slug}` and `:::
|
|
2
|
+
* The `{#slug}` and `:::figure {#slug}` anchors a note declares.
|
|
3
3
|
*
|
|
4
|
-
* A bare `#` heading starts a journal page without declaring a slug
|
|
5
|
-
*
|
|
4
|
+
* A bare `#` heading starts a journal page without declaring a slug, and so
|
|
5
|
+
* does a figure fence that declares no id. A fence that declares one declares a
|
|
6
|
+
* slug and starts an addressable journal page.
|
|
6
7
|
*
|
|
7
8
|
* @param {string} body - The note's markdown body, frontmatter already removed.
|
|
8
9
|
* @param {number} [bodyLine] - The 1-based file line the body starts on, from
|
|
9
10
|
* `parseMarkdownFile`. Anchors are reported at their position in the **file**,
|
|
10
11
|
* so an editor can jump straight to one; passing nothing numbers from the body.
|
|
12
|
+
* @param {(address: string) => string|undefined} [resolveRole] - From a
|
|
13
|
+
* picture's address to the role its asset declares, so a figure anchor's
|
|
14
|
+
* `name` reads `Map 1` rather than `Figure 1` where it is due — see
|
|
15
|
+
* {@link module:engine/content-figures.scanFigures}.
|
|
11
16
|
* @returns {Array<{slug: string, name: string, level: number, line: number}>}
|
|
12
17
|
* In document order.
|
|
13
18
|
*/
|
|
14
|
-
export function collectAnchors(body: string, bodyLine?: number): Array<{
|
|
19
|
+
export function collectAnchors(body: string, bodyLine?: number, resolveRole?: (address: string) => string | undefined): Array<{
|
|
15
20
|
slug: string;
|
|
16
21
|
name: string;
|
|
17
22
|
level: number;
|
|
@@ -61,6 +61,29 @@ export function assetAddressIndex(records?: readonly object[], { config, foreign
|
|
|
61
61
|
} | undefined;
|
|
62
62
|
types?: Iterable<string> | undefined;
|
|
63
63
|
}): object;
|
|
64
|
+
/**
|
|
65
|
+
* What a renderer needs to size one picture, keyed by the pathname its
|
|
66
|
+
* address resolves to.
|
|
67
|
+
*
|
|
68
|
+
* An image reaches a renderer as the resolved pathname an embed or an authored
|
|
69
|
+
* body image already carries — see {@link readAssetAddress} — never as the
|
|
70
|
+
* address that produced it, so the lookup a renderer wants is by pathname, not
|
|
71
|
+
* by {@link assetAddressIndex}'s own `assets` map.
|
|
72
|
+
*
|
|
73
|
+
* @param {readonly object[]} records - Asset records, local or foreign.
|
|
74
|
+
* @returns {Map<string, {type: string, role?: string, width: number|"", height: number|""}>}
|
|
75
|
+
* One entry per addressable file, carrying only what a renderer sizes a
|
|
76
|
+
* picture from. `role` is omitted when the record states none; `width` and
|
|
77
|
+
* `height` are always present, blank (`""`) for a vector — the record's own
|
|
78
|
+
* convention, carried through rather than collapsed into an absence a
|
|
79
|
+
* renderer could not tell apart from "no asset resolved at all".
|
|
80
|
+
*/
|
|
81
|
+
export function assetImageInfoByPathname(records?: readonly object[]): Map<string, {
|
|
82
|
+
type: string;
|
|
83
|
+
role?: string;
|
|
84
|
+
width: number | "";
|
|
85
|
+
height: number | "";
|
|
86
|
+
}>;
|
|
64
87
|
/**
|
|
65
88
|
* The asset one authored value names, or why it names none.
|
|
66
89
|
*
|
|
@@ -116,6 +139,47 @@ export function resolveArtRecord(index: object, value: unknown, defaultType: str
|
|
|
116
139
|
path: string;
|
|
117
140
|
};
|
|
118
141
|
} | null;
|
|
142
|
+
/**
|
|
143
|
+
* Every asset's role, keyed by the pathname it resolves to — the form a body
|
|
144
|
+
* carries once an embed's address has been rewritten into the ordinary image
|
|
145
|
+
* every surface renders ({@link module:engine/content-embeds.resolveEmbeds}).
|
|
146
|
+
*
|
|
147
|
+
* This is the lookup a `:::figure` fence's `map` counter reaches through —
|
|
148
|
+
* see {@link module:engine/content-figures.scanFigures}'s `resolveRole` —
|
|
149
|
+
* for a caller that reads a body after that rewrite: a Foundry journal, an
|
|
150
|
+
* item or actor's documentation, and the book.
|
|
151
|
+
*
|
|
152
|
+
* @param {object} index - From {@link module:engine/wikilinks.buildWikilinkIndex},
|
|
153
|
+
* or the equivalent the site and the book build.
|
|
154
|
+
* @returns {Map<string, string>} Pathname → role, one entry per asset that
|
|
155
|
+
* declares one.
|
|
156
|
+
*/
|
|
157
|
+
export function pathnameRoles(index: object): Map<string, string>;
|
|
158
|
+
/**
|
|
159
|
+
* Flag a note whose art slot names a picture that is not the size that slot
|
|
160
|
+
* is cut to.
|
|
161
|
+
*
|
|
162
|
+
* The size is stated by the slot itself, in
|
|
163
|
+
* {@link module:engine/art-slots.ART_SLOTS}, so it is written once and a slot
|
|
164
|
+
* that states none asks nothing of the picture it names. Today the hero image
|
|
165
|
+
* is the one slot with a fixed strip to fill; a picture written in prose is
|
|
166
|
+
* fitted to the room it has and is never measured here.
|
|
167
|
+
*
|
|
168
|
+
* A vector carries no pixel size to compare, and neither does a raster whose
|
|
169
|
+
* header cannot be read; neither is flagged.
|
|
170
|
+
*
|
|
171
|
+
* @param {readonly object[]} records - The corpus, notes and assets together.
|
|
172
|
+
* @param {object} [opts]
|
|
173
|
+
* @param {object} [opts.config] - The resolved build configuration.
|
|
174
|
+
* @param {string} [opts.assetsBase] - Where the asset roots sit, so a finding
|
|
175
|
+
* names the file from the working directory as every other finding does.
|
|
176
|
+
* @returns {object[]} A finding per picture off its slot's size,
|
|
177
|
+
* `severity: "error"`.
|
|
178
|
+
*/
|
|
179
|
+
export function checkArtSlotSizes(records?: readonly object[], { config, assetsBase }?: {
|
|
180
|
+
config?: object | undefined;
|
|
181
|
+
assetsBase?: string | undefined;
|
|
182
|
+
}): object[];
|
|
119
183
|
/**
|
|
120
184
|
* The pathname an art value names, in the form an authored one takes.
|
|
121
185
|
*
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* The four art slots, in the order the specification tabulates them.
|
|
3
3
|
*
|
|
4
4
|
* `banner` is the one that reaches no compiled document: it is the page's hero
|
|
5
|
-
* image, read by the site and by
|
|
5
|
+
* image, read by the site and by nothing else. The book's section plates read a
|
|
6
|
+
* banner of their own, from the book plan's `presentation.page.banner`.
|
|
6
7
|
* That is what `document: false` states, and it is why the inert-art check
|
|
7
8
|
* skips it — a key that is *meant* to reach no document is not an inert key.
|
|
8
9
|
*
|
|
@@ -19,6 +19,16 @@ export function collectAssetRecords(assetsBase: string, { contentPackage, proble
|
|
|
19
19
|
contentPackage: string;
|
|
20
20
|
problems?: object[] | undefined;
|
|
21
21
|
}): Array<Record<string, any>>;
|
|
22
|
+
/**
|
|
23
|
+
* The closed set of roles a picture may declare.
|
|
24
|
+
*
|
|
25
|
+
* Shared with the field declaration below and with every medium that sizes a
|
|
26
|
+
* picture by its role, so the vocabulary cannot drift between the record that
|
|
27
|
+
* carries it and the renderer that reads it.
|
|
28
|
+
*
|
|
29
|
+
* @type {readonly string[]}
|
|
30
|
+
*/
|
|
31
|
+
export const ASSET_ROLES: readonly string[];
|
|
22
32
|
/**
|
|
23
33
|
* The file a directory records provenance for its subtree in.
|
|
24
34
|
*
|
|
@@ -47,6 +57,18 @@ export const PROVENANCE_SIDECAR_SUFFIX: string;
|
|
|
47
57
|
* state this key. Omitting one is a finding rather than a blank, because a
|
|
48
58
|
* record resolves wholesale: the nearest one is the whole answer, so a key it
|
|
49
59
|
* leaves out is not inherited from above but simply absent.
|
|
60
|
+
* @property {"boolean"|"integer"} [type] - The value's own type, for a field
|
|
61
|
+
* whose answer is not a string. Omitted for every string field; `ai` carries
|
|
62
|
+
* the YAML boolean itself rather than a stringified copy, and `width` and
|
|
63
|
+
* `height` carry the pixel count the walk measured. Each is refused rather
|
|
64
|
+
* than coerced when the value does not match.
|
|
65
|
+
* @property {readonly string[]} [values] - The closed set a provenance
|
|
66
|
+
* declaration must choose one of; a value outside it is a finding and the
|
|
67
|
+
* key is left blank, the same treatment an `ai` value of the wrong shape
|
|
68
|
+
* gets. `role` is the one field that carries it.
|
|
69
|
+
* @property {string} [onlyType] - The one asset type this field may be
|
|
70
|
+
* declared for. A provenance record stating it for another type is a
|
|
71
|
+
* finding, and the value is dropped rather than carried through.
|
|
50
72
|
* @property {string} describe - One line, for the author-facing reference.
|
|
51
73
|
*/
|
|
52
74
|
/**
|
|
@@ -105,6 +127,27 @@ export type AssetRecordField = {
|
|
|
105
127
|
* leaves out is not inherited from above but simply absent.
|
|
106
128
|
*/
|
|
107
129
|
required?: boolean | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* - The value's own type, for a field
|
|
132
|
+
* whose answer is not a string. Omitted for every string field; `ai` carries
|
|
133
|
+
* the YAML boolean itself rather than a stringified copy, and `width` and
|
|
134
|
+
* `height` carry the pixel count the walk measured. Each is refused rather
|
|
135
|
+
* than coerced when the value does not match.
|
|
136
|
+
*/
|
|
137
|
+
type?: "boolean" | "integer" | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* - The closed set a provenance
|
|
140
|
+
* declaration must choose one of; a value outside it is a finding and the
|
|
141
|
+
* key is left blank, the same treatment an `ai` value of the wrong shape
|
|
142
|
+
* gets. `role` is the one field that carries it.
|
|
143
|
+
*/
|
|
144
|
+
values?: readonly string[] | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* - The one asset type this field may be
|
|
147
|
+
* declared for. A provenance record stating it for another type is a
|
|
148
|
+
* finding, and the value is dropped rather than carried through.
|
|
149
|
+
*/
|
|
150
|
+
onlyType?: string | undefined;
|
|
108
151
|
/**
|
|
109
152
|
* - One line, for the author-facing reference.
|
|
110
153
|
*/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The replacement record for one asset address, or `null`.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} address - A canonical asset address.
|
|
5
|
+
* @param {object} opts
|
|
6
|
+
* @param {string} opts.localPackage - The compiling package's own segment.
|
|
7
|
+
* @param {readonly string[]} opts.replacements - The package segments of
|
|
8
|
+
* every relationship declaring `assetReplacement: true`, in declaration
|
|
9
|
+
* order.
|
|
10
|
+
* @param {Map<string, object>} opts.index - The merged content index, keyed
|
|
11
|
+
* by canonical address.
|
|
12
|
+
* @returns {{record: object, package: string}|null} The first replacement
|
|
13
|
+
* carrying the address, or `null` when none does.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveAssetReplacement(address: string, { localPackage, replacements, index }: {
|
|
16
|
+
localPackage: string;
|
|
17
|
+
replacements: readonly string[];
|
|
18
|
+
index: Map<string, object>;
|
|
19
|
+
}): {
|
|
20
|
+
record: object;
|
|
21
|
+
package: string;
|
|
22
|
+
} | null;
|
|
@@ -27,6 +27,24 @@ export function assetTypeOfRoot(root: unknown): AssetType | undefined;
|
|
|
27
27
|
* @returns {boolean} Whether it matches {@link ADDRESS_SEGMENT_PATTERN}.
|
|
28
28
|
*/
|
|
29
29
|
export function isAssetShortcode(shortcode: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The pixel dimensions a raster image's own header states.
|
|
32
|
+
*
|
|
33
|
+
* Read from the file's bytes directly rather than through a decoder, so a
|
|
34
|
+
* corrupt or partial file fails closed — the same `undefined` answer as a
|
|
35
|
+
* format this carries no reader for — instead of throwing out of the asset
|
|
36
|
+
* walk. An SVG has no pixel dimensions to read; stating one would be a
|
|
37
|
+
* fabricated viewBox reading rather than a fact about the file.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} absPath - The file's absolute path.
|
|
40
|
+
* @param {string} ext - Its extension, lowercase and dot-led.
|
|
41
|
+
* @returns {{width: number, height: number}|undefined} The declared size, or
|
|
42
|
+
* `undefined` when the format carries none, or the header cannot be read.
|
|
43
|
+
*/
|
|
44
|
+
export function imageDimensions(absPath: string, ext: string): {
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
} | undefined;
|
|
30
48
|
/**
|
|
31
49
|
* The `<system>` segment every asset address carries.
|
|
32
50
|
*
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The tallies one pass accumulates while walking the tree.
|
|
3
|
-
*
|
|
4
|
-
* `declined` and `skippedOther` are deliberately separate numbers. A declined
|
|
5
|
-
* note is one this build **refused** — it declares a retired frontmatter field
|
|
6
|
-
* — and it is an error; a skipped one legitimately belongs to another pass, and
|
|
7
|
-
* there are thousands of those. Folding the first into the second is what let a
|
|
8
|
-
* whole tree be filtered out in silence.
|
|
9
|
-
*
|
|
10
|
-
* @typedef {object} PassStats
|
|
11
|
-
* @property {number} compiled - Notes that became a document.
|
|
12
|
-
* @property {number} skippedNoId - Notes with no `id`, where that is tolerated.
|
|
13
|
-
* @property {number} skippedOther - Notes this pass does not claim.
|
|
14
|
-
* @property {number} declined - Notes this pack **refused** — one declaring a
|
|
15
|
-
* retired frontmatter field, or one routed to a system pack whose system it
|
|
16
|
-
* says nothing about. Counted as errors, never as skips.
|
|
17
|
-
*/
|
|
18
1
|
/**
|
|
19
2
|
* The shared walk → filter → expand → convert → build → write → count loop.
|
|
20
3
|
*
|
|
@@ -45,6 +45,22 @@ export function resolveEmbed(index: object, embed: ParsedEmbed): {
|
|
|
45
45
|
target: string;
|
|
46
46
|
type?: string;
|
|
47
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* The role an address's asset declares, read through the same resolution an
|
|
50
|
+
* embed's address takes.
|
|
51
|
+
*
|
|
52
|
+
* This is the lookup a `:::figure` fence's `map` counter reaches through —
|
|
53
|
+
* see {@link module:engine/content-figures.scanFigures}'s `resolveRole` — for
|
|
54
|
+
* an address still in its authored form, before {@link resolveEmbeds} has
|
|
55
|
+
* rewritten it into the ordinary image every surface renders.
|
|
56
|
+
*
|
|
57
|
+
* @param {object} index - From {@link module:engine/wikilinks.buildWikilinkIndex},
|
|
58
|
+
* or the equivalent the site and the book build.
|
|
59
|
+
* @param {string} address - The address as authored, inside `![[...]]`.
|
|
60
|
+
* @returns {string|undefined} The role, or `undefined` for a note's address,
|
|
61
|
+
* one that resolves nowhere, or a picture that declares none.
|
|
62
|
+
*/
|
|
63
|
+
export function embedRole(index: object, address: string): string | undefined;
|
|
48
64
|
/**
|
|
49
65
|
* What is wrong with one embed's directive or placement, if anything.
|
|
50
66
|
*
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/** Number a sequence of figures with counters shared across documents. */
|
|
2
|
+
export function numberFigures(figures: any, counts: any): any;
|
|
3
|
+
/**
|
|
4
|
+
* Read every `:::figure` fence in a body.
|
|
5
|
+
*
|
|
6
|
+
* SQL fences are expanded before this pass, so their output is a table.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} source - A note body with expanded tables.
|
|
9
|
+
* @param {object} [options] - Options.
|
|
10
|
+
* @param {(address: string) => string|undefined} [options.resolveRole] - From
|
|
11
|
+
* a picture's address to the role its asset declares, so a picture whose
|
|
12
|
+
* asset declares `role: map` counts as `map` rather than `figure`. Omitted,
|
|
13
|
+
* every picture counts as `figure` — the same reading a role other than
|
|
14
|
+
* `map` gets.
|
|
15
|
+
* @returns {{figures: Array<{id: string, slug: string, caption: string,
|
|
16
|
+
* hasCaption: boolean, classes: string[], kind: string, number: number,
|
|
17
|
+
* label: string, line: number, bodyStart: number, bodyEnd: number,
|
|
18
|
+
* captionStart: number, captionEnd: number, close: number}>,
|
|
19
|
+
* errors: Array<{line: number, column: number, message: string}>}}
|
|
20
|
+
*/
|
|
21
|
+
export function scanFigures(source: string, { resolveRole }?: {
|
|
22
|
+
resolveRole?: ((address: string) => string | undefined) | undefined;
|
|
23
|
+
}): {
|
|
24
|
+
figures: Array<{
|
|
25
|
+
id: string;
|
|
26
|
+
slug: string;
|
|
27
|
+
caption: string;
|
|
28
|
+
hasCaption: boolean;
|
|
29
|
+
classes: string[];
|
|
30
|
+
kind: string;
|
|
31
|
+
number: number;
|
|
32
|
+
label: string;
|
|
33
|
+
line: number;
|
|
34
|
+
bodyStart: number;
|
|
35
|
+
bodyEnd: number;
|
|
36
|
+
captionStart: number;
|
|
37
|
+
captionEnd: number;
|
|
38
|
+
close: number;
|
|
39
|
+
}>;
|
|
40
|
+
errors: Array<{
|
|
41
|
+
line: number;
|
|
42
|
+
column: number;
|
|
43
|
+
message: string;
|
|
44
|
+
}>;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Render figure fences as HTML, leaving other Markdown untouched.
|
|
48
|
+
*
|
|
49
|
+
* A code, table or prose figure's contents are left as Markdown inside the
|
|
50
|
+
* wrapper, blank-line separated from its tags exactly as
|
|
51
|
+
* {@link module:engine/content-blocks.renderBlocks} leaves a named block's
|
|
52
|
+
* body — so the surrounding render sees it as part of its own document and a
|
|
53
|
+
* footnote reference inside it resolves against the note's own definitions.
|
|
54
|
+
*
|
|
55
|
+
* A figure's contents are rendered here rather than left for a later pass,
|
|
56
|
+
* because a picture-only fence has to become the surface's own `<figure>`
|
|
57
|
+
* markup directly inside the wrapper this function writes; the surrounding
|
|
58
|
+
* render never sees it as Markdown, so a footnote reference inside one is not
|
|
59
|
+
* resolved, the same gap a block's own title carries.
|
|
60
|
+
*
|
|
61
|
+
* @param {string} source - A note body with expanded tables.
|
|
62
|
+
* @param {(markdown: string) => string} [renderMarkdown] - How to render a
|
|
63
|
+
* figure's own contents.
|
|
64
|
+
* @param {Array<{id: string, label: string}>} [numbers] - Labels assigned by a
|
|
65
|
+
* surface that counts across documents, matched by id.
|
|
66
|
+
* @param {object} [options] - Options.
|
|
67
|
+
* @param {(address: string) => string|undefined} [options.resolveRole] - See
|
|
68
|
+
* {@link scanFigures}.
|
|
69
|
+
* @returns {{markdown: string, errors: Array<{line: number, column: number, message: string}>}}
|
|
70
|
+
*/
|
|
71
|
+
export function renderFigureBlocks(source: string, renderMarkdown?: (markdown: string) => string, numbers?: Array<{
|
|
72
|
+
id: string;
|
|
73
|
+
label: string;
|
|
74
|
+
}>, { resolveRole }?: {
|
|
75
|
+
resolveRole?: ((address: string) => string | undefined) | undefined;
|
|
76
|
+
}): {
|
|
77
|
+
markdown: string;
|
|
78
|
+
errors: Array<{
|
|
79
|
+
line: number;
|
|
80
|
+
column: number;
|
|
81
|
+
message: string;
|
|
82
|
+
}>;
|
|
83
|
+
};
|
|
84
|
+
/** A figure's automatically determined kind, and the word that labels it. */
|
|
85
|
+
export const FIGURE_NAMES: Readonly<{
|
|
86
|
+
code: "Code";
|
|
87
|
+
table: "Table";
|
|
88
|
+
figure: "Figure";
|
|
89
|
+
map: "Map";
|
|
90
|
+
prose: "Prose";
|
|
91
|
+
}>;
|
|
92
|
+
/**
|
|
93
|
+
* The classes a figure takes.
|
|
94
|
+
*
|
|
95
|
+
* `.border` states that the captioned thing is drawn inside a border, and each
|
|
96
|
+
* medium owns what that means. The vocabulary is closed: a class absent from it
|
|
97
|
+
* is a finding naming the class.
|
|
98
|
+
*
|
|
99
|
+
* @type {readonly string[]}
|
|
100
|
+
*/
|
|
101
|
+
export const FIGURE_CLASSES: readonly string[];
|
|
@@ -81,3 +81,10 @@ export function footnoteFindings(source: string): Array<{
|
|
|
81
81
|
column: number;
|
|
82
82
|
message: string;
|
|
83
83
|
}>;
|
|
84
|
+
/**
|
|
85
|
+
* A footnote reference's shape, wherever it is written — excluding a
|
|
86
|
+
* definition's own `[^id]:` opener, which this never matches.
|
|
87
|
+
*
|
|
88
|
+
* @type {RegExp}
|
|
89
|
+
*/
|
|
90
|
+
export const FOOTNOTE_REFERENCE: RegExp;
|