@heroiclands/package-build 23.0.0 → 23.1.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.
Files changed (153) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +1 -1
  3. package/bin/content-commands.mjs +1 -1
  4. package/ci/content-format-reference.mjs +46 -0
  5. package/docs/api.md +124 -141
  6. package/docs/authoring/assets.md +1 -1
  7. package/docs/authoring/dates-and-calendars.md +12 -6
  8. package/docs/authoring/frontmatter.md +2 -2
  9. package/docs/authoring/links-and-markup.md +145 -29
  10. package/docs/commands.md +8 -10
  11. package/docs/configuration.md +13 -11
  12. package/docs/content-format.md +2 -2
  13. package/docs/guides/book.md +59 -4
  14. package/docs/guides/icons.md +4 -5
  15. package/docs/guides/packs.md +6 -0
  16. package/docs/guides/reference-pages.md +21 -1
  17. package/docs/guides/release-and-deploy.md +17 -1
  18. package/docs/guides/site.md +17 -18
  19. package/docs/reference/format-details.md +877 -276
  20. package/docs/reference/note-types.md +278 -91
  21. package/docs/reference/theme-pages.md +58 -97
  22. package/engine/address-values.mjs +124 -4
  23. package/engine/address.mjs +44 -3
  24. package/engine/anchors.mjs +103 -3
  25. package/engine/art-slots.mjs +2 -9
  26. package/engine/base-compiler.mjs +25 -6
  27. package/engine/calendar-artifacts.mjs +4 -1
  28. package/engine/calendar-notes.mjs +166 -102
  29. package/engine/content-format-check.mjs +2 -3
  30. package/engine/content-format.mjs +44 -1
  31. package/engine/content-format.yaml +79 -16
  32. package/engine/content-images.mjs +10 -1
  33. package/engine/content-index.mjs +37 -9
  34. package/engine/content-links.mjs +24 -5
  35. package/engine/content-tables.mjs +24 -3
  36. package/engine/data-keys.mjs +347 -0
  37. package/engine/derived-sections.mjs +322 -0
  38. package/engine/diagnostics.mjs +28 -0
  39. package/engine/event-fields.mjs +187 -0
  40. package/engine/event-rows.mjs +126 -0
  41. package/engine/event-views.mjs +305 -0
  42. package/engine/exported-scene.mjs +29 -53
  43. package/engine/frontmatter-lint.mjs +103 -77
  44. package/engine/frontmatter.mjs +7 -2
  45. package/engine/generate.mjs +53 -0
  46. package/engine/generated-sections.mjs +223 -0
  47. package/engine/heading-attributes.mjs +4 -2
  48. package/engine/helpers.mjs +12 -1
  49. package/engine/holdings.mjs +12 -33
  50. package/engine/ids.mjs +17 -11
  51. package/engine/index.mjs +4 -4
  52. package/engine/infobox-render.mjs +21 -6
  53. package/engine/infobox.mjs +217 -99
  54. package/engine/journals.mjs +104 -47
  55. package/engine/literature-notes.mjs +4 -1
  56. package/engine/literature-works.mjs +21 -13
  57. package/engine/map-graphviz.mjs +4 -18
  58. package/engine/markdown-expressions.mjs +116 -11
  59. package/engine/metadata-index.mjs +26 -0
  60. package/engine/near-miss.mjs +90 -0
  61. package/engine/note-addresses.mjs +75 -19
  62. package/engine/note-dates.mjs +5 -3
  63. package/engine/note-event-terms.mjs +364 -0
  64. package/engine/note-events.mjs +823 -0
  65. package/engine/note-vocabulary.mjs +184 -88
  66. package/engine/office-holders.mjs +20 -54
  67. package/engine/packagebuild-index.mjs +16 -1
  68. package/engine/pdf-build.mjs +97 -60
  69. package/engine/pdf-index.mjs +263 -0
  70. package/engine/pdf-render.mjs +47 -5
  71. package/engine/place-relation-terms.mjs +174 -0
  72. package/engine/place-relations.mjs +72 -160
  73. package/engine/rank-ladder.mjs +14 -41
  74. package/engine/reckoning-markers.mjs +2 -0
  75. package/engine/region-events.mjs +6 -12
  76. package/engine/scenes.mjs +73 -468
  77. package/engine/site-build.mjs +75 -101
  78. package/engine/site-index.mjs +3 -1
  79. package/engine/site-maps.mjs +43 -29
  80. package/engine/site-preview.mjs +40 -31
  81. package/engine/social-ties.mjs +2 -1
  82. package/engine/sql-tables.mjs +212 -9
  83. package/engine/standing-terms.mjs +145 -6
  84. package/engine/standings.mjs +37 -49
  85. package/engine/web-wikilinks.mjs +21 -1
  86. package/engine/wikilink-syntax.mjs +34 -4
  87. package/engine/wikilinks.mjs +27 -2
  88. package/hugo-theme/layouts/partials/infobox/entry.html +4 -1
  89. package/hugo-theme/layouts/partials/page-body.html +0 -3
  90. package/hugo-theme/static/css/style.css +25 -55
  91. package/package.json +1 -2
  92. package/packagebuild-metadata.jsonl +13 -13
  93. package/sohl/note-schemas.mjs +8 -73
  94. package/types/engine/address-values.d.mts +50 -3
  95. package/types/engine/address.d.mts +21 -0
  96. package/types/engine/anchors.d.mts +49 -2
  97. package/types/engine/art-slots.d.mts +1 -1
  98. package/types/engine/base-compiler.d.mts +13 -4
  99. package/types/engine/calendar-notes.d.mts +7 -0
  100. package/types/engine/content-format.d.mts +52 -0
  101. package/types/engine/content-images.d.mts +5 -1
  102. package/types/engine/content-tables.d.mts +9 -1
  103. package/types/engine/data-keys.d.mts +145 -0
  104. package/types/engine/derived-sections.d.mts +73 -0
  105. package/types/engine/diagnostics.d.mts +15 -0
  106. package/types/engine/event-fields.d.mts +99 -0
  107. package/types/engine/event-rows.d.mts +12 -0
  108. package/types/engine/event-views.d.mts +67 -0
  109. package/types/engine/exported-scene.d.mts +5 -2
  110. package/types/engine/frontmatter-lint.d.mts +3 -3
  111. package/types/engine/generated-sections.d.mts +143 -0
  112. package/types/engine/holdings.d.mts +6 -20
  113. package/types/engine/ids.d.mts +15 -12
  114. package/types/engine/index.d.mts +1 -1
  115. package/types/engine/infobox.d.mts +13 -3
  116. package/types/engine/journals.d.mts +24 -11
  117. package/types/engine/literature-works.d.mts +1 -2
  118. package/types/engine/map-graphviz.d.mts +2 -10
  119. package/types/engine/markdown-expressions.d.mts +12 -3
  120. package/types/engine/near-miss.d.mts +42 -0
  121. package/types/engine/note-addresses.d.mts +7 -1
  122. package/types/engine/note-event-terms.d.mts +68 -0
  123. package/types/engine/note-events.d.mts +71 -0
  124. package/types/engine/note-vocabulary.d.mts +37 -8
  125. package/types/engine/office-holders.d.mts +3 -0
  126. package/types/engine/pdf-index.d.mts +35 -0
  127. package/types/engine/pdf-render.d.mts +8 -2
  128. package/types/engine/place-relation-terms.d.mts +83 -0
  129. package/types/engine/place-relations.d.mts +11 -66
  130. package/types/engine/rank-ladder.d.mts +2 -0
  131. package/types/engine/region-events.d.mts +6 -12
  132. package/types/engine/scenes.d.mts +6 -32
  133. package/types/engine/site-build.d.mts +8 -22
  134. package/types/engine/site-maps.d.mts +15 -7
  135. package/types/engine/sql-tables.d.mts +77 -2
  136. package/types/engine/standing-terms.d.mts +37 -4
  137. package/types/engine/standings.d.mts +14 -9
  138. package/types/engine/wikilink-syntax.d.mts +20 -0
  139. package/types/engine/wikilinks.d.mts +3 -2
  140. package/docs/guides/government-migration.md +0 -52
  141. package/engine/itinerary-scenes.mjs +0 -166
  142. package/engine/lore-events.mjs +0 -197
  143. package/engine/map-notes.mjs +0 -1309
  144. package/engine/map-raster.mjs +0 -51
  145. package/hugo-theme/layouts/partials/holdings/entry.html +0 -21
  146. package/hugo-theme/layouts/partials/holdings/kind-groups.html +0 -71
  147. package/hugo-theme/layouts/partials/holdings.html +0 -61
  148. package/hugo-theme/layouts/partials/literature-works.html +0 -29
  149. package/hugo-theme/layouts/partials/place-map.html +0 -9
  150. package/types/engine/itinerary-scenes.d.mts +0 -29
  151. package/types/engine/lore-events.d.mts +0 -14
  152. package/types/engine/map-notes.d.mts +0 -297
  153. package/types/engine/map-raster.d.mts +0 -8
