@heroiclands/package-build 22.15.1 → 22.16.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 +95 -0
- package/README.md +39 -678
- package/bin/{content-build.mjs → content-commands.mjs} +197 -118
- package/bin/package-build.mjs +303 -42
- package/bin/report.mjs +1 -1
- package/ci/ci-docker.mjs +6 -3
- package/ci/ci-steps.mjs +6 -4
- package/ci/content-format-reference.mjs +106 -0
- package/config.mjs +22 -2
- package/content-config.mjs +74 -134
- package/docs/api.md +294 -234
- package/docs/authoring/assets.md +31 -0
- package/docs/authoring/dates-and-calendars.md +33 -0
- package/docs/authoring/first-note.md +48 -0
- package/docs/authoring/frontmatter.md +40 -0
- package/docs/authoring/links-and-markup.md +137 -0
- package/docs/commands.md +631 -162
- package/docs/configuration.md +176 -140
- package/docs/content-format.md +50 -4229
- package/docs/design.md +32 -0
- package/docs/diagnostics.md +29 -22
- package/docs/getting-started.md +21 -877
- package/docs/guides/book.md +153 -0
- package/docs/guides/e2e.md +143 -0
- package/docs/guides/icons.md +126 -0
- package/docs/guides/localization.md +120 -0
- package/docs/guides/module-project.md +915 -0
- package/docs/guides/packs.md +167 -0
- package/docs/guides/reference-pages.md +148 -0
- package/docs/guides/release-and-deploy.md +114 -0
- package/docs/guides/site.md +152 -0
- package/docs/guides/system-project.md +45 -0
- package/docs/index.md +16 -0
- package/docs/project-setup.md +54 -35
- package/docs/reference/format-details.md +4420 -0
- package/docs/reference/note-types.md +531 -0
- package/engine/address-render.mjs +26 -0
- package/engine/address.mjs +3 -20
- package/engine/anchors.mjs +15 -6
- package/engine/asset-bindings.mjs +6 -2
- package/engine/base-compiler.mjs +47 -11
- package/engine/being-measurements.mjs +70 -0
- package/engine/calendar-artifacts.mjs +1 -1
- package/engine/calendar-choice.mjs +32 -0
- package/engine/calendar-human.mjs +71 -0
- package/engine/calendar-notes.mjs +41 -3
- package/engine/calendars.mjs +8 -1
- package/engine/changelog-lint.mjs +2 -2
- package/engine/code-fences.mjs +23 -97
- package/engine/compile-corpus.mjs +6 -7
- package/engine/content-admonitions.mjs +114 -0
- package/engine/content-captions.mjs +181 -0
- package/engine/content-embeds.mjs +2 -2
- package/engine/content-footnotes.mjs +34 -0
- package/engine/content-format-check.mjs +2 -2
- package/engine/content-format.mjs +127 -73
- package/engine/content-format.yaml +745 -0
- package/engine/content-html.mjs +1 -1
- package/engine/content-icons.mjs +45 -92
- package/engine/content-images.mjs +22 -74
- package/engine/content-index.mjs +12 -3
- package/engine/content-links.mjs +21 -26
- package/engine/content-lint.mjs +1 -5
- package/engine/content-secrets.mjs +3 -1
- package/engine/content-tables.mjs +47 -1257
- package/engine/culture-choice.mjs +32 -0
- package/engine/date-conversion.mjs +47 -0
- package/engine/declaration-check.mjs +87 -0
- package/engine/docs-checks.mjs +140 -0
- package/engine/documentation-links.mjs +31 -0
- package/engine/exported-scene.mjs +1 -1
- package/engine/extension-attributes.mjs +74 -0
- package/engine/field-reference.mjs +1 -1
- package/engine/field-spec.mjs +4 -0
- package/engine/foreign-catalog.mjs +5 -5
- package/engine/format-generated.mjs +15 -0
- package/engine/foundry-entries.mjs +3 -1
- package/engine/frontmatter-lint.mjs +5 -1
- package/engine/frontmatter.mjs +10 -0
- package/engine/generate.mjs +2 -2
- package/engine/helpers.mjs +71 -117
- package/engine/homepage.mjs +2 -3
- package/engine/index-records.mjs +1 -0
- package/engine/index.mjs +18 -3
- package/engine/infobox-registry.mjs +3 -1
- package/engine/infobox.mjs +38 -20
- package/engine/item-compiler.mjs +10 -8
- package/engine/item-docs.mjs +7 -6
- package/engine/journals.mjs +51 -10
- package/engine/macros.mjs +1 -1
- package/engine/map-build.mjs +1 -1
- package/engine/map-dot.mjs +1 -1
- package/engine/markdown-expressions.mjs +117 -0
- package/engine/metadata-index.mjs +7 -3
- package/engine/note-addresses.mjs +1 -0
- package/engine/note-dates.mjs +283 -61
- package/engine/note-package.mjs +5 -25
- package/engine/note-state.mjs +6 -2
- package/engine/note-vocabulary.mjs +74 -19
- package/engine/number-words.mjs +75 -0
- package/engine/office-holders.mjs +188 -0
- package/engine/pack-config.mjs +2 -15
- package/engine/pack-router.mjs +24 -5
- package/engine/packages.mjs +3 -2
- package/engine/pathnames.mjs +21 -24
- package/engine/pdf-build.mjs +217 -55
- package/engine/pdf-fonts.mjs +2 -2
- package/engine/pdf-images.mjs +82 -0
- package/engine/pdf-render.mjs +174 -22
- package/engine/populations.mjs +3 -2
- package/engine/project-init.mjs +499 -0
- package/engine/prose-config.mjs +1 -1
- package/engine/prose-lint.mjs +7 -6
- package/engine/readability-lint.mjs +86 -0
- package/engine/reckoning-markers.mjs +205 -93
- package/engine/scenes.mjs +5 -2
- package/engine/schema-check.mjs +3 -3
- package/engine/site-build.mjs +87 -37
- package/engine/site-config.mjs +8 -8
- package/engine/site-index.mjs +4 -0
- package/engine/site-maps.mjs +1 -1
- package/engine/site-preview.mjs +19 -8
- package/engine/social-ties.mjs +5 -1
- package/engine/sql-tables.mjs +92 -22
- package/engine/web-wikilinks.mjs +15 -31
- package/engine/wikilink-syntax.mjs +4 -1
- package/engine/wikilinks.mjs +12 -14
- package/hm3/item-fields.mjs +1 -1
- package/hm3/items.mjs +12 -45
- package/index.mjs +2 -14
- package/manifest.mjs +31 -4
- package/markdownlint-config.mjs +1 -1
- package/package.json +32 -11
- package/prettier-config.mjs +1 -1
- package/sohl/being-info.mjs +3 -145
- package/sohl/index.mjs +1 -1
- package/sohl/infobox.mjs +2 -1
- package/sohl/item-builders.mjs +3 -27
- package/sohl/item-fields.mjs +61 -22
- package/sohl/kb-passes.mjs +2 -2
- package/sohl/note-schemas.mjs +0 -8
- package/stage.mjs +19 -0
- package/types/config.d.mts +12 -3
- package/types/content-config.d.mts +15 -81
- package/types/engine/address-render.d.mts +13 -0
- package/types/engine/address.d.mts +2 -11
- package/types/engine/anchors.d.mts +3 -4
- package/types/engine/asset-bindings.d.mts +9 -2
- package/types/engine/base-compiler.d.mts +1 -2
- package/types/engine/being-measurements.d.mts +16 -0
- package/types/engine/calendar-choice.d.mts +14 -0
- package/types/engine/calendar-human.d.mts +4 -0
- package/types/engine/calendar-notes.d.mts +2 -0
- package/types/engine/calendars.d.mts +5 -3
- package/types/engine/code-fences.d.mts +6 -72
- package/types/engine/compile-corpus.d.mts +1 -3
- package/types/engine/content-admonitions.d.mts +24 -0
- package/types/engine/content-captions.d.mts +45 -0
- package/types/engine/content-footnotes.d.mts +10 -0
- package/types/engine/content-format-check.d.mts +17 -4
- package/types/engine/content-format.d.mts +24 -11
- package/types/engine/content-icons.d.mts +14 -23
- package/types/engine/content-images.d.mts +2 -2
- package/types/engine/content-index.d.mts +9 -2
- package/types/engine/content-links.d.mts +3 -5
- package/types/engine/content-tables.d.mts +11 -140
- package/types/engine/culture-choice.d.mts +14 -0
- package/types/engine/date-conversion.d.mts +4 -0
- package/types/engine/declaration-check.d.mts +24 -0
- package/types/engine/docs-checks.d.mts +28 -0
- package/types/engine/documentation-links.d.mts +7 -0
- package/types/engine/exported-scene.d.mts +6 -2
- package/types/engine/extension-attributes.d.mts +14 -0
- package/types/engine/field-spec.d.mts +9 -0
- package/types/engine/format-generated.d.mts +7 -0
- package/types/engine/frontmatter.d.mts +14 -4
- package/types/engine/generate.d.mts +1 -1
- package/types/engine/helpers.d.mts +37 -92
- package/types/engine/homepage.d.mts +2 -3
- package/types/engine/index.d.mts +5 -0
- package/types/engine/infobox-registry.d.mts +3 -1
- package/types/engine/infobox.d.mts +17 -6
- package/types/engine/item-compiler.d.mts +4 -4
- package/types/engine/item-docs.d.mts +4 -3
- package/types/engine/journals.d.mts +10 -7
- package/types/engine/map-graphviz.d.mts +1 -1
- package/types/engine/markdown-expressions.d.mts +17 -0
- package/types/engine/note-dates.d.mts +47 -1
- package/types/engine/note-package.d.mts +3 -19
- package/types/engine/note-state.d.mts +2 -1
- package/types/engine/note-vocabulary.d.mts +9 -0
- package/types/engine/number-words.d.mts +4 -0
- package/types/engine/office-holders.d.mts +14 -0
- package/types/engine/pack-config.d.mts +1 -1
- package/types/engine/packages.d.mts +3 -2
- package/types/engine/pdf-images.d.mts +38 -0
- package/types/engine/populations.d.mts +2 -2
- package/types/engine/project-init.d.mts +17 -0
- package/types/engine/prose-config.d.mts +1 -1
- package/types/engine/prose-lint.d.mts +3 -2
- package/types/engine/readability-lint.d.mts +22 -0
- package/types/engine/reckoning-markers.d.mts +4 -2
- package/types/engine/schema-check.d.mts +3 -3
- package/types/engine/site-build.d.mts +38 -28
- package/types/engine/site-config.d.mts +2 -2
- package/types/engine/site-index.d.mts +4 -0
- package/types/engine/site-preview.d.mts +1 -1
- package/types/engine/social-ties.d.mts +8 -2
- package/types/engine/sql-tables.d.mts +13 -2
- package/types/engine/web-wikilinks.d.mts +2 -1
- package/types/engine/wikilinks.d.mts +7 -1
- package/types/hm3/items.d.mts +5 -6
- package/types/labels.d.mts +40 -0
- package/types/manifest.d.mts +3 -3
- package/types/sohl/actors.d.mts +2 -2
- package/types/sohl/being-info.d.mts +3 -43
- package/types/sohl/index.d.mts +1 -1
- package/types/sohl/infobox.d.mts +5 -2
- package/types/sohl/item-fields.d.mts +4 -13
- package/types/stage.d.mts +9 -0
- package/CONTENT.md +0 -3239
package/docs/api.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
shortcode: api
|
|
3
|
+
name: { full: "API reference" }
|
|
4
|
+
type: doc
|
|
5
|
+
subType: reference
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# API reference
|
|
2
9
|
|
|
3
10
|
`@heroiclands/package-build` exposes its programmatic surface through
|
|
@@ -111,6 +118,16 @@ Deterministic document ids, derived by hashing rather than stored, so compile pa
|
|
|
111
118
|
| `compendiumUuid` | `compendiumUuid(packageId, type, id, packName)` | `string` — `Compendium.<packageId>.<pack>.<DocumentType>.<id>` | composing a document's full compendium UUID in the one place it is spelled |
|
|
112
119
|
| `pageUuid` | `pageUuid(entryUuid, pageId)` | `string` — the page's UUID | composing the UUID of a JournalEntry page |
|
|
113
120
|
|
|
121
|
+
### `engine.formatGenerated`
|
|
122
|
+
|
|
123
|
+
`formatGenerated(text, filepath)` returns a promise for text formatted with
|
|
124
|
+
the Prettier configuration that applies to the destination path. Generators
|
|
125
|
+
can write the result directly without introducing formatting drift.
|
|
126
|
+
|
|
127
|
+
| Export | Signature | Returns | Use it when |
|
|
128
|
+
| ----------------- | --------------------------------- | ----------------- | ----------------------------- |
|
|
129
|
+
| `formatGenerated` | `formatGenerated(text, filepath)` | `Promise<string>` | writing a generated text file |
|
|
130
|
+
|
|
114
131
|
### `engine.systemBlock`
|
|
115
132
|
|
|
116
133
|
The per-system frontmatter block: how one note feeds more than one game system through properties named after that system (`<system>.system`, `<system>.type`, `<system>.img`, `<system>.items` on actors). Resolves a field's value through the block, the shared top level, and a retiring position in that order, and merges an authored `<system>.system` onto a compiler-built one without disturbing what the builder already wrote.
|
|
@@ -146,7 +163,7 @@ Where code lives in a markdown body, so a rewriter can leave it alone. Every bui
|
|
|
146
163
|
| Export | Signature | Returns | Use it when |
|
|
147
164
|
| --------------------- | ---------------------------------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
148
165
|
| `FENCE_LINE` | `const FENCE_LINE` | — | matching a fence line, capturing its indent, marker, and info string |
|
|
149
|
-
| `parseHeaderArgs` | `parseHeaderArgs(info)` | `{language, args}`
|
|
166
|
+
| `parseHeaderArgs` | `parseHeaderArgs(info)` | `{language, args, problems}` | reading a fence's language and braced attributes |
|
|
150
167
|
| `codeRegions` | `codeRegions(markdown, ...)` | `Array<{start, end}>` | getting every code region in a markdown body as character offsets |
|
|
151
168
|
| `replaceOutsideCode` | `replaceOutsideCode(markdown, pattern, replacer, options)` | `string` — the rewritten body | running `String.prototype.replace` while skipping anything inside code |
|
|
152
169
|
| `matchAllOutsideCode` | `matchAllOutsideCode(markdown, pattern, options)` | `Array<RegExpMatchArray>` | running `String.prototype.matchAll` while skipping anything inside code |
|
|
@@ -335,6 +352,7 @@ The closed half of a note's frontmatter: the `data:` container and each type's `
|
|
|
335
352
|
| Export | Signature | Returns | Use it when |
|
|
336
353
|
| ------------------------- | -------------------------------------------- | ---------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
337
354
|
| `DRAFT_TAG` | `const DRAFT_TAG` | — | naming the declared tag that marks a note as unfinished |
|
|
355
|
+
| `GM_TAG` | `const GM_TAG` | — | naming the declared tag that marks a GM-only note |
|
|
338
356
|
| `NOTE_VOCABULARY` | `const NOTE_VOCABULARY` | — | looking up, per content type, its `data:` field list and its closed `subType` values |
|
|
339
357
|
| `SHARED_DATA_FIELDS` | `const SHARED_DATA_FIELDS` | `readonly DataFieldSpec[]` | reading the `data:` keys every type accepts, whatever it is — the art slots legal everywhere |
|
|
340
358
|
| `DECLARED_TAGS` | `const DECLARED_TAGS` | — | looking up the tags a note type may declare, grouped |
|
|
@@ -343,6 +361,7 @@ The closed half of a note's frontmatter: the `data:` container and each type's `
|
|
|
343
361
|
| `exclusiveTagGroups` | `exclusiveTagGroups(type, groups)` | `Array<{slot, tags}>` | reading the single-valued tag slots a note type has, such as a being's kind |
|
|
344
362
|
| `hasTag` | `hasTag(fm, tag)` | `boolean` | checking whether a note carries a given tag, whatever scalar-or-list form it was authored in |
|
|
345
363
|
| `isDraftNote` | `isDraftNote(fm)` | `boolean` | checking whether a note is tagged as an unfinished draft |
|
|
364
|
+
| `isGmNote` | `isGmNote(fm)` | `boolean` | checking whether a note is restricted to GM-facing output |
|
|
346
365
|
| `subTypeCharsetMessage` | `subTypeCharsetMessage(value)` | `string` | building the message for a `subType` outside the address charset |
|
|
347
366
|
| `typeCharsetMessage` | `typeCharsetMessage(type)` | `string` | building the message for a `type` outside the address charset |
|
|
348
367
|
| `assertVocabularyCharset` | `assertVocabularyCharset(vocabulary, where)` | throws | refusing a vocabulary declaration whose type or subType breaks the address charset |
|
|
@@ -423,7 +442,7 @@ The three states of a note — **stub**, **draft**, **full** — and the one obs
|
|
|
423
442
|
| `journalHasContent` | `journalHasContent(body)` | `boolean` | asking whether the JournalEntry a body compiles into would hold anything, which is what decides whether one is made at all |
|
|
424
443
|
| `PLACEHOLDER_PHRASES` | `const PLACEHOLDER_PHRASES` | `ReadonlyArray<string>` | reading the phrases that stand in for prose nobody has written |
|
|
425
444
|
| `placeholderBody` | `placeholderBody(body)` | `Array<{phrase: string, line: number}>` | finding a body that reduces to nothing but placeholders, which is an abandoned draft rather than a stub |
|
|
426
|
-
| `bodyWordCount` | `bodyWordCount(body)` | `number` | counting
|
|
445
|
+
| `bodyWordCount` | `bodyWordCount(body)` | `number` | counting rendered prose, with wikilinks as one word and closed dashes, slashes, and ellipses separating adjacent words |
|
|
427
446
|
|
|
428
447
|
### `engine.draftNotice`
|
|
429
448
|
|
|
@@ -471,7 +490,7 @@ What a place is next to (`data.borders`) and reachable from (`data.routes`): the
|
|
|
471
490
|
|
|
472
491
|
### `engine.holdings`
|
|
473
492
|
|
|
474
|
-
What lies within a place, who holds it, and what an affiliation holds — read off `data.parents` and `data.domains` across this package and every fetched index, inverted into the `contains`, `held_by` and `holdings` lists the site build writes — and the tenure check `
|
|
493
|
+
What lies within a place, who holds it, and what an affiliation holds — read off `data.parents` and `data.domains` across this package and every fetched index, inverted into the `contains`, `held_by` and `holdings` lists the site build writes — and the tenure check `package-build lint` runs on a place.
|
|
475
494
|
|
|
476
495
|
| Export | Signature | Returns | Use it when |
|
|
477
496
|
| ---------------------- | ------------------------------------ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -485,7 +504,7 @@ What lies within a place, who holds it, and what an affiliation holds — read o
|
|
|
485
504
|
|
|
486
505
|
### `engine.populations`
|
|
487
506
|
|
|
488
|
-
Whether a world's population figures agree from the region down — the polities and regions inside a place against what it states, a settlement against every place containing it, and a `doc` note's cited figures against the notes that own them. `
|
|
507
|
+
Whether a world's population figures agree from the region down — the polities and regions inside a place against what it states, a settlement against every place containing it, and a `doc` note's cited figures against the notes that own them. `package-build lint` runs all four as warnings.
|
|
489
508
|
|
|
490
509
|
| Export | Signature | Returns | Use it when |
|
|
491
510
|
| ----------------------- | ---------------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
@@ -545,7 +564,7 @@ The geometry of the map from a place and of the chart from one, as arithmetic ov
|
|
|
545
564
|
|
|
546
565
|
### `engine.mapDot`
|
|
547
566
|
|
|
548
|
-
The drawings of `
|
|
567
|
+
The drawings of `package-build map` as DOT text, sharing one style table: shape, colour and size by `subType`, an anomaly overriding colour alone, every label a `name.full`, every tooltip an address, and a `URL` where the place carries one so the SVG's names are links.
|
|
549
568
|
|
|
550
569
|
| Export | Signature | Returns | Use it when |
|
|
551
570
|
| ------------ | -------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
@@ -567,7 +586,7 @@ The npm-installed Graphviz runtime draws SVG maps and supplies the plain positio
|
|
|
567
586
|
|
|
568
587
|
### `engine.mapBuild`
|
|
569
588
|
|
|
570
|
-
`
|
|
589
|
+
`package-build map` as a function: drawings written under an output directory, with each `.dot` beside its `.svg` and tree anomalies returned as findings.
|
|
571
590
|
|
|
572
591
|
| Export | Signature | Returns | Use it when |
|
|
573
592
|
| --------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------- | ----------------------------------------------------------------------------- |
|
|
@@ -578,7 +597,7 @@ The npm-installed Graphviz runtime draws SVG maps and supplies the plain positio
|
|
|
578
597
|
|
|
579
598
|
### `engine.siteMaps`
|
|
580
599
|
|
|
581
|
-
The map from each place, drawn for the site: `
|
|
600
|
+
The map from each place, drawn for the site: `package-build site` draws the map from every place of this package that states, or is named in, a border or a route — with the site's base, so every name links through it — and the page writer lays each drawing beside its page as `from-<shortcode>.svg` and names it in the front matter as `map`. `site.maps: false` draws none.
|
|
582
601
|
|
|
583
602
|
| Export | Signature | Returns | Use it when |
|
|
584
603
|
| -------------- | ------------------------------------------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------- |
|
|
@@ -612,6 +631,7 @@ The neutral day spelling is `<year>.<day>[:HHMMSS]`. The pure conversion functio
|
|
|
612
631
|
| ------------------------- | ---------------------------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------- |
|
|
613
632
|
| `CANONICAL_EPOCH` | `const CANONICAL_EPOCH` | — | naming where the canonical axis's own year 1 sits |
|
|
614
633
|
| `canonicalYear` | `canonicalYear(year, epoch?)` | `number` — the signed year on the axis | converting a year written in one reckoning to the number everything compares on |
|
|
634
|
+
| `eraYear` | `eraYear(canonical, epoch?)` | signed era year without zero | printing a canonical year in a chosen reckoning |
|
|
615
635
|
| `dateSortKey` | `dateSortKey(year, month, day)` | `number` | ordering mixed-precision dates against a single number |
|
|
616
636
|
| `calendarStructure` | `calendarStructure(calendar)` | `{months}` — `null` where unstated | reading the months a calendar keeps, before phrasing a finding |
|
|
617
637
|
| `daysInMonth` | `daysInMonth(calendar, month)` | `number` — `null` where unstated | bounding a written day against the month it names |
|
|
@@ -627,23 +647,65 @@ The neutral day spelling is `<year>.<day>[:HHMMSS]`. The pure conversion functio
|
|
|
627
647
|
|
|
628
648
|
### `engine.noteDates`
|
|
629
649
|
|
|
630
|
-
A date on a note is one authored string. `<year>.<day>[:HHMMSS]` names a calendar-neutral day; `VR
|
|
650
|
+
A date on a note is one authored string. `<year>.<day>[:HHMMSS]` names a calendar-neutral day; `datefrom vrcal 23 Taranis 326 VR` names a calendar, a named month, and an era. Either form may begin with `~` for an approximate date. A resolved calendar date carries a canonical year, day, span and sort key. Print `prose ?? text`, order on `sort`, and do arithmetic on `canonicalYear`. The literal `unknown` has no sort key or canonical year. `resolvedDateFields` supplies identical derived records to JSONL and generated page frontmatter.
|
|
651
|
+
|
|
652
|
+
| Export | Signature | Returns | Use it when |
|
|
653
|
+
| ----------------------- | ------------------------------------------------ | -------------------------------------------------- | -------------------------------------------------------------- |
|
|
654
|
+
| `UNKNOWN_DATE` | `const UNKNOWN_DATE` | — | naming the literal that says a date is not recorded |
|
|
655
|
+
| `NOTE_DATE_PATTERN` | `const NOTE_DATE_PATTERN` | — | matching the date grammar directly |
|
|
656
|
+
| `DATEFROM_PATTERN` | `const DATEFROM_PATTERN` | — | recognizing a named calendar conversion in frontmatter |
|
|
657
|
+
| `ERA_QUALIFIER_PATTERN` | `const ERA_QUALIFIER_PATTERN` | — | checking that a string is an era qualifier a date could carry |
|
|
658
|
+
| `parseNoteDate` | `parseNoteDate(value, options)` | `{date, findings}` — `date` is `null` when refused | reading a note's authored date, with every finding it earned |
|
|
659
|
+
| `eraCovering` | `eraCovering(date, eras, daysPerYear)` | one era or `null`; throws on overlap | selecting the era covering a resolved date's full precision |
|
|
660
|
+
| `formatNoteDate` | `formatNoteDate(date, era, daysPerYear)` | `{era, year, month, day, text, prose}` or `null` | printing a resolved date in a chosen era or its authored form |
|
|
661
|
+
| `formatDateInCalendar` | `formatDateInCalendar(date, reference, context)` | printable record or `null` | selecting a calendar's era and printing a resolved date in it |
|
|
662
|
+
| `calendarEras` | `calendarEras(reference, context)` | ordered era records | resolving an addressed calendar or one of its eras |
|
|
663
|
+
| `resolvedDateFields` | `resolvedDateFields(fm, context)` | map of normalized dates | deriving being and lore event date records for index and pages |
|
|
664
|
+
|
|
665
|
+
### `engine.dateConversion`
|
|
666
|
+
|
|
667
|
+
The exact-day conversion functions use the corpus reckoning context. A calendar with several eras requires an era in the named date. They reject dates outside the selected calendar and gaps between its eras. Approximate input keeps its `~` prefix in the result.
|
|
668
|
+
|
|
669
|
+
| Export | Signature | Returns | Use it when |
|
|
670
|
+
| ------------------ | --------------------------------------------------- | --------------------- | --------------------------------------------- |
|
|
671
|
+
| `dateFromCalendar` | `dateFromCalendar(reference, value, context)` | canonical date string | converting one calendar day to the world axis |
|
|
672
|
+
| `dateToCalendar` | `dateToCalendar(reference, canonicalDate, context)` | calendar date string | expressing one canonical day in a calendar |
|
|
673
|
+
|
|
674
|
+
### `engine.calendarChoice`
|
|
675
|
+
|
|
676
|
+
`checkCalendarChoice(note, { index })` checks that an explicitly selected calendar Address on a being or place resolves to a calendar note.
|
|
677
|
+
|
|
678
|
+
| Export | Signature | Returns | Use it when |
|
|
679
|
+
| --------------------- | ------------------------------------ | -------- | ----------------------------------------------- |
|
|
680
|
+
| `checkCalendarChoice` | `checkCalendarChoice(note, options)` | findings | validating a being's or place's chosen calendar |
|
|
681
|
+
|
|
682
|
+
### `engine.cultureChoice`
|
|
683
|
+
|
|
684
|
+
`checkCultureChoice(note, { index })` checks that a being's `data.culture`
|
|
685
|
+
Address resolves to a lore note with `subType: culture`. The being vocabulary
|
|
686
|
+
invokes the check during frontmatter lint.
|
|
687
|
+
|
|
688
|
+
| Export | Signature | Returns | Use it when |
|
|
689
|
+
| -------------------- | ----------------------------------- | -------- | ----------------------------------------- |
|
|
690
|
+
| `checkCultureChoice` | `checkCultureChoice(note, options)` | findings | validating a being's primary culture note |
|
|
691
|
+
|
|
692
|
+
### `engine.markdownExpressions`
|
|
693
|
+
|
|
694
|
+
`renderMarkdownExpressions(body, { fm, dates, sqlResults, file, bodyLine })` expands scalar frontmatter references and registered Handlebars helpers outside Markdown code. The `dateformat` helper uses `formatDateInCalendar`; `gt`, `gte`, `lt`, `lte`, `eq`, `and`, `or`, and `not` evaluate explicit comparisons. The `sql` helper reads a prepared scalar result, which must contain one row and one column. `sqlQueriesInMarkdown` discovers SQL calls, including nested calls; `prepareInlineSqlExpressions` evaluates them through the same DuckDB connection as SQL tables. The renderer returns `{ markdown, findings }`, with source positions for invalid expressions. Site, Foundry and PDF passes invoke it after generated tables expand and before links resolve. Hugo shortcodes remain literal for the site renderer.
|
|
631
695
|
|
|
632
|
-
| Export
|
|
633
|
-
|
|
|
634
|
-
| `
|
|
635
|
-
| `
|
|
636
|
-
| `ERA_QUALIFIER_PATTERN` | `const ERA_QUALIFIER_PATTERN` | — | checking that a string is an era qualifier a date could carry |
|
|
637
|
-
| `parseNoteDate` | `parseNoteDate(value, options)` | `{date, findings}` — `date` is `null` when refused | reading a note's authored date, with every finding it earned |
|
|
696
|
+
| Export | Signature | Returns | Use it when |
|
|
697
|
+
| --------------------------- | ------------------------------------------ | ---------------------- | ----------------------------------------------- |
|
|
698
|
+
| `renderMarkdownExpressions` | `renderMarkdownExpressions(body, options)` | `{markdown, findings}` | expanding authored expressions in prose |
|
|
699
|
+
| `sqlQueriesInMarkdown` | `sqlQueriesInMarkdown(body)` | query strings | preparing inline SQL alongside generated tables |
|
|
638
700
|
|
|
639
701
|
### `engine.reckoningMarkers`
|
|
640
702
|
|
|
641
|
-
The corpus registry maps
|
|
703
|
+
The corpus registry maps every declared era to its calendar and each marker to exactly one era. Era starts may use the canonical axis or another declared era. Within one calendar, starts increase; the next start bounds the preceding era unless an explicit end leaves a gap. The first era also covers dates before its start and counts them with negative years. Later eras accept only forward year counts. Unknown eras, duplicate markers, invalid bounds, overlapping eras and dependency cycles are findings. Short qualifiers are ambiguous when they name eras in several packages; a full address selects one. This registry governs note dates; calendar definitions emitted for Foundry retain their consumer format.
|
|
642
704
|
|
|
643
|
-
| Export | Signature | Returns
|
|
644
|
-
| ------------------------- | --------------------------------------------- |
|
|
645
|
-
| `resolveReckoningMarkers` | `resolveReckoningMarkers(index, daysPerYear)` | `{markers, findings}` | resolving authored
|
|
646
|
-
| `reckoningContext` | `reckoningContext(index)` | `{markers, daysPerYear, findings}` | sharing one resolved date context across checks on a corpus |
|
|
705
|
+
| Export | Signature | Returns | Use it when |
|
|
706
|
+
| ------------------------- | --------------------------------------------- | ---------------------------------------- | ----------------------------------------------------------- |
|
|
707
|
+
| `resolveReckoningMarkers` | `resolveReckoningMarkers(index, daysPerYear)` | `{eras, markers, findings}` | resolving authored eras, their markers, and their bounds |
|
|
708
|
+
| `reckoningContext` | `reckoningContext(index)` | `{eras, markers, daysPerYear, findings}` | sharing one resolved date context across checks on a corpus |
|
|
647
709
|
|
|
648
710
|
### `engine.calendarNotes`
|
|
649
711
|
|
|
@@ -672,7 +734,7 @@ A calendar is a `lore` note with `subType: calendar`, declaring the months it ke
|
|
|
672
734
|
calendar files under `build/calendars/`. Each calendar produces a definition
|
|
673
735
|
and an import envelope containing that same definition. The command line entry
|
|
674
736
|
point is `package-build calendars --calendaria-version <version>`; run
|
|
675
|
-
`
|
|
737
|
+
`package-build content-index` first. The generated import envelope carries a
|
|
676
738
|
fixed ISO `exportedAt` sentinel so repeated builds of unchanged source emit
|
|
677
739
|
identical bytes.
|
|
678
740
|
|
|
@@ -761,52 +823,52 @@ The shortcodes a note declares it used to be published under. A package's `(type
|
|
|
761
823
|
|
|
762
824
|
The published content index — the artifact packages exchange addresses through. **A package publishes its own index; a consumer fetches the ones it depends on.** That is the whole mechanism, and it replaces a vendored link manifest that each repository committed a copy of every other repository's file into. Vendoring failed three ways, and only the last is about staleness:
|
|
763
825
|
|
|
764
|
-
| Export | Signature | Returns
|
|
765
|
-
| ------------------------------ | ---------------------------------------------------------- |
|
|
766
|
-
| `METADATA_RELATIONSHIP_KINDS` | `const METADATA_RELATIONSHIP_KINDS` | —
|
|
767
|
-
| `metadataFileName` | `function metadataFileName(pkg)` | {string} The file name, e.g.
|
|
768
|
-
| `metadataRelationships` | `function metadataRelationships(config)` | {Array<{id: string, manifest: string, kind: string, verified: string\|undefined}>} The dependencies, in declaration order.
|
|
769
|
-
| `noContentIndexPackages` | `function noContentIndexPackages(config)` | {ReadonlySet<string>} The content package names.
|
|
770
|
-
| `metadataCacheDir` | `function metadataCacheDir(config, id, version)` | {string} The directory.
|
|
771
|
-
| `isComplete` | `const isComplete` | {boolean} True when it was fetched to completion.
|
|
772
|
-
| `markComplete` | `function markComplete(dir)` | {void}
|
|
773
|
-
| `cachedMetadataFiles` | `function cachedMetadataFiles(config)` | {string[]} One index file per declared dependency.
|
|
774
|
-
| `cachedMetadataIndexes` | `function cachedMetadataIndexes(config)` | {Array<{id: string, file: string}>} One entry per declared dependency.
|
|
775
|
-
| `newestVersionDir` | `function newestVersionDir(dirs)` | {string} The newest one.
|
|
776
|
-
| `loadForeignIndexes` | `function loadForeignIndexes(config, localPackages, bases` | {{index: Map<string, object>, packages: Set<string>, stale: Array<{package: string, reason: string}>}} The resolved addresses, which packages contributed, and what could not be read. | Resolve every foreign address this build can cite, from the fetched indexes. |
|
|
777
|
-
| `cachedIndexPath` | `function cachedIndexPath(config, pkg)` | {string} A path to name in a diagnostic.
|
|
778
|
-
| `unaddressableForeignPackages` | `function unaddressableForeignPackages(foreignIndex)` | {Array<{package: string, entries: number, sampleKey: string}>} One finding per drifted package, in the order the index first names each.
|
|
779
|
-
| `formatUnaddressableFinding` | `function formatUnaddressableFinding(finding, config)` | {string} The formatted diagnostic, path first on the line.
|
|
826
|
+
| Export | Signature | Returns | Use it when |
|
|
827
|
+
| ------------------------------ | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
828
|
+
| `METADATA_RELATIONSHIP_KINDS` | `const METADATA_RELATIONSHIP_KINDS` | — | The relationship kinds that are dependencies, and therefore citable. |
|
|
829
|
+
| `metadataFileName` | `function metadataFileName(pkg)` | {string} The file name, e.g. | What a package's content index is called, wherever it is written or fetched. |
|
|
830
|
+
| `metadataRelationships` | `function metadataRelationships(config)` | {Array<{id: string, manifest: string, kind: string, verified: string\|undefined}>} The dependencies, in declaration order. | Every dependency whose published index this build resolves addresses through. |
|
|
831
|
+
| `noContentIndexPackages` | `function noContentIndexPackages(config)` | {ReadonlySet<string>} The content package names. | Every package a relationship declares `contentIndex: false` on, keyed by the content package name a link into it would use. |
|
|
832
|
+
| `metadataCacheDir` | `function metadataCacheDir(config, id, version)` | {string} The directory. | The cache directory for one dependency's index at one version. |
|
|
833
|
+
| `isComplete` | `const isComplete` | {boolean} True when it was fetched to completion. | Whether a dependency's cache is present and complete. |
|
|
834
|
+
| `markComplete` | `function markComplete(dir)` | {void} | Mark a dependency's cache complete. |
|
|
835
|
+
| `cachedMetadataFiles` | `function cachedMetadataFiles(config)` | {string[]} One index file per declared dependency. | The fetched index files this build resolves foreign addresses against. |
|
|
836
|
+
| `cachedMetadataIndexes` | `function cachedMetadataIndexes(config)` | {Array<{id: string, file: string}>} One entry per declared dependency. | The same fetched indexes, each paired with the package that published it. |
|
|
837
|
+
| `newestVersionDir` | `function newestVersionDir(dirs)` | {string} The newest one. | The newest cached version among several version-keyed cache directories. |
|
|
838
|
+
| `loadForeignIndexes` | `function loadForeignIndexes(config, localPackages, bases` | `{{index: Map<string, object>, packages: Set<string>, stale: Array<{package: string, reason: string}>}}` The resolved addresses, which packages contributed, and what could not be read. | Resolve every foreign address this build can cite, from the fetched indexes. |
|
|
839
|
+
| `cachedIndexPath` | `function cachedIndexPath(config, pkg)` | {string} A path to name in a diagnostic. | Where a dependency's fetched index sits, for naming it in a diagnostic. |
|
|
840
|
+
| `unaddressableForeignPackages` | `function unaddressableForeignPackages(foreignIndex)` | {Array<{package: string, entries: number, sampleKey: string}>} One finding per drifted package, in the order the index first names each. | Whether a fetched index can still be _addressed_, as distinct from read. |
|
|
841
|
+
| `formatUnaddressableFinding` | `function formatUnaddressableFinding(finding, config)` | {string} The formatted diagnostic, path first on the line. | One finding, in the standard `file:line:column: severity: message` form. |
|
|
780
842
|
|
|
781
843
|
### `engine.foundryEntries`
|
|
782
844
|
|
|
783
845
|
Emitting this package's cross-package link manifest. `engine/content-address.mjs` owns the address _grammar_ — how a key is version is read, how a foreign file resolves. This module owns the _pass_: walking a content tree and deriving, for every note it publishes, the addresses that entry states. The two halves were split across the format module and a hand-written script in each consuming repository, which is how the two scripts came to differ in ways nobody chose — one routes its UUIDs through the pack router and one does not, and neither knew.
|
|
784
846
|
|
|
785
|
-
| Export | Signature | Returns
|
|
786
|
-
| ----------------------- | ------------------------------------------------------- |
|
|
787
|
-
| `LEAD_ANCHOR` | `const LEAD_ANCHOR` | —
|
|
788
|
-
| `anchorsOf` | `function anchorsOf(entryUuid, entryId, body, name)` | {Record<string, string>} The anchors.
|
|
789
|
-
| `entriesForNote` | `function entriesForNote(fm, name, address, body, ctx)` | {Array<object>} One or two entries, in {@link buildManifest}'s shape.
|
|
790
|
-
| `collectFoundryEntries` | `function collectFoundryEntries(contentBase, ctx)` | {{entries: Array<object>, notes: number, skipped: Array<{file: string, reason: string}>}} | Every note this package publishes, as manifest entries. |
|
|
791
|
-
| `foundryIdentities` | `function foundryIdentities(config` | {{contentPackage: string, foundryPackageId: string, packRouter: object, web: boolean, skipDirectories: readonly string[]}} | The identities an emission runs against, from configuration. |
|
|
792
|
-
| `entryContext` | `function entryContext(config` | {{contentPackage: string, foundryPackageId: string, packRouter: object, web: boolean, skipDirectories: readonly string[]}} | The identities an emission runs against, from configuration. |
|
|
847
|
+
| Export | Signature | Returns | Use it when |
|
|
848
|
+
| ----------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
|
|
849
|
+
| `LEAD_ANCHOR` | `const LEAD_ANCHOR` | — | The reserved anchor name for a journal's **first** page. |
|
|
850
|
+
| `anchorsOf` | `function anchorsOf(entryUuid, entryId, body, name)` | {Record<string, string>} The anchors. | Every page of a note's journal, as `anchorName → whole UUID`. |
|
|
851
|
+
| `entriesForNote` | `function entriesForNote(fm, name, address, body, ctx)` | {Array<object>} One or two entries, in {@link buildManifest}'s shape. | The manifest entries a single note produces. |
|
|
852
|
+
| `collectFoundryEntries` | `function collectFoundryEntries(contentBase, ctx)` | `{{entries: Array<object>, notes: number, skipped: Array<{file: string, reason: string}>}}` | Every note this package publishes, as manifest entries. |
|
|
853
|
+
| `foundryIdentities` | `function foundryIdentities(config` | `{{contentPackage: string, foundryPackageId: string, packRouter: object, web: boolean, skipDirectories: readonly string[]}}` | The identities an emission runs against, from configuration. |
|
|
854
|
+
| `entryContext` | `function entryContext(config` | `{{contentPackage: string, foundryPackageId: string, packRouter: object, web: boolean, skipDirectories: readonly string[]}}` | The identities an emission runs against, from configuration. |
|
|
793
855
|
|
|
794
856
|
### `engine.contentIndex`
|
|
795
857
|
|
|
796
858
|
Emitting this package's content index. Every content build already walks the whole note tree and parses every note's frontmatter — the pack compilers, the site build, and the content-table expander each do it — and every one of them throws the result away when it finishes. So nothing outside a build can ask a question about the content: "which beings carry no `kbcat`?", "what does this table actually select?", "did that type rename leave anything behind?" have no answer short of writing a throwaway script that re-walks the tree. Eight dead Bestiary tables shipped for weeks behind exactly that gap.
|
|
797
859
|
|
|
798
|
-
| Export | Signature | Returns
|
|
799
|
-
| ----------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
800
|
-
| `noteAddress` | `function noteAddress(frontmatter, contentPackage)` | {{slug: string, canonical: string}\|null} `slug` is what goes inside `[[…]]` within this package; `canonical` is the fully qualified key the manifest files the note under, carrying the package and the system as well.
|
|
801
|
-
| `sortKeysDeep` | `function sortKeysDeep(value)` | {unknown} The value with every plain object's keys in sorted order.
|
|
802
|
-
| `asciiName` | `function asciiName(name)` | {string\|null} The ASCII form, or `null` when there is no name, or nothing printable survives.
|
|
803
|
-
| `asciiAliases` | `function asciiAliases(aliases)` | {Array<string>} Possibly empty, never null: a note with no aliases has an empty set of them, which is a fact rather than a missing value, and a consumer iterating it should not have to check first.
|
|
804
|
-
| `serializeContentIndex` | `function serializeContentIndex(records)` | {string} One compact JSON object per line, newline-terminated.
|
|
805
|
-
| `indexRecordsFor` | `indexRecordsFor({ contentBase, config, skipDirectories, problems })` | {object[]} One record per note, plus one per documentation entry.
|
|
806
|
-
| `indexRecordsForNote` | `indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absPath, contentPackage, manifest, addressContext })` | `object[]`
|
|
807
|
-
| `emitContentIndex` | `emitContentIndex({ contentBase, outDir, config })` | {{file: string, notes: number, assets: number, records: number, bytes: number, full: number, draft: number, stub: number}} Where it was written, how many notes and how many assets it holds, how many records that is in all, its size, and the ladder those notes sit on. | Emit this package's content index. |
|
|
808
|
-
| `buildIndexRecord` | `buildIndexRecord({ frontmatter, relPath, absPath, contentPackage, body, bodyLine, manifest })` | `Record<string, any>` — the record, with derived fields sorted deep
|
|
809
|
-
| `collectContentIndex` | `collectContentIndex(contentBase, { contentPackage, skipDirectories, assetsBase, manifest, problems })` | `Array<Record<string, any>>`
|
|
860
|
+
| Export | Signature | Returns | Use it when |
|
|
861
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
862
|
+
| `noteAddress` | `function noteAddress(frontmatter, contentPackage)` | {{slug: string, canonical: string}\|null} `slug` is what goes inside `[[…]]` within this package; `canonical` is the fully qualified key the manifest files the note under, carrying the package and the system as well. | The address a wikilink writes to reach a note, or `null` when it has none. |
|
|
863
|
+
| `sortKeysDeep` | `function sortKeysDeep(value)` | {unknown} The value with every plain object's keys in sorted order. | Recursively sort an object's keys, so serialization is order-independent. |
|
|
864
|
+
| `asciiName` | `function asciiName(name)` | {string\|null} The ASCII form, or `null` when there is no name, or nothing printable survives. | A note's display name reduced to printable 7-bit ASCII. |
|
|
865
|
+
| `asciiAliases` | `function asciiAliases(aliases)` | {Array<string>} Possibly empty, never null: a note with no aliases has an empty set of them, which is a fact rather than a missing value, and a consumer iterating it should not have to check first. | A note's `name.aliases` reduced to printable 7-bit ASCII, in order. |
|
|
866
|
+
| `serializeContentIndex` | `function serializeContentIndex(records)` | {string} One compact JSON object per line, newline-terminated. | Serialize records as JSON Lines. |
|
|
867
|
+
| `indexRecordsFor` | `indexRecordsFor({ contentBase, config, skipDirectories, problems })` | {object[]} One record per note, plus one per documentation entry. | The index records for a content tree, without writing anything. |
|
|
868
|
+
| `indexRecordsForNote` | `indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absPath, contentPackage, manifest, addressContext })` | `object[]` | Derive the note's own record and its documentation record from parsed text. |
|
|
869
|
+
| `emitContentIndex` | `emitContentIndex({ contentBase, outDir, config })` | `{{file: string, notes: number, assets: number, records: number, bytes: number, full: number, draft: number, stub: number}}` Where it was written, how many notes and how many assets it holds, how many records that is in all, its size, and the ladder those notes sit on. | Emit this package's content index. |
|
|
870
|
+
| `buildIndexRecord` | `buildIndexRecord({ frontmatter, relPath, absPath, contentPackage, body, bodyLine, manifest })` | `Record<string, any>` — the record, with derived fields sorted deep | building one note's content-index record; refuses a note that authors a key the index derives itself (`package` among them) before building anything |
|
|
871
|
+
| `collectContentIndex` | `collectContentIndex(contentBase, { contentPackage, skipDirectories, assetsBase, manifest, problems })` | `Array<Record<string, any>>` | reading a whole content tree into index records, in a total order independent of directory-read order; an item note yields two records (its own and its documentation journal's), and each asset root yields one per file |
|
|
810
872
|
|
|
811
873
|
`engine.contentIndex` also re-exports eight names from neighbouring leaf modules, at this same import path:
|
|
812
874
|
|
|
@@ -874,24 +936,27 @@ The toolchain's own content index — the files it ships, addressed. Every other
|
|
|
874
936
|
|
|
875
937
|
### `engine.siteBuild`
|
|
876
938
|
|
|
877
|
-
Publishing a content tree as a website.
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
|
883
|
-
|
|
|
884
|
-
| `
|
|
885
|
-
| `
|
|
886
|
-
| `
|
|
887
|
-
| `
|
|
888
|
-
| `
|
|
889
|
-
| `
|
|
890
|
-
| `
|
|
891
|
-
| `
|
|
892
|
-
| `
|
|
893
|
-
| `
|
|
894
|
-
| `
|
|
939
|
+
Publishing a content tree as a website. `collectContentPages` gathers authored
|
|
940
|
+
pages and link findings, while `collectHomepages` gathers package homepages.
|
|
941
|
+
`writeHomepages` places those homepages at each package's site root. The same
|
|
942
|
+
content tree can also compile into Foundry compendium packs.
|
|
943
|
+
|
|
944
|
+
| Export | Signature | Returns | Use it when |
|
|
945
|
+
| --------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
946
|
+
| `collectContentPages` | `function collectContentPages(contentBase, ctx)` | `{{pages: object[], addressFindings: object[], fmLinkFindings: object[]}}` | The content tree's pages, and what could not be addressed. |
|
|
947
|
+
| `collectHomepages` | `function collectHomepages(contentBase, ctx)` | `{{pages: object[], addressFindings: object[]}}` The homepage notes, in walk order, and the ones among them that could not be addressed. | The package's homepage notes — the authored page at `/<contentPackage>/`. |
|
|
948
|
+
| `writeHomepages` | `function writeHomepages(outRoot, pages, config)` | {number} How many pages were written. | Writes each homepage as the package root's `_index.md`. |
|
|
949
|
+
| `siteGates` | `function siteGates(pages, findings,` | {object} The gate results and, when they pass, the built index. | The integrity gates a site build runs before it writes anything. |
|
|
950
|
+
| `emptyGates` | `function emptyGates()` | {object} An all-clear gate result. | The gate result of a build that ran none of them. |
|
|
951
|
+
| `gatesFailed` | `function gatesFailed(gates)` | — | Whether any gate produced a finding. |
|
|
952
|
+
| `tableUniverse` | `function tableUniverse(pages)` | {Map<string, object[]>} Package → the notes it may tabulate. | The universe a generated table searches, grouped by package. |
|
|
953
|
+
| `pageFrontmatter` | `function pageFrontmatter(page,` | {object} The frontmatter to write. | The frontmatter a page publishes with. |
|
|
954
|
+
| `pageDestination` | `function pageDestination(page, { bundle })` | — | Where a page is written, relative to the output root: flat, or as a leaf bundle when it carries a file beside itself. |
|
|
955
|
+
| `renderSitePage` | `renderSitePage(page, options)` | `{body, data, resolved, tableErrors, secretErrors, wikiErrors, imageErrors}` | Transform one page with the same passes the site writer uses. |
|
|
956
|
+
| `renderPages` | `function renderPages(pages, options)` | `{{written: number, byKind: Record<string, number>, tableErrors: object[], wikiErrors: object[]}}` | Renders and writes every page. |
|
|
957
|
+
| `resolveSitePass` | `function resolveSitePass(name, options)` | `{{beforeLinks?: Function}}` The bundle. | Resolves `site.pass` to its bundle. |
|
|
958
|
+
| `sitePageDecorator` | `sitePageDecorator(config, index)` | Function | Add the site's infobox and being metadata to a rendered page. |
|
|
959
|
+
| `buildSite` | `buildSite({ config, sqlTables })` | `{{gates: object, stats: object\|null, tableErrors: object[], wikiErrors: object[], mapFindings: object[], manifests: object\|null}}` | Builds a Hugo content tree from a content tree, and reports what it found. |
|
|
895
960
|
|
|
896
961
|
### `engine.sitePreview`
|
|
897
962
|
|
|
@@ -923,96 +988,96 @@ try {
|
|
|
923
988
|
|
|
924
989
|
Linting a content tree's **addresses** — the rules every package's notes are authored against, wherever those notes live. These rules do not live in a consumer's `utils/`, which has two consequences and no upside. `thalorna` and `kethira` notes were checked by nothing at all, so the packages most likely to carry authoring mistakes were the ones nothing inspected. And one rule with two implementations can disagree without anything detecting it, which the canonical-separator handling already did once on each side.
|
|
925
990
|
|
|
926
|
-
| Export | Signature | Returns
|
|
927
|
-
| ------------------- | ---------------------------------------------------------------------------------------------- |
|
|
928
|
-
| `SHORTCODE_PATTERN` | `const SHORTCODE_PATTERN` | —
|
|
929
|
-
| `isValidShortcode` | `function isValidShortcode(value)` | {boolean} `true` when it matches {@link SHORTCODE_PATTERN}.
|
|
930
|
-
| `lintContentTree` | `lintContentTree(contentBase, { skipDirectories, contentPackage, config, records, problems })` | {{findings: Array<{file: string, line?: number, column?: number, severity: "error"\|"warning", message: string}>, notes: number, keys: number}} The findings, and what was inspected to produce them. | Lint every address in a content tree. |
|
|
991
|
+
| Export | Signature | Returns | Use it when |
|
|
992
|
+
| ------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
993
|
+
| `SHORTCODE_PATTERN` | `const SHORTCODE_PATTERN` | — | The shape every `shortcode` must match: ASCII letters and digits only. |
|
|
994
|
+
| `isValidShortcode` | `function isValidShortcode(value)` | {boolean} `true` when it matches {@link SHORTCODE_PATTERN}. | Whether a value is a well-formed shortcode. |
|
|
995
|
+
| `lintContentTree` | `lintContentTree(contentBase, { skipDirectories, contentPackage, config, records, problems })` | `{{findings: Array<{file: string, line?: number, column?: number, severity: "error"\|"warning", message: string}>, notes: number, keys: number}}` The findings, and what was inspected to produce them. | Lint every address in a content tree. |
|
|
931
996
|
|
|
932
997
|
### `engine.contentCharset`
|
|
933
998
|
|
|
934
999
|
The charset authored content is held to, so a book can choose its face. The packs and the website render in whatever font the reader's browser or Foundry supplies, and a glyph nobody has is somebody else's problem. **A book is not that.** A PDF embeds the faces it sets, so every character in the corpus is a claim on the book's typeface — and the claim is silent, which is what makes it expensive.
|
|
935
1000
|
|
|
936
|
-
| Export | Signature | Returns
|
|
937
|
-
| -------------------- | ------------------------------------------ |
|
|
938
|
-
| `isLetterTier` | `function isLetterTier(cp)` | {boolean} Whether Tier 1 admits it.
|
|
939
|
-
| `TYPOGRAPHY` | `const TYPOGRAPHY` | —
|
|
940
|
-
| `NOTATION` | `const NOTATION` | —
|
|
941
|
-
| `isAllowedCodePoint` | `function isAllowedCodePoint(cp)` | {boolean} Whether it is allowed outside a code fence.
|
|
942
|
-
| `isDiagramCodePoint` | `function isDiagramCodePoint(cp)` | {boolean} Whether a fence may carry it.
|
|
943
|
-
| `refusalFor` | `function refusalFor(cp)` | {string} A clause naming what it is and what to do instead.
|
|
944
|
-
| `decomposedRuns` | `function decomposedRuns(text)` | {Array<{sequence: string, composed: string, index: number}>} Each offending run, in the order it appears.
|
|
945
|
-
| `checkText` | `function checkText(text, file)` | {Array<{file: string, line: number, column: number, severity: "warning", message: string}>} What is wrong, in file order.
|
|
946
|
-
| `lintContentCharset` | `function lintContentCharset(contentBase,` | {{findings: Array<{file: string, line: number, column: number, severity: "warning", message: string}>, files: number}} The findings, and how many files produced them. | Walk a content tree and check every authored file in it. |
|
|
1001
|
+
| Export | Signature | Returns | Use it when |
|
|
1002
|
+
| -------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
|
|
1003
|
+
| `isLetterTier` | `function isLetterTier(cp)` | {boolean} Whether Tier 1 admits it. | Tier 1 — the letters, and the two whitespace characters a file is made of. |
|
|
1004
|
+
| `TYPOGRAPHY` | `const TYPOGRAPHY` | — | Tier 2 — typography, enumerated one codepoint at a time. |
|
|
1005
|
+
| `NOTATION` | `const NOTATION` | — | Tier 3 — the notation the rules and price tables are written in. |
|
|
1006
|
+
| `isAllowedCodePoint` | `function isAllowedCodePoint(cp)` | {boolean} Whether it is allowed outside a code fence. | Whether the charset admits a code point anywhere in a note. |
|
|
1007
|
+
| `isDiagramCodePoint` | `function isDiagramCodePoint(cp)` | {boolean} Whether a fence may carry it. | Whether a code point is diagram furniture, admitted inside a fence only. |
|
|
1008
|
+
| `refusalFor` | `function refusalFor(cp)` | {string} A clause naming what it is and what to do instead. | The reason a code point is refused. |
|
|
1009
|
+
| `decomposedRuns` | `function decomposedRuns(text)` | {Array<{sequence: string, composed: string, index: number}>} Each offending run, in the order it appears. | Every non-NFC run in a string, with the composed form it should have been. |
|
|
1010
|
+
| `checkText` | `function checkText(text, file)` | {Array<{file: string, line: number, column: number, severity: "warning", message: string}>} What is wrong, in file order. | Check one file's text against the charset and the normalization rule. |
|
|
1011
|
+
| `lintContentCharset` | `function lintContentCharset(contentBase,` | `{{findings: Array<{file: string, line: number, column: number, severity: "warning", message: string}>, files: number}}` The findings, and how many files produced them. | Walk a content tree and check every authored file in it. |
|
|
947
1012
|
|
|
948
1013
|
### `engine.contentIcons`
|
|
949
1014
|
|
|
950
1015
|
Naming an interface icon in a note, without drawing it there. The user guide describes Foundry's interface, and it did so by pasting Unicode lookalikes of the icons the sheets actually draw: `☆` for the improve flag, `✎` for the formula editor, `◆` in the success-value table, `★★★` for mastery. The system renders every one of those with **Font Awesome** — a `fa-regular fa-star`, a `fa-solid fa-pen-to-square` — so the note and the screen it describes were drawing different pictures, and drifting apart with every sheet change.
|
|
951
1016
|
|
|
952
|
-
| Export | Signature | Returns
|
|
953
|
-
| --------------------- | -------------------------------------------- |
|
|
954
|
-
| `EMPTY_ICON_REGISTRY` | `const EMPTY_ICON_REGISTRY` | —
|
|
955
|
-
| `familyOf` | `function familyOf(entry, registry` | {string\|undefined} The family name, or nothing when neither the entry nor the registry says.
|
|
956
|
-
| `ICON_SIZES` | `const ICON_SIZES` | —
|
|
957
|
-
| `ICON_ATTRIBUTES` | `const ICON_ATTRIBUTES` | —
|
|
958
|
-
| `parseIconAttributes` | `function parseIconAttributes(raw)` | {{attrs: Record<string, string>, problems: string[]}} What was written, and what cannot be honoured. | Read the brace of an icon token. |
|
|
959
|
-
| `ICON_PATTERN` | `const ICON_PATTERN` | —
|
|
960
|
-
| `resolveIcon` | `function resolveIcon(name, registry` | {object\|null} The entry, or `null` when the registry does not declare it.
|
|
961
|
-
| `iconHtml` | `function iconHtml(entry, attrs` | {string} An `<i>` element.
|
|
962
|
-
| `iconsIn` | `function iconsIn(text)` | {Array<{name: string, index: number, raw: string}>} What it names.
|
|
963
|
-
| `lintIcons` | `function lintIcons(text, file, registry` | {Array<{file: string, line: number, column: number, severity: "warning", message: string}>}
|
|
964
|
-
| `checkIconRegistry` | `function checkIconRegistry(registry, where` | {Array<{severity: "warning", message: string}>} What is wrong with it.
|
|
965
|
-
| `lintContentIcons` | `function lintContentIcons(contentBase,` | {{findings: Array<{file: string, line: number, column: number, severity: "warning", message: string}>, files: number}} What it found. | Walk a content tree and report every icon name its registry does not declare. |
|
|
966
|
-
| `iconPlugin` | `function iconPlugin(registry` | {(md: object) => void} A markdown-it plugin.
|
|
1017
|
+
| Export | Signature | Returns | Use it when |
|
|
1018
|
+
| --------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
1019
|
+
| `EMPTY_ICON_REGISTRY` | `const EMPTY_ICON_REGISTRY` | — | The registry a package that declares none gets: nothing at all. |
|
|
1020
|
+
| `familyOf` | `function familyOf(entry, registry` | {string\|undefined} The family name, or nothing when neither the entry nor the registry says. | The family an entry draws from, named or defaulted. |
|
|
1021
|
+
| `ICON_SIZES` | `const ICON_SIZES` | — | The sizes a note may ask for, and what each means on a page. |
|
|
1022
|
+
| `ICON_ATTRIBUTES` | `const ICON_ATTRIBUTES` | — | The attribute names a note may write, and how each is validated. |
|
|
1023
|
+
| `parseIconAttributes` | `function parseIconAttributes(raw)` | `{{attrs: Record<string, string>, problems: string[]}}` What was written, and what cannot be honoured. | Read the brace of an icon token. |
|
|
1024
|
+
| `ICON_PATTERN` | `const ICON_PATTERN` | — | The shape a note writes, and the one this module claims. |
|
|
1025
|
+
| `resolveIcon` | `function resolveIcon(name, registry` | {object\|null} The entry, or `null` when the registry does not declare it. | Look one name up. |
|
|
1026
|
+
| `iconHtml` | `function iconHtml(entry, attrs` | {string} An `<i>` element. | The HTML the journals and the website emit — what the system already renders. |
|
|
1027
|
+
| `iconsIn` | `function iconsIn(text)` | {Array<{name: string, index: number, raw: string}>} What it names. | Every icon a string names, in the order written. |
|
|
1028
|
+
| `lintIcons` | `function lintIcons(text, file, registry` | {Array<{file: string, line: number, column: number, severity: "warning"\|"error", message: string}>} Findings for names and syntax. | Report every icon a tree names that its registry does not declare. |
|
|
1029
|
+
| `checkIconRegistry` | `function checkIconRegistry(registry, where` | {Array<{severity: "warning", message: string}>} What is wrong with it. | What is wrong with a package's declared registry. |
|
|
1030
|
+
| `lintContentIcons` | `function lintContentIcons(contentBase,` | `{{findings: Array<{file: string, line: number, column: number, severity: "warning", message: string}>, files: number}}` What it found. | Walk a content tree and report every icon name its registry does not declare. |
|
|
1031
|
+
| `iconPlugin` | `function iconPlugin(registry` | {(md: object) => void} A markdown-it plugin. | A markdown-it plugin rendering `:icon name:` inline. |
|
|
967
1032
|
|
|
968
1033
|
### `engine.contentHtml`
|
|
969
1034
|
|
|
970
|
-
Raw HTML in a note's prose, reported. **A note is markdown.** What markdown cannot say, a note does not say — it gets a construct every surface can render, the way `:icon
|
|
1035
|
+
Raw HTML in a note's prose, reported. **A note is markdown.** What markdown cannot say, a note does not say — it gets a construct every surface can render, the way `:icon …:` replaces a pasted glyph.
|
|
971
1036
|
|
|
972
|
-
| Export | Signature | Returns
|
|
973
|
-
| ----------------- | --------------------------------------- |
|
|
974
|
-
| `HTML_TAG` | `const HTML_TAG` | —
|
|
975
|
-
| `htmlMessage` | `function htmlMessage(tag)` | {string} The message, unpunctuated at the end as a finding is.
|
|
976
|
-
| `checkHtml` | `function checkHtml(body, file,` | {Array<{file: string, line: number, column: number, severity: "warning", message: string}>} One finding per tag, in source order.
|
|
977
|
-
| `lintContentHtml` | `function lintContentHtml(contentBase,` | {{findings: Array<{file: string, line: number, column: number, severity: "warning", message: string}>, files: number}} The findings, and how many files were read. | Walk a content tree and report raw HTML in every note's prose. |
|
|
1037
|
+
| Export | Signature | Returns | Use it when |
|
|
1038
|
+
| ----------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
|
|
1039
|
+
| `HTML_TAG` | `const HTML_TAG` | — | A raw HTML tag, opening, closing or self-closing. |
|
|
1040
|
+
| `htmlMessage` | `function htmlMessage(tag)` | {string} The message, unpunctuated at the end as a finding is. | What a note carrying raw HTML is told. |
|
|
1041
|
+
| `checkHtml` | `function checkHtml(body, file,` | {Array<{file: string, line: number, column: number, severity: "warning", message: string}>} One finding per tag, in source order. | Every raw HTML tag in one note's body. |
|
|
1042
|
+
| `lintContentHtml` | `function lintContentHtml(contentBase,` | `{{findings: Array<{file: string, line: number, column: number, severity: "warning", message: string}>, files: number}}` The findings, and how many files were read. | Walk a content tree and report raw HTML in every note's prose. |
|
|
978
1043
|
|
|
979
1044
|
### `engine.contentEmbeds`
|
|
980
1045
|
|
|
981
1046
|
`![[address|label]]` — the wikilink that renders a picture where it stands. An embed is the wikilink the syntax module defines, with `!` meaning _render it here_, and the syntax supplying the default type `image`. It resolves to an ordinary markdown image before any surface renders it, so the figure, the staging list and the directive all come from the image machinery that already exists. An embed reaches asset types only.
|
|
982
1047
|
|
|
983
|
-
| Export | Signature | Returns
|
|
984
|
-
| -------------------- | ---------------------------------------- |
|
|
985
|
-
| `EMBED_DEFAULT_TYPE` | `const EMBED_DEFAULT_TYPE` | —
|
|
986
|
-
| `EMBED_PATTERN` | `const EMBED_PATTERN` | —
|
|
987
|
-
| `embedsIn` | `function embedsIn(body)` | {ParsedEmbed[]} One entry per embed.
|
|
988
|
-
| `resolveEmbed` | `function resolveEmbed(index, embed)` | {{pathname: string}\|{reason: string, target: string, type?: string}} The authored pathname, or the finding. | What one embed resolves to, or why it does not. |
|
|
989
|
-
| `embedProblems` | `function embedProblems(embed)` | {Array<{link: string, offset: number, message: string}>} One entry per defect.
|
|
990
|
-
| `resolveEmbeds` | `function resolveEmbeds(body, ctx)` | {{markdown: string, unresolved: Array<object>, problems: Array<object>}} The body, the embeds that named nothing, and the directives that could not be honoured. | Rewrite every embed into the image each surface renders. |
|
|
991
|
-
| `checkEmbeds` | `function checkEmbeds(body, file, opts)` | {Array<{file: string, line: number, column: number\|undefined, severity: "error", message: string}>} One finding per defect, in source order.
|
|
1048
|
+
| Export | Signature | Returns | Use it when |
|
|
1049
|
+
| -------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- |
|
|
1050
|
+
| `EMBED_DEFAULT_TYPE` | `const EMBED_DEFAULT_TYPE` | — | The type a bare shortcode takes, supplied by the syntax itself. |
|
|
1051
|
+
| `EMBED_PATTERN` | `const EMBED_PATTERN` | — | An embed, as authored, with the directive it may carry. |
|
|
1052
|
+
| `embedsIn` | `function embedsIn(body)` | {ParsedEmbed[]} One entry per embed. | Every embed in one body, in source order. |
|
|
1053
|
+
| `resolveEmbed` | `function resolveEmbed(index, embed)` | `{{pathname: string}\|{reason: string, target: string, type?: string}}` The authored pathname, or the finding. | What one embed resolves to, or why it does not. |
|
|
1054
|
+
| `embedProblems` | `function embedProblems(embed)` | {Array<{link: string, offset: number, message: string}>} One entry per defect. | What is wrong with one embed's directive or placement. |
|
|
1055
|
+
| `resolveEmbeds` | `function resolveEmbeds(body, ctx)` | `{{markdown: string, unresolved: Array<object>, problems: Array<object>}}` The body, the embeds that named nothing, and the directives that could not be honoured. | Rewrite every embed into the image each surface renders. |
|
|
1056
|
+
| `checkEmbeds` | `function checkEmbeds(body, file, opts)` | {Array<{file: string, line: number, column: number\|undefined, severity: "error", message: string}>} One finding per defect, in source order. | Every defect in one note's embeds, located. |
|
|
992
1057
|
|
|
993
1058
|
### `engine.contentImages`
|
|
994
1059
|
|
|
995
|
-
An image saying how wide it is and where it sits. A directive in the curly-attribute convention Pandoc and Kramdown use supplies a width class, a named `size
|
|
996
|
-
|
|
997
|
-
| Export | Signature | Returns
|
|
998
|
-
| --------------------- | ----------------------------------------------- |
|
|
999
|
-
| `IMAGE_CLASSES` | `const IMAGE_CLASSES` | —
|
|
1000
|
-
| `IMAGE_SIZES` | `const IMAGE_SIZES` | —
|
|
1001
|
-
| `IMAGE_FLOATS` | `const IMAGE_FLOATS` | —
|
|
1002
|
-
| `IMAGE_FIGURE_CLASS` | `const IMAGE_FIGURE_CLASS` | —
|
|
1003
|
-
| `IMAGE_PATTERN` | `const IMAGE_PATTERN` | —
|
|
1004
|
-
| `imageSourceProblem` | `function imageSourceProblem(src)` | {string} The problem, as a finding's sentence, or `""`.
|
|
1005
|
-
| `parseImageDirective` | `function parseImageDirective(raw)` | {{classes: string[], size: string, float: string, problems: string[]}} What was written, and what cannot be honoured. | Read the directive on an image. |
|
|
1006
|
-
| `figureClasses` | `function figureClasses(directive)` | {string} A space-separated class list.
|
|
1007
|
-
| `escapeHtml` | `function escapeHtml(text)` | {string} The same value, safe in markup.
|
|
1008
|
-
| `imageFigureHtml` | `function imageFigureHtml(image)` | {string} The figure, as one HTML block.
|
|
1009
|
-
| `standsAlone` | `function standsAlone(text, start, end)` | {boolean} Whether the match is a block of its own.
|
|
1010
|
-
| `imagesIn` | `function imagesIn(body)` | {Array<{alt: string, src: string, title: string, directive: string, index: number, length: number, block: boolean}>} One entry per image.
|
|
1011
|
-
| `imageSourcesIn` | `function imageSourcesIn(body)` | {string[]} The addresses, with repeats.
|
|
1012
|
-
| `checkImages` | `function checkImages(body, file,` | {Array<{file: string, line: number, column: number\|undefined, severity: "error", message: string}>} One finding per defect, in source order.
|
|
1013
|
-
| `lintContentImages` | `function lintContentImages(contentBase,` | {{findings: Array<{file: string, line: number, column: number\|undefined, severity: "error", message: string}>, files: number}} What it found. | Walk a content tree and report every image it cannot render as authored. |
|
|
1014
|
-
| `renderImageFigures` | `function renderImageFigures(body, resolveSrc)` | {string} The same body, with each block image as a `<figure>`.
|
|
1015
|
-
| `imagePlugin` | `function imagePlugin()` | {(md: object) => void} A markdown-it plugin.
|
|
1060
|
+
An image saying how wide it is and where it sits. A directive in the curly-attribute convention Pandoc and Kramdown use supplies a width class, a named `size`, and a `float` position. The named size sets a maximum display width for each surface.
|
|
1061
|
+
|
|
1062
|
+
| Export | Signature | Returns | Use it when |
|
|
1063
|
+
| --------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
|
|
1064
|
+
| `IMAGE_CLASSES` | `const IMAGE_CLASSES` | — | The width classes an image may carry, and what each means to a renderer. |
|
|
1065
|
+
| `IMAGE_SIZES` | `const IMAGE_SIZES` | — | The named sizes an image directive accepts. |
|
|
1066
|
+
| `IMAGE_FLOATS` | `const IMAGE_FLOATS` | — | The `float` positions an image may take, and where each puts it. |
|
|
1067
|
+
| `IMAGE_FIGURE_CLASS` | `const IMAGE_FIGURE_CLASS` | — | The class every figure carries, whatever its width or position. |
|
|
1068
|
+
| `IMAGE_PATTERN` | `const IMAGE_PATTERN` | — | A markdown image, with the directive it may carry. |
|
|
1069
|
+
| `imageSourceProblem` | `function imageSourceProblem(src)` | {string} The problem, as a finding's sentence, or `""`. | What is wrong with an image's address, or `""` when nothing is. |
|
|
1070
|
+
| `parseImageDirective` | `function parseImageDirective(raw)` | `{{classes: string[], size: string, float: string, problems: string[]}}` What was written, and what cannot be honoured. | Read the directive on an image. |
|
|
1071
|
+
| `figureClasses` | `function figureClasses(directive)` | {string} A space-separated class list. | The classes a figure carries, from a parsed directive. |
|
|
1072
|
+
| `escapeHtml` | `function escapeHtml(text)` | {string} The same value, safe in markup. | Text going inside an HTML attribute or between tags. |
|
|
1073
|
+
| `imageFigureHtml` | `function imageFigureHtml(image)` | {string} The figure, as one HTML block. | One image as the `<figure>` both HTML surfaces render. |
|
|
1074
|
+
| `standsAlone` | `function standsAlone(text, start, end)` | {boolean} Whether the match is a block of its own. | Whether a match sits alone in its own paragraph. |
|
|
1075
|
+
| `imagesIn` | `function imagesIn(body)` | {Array<{alt: string, src: string, title: string, directive: string, index: number, length: number, block: boolean}>} One entry per image. | Every image in one body, with its directive and its position. |
|
|
1076
|
+
| `imageSourcesIn` | `function imageSourcesIn(body)` | {string[]} The addresses, with repeats. | Every image address one body names, in order of appearance. |
|
|
1077
|
+
| `checkImages` | `function checkImages(body, file,` | {Array<{file: string, line: number, column: number\|undefined, severity: "error", message: string}>} One finding per defect, in source order. | Every defect in one note's images. |
|
|
1078
|
+
| `lintContentImages` | `function lintContentImages(contentBase,` | `{{findings: Array<{file: string, line: number, column: number\|undefined, severity: "error", message: string}>, files: number}}` What it found. | Walk a content tree and report every image it cannot render as authored. |
|
|
1079
|
+
| `renderImageFigures` | `function renderImageFigures(body, resolveSrc)` | {string} The same body, with each block image as a `<figure>`. | Rewrite every block image in a body into the figure the website publishes. |
|
|
1080
|
+
| `imagePlugin` | `function imagePlugin()` | {(md: object) => void} A markdown-it plugin. | A markdown-it plugin that reads an image's directive and renders its figure. |
|
|
1016
1081
|
|
|
1017
1082
|
### `engine.pathnames`
|
|
1018
1083
|
|
|
@@ -1032,13 +1097,13 @@ One authored pathname, and the four addresses it resolves to. A note names a fil
|
|
|
1032
1097
|
|
|
1033
1098
|
Resolving every link in a content tree, and reporting the ones that land nowhere. Three link defects survive both content builds silently, so neither the pack compilers nor a site build catches them:
|
|
1034
1099
|
|
|
1035
|
-
| Export | Signature | Returns
|
|
1036
|
-
| -------------------- | ---------------------------------------------------------------------------------------- |
|
|
1037
|
-
| `anchorsOf` | `function anchorsOf(body)` | {Set<string>} The declared anchor slugs.
|
|
1038
|
-
| `buildLinkIndex` | `buildLinkIndex(contentBase, { config, skipDirectories, sqlTables, records, problems })` | {object} The notes, the index, and the resolvers built over it.
|
|
1039
|
-
| `auditHomepageLinks` | `function auditHomepageLinks(index)` | {Array<{note: object, field: string, url: string, text: string, occurrence: number, message: string}>} One finding per defect, `text` and `occurrence` locating it in the note's raw source.
|
|
1040
|
-
| `auditLinks` | `function auditLinks(index)` | {{deadAnchors: object[], deadAddresses: object[], unlabelledLinks: object[], frontmatterLinks: object[], homepageLinks: object[], usedManifest: Set<string>}} The findings, and which addresses a foreign manifest answered. | Every link in a tree that lands nowhere. |
|
|
1041
|
-
| `walkReachability` | `function walkReachability(index,` | {{root: object, reached: Set<object>, orphans: object[]}} The root, everything reached from it, and the corpus members that were not. | Walk a corpus from its root and report what nothing links to. |
|
|
1100
|
+
| Export | Signature | Returns | Use it when |
|
|
1101
|
+
| -------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------- |
|
|
1102
|
+
| `anchorsOf` | `function anchorsOf(body)` | {Set<string>} The declared anchor slugs. | Every `{#anchor}` a note declares on a heading. |
|
|
1103
|
+
| `buildLinkIndex` | `buildLinkIndex(contentBase, { config, skipDirectories, sqlTables, records, problems })` | {object} The notes, the index, and the resolvers built over it. | Read a content tree into the index a link resolves against. |
|
|
1104
|
+
| `auditHomepageLinks` | `function auditHomepageLinks(index)` | {Array<{note: object, field: string, url: string, text: string, occurrence: number, message: string}>} One finding per defect, `text` and `occurrence` locating it in the note's raw source. | Every defect in the addresses a package homepage carries. |
|
|
1105
|
+
| `auditLinks` | `function auditLinks(index)` | `{{deadAnchors: object[], deadAddresses: object[], unlabelledLinks: object[], frontmatterLinks: object[], homepageLinks: object[], usedManifest: Set<string>}}` The findings, and which addresses a foreign manifest answered. | Every link in a tree that lands nowhere. |
|
|
1106
|
+
| `walkReachability` | `function walkReachability(index,` | `{{root: object, reached: Set<object>, orphans: object[]}}` The root, everything reached from it, and the corpus members that were not. | Walk a corpus from its root and report what nothing links to. |
|
|
1042
1107
|
|
|
1043
1108
|
### `engine.webWikilinks`
|
|
1044
1109
|
|
|
@@ -1051,44 +1116,40 @@ Wikilink resolution for the knowledgebase build. The same authored links the pac
|
|
|
1051
1116
|
|
|
1052
1117
|
### `engine.contentTables`
|
|
1053
1118
|
|
|
1054
|
-
|
|
1119
|
+
Prepared SQL content tables are expanded into Markdown before link resolution.
|
|
1120
|
+
A query selecting no rows reports an error unless its fence states
|
|
1121
|
+
`{allow-empty=true}`.
|
|
1055
1122
|
|
|
1056
|
-
| Export | Signature
|
|
1057
|
-
| --------------------- |
|
|
1058
|
-
| `
|
|
1059
|
-
| `resolveField` | `function resolveField(doc, path)` | {unknown} `null` when the note has no such field. | Resolve a dotted path against a content note. |
|
|
1060
|
-
| `evaluate` | `function evaluate(node, doc, self)` | {unknown} | Evaluate one parsed expression against a note. |
|
|
1061
|
-
| `selectRows` | `function selectRows(spec, docs, self)` | {Array<ContentTableDoc>} The matching notes, sorted and limited. | The notes a query selects, in the order its `SORT` keys give. |
|
|
1062
|
-
| `renderContentTable` | `function renderContentTable(spec, rows, linkable, self)` | {string} The markdown table (no trailing newline). | Build the markdown table for one query. |
|
|
1063
|
-
| `expandContentTables` | `expandContentTables(markdown, { docs, linkable, source, self, sqlTables })` | `{markdown: string, errors: object[], lineMap: object[], warnings: object[]}` | expanding every fenced `dataview` block in a markdown body; a block that cannot be honoured is left verbatim and reported in `errors` rather than failing the build, and a query matching no note renders as an empty table |
|
|
1123
|
+
| Export | Signature | Returns | Use it when |
|
|
1124
|
+
| --------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
1125
|
+
| `expandContentTables` | `expandContentTables(markdown, { source, sqlTables })` | `{markdown: string, errors: object[], lineMap: object[], warnings: object[]}` | Replace prepared SQL fences and preserve source locations. |
|
|
1064
1126
|
|
|
1065
1127
|
### `engine.helpers`
|
|
1066
1128
|
|
|
1067
|
-
Shared helpers for the pack compilers in `packages/
|
|
1068
|
-
|
|
1069
|
-
| Export | Signature | Returns
|
|
1070
|
-
| ------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
1071
|
-
| `md` | `const md` | —
|
|
1072
|
-
| `renderFoundryMarkdown` | `function renderFoundryMarkdown(body)` | `string` — HTML with secret sections for GM passages.
|
|
1073
|
-
| `parseMarkdownFile` | `function parseMarkdownFile(filePath)` | —
|
|
1074
|
-
| `assertStatedScope` | `function assertStatedScope(skipDirectories, who)` | {void}
|
|
1075
|
-
| `assertSuppliedCorpus` | `function assertSuppliedCorpus(records, who)` | {void}
|
|
1076
|
-
| `statedTemplatePriority` | `function statedTemplatePriority(fm, label,` | {number\|null} The priority, or `null` when the note is not a template or states nothing.
|
|
1077
|
-
| `resolveTemplatePriority` | `function resolveTemplatePriority(fm, label,` | {number\|undefined} The template priority, or `undefined` when null.
|
|
1078
|
-
| `systemTemplatePriority` | `function systemTemplatePriority(fm, label)` | {number\|null} The template priority, or `null` for a document that is not a template.
|
|
1079
|
-
| `makeFilename` | `function makeFilename(name, id)` | —
|
|
1080
|
-
| `resolveImg` | `function resolveImg(raw, config` | {string \| null} the Foundry-relative path; `""` for a deliberate blank, and `null` when the note names no art at all.
|
|
1081
|
-
| `resolveName` | `function resolveName(fm, defaultValue` | —
|
|
1082
|
-
| `supportedCoreVersion` | `function supportedCoreVersion(config` | {string} The declared `compatibility.minimum`.
|
|
1083
|
-
| `buildStats` | `function buildStats(systemVersion` | {object} The `_stats` block.
|
|
1084
|
-
| `statsForPack` | `function statsForPack(packSystem, config` | {object} The `_stats` block for that pack.
|
|
1085
|
-
| `defaultStats` | `function defaultStats()` | {object} The default `_stats` block, shared by every compiler.
|
|
1086
|
-
| `buildContentLinkIndex` | `buildContentLinkIndex(contentBase, router, { skipDirectories, config, records, problems })` | {{byShortcode: Map, types: Set}} From `buildWikilinkIndex`. | Indexes **every** note in the content tree so any pack compiler can resolve a wikilink to any other document. |
|
|
1087
|
-
| `convertNoteWikilinks` | `convertNoteWikilinks(body, { type, id, pack, docPack, index, name, file, bodyLine, bodyColumn, lineMap })` | {{markdown: string, unresolved: Array<object>}} | Converts the wikilinks in one note's markdown, reporting any that have no target in the content tree. |
|
|
1088
|
-
| `
|
|
1089
|
-
| `
|
|
1090
|
-
| `
|
|
1091
|
-
| `walkMarkdownTree` | `walkMarkdownTree(rootDir, { skipDirectories })` | generator yielding `{frontmatter, body, description, bodyLine?, bodyColumn?, file, absPath}` | walking a content tree and reading every markdown file's frontmatter and body; `skipDirectories` is required rather than defaulted, so two callers cannot silently disagree about the corpus's scope |
|
|
1129
|
+
Shared helpers for the pack compilers in `packages/package-build/`. The HeroicLands vault is authoritative for compendium item data. Pack compilers walk the vault, read markdown files with YAML frontmatter, and emit Foundry-compatible JSON. These helpers handle the common shape: markdown parsing, frontmatter access (including the nested `sohl:` block), filename generation, and slug normalization.
|
|
1130
|
+
|
|
1131
|
+
| Export | Signature | Returns | Use it when |
|
|
1132
|
+
| ------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1133
|
+
| `md` | `const md` | — | The markdown renderer every surface shares. |
|
|
1134
|
+
| `renderFoundryMarkdown` | `function renderFoundryMarkdown(body)` | `string` — HTML with secret sections for GM passages. | Rendering a note body for a Foundry document. |
|
|
1135
|
+
| `parseMarkdownFile` | `function parseMarkdownFile(filePath)` | — | Parses a markdown file with YAML frontmatter. |
|
|
1136
|
+
| `assertStatedScope` | `function assertStatedScope(skipDirectories, who)` | {void} | Refuse a corpus read whose scope its caller did not state. |
|
|
1137
|
+
| `assertSuppliedCorpus` | `function assertSuppliedCorpus(records, who)` | {void} | Refuse a corpus read whose records its caller did not supply. |
|
|
1138
|
+
| `statedTemplatePriority` | `function statedTemplatePriority(fm, label,` | {number\|null} The priority, or `null` when the note is not a template or states nothing. | The template priority a note states, for a system that treats an unstated one as "not a template" rather than as an authoring error. |
|
|
1139
|
+
| `resolveTemplatePriority` | `function resolveTemplatePriority(fm, label,` | {number\|undefined} The template priority, or `undefined` when null. | Resolve the required `templatePriority` frontmatter for an Item/Actor entry (the archetype contract). |
|
|
1140
|
+
| `systemTemplatePriority` | `function systemTemplatePriority(fm, label)` | {number\|null} The template priority, or `null` for a document that is not a template. | The value a document's `system.templatePriority` carries, from the required `templatePriority` frontmatter (`archetype` is the legacy spelling). |
|
|
1141
|
+
| `makeFilename` | `function makeFilename(name, id)` | — | Generates a compendium-source filename: `Name_id.json` with non- alphanumeric runs replaced by underscores. |
|
|
1142
|
+
| `resolveImg` | `function resolveImg(raw, config` | {string \| null} the Foundry-relative path; `""` for a deliberate blank, and `null` when the note names no art at all. | Translate a content-relative image path into its Foundry-relative form. |
|
|
1143
|
+
| `resolveName` | `function resolveName(fm, defaultValue` | — | Resolves the display name from frontmatter, preferring `name.full`, falling back to `name` (if string), then `defaultValue`. |
|
|
1144
|
+
| `supportedCoreVersion` | `function supportedCoreVersion(config` | {string} The declared `compatibility.minimum`. | The oldest Foundry core this package supports, stamped into every compiled document as `_stats.coreVersion`. |
|
|
1145
|
+
| `buildStats` | `function buildStats(systemVersion` | {object} The `_stats` block. | Default `_stats` block for compiled compendium entries. |
|
|
1146
|
+
| `statsForPack` | `function statsForPack(packSystem, config` | {object} The `_stats` block for that pack. | The `_stats` block for one pack, stamped with the system that pack is for. |
|
|
1147
|
+
| `defaultStats` | `function defaultStats()` | {object} The default `_stats` block, shared by every compiler. | The `_stats` block every compiler stamps on an entry it emits, built once. |
|
|
1148
|
+
| `buildContentLinkIndex` | `buildContentLinkIndex(contentBase, router, { skipDirectories, config, records, problems })` | `{{byShortcode: Map, types: Set}}` From `buildWikilinkIndex`. | Indexes **every** note in the content tree so any pack compiler can resolve a wikilink to any other document. |
|
|
1149
|
+
| `convertNoteWikilinks` | `convertNoteWikilinks(body, { type, id, pack, docPack, index, name, file, bodyLine, bodyColumn, lineMap })` | `{{markdown: string, unresolved: Array<object>}}` | Converts the wikilinks in one note's markdown, reporting any that have no target in the content tree. |
|
|
1150
|
+
| `expandNoteTables` | `function expandNoteTables(body,` | `{{markdown: string, lineMap: Array<{line: number, generated: boolean}>}}` The body with every table expanded, and where each emitted line came from — which is what lets a diagnostic about the expanded body name an authored position. | Expand prepared SQL tables in one note's markdown, before wikilinks are resolved — so a generated cell may itself be a wikilink. |
|
|
1151
|
+
| `folderFilename` | `function folderFilename(name, id)` | — | Builds a compendium-source filename for a folder JSON document: `folder_Name_id.json` with non-alphanumeric runs replaced by underscores. |
|
|
1152
|
+
| `walkMarkdownTree` | `walkMarkdownTree(rootDir, { skipDirectories })` | generator yielding `{frontmatter, body, description, bodyLine?, bodyColumn?, file, absPath}` | walking a content tree and reading every markdown file's frontmatter and body; `skipDirectories` is required rather than defaulted, so two callers cannot silently disagree about the corpus's scope |
|
|
1092
1153
|
|
|
1093
1154
|
### `engine.itemRegistry`
|
|
1094
1155
|
|
|
@@ -1137,9 +1198,9 @@ Wikilink resolution for the pack compilers. Content notes link to one another wi
|
|
|
1137
1198
|
| `resolveItemDocType` | `function resolveItemDocType(qualifier, types)` | {string\|null} The underlying document type, or `null` when the qualifier is not a virtual one. | Reads an accepted `doc<type>` input alias as its authored type. |
|
|
1138
1199
|
| `readQualifier` | `function readQualifier(target, types, packages, noIndexPackages)` | {{type: string, shortcode: string, itemDoc: boolean, package?: string, system?: string, reason?: undefined} \| {reason: "unknown-type"\|"no-content-index", package?: string} \| null} The resolved qualifier; a `reason` when the target is definitely qualified but names no known type or no fetched index; or `null` when it is not an address at all. | Read a link target as a **qualified** `type-shortcode` reference, or report that it does not parse as one. |
|
|
1139
1200
|
| `anchorPageId` | `function anchorPageId(noteId, anchorSlug)` | {string} A 16-character alphanumeric id. | The deterministic JournalEntryPage id for one anchor: SHA-256 of `"<noteId>-<anchorSlug>"`, base64-encoded, reduced to the 16 alphanumeric characters a Foundry id allows. |
|
|
1140
|
-
| `buildWikilinkIndex` | `function buildWikilinkIndex(docs, packageId, foreign, contentPackage)` | {{byShortcode: Map<string, object>, types: Set<string>}} `types` is every type the tree actually contains, so a qualifier naming no real type can be told apart from a missing target.
|
|
1201
|
+
| `buildWikilinkIndex` | `function buildWikilinkIndex(docs, packageId, foreign, contentPackage)` | `{{byShortcode: Map<string, object>, types: Set<string>}}` `types` is every type the tree actually contains, so a qualifier naming no real type can be told apart from a missing target. | Builds the link-resolution tables for a content tree. |
|
|
1141
1202
|
| `resolveReference` | `function resolveReference(index, ref, hint)` | {{name?: string, uuid?: string, address?: string, subType?: string}\|undefined} The target, or `undefined` where nothing answers. | Resolve one reference — a bare shortcode, a short address or a canonical one — to what a compendium can use. |
|
|
1142
|
-
| `convertWikilinks` | `function convertWikilinks(markdown,` | {{markdown: string, unresolved: Array<{link: string, target: string, offset: number, reason: string, packages?: string[], anchor?: string}>}} Each `reason` is one of {@link LINK_FINDING_REASONS}, the vocabulary all three resolvers share — `ambiguous` carries the claiming `packages` and `unknown-anchor` the section it named.
|
|
1203
|
+
| `convertWikilinks` | `function convertWikilinks(markdown,` | `{{markdown: string, unresolved: Array<{link: string, target: string, offset: number, reason: string, packages?: string[], anchor?: string}>}}` Each `reason` is one of {@link LINK_FINDING_REASONS}, the vocabulary all three resolvers share — `ambiguous` carries the claiming `packages` and `unknown-anchor` the section it named. | Rewrites every wikilink in a markdown body as a Foundry UUID enricher. |
|
|
1143
1204
|
|
|
1144
1205
|
### `engine.wikilinkSyntax`
|
|
1145
1206
|
|
|
@@ -1161,7 +1222,9 @@ What a `[[…]]` **is**, before anything decides where it points. One authored l
|
|
|
1161
1222
|
|
|
1162
1223
|
### `engine.siteIndex`
|
|
1163
1224
|
|
|
1164
|
-
**The address index a site build resolves its wikilinks against.**
|
|
1225
|
+
**The address index a site build resolves its wikilinks against.**
|
|
1226
|
+
`buildSiteIndex` gathers addressable pages and ambiguity findings. `wikiContext`
|
|
1227
|
+
provides the per-page context used when resolving a link such as `[[Something]]`.
|
|
1165
1228
|
|
|
1166
1229
|
| Export | Signature | Returns | Use it when |
|
|
1167
1230
|
| ------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
|
|
@@ -1173,12 +1236,12 @@ What a `[[…]]` **is**, before anything decides where it points. One authored l
|
|
|
1173
1236
|
|
|
1174
1237
|
The document tree a PDF is built from, and the plan it resolves to. The packs and the website both render the _whole_ content tree: every note becomes a document and a page, and the three surfaces agreeing about what the content is, is the point. **A book is not that.** It is a selection — a declared structure whose leaves pick notes out of the corpus by a `WHERE` clause, interleaved with prose that may not live in the content tree at all.
|
|
1175
1238
|
|
|
1176
|
-
| Export | Signature | Returns
|
|
1177
|
-
| ------------------- | ------------------------------------------ |
|
|
1178
|
-
| `PRESENTATION_KEYS` | `const PRESENTATION_KEYS` | —
|
|
1179
|
-
| `parseDocumentTree` | `function parseDocumentTree(raw,` | {{nodes: object[], findings: object[]}} The flattened tree and what was wrong with it. | Validate the raw tree and flatten it into nodes. |
|
|
1180
|
-
| `runTreeFilters` | `async function runTreeFilters(nodes, db,` | {Promise<{selections: Map<string, object[]>, findings: object[]}>}
|
|
1181
|
-
| `planDocument` | `function planDocument(nodes,` | {{entries: object[], links: Map<string, string>, stats: object}} The plan, the address→anchor map inbound wikilinks resolve through, and what the selection came to. | Resolve the flattened tree into the document plan. |
|
|
1239
|
+
| Export | Signature | Returns | Use it when |
|
|
1240
|
+
| ------------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
1241
|
+
| `PRESENTATION_KEYS` | `const PRESENTATION_KEYS` | — | Presentation a node may declare, and that its descendants inherit. |
|
|
1242
|
+
| `parseDocumentTree` | `function parseDocumentTree(raw,` | `{{nodes: object[], findings: object[]}}` The flattened tree and what was wrong with it. | Validate the raw tree and flatten it into nodes. |
|
|
1243
|
+
| `runTreeFilters` | `async function runTreeFilters(nodes, db,` | {Promise<{selections: Map<string, object[]>, findings: object[]}>} | Run every filter, and report the ones that would not run. |
|
|
1244
|
+
| `planDocument` | `function planDocument(nodes,` | `{{entries: object[], links: Map<string, string>, stats: object}}` The plan, the address→anchor map inbound wikilinks resolve through, and what the selection came to. | Resolve the flattened tree into the document plan. |
|
|
1182
1245
|
|
|
1183
1246
|
### `engine.pdfRender`
|
|
1184
1247
|
|
|
@@ -1217,7 +1280,7 @@ The content tree, built into a book. The I/O half of the PDF surface: it reads t
|
|
|
1217
1280
|
| `buildPdf` | `async buildPdf({ config, out, version, compile })` | {Promise<object>} `{ built, reason, findings, typ, pdf, stats }`. | Build the book. |
|
|
1218
1281
|
| `stagedImagePath` | `function stagedImagePath(src, config)` | {{from: string, to: string}\|null} The file, and where under the output directory it is staged. | The file on disk an authored image address names, or `null`. |
|
|
1219
1282
|
| `stageBanners` | `function stageBanners(entries, config, outDir, findings)` | {Map<string, string>} Declared path → the staged file's path, relative to the `.typ`. | Copy every banner the document tree names into the output directory. |
|
|
1220
|
-
| `compileTypst` | `function compileTypst(typPath, pdfPath, pdf` | {{ok: boolean, message: string, findings: object[]}} What happened.
|
|
1283
|
+
| `compileTypst` | `function compileTypst(typPath, pdfPath, pdf` | `{{ok: boolean, message: string, findings: object[]}}` What happened. | Run Typst over the emitted source. |
|
|
1221
1284
|
| `typstArgs` | `function typstArgs(typPath, pdfPath, pdf)` | {string[]} The arguments, in order. | The command line the compile runs, as data. |
|
|
1222
1285
|
| `typstWarnings` | `function typstWarnings(output)` | {object[]} One finding per warning the compiler wrote. | The compiler's own warnings, as findings. |
|
|
1223
1286
|
| `BOOK_FONTS_PATH` | `const BOOK_FONTS_PATH` | {string} The directory holding them. | The faces the book is set in, shipped with this package. |
|
|
@@ -1265,29 +1328,29 @@ Macros pack compiler — produces JSON pack files for the "macros" Foundry compe
|
|
|
1265
1328
|
|
|
1266
1329
|
**Map notes** — the markdown → Foundry `Scene` translation. A map note carries an _essence_: a curated, hand-owned subset of what a Scene record holds, exactly as a weapon note carries a weapon's essence rather than an Item's schema. Everything a Scene needs and nobody should have to author — the canvas defaults, the embedded `Level`, every derived region field — is synthesised here.
|
|
1267
1330
|
|
|
1268
|
-
| Export | Signature | Returns
|
|
1269
|
-
| ------------------------------ | ----------------------------------------------- |
|
|
1270
|
-
| `isMapType` | `function isMapType(type)` | {boolean} True for a map type.
|
|
1271
|
-
| `MAP_SUBTYPE_PROFILES` | `const MAP_SUBTYPE_PROFILES` | —
|
|
1272
|
-
| `mapProfile` | `function mapProfile(subType)` | {object} The profile from {@link MAP_SUBTYPE_PROFILES}.
|
|
1273
|
-
| `DEFAULT_LEVEL_ID` | `const DEFAULT_LEVEL_ID` | —
|
|
1274
|
-
| `regionDocId` | `function regionDocId(sceneId, key, pinned)` | {string} A 16-character Foundry id.
|
|
1275
|
-
| `behaviorDocId` | `function behaviorDocId(regionId, key, pinned)` | {string} A 16-character Foundry id.
|
|
1276
|
-
| `regionColor` | `function regionColor(key)` | {string} A CSS hex colour.
|
|
1277
|
-
| `assertPixelGeometry` | `function assertPixelGeometry(coords, geom)` | —
|
|
1278
|
-
| `assertGridLocation` | `function assertGridLocation(at, geom)` | —
|
|
1279
|
-
| `wallRestrictions` | `function wallRestrictions(spec, label)` | {{move: number, sight: number, light: number, sound: number}} The Wall restriction fields. | Compile a wall's `blocks:` / `limits:` lists into Foundry's four numeric restriction fields. |
|
|
1280
|
-
| `buildShape` | `function buildShape(spec, geom)` | {object} The Foundry shape record.
|
|
1281
|
-
| `REGION_BEHAVIOR_TYPES` | `const REGION_BEHAVIOR_TYPES` | —
|
|
1282
|
-
| `BANNED_REGION_BEHAVIOR_TYPES` | `const BANNED_REGION_BEHAVIOR_TYPES` | —
|
|
1283
|
-
| `buildScene` | `function buildScene(fm, ctx)` | {object} The Scene document, keyed for the pack.
|
|
1284
|
-
| `buildLevel` | `function buildLevel(sohl, sceneId, img` | {object} The Level document, keyed for the pack.
|
|
1285
|
-
| `buildWalls` | `function buildWalls(sohl, geom, ctx)` | {object[]} The Wall documents.
|
|
1286
|
-
| `buildLights` | `function buildLights(sohl, geom, ctx)` | {object[]} The AmbientLight documents.
|
|
1287
|
-
| `buildTiles` | `function buildTiles(sohl, geom, ctx)` | {object[]} The Tile documents.
|
|
1288
|
-
| `buildSounds` | `function buildSounds(sohl, geom, ctx)` | {object[]} The AmbientSound documents.
|
|
1289
|
-
| `buildLocations` | `function buildLocations(sohl, geom, ctx)` | {object[]} The Note documents.
|
|
1290
|
-
| `buildRegions` | `function buildRegions(sohl, geom, ctx)` | {object[]} The Region documents.
|
|
1331
|
+
| Export | Signature | Returns | Use it when |
|
|
1332
|
+
| ------------------------------ | ----------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
1333
|
+
| `isMapType` | `function isMapType(type)` | {boolean} True for a map type. | Whether a content note's type compiles into a Scene. |
|
|
1334
|
+
| `MAP_SUBTYPE_PROFILES` | `const MAP_SUBTYPE_PROFILES` | — | Per-subtype canvas defaults, emitted **explicitly** on every scene. |
|
|
1335
|
+
| `mapProfile` | `function mapProfile(subType)` | {object} The profile from {@link MAP_SUBTYPE_PROFILES}. | The canvas profile for a map subType. |
|
|
1336
|
+
| `DEFAULT_LEVEL_ID` | `const DEFAULT_LEVEL_ID` | — | Foundry's own id for the level a scene is created with (`Scene.metadata.defaultLevelId`). |
|
|
1337
|
+
| `regionDocId` | `function regionDocId(sceneId, key, pinned)` | {string} A 16-character Foundry id. | The id of one region within its scene. |
|
|
1338
|
+
| `behaviorDocId` | `function behaviorDocId(regionId, key, pinned)` | {string} A 16-character Foundry id. | The id of one behaviour within its region. |
|
|
1339
|
+
| `regionColor` | `function regionColor(key)` | {string} A CSS hex colour. | A region's highlight colour, derived from its key. |
|
|
1340
|
+
| `assertPixelGeometry` | `function assertPixelGeometry(coords, geom)` | — | Reject geometry authored in grid squares where pixels belong. |
|
|
1341
|
+
| `assertGridLocation` | `function assertGridLocation(at, geom)` | — | Reject a map pin authored in pixels where grid squares belong. |
|
|
1342
|
+
| `wallRestrictions` | `function wallRestrictions(spec, label)` | `{{move: number, sight: number, light: number, sound: number}}` The Wall restriction fields. | Compile a wall's `blocks:` / `limits:` lists into Foundry's four numeric restriction fields. |
|
|
1343
|
+
| `buildShape` | `function buildShape(spec, geom)` | {object} The Foundry shape record. | Compile one authored shape into a Foundry shape record. |
|
|
1344
|
+
| `REGION_BEHAVIOR_TYPES` | `const REGION_BEHAVIOR_TYPES` | — | The behaviour types a map note may carry (v1). |
|
|
1345
|
+
| `BANNED_REGION_BEHAVIOR_TYPES` | `const BANNED_REGION_BEHAVIOR_TYPES` | — | Behaviour types a map note may **never** carry, and why. |
|
|
1346
|
+
| `buildScene` | `function buildScene(fm, ctx)` | {object} The Scene document, keyed for the pack. | Compile a map note into a Scene document, embedded documents and all. |
|
|
1347
|
+
| `buildLevel` | `function buildLevel(sohl, sceneId, img` | {object} The Level document, keyed for the pack. | Synthesise the scene's single embedded Level from `img:` / `overlay:`. |
|
|
1348
|
+
| `buildWalls` | `function buildWalls(sohl, geom, ctx)` | {object[]} The Wall documents. | Compile the `walls:` and `doors:` blocks into Wall documents. |
|
|
1349
|
+
| `buildLights` | `function buildLights(sohl, geom, ctx)` | {object[]} The AmbientLight documents. | Compile the `lights:` block into AmbientLight documents. |
|
|
1350
|
+
| `buildTiles` | `function buildTiles(sohl, geom, ctx)` | {object[]} The Tile documents. | Compile the `tiles:` block into Tile documents. |
|
|
1351
|
+
| `buildSounds` | `function buildSounds(sohl, geom, ctx)` | {object[]} The AmbientSound documents. | Compile the `sounds:` block into AmbientSound documents. |
|
|
1352
|
+
| `buildLocations` | `function buildLocations(sohl, geom, ctx)` | {object[]} The Note documents. | Compile the `locations:` block into Note documents — the map pins. |
|
|
1353
|
+
| `buildRegions` | `function buildRegions(sohl, geom, ctx)` | {object[]} The Region documents. | Compile the `regions:` block into Region documents with their behaviours. |
|
|
1291
1354
|
|
|
1292
1355
|
### `engine.scenes`
|
|
1293
1356
|
|
|
@@ -1376,14 +1439,12 @@ The SoHL-specific half of the toolchain: the knowledge of the Song of Heroic Lan
|
|
|
1376
1439
|
Every module beneath `./sohl` is also reachable as its own entry point, e.g. `@heroiclands/package-build/sohl/being-info`.
|
|
1377
1440
|
|
|
1378
1441
|
```js
|
|
1379
|
-
import { isBeing, GEAR_TYPE_TO_KEY
|
|
1442
|
+
import { isBeing, GEAR_TYPE_TO_KEY } from "@heroiclands/package-build/sohl";
|
|
1380
1443
|
|
|
1381
1444
|
console.log(isBeing({ type: "being" }));
|
|
1382
1445
|
// -> true
|
|
1383
1446
|
console.log(GEAR_TYPE_TO_KEY.weapongear);
|
|
1384
1447
|
// -> "weapons"
|
|
1385
|
-
console.log(deriveBeingInfo({ items: [] }, new Map()));
|
|
1386
|
-
// -> { items: [] }
|
|
1387
1448
|
```
|
|
1388
1449
|
|
|
1389
1450
|
### `sohl.itemBuilders`
|
|
@@ -1448,15 +1509,14 @@ The `sohl` knowledgebase's own body pass: a rewrite driven by a TypeDoc symbol m
|
|
|
1448
1509
|
|
|
1449
1510
|
### Flat exports (not under a namespace)
|
|
1450
1511
|
|
|
1451
|
-
| Export | Signature
|
|
1452
|
-
| ----------------------- |
|
|
1453
|
-
| `DEFAULT_ITEM_ART` | `const DEFAULT_ITEM_ART`
|
|
1454
|
-
| `defaultItemArt` | `defaultItemArt(type)`
|
|
1455
|
-
| `AFFILIATION_STANDINGS` | `const AFFILIATION_STANDINGS`
|
|
1456
|
-
| `BEING_TYPE` | `const BEING_TYPE`
|
|
1457
|
-
| `GEAR_TYPE_TO_KEY` | `const GEAR_TYPE_TO_KEY`
|
|
1458
|
-
| `isBeing` | `isBeing(fm)`
|
|
1459
|
-
| `deriveBeingInfo` | `deriveBeingInfo(sohl, index)` | `object\|null\|undefined` | deriving a being's info-block fields (`skills`, `gear`, `spells`, `talents`) from its raw embedded `sohl.items[]`, resolved against a content index; authored values always win over derived ones |
|
|
1512
|
+
| Export | Signature | Returns | Use it when |
|
|
1513
|
+
| ----------------------- | ----------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1514
|
+
| `DEFAULT_ITEM_ART` | `const DEFAULT_ITEM_ART` | — | reading the full map of default item artwork keyed by SoHL Item document subtype — the single source both the compendium builder and the runtime `SohlItem.getDefaultArtwork` read |
|
|
1515
|
+
| `defaultItemArt` | `defaultItemArt(type)` | `string` — the default image path | getting the default art path for a document subtype, throwing (fail-fast) rather than defaulting silently when the type is unknown |
|
|
1516
|
+
| `AFFILIATION_STANDINGS` | `const AFFILIATION_STANDINGS` | — | reading the closed set of stances an authored `relation` map may use between two affiliations |
|
|
1517
|
+
| `BEING_TYPE` | `const BEING_TYPE` | — | identifying the note type `"being"` |
|
|
1518
|
+
| `GEAR_TYPE_TO_KEY` | `const GEAR_TYPE_TO_KEY` | — | mapping each gear note type to its infobox group |
|
|
1519
|
+
| `isBeing` | `isBeing(fm)` | `boolean` | checking whether a note's frontmatter describes a being |
|
|
1460
1520
|
|
|
1461
1521
|
## `./hm3`
|
|
1462
1522
|
|
|
@@ -1567,14 +1627,13 @@ const config = defineConfig({
|
|
|
1567
1627
|
| `DEFAULT_PATHS` | `const DEFAULT_PATHS` | — | reading the conventional directory layout a build reads from and writes to, relative to `rootDir` |
|
|
1568
1628
|
| `DEFAULT_ADDRESS_SCHEME` | `const DEFAULT_ADDRESS_SCHEME` | — | reading an unconfigured repository's address-scheme defaults (`prefix`, where the content tree mounts inside the package) |
|
|
1569
1629
|
| `RETIRED_ADDRESS_KEYS` | `const RETIRED_ADDRESS_KEYS` | — | reading which address-scheme keys a configuration may no longer declare (e.g. `landing`) — declaring one is a refusal, not a silent no-op |
|
|
1570
|
-
| `SITE_MODES` | `const SITE_MODES` | — | reading the publishing modes `publish.site` may name, weakest first |
|
|
1571
1630
|
| `DERIVED_SYSTEM_VERSION` | `const DERIVED_SYSTEM_VERSION` | — | the loader-only symbol key `defineConfig` uses internally to receive a resolved system version; not something a configuration author writes |
|
|
1572
|
-
| `publishesContentPages` | `publishesContentPages(config)` | `boolean` | checking whether
|
|
1631
|
+
| `publishesContentPages` | `publishesContentPages(config)` | `boolean` | checking whether the authored content tree contains notes beyond its homepage, shared by site, PDF, index, and Foundry address emission |
|
|
1573
1632
|
| `DERIVED_HUGO_KEYS` | `const DERIVED_HUGO_KEYS` | — | reading which Hugo keys `site.hugo` may not declare because the site build generates them, each naming its source (declaring one is an error naming the key); a dotted key covers everything beneath it |
|
|
1574
1633
|
|
|
1575
1634
|
## `./config`
|
|
1576
1635
|
|
|
1577
|
-
The per-repository **packaging** configuration
|
|
1636
|
+
The per-repository **packaging** configuration is the `packageBuild:` section of `package-build.config.yaml`. The content configuration loader reads the same file, so `packageKind` and `foundryPackage` are declared once. The content and packaging validators each check their own keys.
|
|
1578
1637
|
|
|
1579
1638
|
```js
|
|
1580
1639
|
// Run from a consuming repository's root, where package-build.config.yaml lives.
|
|
@@ -1589,12 +1648,12 @@ console.log(config.stageDir);
|
|
|
1589
1648
|
| `DERIVED_MANIFEST_KEYS` | `const DERIVED_MANIFEST_KEYS` | — | reading which manifest keys a repository may not declare because the build derives them (declaring one is an error naming the key) |
|
|
1590
1649
|
| `resolvePackageBuildConfig` | `resolvePackageBuildConfig(shared)` | `Readonly<PackageBuildConfig>` | validating the `packageBuild:` section from an already-loaded shared configuration — the pure half, usable without touching disk |
|
|
1591
1650
|
| `loadPackageBuildConfig` | `loadPackageBuildConfig()` | `Readonly<PackageBuildConfig>` | reading and validating the repository's resolved package-build configuration from disk, read fresh on each call rather than cached at import |
|
|
1592
|
-
| `checkHomepage` | `checkHomepage(homepage, contentPackage)` | `void` | validating a resolved `homepage` against `contentPackage` — called by `
|
|
1651
|
+
| `checkHomepage` | `checkHomepage(homepage, contentPackage)` | `void` | validating a resolved `homepage` against `contentPackage` — called by `package-build site` before the generated `baseURL` is written, not by `resolvePackageBuildConfig` itself |
|
|
1593
1652
|
| `fail` | `fail(where, problem)` | `never` | rejecting a configured value from a sibling module, naming the dotted key path it was written under, so the loader can resolve it to a line and column |
|
|
1594
1653
|
|
|
1595
1654
|
## `./prettier`
|
|
1596
1655
|
|
|
1597
|
-
The shared Prettier configuration, published as a Prettier config module so an editor's format-on-save agrees with `
|
|
1656
|
+
The shared Prettier configuration, published as a Prettier config module so an editor's format-on-save agrees with `package-build format`, which already applies these rules without a consumer declaring anything.
|
|
1598
1657
|
|
|
1599
1658
|
```js
|
|
1600
1659
|
// prettier.config.mjs
|
|
@@ -1607,7 +1666,7 @@ export { default } from "@heroiclands/package-build/prettier";
|
|
|
1607
1666
|
|
|
1608
1667
|
## `./markdownlint`
|
|
1609
1668
|
|
|
1610
|
-
The shared markdownlint rules, as a markdownlint-cli2 options module, applied without a consumer declaring anything by `
|
|
1669
|
+
The shared markdownlint rules, as a markdownlint-cli2 options module, applied without a consumer declaring anything by `package-build markdown`. Exists for an editor's markdownlint extension, and for a consumer that wants to extend rather than replace the set.
|
|
1611
1670
|
|
|
1612
1671
|
```js
|
|
1613
1672
|
// .markdownlint-cli2.mjs
|
|
@@ -1841,6 +1900,7 @@ console.log(missingSources([["does/not/exist", "x"]]));
|
|
|
1841
1900
|
| `missingSources` | `missingSources(entries, cwd = process.cwd())` | `string[]` | checking a whole `[source, dest]` list for absent sources up front, so every problem is reported at once rather than one rebuild at a time |
|
|
1842
1901
|
| `copyTree` | `copyTree(src, dest, { transform } = {})` | `number` — files written | recursively copying a file or directory, optionally rewriting each file's content as it's staged instead of copying bytes verbatim |
|
|
1843
1902
|
| `stageAssets` | `stageAssets(entries, { cwd = process.cwd(), transform } = {})` | `{entries: number, files: number}` | copying every listed `[source, dest]` pair into the stage, refusing to start at all if any source is absent |
|
|
1903
|
+
| `resetStage` | `resetStage(root, stageDir)` | `boolean` — whether stage existed | clearing the assembled package before a complete build while preserving other generated outputs |
|
|
1844
1904
|
| `cleanBuildArtifacts` | `cleanBuildArtifacts(root, { extra = [], includeNodeModules = false } = {})` | `string[]` — directories removed | removing the build artefacts a repository regenerates, safely repeatable since an already-clean directory is not an error |
|
|
1845
1905
|
|
|
1846
1906
|
## `./templates`
|