@@ -134,14 +134,18 @@ export function dataFields(type: string, vocabulary?: Readonly<Record<string, Ty
134
134
  */
135
135
  export function subTypes(type: string, vocabulary?: Readonly<Record<string, TypeVocabulary>>): readonly string[] | null | undefined;
136
136
  /**
137
- * Accepted migration input with no canonical field or emitted value.
137
+ * What happened to or at a subject — the `events` key, declared once and spread
138
+ * into every type that carries events, so the schema cannot differ between
139
+ * them. The entry's own schema and its check live in
140
+ * {@link module:engine/note-events}.
138
141
  *
139
- * Legacy affiliation domains are ignored. They never supply a government.
140
- * @param {string} type - The note type.
141
- * @param {string} key - An authored data key.
142
- * @returns {boolean} Whether the obsolete key is accepted during migration.
142
+ * Declared here rather than in that module because its imports reach back to
143
+ * this one: a function declaration is bound before either module runs, and an
144
+ * object is not.
145
+ *
146
+ * @type {DataFieldSpec}
143
147
  */
144
- export function isLegacyDataField(type: string, key: string): boolean;
148
+ export const EVENTS_FIELD: DataFieldSpec;
145
149
  /**
146
150
  * One top-level frontmatter key.
147
151
  *
@@ -389,6 +393,16 @@ export type DataFieldSpec = {
389
393
  * - Allowed Address types, separate from `ref`.
390
394
  */
391
395
  accepts?: readonly string[] | undefined;
396
+ /**
397
+ * - The anchor kinds an
398
+ * Address here may name with `#<anchor>`. Absent, an anchor is refused.
399
+ */
400
+ anchors?: readonly ("event" | "prose")[] | undefined;
401
+ /**
402
+ * - The Address names exactly one event: an
403
+ * anchor of kind `event`, or a note holding one event and no more.
404
+ */
405
+ single?: boolean | undefined;
392
406
  /**
393
407
  * - Infobox text for an explicitly authored null with a declared meaning.
394
408
  */
@@ -407,8 +421,7 @@ export type DataFieldSpec = {
407
421
  entryShape?: string | undefined;
408
422
  /**
409
423
  * - The Address's default type, an art slot declares
410
- * one — `icon` for `icon` and `tokenIcon`, `image` for `bgImage` and
411
- * `banner` — so `icon: anvil` names `icon-anvil` while a value carrying the
424
+ * one — `icon` for `icon` and `tokenIcon`, `image` for `banner` — so `icon: anvil` names `icon-anvil` while a value carrying the
412
425
  * separator states its own address. Distinct from a `FieldSpec`'s `code`
413
426
  * ({@link module :engine/field-spec}), which names a **Shortcode** instead.
414
427
  */
@@ -431,6 +444,22 @@ export type DataFieldSpec = {
431
444
  check?: ((note: object, opts: {
432
445
  index?: object;
433
446
  }) => object[]) | undefined;
447
+ /**
448
+ * - The
449
+ * keys of a value that is a map, closed to them — see
450
+ * {@link module :engine/data-keys}.
451
+ */
452
+ fields?: readonly import("./data-keys.mjs").InnerKeySpec[] | undefined;
453
+ /**
454
+ * - What one entry of a list value is, where the
455
+ * entries are not Addresses (`entryKind` says that).
456
+ */
457
+ entries?: object | undefined;
458
+ /**
459
+ * - What the value under each key of a keyed map
460
+ * is, where the keys are data rather than declared names.
461
+ */
462
+ values?: object | undefined;
434
463
  /**
435
464
  * - One line, for the author-facing reference.
436
465
  */
@@ -12,3 +12,6 @@ export function checkDatedOffices(note: object, { index }?: {
12
12
  column?: number;
13
13
  file: any;
14
14
  }[];
15
+ import { HOLDER_FIELDS } from "./standing-terms.mjs";
16
+ import { OFFICE_FIELDS } from "./standing-terms.mjs";
17
+ export { HOLDER_FIELDS, OFFICE_FIELDS };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The marker an entry heading or an authored mention carries.
3
+ *
4
+ * @param {string} slug - The address slug of the note the marker is about.
5
+ * @param {boolean} [main] - Whether this is the note's own entry.
6
+ * @returns {string} Typst markup occupying no space.
7
+ */
8
+ export function indexMarker(slug: string, main?: boolean): string;
9
+ /**
10
+ * Every term the book's index lists, in index order.
11
+ *
12
+ * @param {object[]} entries - The plan's entries.
13
+ * @returns {Array<{letter: string, name: string, slug: string, see?: string}>}
14
+ * Terms with `see` set for a cross-reference to the main name it points at.
15
+ */
16
+ export function indexTerms(entries: object[]): Array<{
17
+ letter: string;
18
+ name: string;
19
+ slug: string;
20
+ see?: string;
21
+ }>;
22
+ /**
23
+ * The Typst function definitions the markers and the chapter rely on.
24
+ *
25
+ * @returns {string} Typst source.
26
+ */
27
+ export function indexPreamble(): string;
28
+ /**
29
+ * The index chapter, ready to follow the last entry.
30
+ *
31
+ * @param {object[]} entries - The plan's entries.
32
+ * @param {string} title - The book's title, which kicks the chapter.
33
+ * @returns {string} Typst source, or "" when the book has nothing to index.
34
+ */
35
+ export function indexChapter(entries: object[], title: string): string;
@@ -99,6 +99,10 @@ export function stripHtmlComments(markdown: string): string;
99
99
  * at. Every link the book sets as a URL is resolved against it, because a
100
100
  * reader holding a PDF has no page to resolve a path against — see
101
101
  * {@link renderLink}.
102
+ * @param {boolean} [opts.generated] - Whether the Markdown is a note's
103
+ * generated sections rather than its author's text — see
104
+ * {@link module:engine/generated-sections}. Their links follow the rules
105
+ * {@link renderLink} states for generated links.
102
106
  * @returns {string} Typst markup.
103
107
  */
104
108
  export function markdownToTypst(markdown: string, opts?: {
@@ -125,6 +129,7 @@ export function markdownToTypst(markdown: string, opts?: {
125
129
  }[] | undefined;
126
130
  prepared?: boolean | undefined;
127
131
  url?: string | undefined;
132
+ generated?: boolean | undefined;
128
133
  }): string;
129
134
  /**
130
135
  * A page address as a reader of the book can follow it.
@@ -325,8 +330,9 @@ export function renderBook({ plan, bodies, title, subtitle, front, fonts, versio
325
330
  * that would have contained it, which is where a reader wants to end up anyway;
326
331
  * a link with no entry to fall back to becomes plain text. Both are reported.
327
332
  *
328
- * A declaration is a label not preceded by `#link(` — the only two places a
329
- * label appears are the heading that declares one and the link that uses one.
333
+ * A declaration is a label preceded by neither `#link(` nor `locate(` — a
334
+ * label appears in the heading that declares it, the link that uses it, and
335
+ * the page lookup a generated link prints after itself.
330
336
  *
331
337
  * @param {string} source - The assembled Typst document.
332
338
  * @param {object[]} [findings] - Collected here rather than thrown.
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The closed sets a place's `borders` and `routes` are held to, and the keys
3
+ * one entry of each carries.
4
+ *
5
+ * A leaf module, importing nothing: the note vocabulary reads the entry
6
+ * declarations as it loads, and {@link module:engine/place-relations}, which
7
+ * checks what the values mean, reaches the vocabulary through the Address
8
+ * reader.
9
+ *
10
+ * @module
11
+ */
12
+ /**
13
+ * The type a border's or a route's `to` names.
14
+ *
15
+ * It is both the default its `<type>` segment takes when an author omits it and
16
+ * the whole of the set the position accepts, which is what makes `vylar` and
17
+ * `place-vylar` the same Address and a `to` naming a `lore` note an error rather
18
+ * than a lookup that quietly finds nothing.
19
+ *
20
+ * @type {string}
21
+ */
22
+ export const RELATION_TYPE: string;
23
+ /**
24
+ * The eight compass bearings, clockwise from north.
25
+ *
26
+ * Where a neighbour or a destination lies from the place stating it. The
27
+ * order is load-bearing: {@link oppositeBearing} reads four steps around it.
28
+ *
29
+ * @type {readonly string[]}
30
+ */
31
+ export const BEARINGS: readonly string[];
32
+ /**
33
+ * The modes a route is travelled by: `land`, `boat` on a river or a lake,
34
+ * `ship` on open sea.
35
+ *
36
+ * @type {readonly string[]}
37
+ */
38
+ export const ROUTE_MODES: readonly string[];
39
+ /**
40
+ * The days markers a route may state.
41
+ *
42
+ * Each is "about this, under normal conditions": `10`, `20` and `30` are one,
43
+ * two and three ten-day weeks, `180` is many months, `360` is "who knows".
44
+ *
45
+ * @type {readonly number[]}
46
+ */
47
+ export const TRAVEL_DAYS: readonly number[];
48
+ /**
49
+ * The terrain registry, each terrain naming the modes that cross it.
50
+ *
51
+ * A land terrain is crossed by land alone; open sea by ship; a river or a lake
52
+ * by boat; a coast by all three, because a coast road and a coasting voyage
53
+ * are both journeys along it.
54
+ *
55
+ * @type {Readonly<Record<string, readonly string[]>>}
56
+ */
57
+ export const TERRAIN_MODES: Readonly<Record<string, readonly string[]>>;
58
+ /**
59
+ * The terrain names, in registry order — the closed set a `terrain` list
60
+ * draws from.
61
+ *
62
+ * @type {readonly string[]}
63
+ */
64
+ export const TERRAINS: readonly string[];
65
+ /**
66
+ * The keys a `borders` entry carries, as inner-key declarations. Both are
67
+ * required.
68
+ *
69
+ * @type {readonly import("./data-keys.mjs").InnerKeySpec[]}
70
+ */
71
+ export const BORDER_FIELDS: readonly import("./data-keys.mjs").InnerKeySpec[];
72
+ /**
73
+ * The keys a `routes` entry carries, as inner-key declarations. `to`,
74
+ * `bearing`, `mode` and `days` are required; `terrain` and `leagues` are
75
+ * optional.
76
+ *
77
+ * @type {readonly import("./data-keys.mjs").InnerKeySpec[]}
78
+ */
79
+ export const ROUTE_FIELDS: readonly import("./data-keys.mjs").InnerKeySpec[];
80
+ /** The keys a `borders` entry carries. @type {readonly string[]} */
81
+ export const BORDER_KEYS: readonly string[];
82
+ /** The keys a `routes` entry carries. @type {readonly string[]} */
83
+ export const ROUTE_KEYS: readonly string[];
@@ -38,69 +38,14 @@ export function checkBorders(note: object, { index }?: {
38
38
  export function checkRoutes(note: object, { index }?: {
39
39
  index?: object | undefined;
40
40
  }): object[];
41
- /**
42
- * The type a border's or a route's `to` names.
43
- *
44
- * It is both the default its `<type>` segment takes when an author omits it and
45
- * the whole of the set the position accepts, which is what makes `vylar` and
46
- * `place-vylar` the same Address and a `to` naming a `lore` note an error rather
47
- * than a lookup that quietly finds nothing.
48
- *
49
- * @type {string}
50
- */
51
- export const RELATION_TYPE: string;
52
- /**
53
- * The eight compass bearings, clockwise from north.
54
- *
55
- * Where a neighbour or a destination lies from the place stating it. The
56
- * order is load-bearing: {@link oppositeBearing} reads four steps around it.
57
- *
58
- * @type {readonly string[]}
59
- */
60
- export const BEARINGS: readonly string[];
61
- /**
62
- * The modes a route is travelled by: `land`, `boat` on a river or a lake,
63
- * `ship` on open sea.
64
- *
65
- * @type {readonly string[]}
66
- */
67
- export const ROUTE_MODES: readonly string[];
68
- /**
69
- * The days markers a route may state.
70
- *
71
- * Each is "about this, under normal conditions": `10`, `20` and `30` are one,
72
- * two and three ten-day weeks, `180` is many months, `360` is "who knows".
73
- *
74
- * @type {readonly number[]}
75
- */
76
- export const TRAVEL_DAYS: readonly number[];
77
- /**
78
- * The terrain registry, each terrain naming the modes that cross it.
79
- *
80
- * A land terrain is crossed by land alone; open sea by ship; a river or a lake
81
- * by boat; a coast by all three, because a coast road and a coasting voyage
82
- * are both journeys along it.
83
- *
84
- * @type {Readonly<Record<string, readonly string[]>>}
85
- */
86
- export const TERRAIN_MODES: Readonly<Record<string, readonly string[]>>;
87
- /**
88
- * The terrain names, in registry order — the closed set a `terrain` list
89
- * draws from.
90
- *
91
- * @type {readonly string[]}
92
- */
93
- export const TERRAINS: readonly string[];
94
- /**
95
- * The keys a `borders` entry may carry. Both are required.
96
- *
97
- * @type {readonly string[]}
98
- */
99
- export const BORDER_KEYS: readonly string[];
100
- /**
101
- * The keys a `routes` entry may carry. `to`, `bearing`, `mode` and `days` are
102
- * required; `terrain` and `leagues` are optional.
103
- *
104
- * @type {readonly string[]}
105
- */
106
- export const ROUTE_KEYS: readonly string[];
41
+ import { RELATION_TYPE } from "./place-relation-terms.mjs";
42
+ import { BEARINGS } from "./place-relation-terms.mjs";
43
+ import { ROUTE_MODES } from "./place-relation-terms.mjs";
44
+ import { TRAVEL_DAYS } from "./place-relation-terms.mjs";
45
+ import { TERRAIN_MODES } from "./place-relation-terms.mjs";
46
+ import { TERRAINS } from "./place-relation-terms.mjs";
47
+ import { BORDER_FIELDS } from "./place-relation-terms.mjs";
48
+ import { ROUTE_FIELDS } from "./place-relation-terms.mjs";
49
+ import { BORDER_KEYS } from "./place-relation-terms.mjs";
50
+ import { ROUTE_KEYS } from "./place-relation-terms.mjs";
51
+ export { RELATION_TYPE, BEARINGS, ROUTE_MODES, TRAVEL_DAYS, TERRAIN_MODES, TERRAINS, BORDER_FIELDS, ROUTE_FIELDS, BORDER_KEYS, ROUTE_KEYS };
@@ -38,3 +38,5 @@ export function checkRankLadder(note: {
38
38
  severity: string;
39
39
  message: string;
40
40
  }>;
41
+ export { RUNG_FIELDS };
42
+ import { RUNG_FIELDS } from "./standing-terms.mjs";
@@ -2,19 +2,13 @@
2
2
  * The curated Foundry region-event vocabulary, as plain data.
3
3
  *
4
4
  * Deliberately **plain ESM** — no TypeScript, no `@src` aliases, no Foundry —
5
- * for the same reason `../sohl/default-item-art.mjs` is: the map-note pack
6
- * compiler runs under bare `node`, outside the bundler that resolves `@src` and
7
- * strips types, and it must reject an authored region event that the runtime
8
- * would silently drop. One list here is what keeps the build-time lint and the
9
- * runtime bridge from drifting apart.
5
+ * so the Foundry runtime and any build-time consumer read one list, and the
6
+ * events a region trigger forwards cannot drift between them.
10
7
  *
11
- * It sits in this package rather than in the system's `src/` tree because the
12
- * map-note compiler that reads it is installed as a dependency, and a
13
- * relative path out of the package would resolve to garbage from
14
- * `node_modules`. The runtime reaches it back through the package's
15
- * `./engine/region-events` entry point. It is engine-side, not
16
- * SoHL-side, because any content module that authors a scene region — an
17
- * adventure module included — needs this vocabulary.
8
+ * The runtime reaches it through the package's `./engine/region-events` entry
9
+ * point. It is engine-side, not SoHL-side, because a Scene region exported
10
+ * from any content module — an adventure module included — names its events
11
+ * from this vocabulary.
18
12
  *
19
13
  * The prose explaining *why* each event is curated or excluded lives with the
20
14
  * typed re-exports in `src/entity/event/region-triggers.ts`, which is the
@@ -1,39 +1,19 @@
1
- /**
2
- * Every SoHL action name this build knows about, for the `action:` warning on a
3
- * region trigger.
4
- *
5
- * Deliberately a **superset**, gathered from the localization keys every
6
- * intrinsic action's `title:` points at and from the `shortcode:` / `executor:`
7
- * string literals the action definitions carry. A warning that fires on a real
8
- * action would be worse than one that misses a typo, so the wider net is the
9
- * right one: this only has to recognise the names that exist, not enumerate
10
- * them exactly.
11
- *
12
- * @param {string} repoRoot - The repository root.
13
- * @returns {Set<string>} The known action names.
14
- */
15
- export function collectKnownActionNames(repoRoot: string): Set<string>;
16
1
  /**
17
2
  * Scenes pack compiler.
18
3
  *
19
- * Walks the content tree and compiles every map note into one Scene, resolving
20
- * what one note says about another through an index built before any scene is
21
- * written. It also writes one Adventure per place, bundling those scenes with
22
- * the JournalEntries their prose compiled into, which is what makes a pinned
23
- * scene's id-based references resolve on import.
4
+ * Compiles every map note's exported Scene, and writes one Adventure per place
5
+ * whose scenes carry pins, bundling those scenes with the JournalEntries their
6
+ * prose compiled into.
24
7
  */
25
8
  export class Scenes extends BasePackCompiler {
26
- constructor({ contentBase, assetsBase, dest, skipDirectories, companionDests, folderResolver, repoRoot, config, packName, bundleSourceDirs, corpus, }: {
9
+ constructor({ contentBase, assetsBase, dest, skipDirectories, companionDests, folderResolver, packName, corpus, }: {
27
10
  contentBase: any;
28
11
  assetsBase: any;
29
12
  dest: any;
30
13
  skipDirectories: any;
31
14
  companionDests?: {} | undefined;
32
15
  folderResolver?: (() => null) | undefined;
33
- repoRoot?: string | undefined;
34
- config: any;
35
16
  packName: any;
36
- bundleSourceDirs?: {} | undefined;
37
17
  corpus: any;
38
18
  });
39
19
  /** @type {string} */
@@ -44,13 +24,7 @@ export class Scenes extends BasePackCompiler {
44
24
  * @type {number}
45
25
  */
46
26
  adventureCount: number;
47
- mapConfig: any;
48
- packName: any;
49
- journalSourceDirs: any;
50
- index: Map<string, object> | undefined;
51
- effectsByAddress: Map<string, object> | undefined;
52
- knownActions: Set<string> | undefined;
53
- /** place key → `{name, img, scenes: [], journal: []}` */
27
+ /** place key → `{key, name, scenes: [], journal: [], pinned}` */
54
28
  places: Map<any, any> | undefined;
55
29
  /**
56
30
  * Bundle each pinned place into an Adventure, once every map of it has
@@ -58,7 +32,7 @@ export class Scenes extends BasePackCompiler {
58
32
  *
59
33
  * @returns {Promise<void>}
60
34
  */
61
- finish(stats: any): Promise<void>;
35
+ finish(): Promise<void>;
62
36
  /** @inheritdoc */
63
37
  reportCompiled(stats: any): void;
64
38
  #private;
@@ -182,10 +182,7 @@ export function tableUniverse(pages: object[]): Map<string, object[]>;
182
182
  * about every other page, known only once the whole tree has resolved — see
183
183
  * {@link module:engine/related-pages} — so an authored value is dropped the
184
184
  * way `aliases` is, and {@link renderPages} writes the derived block once it
185
- * holds the graph. Derived geographical and government lists are dropped for the
186
- * same reason — see {@link module:engine/holdings}. **So is `map`**: the
187
- * file a place page names is the one the build drew beside it — see
188
- * {@link module:engine/site-maps} — and a page with no drawing names none.
185
+ * holds the graph.
189
186
  *
190
187
  * @param {object} page - The page.
191
188
  * @param {object} options
@@ -219,25 +216,14 @@ export function pageFrontmatter(page: object, { decorate, webSrc, artSrc }: {
219
216
  * `doc` note's `subType` may be spelled the same as another note's `type`, and
220
217
  * `doc-gear.md` and `weapongear-gear.md` are distinct.
221
218
  *
222
- * **A page that carries a file beside itself is a leaf bundle**, `<slug>/index.md`,
223
- * because that is the one shape under which Hugo hands a page its own
224
- * resources — the map from a place, inlined by the theme through
225
- * `.Resources.Get`. The directory is the page, not a section: it holds no
226
- * `_index.md`, and the page's stated `url` keeps its address exactly where the
227
- * flat file's was.
228
- *
229
219
  * @param {{slug: string}} page - The page.
230
- * @param {object} [opts]
231
- * @param {boolean} [opts.bundle=false] - Whether the page carries a resource.
232
220
  * @returns {string} The file, relative to the mount.
233
221
  */
234
222
  export function pageDestination(page: {
235
223
  slug: string;
236
- }, { bundle }?: {
237
- bundle?: boolean | undefined;
238
224
  }): string;
239
225
  /** Transform one content page without writing the site mount. */
240
- export function renderSitePage(page: any, { index, foreign, universe, pass, decorate, linkable, sqlTables, config, artIndex, figuresByAddress, }: {
226
+ export function renderSitePage(page: any, { index, foreign, universe, pass, decorate, linkable, sqlTables, config, artIndex, figuresByAddress, events, drawings, }: {
241
227
  index: any;
242
228
  foreign: any;
243
229
  universe: any;
@@ -248,6 +234,8 @@ export function renderSitePage(page: any, { index, foreign, universe, pass, deco
248
234
  config: any;
249
235
  artIndex: any;
250
236
  figuresByAddress?: Map<any, any> | undefined;
237
+ events: any;
238
+ drawings?: Map<any, any> | undefined;
251
239
  }): {
252
240
  page: any;
253
241
  body: string;
@@ -311,25 +299,23 @@ export function renderSitePage(page: any, { index, foreign, universe, pass, deco
311
299
  * point the resolver answers, and inverted once between them. Nothing is
312
300
  * resolved twice.
313
301
  *
314
- * **A map is written with its page.** The drawing from a place is made before
302
+ * **A map is set inline in its page.** The drawing from a place is made before
315
303
  * this render — see {@link module:engine/site-maps} — and handed in keyed by
316
- * page URL; the page that owns one is written as a leaf bundle, the file is
317
- * copied beside it, and the front matter names it as `map`. Every other page
318
- * is written flat, and carries no such key.
304
+ * the file name the page's **From here** section names.
319
305
  *
320
306
  * @param {object[]} pages - Every page.
321
307
  * @param {object} options - Everything the render needs. `homepages` is the
322
308
  * homepage as the index knows it — `{ fm, body, url, title }` — which takes
323
309
  * no part in the render and every part in the graph: a content page links
324
310
  * it by wikilink, and its own markdown links name content pages. `maps` is
325
- * each drawing by the URL of the page that carries it.
311
+ * each drawing by the file name a **From here** section names.
326
312
  * @returns {{written: number, byKind: Record<string, number>, tableErrors: object[],
327
313
  * wikiErrors: object[], imageErrors: object[], embedErrors: object[],
328
314
  * related: Map<string, import("./related-pages.mjs").Related>,
329
315
  * maps: number}} `related`
330
316
  * is keyed by page URL, and holds the homepage's block beside every content
331
317
  * page's, so the caller can write it on the page this render does not.
332
- * `maps` counts the pages written with one.
318
+ * `maps` counts the pages carrying a map.
333
319
  */
334
320
  export function renderPages(pages: object[], options: object): {
335
321
  written: number;
@@ -2,8 +2,7 @@
2
2
  * A drawing as the page writer receives it.
3
3
  *
4
4
  * @typedef {object} SiteMap
5
- * @property {string} name - The file's name in the page's bundle, and the
6
- * value of the page's `map` key: `from-<shortcode>.svg`.
5
+ * @property {string} name - The file's name: `from-<shortcode>.svg`.
7
6
  * @property {string} file - Where the drawing is, absolute.
8
7
  */
9
8
  /**
@@ -24,7 +23,7 @@
24
23
  */
25
24
  export function inlineSvg(svg: string): string;
26
25
  /**
27
- * Draw the map from every related place of this package.
26
+ * Draw the map from every place of this package that is given one.
28
27
  *
29
28
  * @param {object} opts
30
29
  * @param {Array<Record<string, any>>} opts.records - The package's index
@@ -36,8 +35,8 @@ export function inlineSvg(svg: string): string;
36
35
  * ending in a slash: what every name in a drawing links through.
37
36
  * @returns {{maps: Map<string, SiteMap>, findings: Array<{file: string,
38
37
  * line?: number, column?: number, severity: "error"|"warning",
39
- * message: string}>}} The drawings, keyed by the URL of the page each
40
- * belongs to, and warnings for relations that name no place.
38
+ * message: string}>}} The drawings, keyed by the file name a **From here**
39
+ * section names, and warnings for relations that name no place.
41
40
  */
42
41
  export function drawSiteMaps({ records, foreignIndex, config, base }: {
43
42
  records: Array<Record<string, any>>;
@@ -54,6 +53,16 @@ export function drawSiteMaps({ records, foreignIndex, config, base }: {
54
53
  message: string;
55
54
  }>;
56
55
  };
56
+ /**
57
+ * The figure the website sets a drawing in: the SVG inline, so its place names
58
+ * stay links, with no blank line inside it — a blank line would end the HTML
59
+ * block and hand the rest of the drawing to the Markdown renderer.
60
+ *
61
+ * @param {string} svg - The drawing, as {@link inlineSvg} wrote it.
62
+ * @param {string} alt - What the drawing shows, for a screen reader.
63
+ * @returns {string} One HTML block.
64
+ */
65
+ export function inlineDrawingFigure(svg: string, alt: string): string;
57
66
  /**
58
67
  * Where the site build draws, below the package root.
59
68
  *
@@ -65,8 +74,7 @@ export const SITE_MAP_DIR: string;
65
74
  */
66
75
  export type SiteMap = {
67
76
  /**
68
- * - The file's name in the page's bundle, and the
69
- * value of the page's `map` key: `from-<shortcode>.svg`.
77
+ * - The file's name: `from-<shortcode>.svg`.
70
78
  */
71
79
  name: string;
72
80
  /**
@@ -164,6 +164,77 @@ export function prepareSqlTables(db: object, sources: Array<{
164
164
  }): Promise<Map<string, object[]>>;
165
165
  /** Evaluate scalar SQL calls before synchronous Markdown renderers run. */
166
166
  export function prepareInlineSqlExpressions(db: any, sources: any): Promise<Map<any, any>>;
167
+ /**
168
+ * Each note's generated sections — the derived lists and the event views — see
169
+ * {@link module:engine/generated-sections}.
170
+ *
171
+ * @param {object|undefined} db - From {@link openNotesDatabase}, over
172
+ * `records`; absent, no event view is asked for.
173
+ * @param {object[]} records - Content-index records, of the audience the
174
+ * surface publishes to.
175
+ * @param {string} contentBase - Root of the content tree.
176
+ * @param {object} [opts]
177
+ * @param {string} [opts.only] - One note file to give sections to; absent,
178
+ * every note.
179
+ * @param {Map<string, object>} [opts.foreignIndex] - The fetched indexes, whose
180
+ * places, affiliations and works the lists take in.
181
+ * @param {object} [opts.config] - The resolved configuration.
182
+ * @param {Map<string, Map<string, string>>} [opts.derived] - The derived
183
+ * lists, from an earlier call over the same records, which are not derived
184
+ * again.
185
+ * @returns {Promise<{sections: Map<string, string>, views: Set<string>,
186
+ * derived: Map<string, Map<string, string>>}>} Note file to its sections,
187
+ * joined in order; the files whose sections hold an event view's fence; and
188
+ * the derived lists alone.
189
+ */
190
+ export function generatedSectionsFor(db: object | undefined, records: object[], contentBase: string, { only, foreignIndex, config, derived: given }?: {
191
+ only?: string | undefined;
192
+ foreignIndex?: Map<string, object> | undefined;
193
+ config?: object | undefined;
194
+ derived?: Map<string, Map<string, string>> | undefined;
195
+ }): Promise<{
196
+ sections: Map<string, string>;
197
+ views: Set<string>;
198
+ derived: Map<string, Map<string, string>>;
199
+ }>;
200
+ /**
201
+ * Join each note's generated sections to its body among the sources a
202
+ * preparation answers, so the fences the event views hold are answered with
203
+ * the author's own, in order after them. A note whose sections hold a fence
204
+ * and whose body holds no directive of its own joins the sources, its body
205
+ * read as {@link prepareTreeSqlTables} reads one.
206
+ *
207
+ * The expansion every surface runs appends the same text again, from the
208
+ * `generated` {@link attachGeneratedSections} sets on the note's results —
209
+ * see {@link module:engine/content-tables.expandContentTables}.
210
+ *
211
+ * @param {{sections: Map<string, string>, views: Set<string>}} generated -
212
+ * From {@link generatedSectionsFor}.
213
+ * @param {Array<{source: string, markdown: string, frontmatter?: object}>} sources -
214
+ * The bodies to answer, extended in place.
215
+ * @returns {void}
216
+ */
217
+ export function joinGeneratedSections(generated: {
218
+ sections: Map<string, string>;
219
+ views: Set<string>;
220
+ }, sources: Array<{
221
+ source: string;
222
+ markdown: string;
223
+ frontmatter?: object;
224
+ }>): void;
225
+ /**
226
+ * Record each note's generated sections on its prepared results, where the
227
+ * table expansion reads them. A note with no results of its own is given an
228
+ * empty set carrying them.
229
+ *
230
+ * @param {Map<string, object[]>} prepared - From {@link prepareSqlTables}.
231
+ * @param {{sections: Map<string, string>}} generated - From
232
+ * {@link generatedSectionsFor}.
233
+ * @returns {void}
234
+ */
235
+ export function attachGeneratedSections(prepared: Map<string, object[]>, generated: {
236
+ sections: Map<string, string>;
237
+ }): void;
167
238
  /**
168
239
  * Answer every `sql` directive in a content tree.
169
240
  *
@@ -189,15 +260,19 @@ export function prepareInlineSqlExpressions(db: any, sources: any): Promise<Map<
189
260
  * A command that also builds a link index holds them already, and deriving
190
261
  * them twice is the duplicated-corpus failure this closes.
191
262
  * @param {"all"|"public"} [opts.audience] - Whether to exclude GM notes.
263
+ * @param {Map<string, object>} [opts.foreignIndex] - The fetched indexes the
264
+ * generated sections take in, where the caller holds them already; absent,
265
+ * they are read from the cache.
192
266
  * @returns {Promise<Map<string, object[]>|undefined>} Results by note path,
193
267
  * carrying `inline` and `pageLists` beside them, or nothing when the tree
194
- * holds no such directive.
268
+ * holds no such directive and no note is given a generated section.
195
269
  */
196
- export function prepareTreeSqlTables(contentBase: string, { config, skipDirectories, records, audience }?: {
270
+ export function prepareTreeSqlTables(contentBase: string, { config, skipDirectories, records, audience, foreignIndex }?: {
197
271
  config?: object | undefined;
198
272
  skipDirectories?: readonly string[] | undefined;
199
273
  records?: object[] | undefined;
200
274
  audience?: "all" | "public" | undefined;
275
+ foreignIndex?: Map<string, object> | undefined;
201
276
  }): Promise<Map<string, object[]> | undefined>;
202
277
  /**
203
278
  * Aliases the renderer reads rather than printing.