@heroiclands/package-build 23.1.0 → 23.2.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 +71 -0
- package/bin/content-commands.mjs +68 -149
- package/bin/package-build.mjs +56 -10
- package/ci/check-banners.mjs +42 -6
- package/ci/confirm-npm-version.mjs +135 -0
- package/ci/content-format-reference.mjs +14 -5
- package/config.mjs +1 -0
- package/container.mjs +185 -4
- package/content-config.mjs +333 -210
- package/deploy.mjs +116 -10
- package/docs/api.md +238 -246
- package/docs/authoring/assets.md +11 -5
- package/docs/authoring/frontmatter.md +1 -1
- package/docs/authoring/links-and-markup.md +87 -0
- package/docs/commands.md +138 -99
- package/docs/configuration.md +277 -125
- package/docs/content-format.md +2 -0
- package/docs/diagnostics.md +48 -13
- package/docs/guides/book.md +341 -21
- package/docs/guides/e2e.md +13 -2
- package/docs/guides/icons.md +14 -4
- package/docs/guides/module-project.md +18 -8
- package/docs/guides/release-and-deploy.md +54 -6
- package/docs/guides/site.md +5 -2
- package/docs/project-setup.md +30 -10
- package/docs/reference/format-details.md +373 -170
- package/docs/reference/note-types.md +128 -109
- package/docs/reference/theme-pages.md +31 -6
- package/e2e.mjs +140 -28
- package/engine/actor-compiler.mjs +22 -31
- package/engine/address-charset.mjs +4 -17
- package/engine/address-fields.mjs +1 -1
- package/engine/address-render.mjs +12 -1
- package/engine/address-values.mjs +6 -0
- package/engine/address.mjs +46 -33
- package/engine/art-fields.mjs +30 -5
- package/engine/art-slots.mjs +10 -1
- package/engine/asset-bindings.mjs +12 -1
- package/engine/base-compiler.mjs +34 -65
- package/engine/being-age.mjs +2 -7
- package/engine/being-measurements.mjs +12 -1
- package/engine/calendar-artifacts.mjs +6 -0
- package/engine/calendar-choice.mjs +12 -1
- package/engine/calendar-format.mjs +12 -1
- package/engine/calendar-human.mjs +12 -1
- package/engine/compile-corpus.mjs +3 -1
- package/engine/content-address.mjs +9 -12
- package/engine/content-alerts.mjs +13 -1
- package/engine/content-blocks.mjs +14 -3
- package/engine/content-embeds.mjs +11 -3
- package/engine/content-figures.mjs +9 -0
- package/engine/content-footnotes.mjs +12 -1
- package/engine/content-format-check.mjs +11 -262
- package/engine/content-format.yaml +5 -2
- package/engine/content-images.mjs +3 -0
- package/engine/content-index.mjs +443 -20
- package/engine/content-links.mjs +29 -35
- package/engine/content-lint.mjs +2 -3
- package/engine/content-poetry.mjs +12 -1
- package/engine/content-slug.mjs +2 -14
- package/engine/content-spans.mjs +13 -1
- package/engine/content-tables.mjs +12 -1
- package/engine/culture-choice.mjs +210 -13
- package/engine/data-keys.mjs +19 -16
- package/engine/date-conversion.mjs +12 -1
- package/engine/declaration-check.mjs +9 -0
- package/engine/derived-fields.mjs +6 -7
- package/engine/diagnostics.mjs +34 -4
- package/engine/docs-checks.mjs +9 -0
- package/engine/document-subtypes.mjs +47 -34
- package/engine/event-views.mjs +139 -14
- package/engine/exported-scene.mjs +92 -28
- package/engine/extension-attributes.mjs +12 -1
- package/engine/field-spec.mjs +11 -102
- package/engine/folder-notes.mjs +0 -64
- package/engine/foreign-catalog.mjs +2 -1
- package/engine/format-generated.mjs +9 -0
- package/engine/foundry-entries.mjs +10 -28
- package/engine/frontmatter-lint.mjs +83 -392
- package/engine/frontmatter.mjs +20 -70
- package/engine/generate.mjs +10 -15
- package/engine/heading-attributes.mjs +12 -1
- package/engine/helpers.mjs +41 -102
- package/engine/holdings.mjs +1 -1
- package/engine/homepage.mjs +3 -10
- package/engine/ids.mjs +1 -167
- package/engine/index-records.mjs +6 -4
- package/engine/index.mjs +0 -3
- package/engine/infobox-render.mjs +15 -3
- package/engine/infobox.mjs +13 -14
- package/engine/item-compiler.mjs +4 -10
- package/engine/item-docs.mjs +3 -5
- package/engine/item-registry.mjs +2 -10
- package/engine/journals.mjs +1 -5
- package/engine/literature-notes.mjs +4 -12
- package/engine/macros.mjs +1 -2
- package/engine/map-graphviz.mjs +12 -1
- package/engine/markdown-expressions.mjs +12 -1
- package/engine/markdownlint-run.mjs +567 -0
- package/engine/metadata-index.mjs +42 -12
- package/engine/note-addresses.mjs +143 -35
- package/engine/note-claims.mjs +14 -28
- package/engine/note-dates.mjs +3 -3
- package/engine/note-frontmatter.mjs +6 -0
- package/engine/note-ids.mjs +8 -14
- package/engine/note-package.mjs +8 -25
- package/engine/note-state.mjs +1 -3
- package/engine/note-vocabulary.mjs +148 -84
- package/engine/number-words.mjs +12 -1
- package/engine/pack-config.mjs +15 -25
- package/engine/pack-router.mjs +10 -16
- package/engine/pathnames.mjs +8 -22
- package/engine/pdf-build.mjs +773 -121
- package/engine/pdf-coverage.mjs +188 -0
- package/engine/pdf-index.mjs +54 -7
- package/engine/pdf-pages.mjs +247 -0
- package/engine/pdf-render.mjs +114 -4
- package/engine/pdf-toc.mjs +29 -32
- package/engine/project-init.mjs +46 -6
- package/engine/prose-config.mjs +1 -1
- package/engine/prose-lint.mjs +52 -88
- package/engine/readability-lint.mjs +9 -0
- package/engine/reckoning-markers.mjs +12 -1
- package/engine/reference-targets.mjs +7 -0
- package/engine/runtime-only-fields.mjs +5 -8
- package/engine/scene-levels.mjs +2 -2
- package/engine/scenes.mjs +1 -1
- package/engine/shortcode-references.mjs +7 -0
- package/engine/site-build.mjs +30 -16
- package/engine/site-index.mjs +10 -16
- package/engine/site-preview.mjs +6 -0
- package/engine/site-root.mjs +8 -1
- package/engine/social-tie-terms.mjs +12 -1
- package/engine/social-ties.mjs +3 -0
- package/engine/sql-tables.mjs +56 -20
- package/engine/standing-terms.mjs +11 -1
- package/engine/standings.mjs +11 -27
- package/engine/system-block.mjs +39 -141
- package/engine/system-vocabulary.mjs +6 -0
- package/engine/walk-files.mjs +69 -0
- package/engine/web-wikilinks.mjs +23 -3
- package/engine/wikilink-syntax.mjs +32 -21
- package/engine/wikilinks.mjs +27 -16
- package/engine/yaml-lint.mjs +7 -4
- package/githooks/attribution.mjs +8 -0
- package/githooks/commit-message.mjs +9 -0
- package/hm3/actors.mjs +9 -48
- package/hm3/default-item-art.mjs +9 -9
- package/hm3/item-fields.mjs +2 -9
- package/hm3/template-priority.mjs +6 -7
- package/hugo-theme/data/banner-kinds.yaml +78 -0
- package/hugo-theme/data/banners.yaml +2 -3
- package/hugo-theme/layouts/404.html +3 -3
- package/hugo-theme/layouts/partials/banner-url.html +31 -7
- package/hugo-theme/layouts/partials/hero-banner.html +13 -14
- package/hugo-theme/layouts/partials/related.html +1 -1
- package/hugo-theme/layouts/partials/warn-missing-banner.html +1 -1
- package/hugo-theme/static/css/style.css +1 -1
- package/manifest.mjs +11 -4
- package/markdownlint-config.mjs +1 -1
- package/package.json +6 -3
- package/release.mjs +83 -18
- package/sohl/actors.mjs +16 -27
- package/sohl/default-item-art.mjs +3 -3
- package/sohl/document-subtypes.mjs +1 -16
- package/sohl/infobox.mjs +2 -3
- package/sohl/item-builders.mjs +5 -8
- package/sohl/item-fields.mjs +5 -35
- package/sohl/items.mjs +0 -4
- package/sohl/kb-passes.mjs +3 -3
- package/types/container.d.mts +116 -5
- package/types/content-config.d.mts +83 -35
- package/types/deploy.d.mts +42 -6
- package/types/e2e.d.mts +35 -3
- package/types/engine/address-charset.d.mts +4 -17
- package/types/engine/address.d.mts +17 -8
- package/types/engine/art-fields.d.mts +7 -4
- package/types/engine/art-slots.d.mts +6 -0
- package/types/engine/base-compiler.d.mts +15 -17
- package/types/engine/content-address.d.mts +9 -12
- package/types/engine/content-embeds.d.mts +4 -2
- package/types/engine/content-format-check.d.mts +0 -64
- package/types/engine/content-index.d.mts +82 -3
- package/types/engine/content-links.d.mts +2 -4
- package/types/engine/culture-choice.d.mts +51 -8
- package/types/engine/data-keys.d.mts +2 -2
- package/types/engine/derived-fields.d.mts +1 -2
- package/types/engine/diagnostics.d.mts +27 -4
- package/types/engine/document-subtypes.d.mts +12 -31
- package/types/engine/event-views.d.mts +14 -2
- package/types/engine/exported-scene.d.mts +3 -2
- package/types/engine/field-spec.d.mts +13 -122
- package/types/engine/folder-notes.d.mts +0 -39
- package/types/engine/foreign-catalog.d.mts +2 -1
- package/types/engine/foundry-entries.d.mts +4 -5
- package/types/engine/frontmatter-lint.d.mts +2 -2
- package/types/engine/frontmatter.d.mts +19 -45
- package/types/engine/generate.d.mts +1 -1
- package/types/engine/helpers.d.mts +25 -42
- package/types/engine/homepage.d.mts +3 -10
- package/types/engine/ids.d.mts +0 -114
- package/types/engine/index-records.d.mts +6 -4
- package/types/engine/index.d.mts +0 -1
- package/types/engine/infobox-render.d.mts +7 -1
- package/types/engine/infobox.d.mts +3 -2
- package/types/engine/item-docs.d.mts +1 -1
- package/types/engine/item-registry.d.mts +2 -4
- package/types/engine/literature-notes.d.mts +1 -1
- package/types/engine/markdownlint-run.d.mts +40 -0
- package/types/engine/metadata-index.d.mts +9 -1
- package/types/engine/note-addresses.d.mts +27 -2
- package/types/engine/note-claims.d.mts +3 -5
- package/types/engine/note-ids.d.mts +2 -4
- package/types/engine/note-package.d.mts +1 -1
- package/types/engine/note-state.d.mts +1 -3
- package/types/engine/note-vocabulary.d.mts +28 -21
- package/types/engine/pack-config.d.mts +2 -6
- package/types/engine/pack-router.d.mts +4 -4
- package/types/engine/pathnames.d.mts +3 -3
- package/types/engine/pdf-build.d.mts +98 -12
- package/types/engine/pdf-coverage.d.mts +60 -0
- package/types/engine/pdf-index.d.mts +34 -5
- package/types/engine/pdf-pages.d.mts +143 -0
- package/types/engine/pdf-render.d.mts +45 -1
- package/types/engine/pdf-toc.d.mts +12 -14
- package/types/engine/prose-config.d.mts +1 -1
- package/types/engine/prose-lint.d.mts +11 -10
- package/types/engine/runtime-only-fields.d.mts +2 -2
- package/types/engine/site-build.d.mts +9 -5
- package/types/engine/site-index.d.mts +4 -5
- package/types/engine/site-root.d.mts +1 -1
- package/types/engine/sql-tables.d.mts +31 -2
- package/types/engine/standing-terms.d.mts +2 -1
- package/types/engine/standings.d.mts +7 -9
- package/types/engine/system-block.d.mts +10 -44
- package/types/engine/walk-files.d.mts +15 -0
- package/types/engine/wikilink-syntax.d.mts +18 -19
- package/types/engine/yaml-lint.d.mts +5 -4
- package/types/hm3/actors.d.mts +1 -2
- package/types/hm3/item-fields.d.mts +2 -4
- package/types/hm3/template-priority.d.mts +6 -7
- package/types/manifest.d.mts +3 -2
- package/types/release.d.mts +12 -7
- package/types/sohl/actors.d.mts +2 -1
- package/types/sohl/document-subtypes.d.mts +1 -2
- package/types/sohl/item-fields.d.mts +3 -7
- package/engine/retired-fields.mjs +0 -631
- package/types/engine/retired-fields.d.mts +0 -354
package/docs/diagnostics.md
CHANGED
|
@@ -109,13 +109,11 @@ different lines or columns instead of collapsing onto the first.
|
|
|
109
109
|
frontmatter key** by searching the fence rather than the whole file — a bare
|
|
110
110
|
search for a key like `name` or `type` would routinely match a line of prose
|
|
111
111
|
first. Passing `value` narrows the match to the entry that carries it, which
|
|
112
|
-
is what a list-valued key (`
|
|
112
|
+
is what a list-valued key (`tags`) needs: the finding belongs on the
|
|
113
113
|
wrong entry, not on the key that introduces the list. `opts.topLevel`
|
|
114
114
|
requires the match at column 1, for a key name that is legal both at the top
|
|
115
|
-
level and nested
|
|
116
|
-
|
|
117
|
-
could resolve to the nested one and tell an author to delete a field they are
|
|
118
|
-
allowed to write.
|
|
115
|
+
level and nested — without it, a finding about the top-level key could
|
|
116
|
+
resolve to the nested one.
|
|
119
117
|
|
|
120
118
|
**`positionOfYamlPath(text, keyPath, opts)`** and
|
|
121
119
|
**`positionOfFrontmatterPath(raw, keyPath, opts)`** locate a node by
|
|
@@ -214,6 +212,48 @@ and the summary carries no position because it has none.
|
|
|
214
212
|
thalorna: 2572 notes — 2089 full, 464 draft, 19 stub.
|
|
215
213
|
```
|
|
216
214
|
|
|
215
|
+
## A worked case: a note's culture
|
|
216
|
+
|
|
217
|
+
`data.culture` has four findings, all errors. Three come from `package-build
|
|
218
|
+
lint` reading what a note wrote, and each sits on the line that makes the note
|
|
219
|
+
wrong. A setting guide with no culture is located at its `subType:` line, the key
|
|
220
|
+
whose value made it a setting guide:
|
|
221
|
+
|
|
222
|
+
```text
|
|
223
|
+
assets/content/Guides/G1.md:5:1: error: a setting guide introduces one culture, so this note must state `data.culture`, naming a culture lore note
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
The field on a `doc` of any other subType is located at the `culture:` key:
|
|
227
|
+
|
|
228
|
+
```text
|
|
229
|
+
assets/content/Guides/G2.md:8:3: error: `data.culture` is stated by a setting guide, and this note's `subType` is not `settingguide`
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
A `lore` note of `subType: culture` is its own culture. It may leave the field
|
|
233
|
+
out or name itself, by its shortcode or by any longer form of its Address; a
|
|
234
|
+
value naming any other note is located at the value, and the message gives the
|
|
235
|
+
Address the value names:
|
|
236
|
+
|
|
237
|
+
```text
|
|
238
|
+
assets/content/Lore/Hillfolk.md:8:12: error: data.culture reedflats-note-lore-reedfolk names another note; a culture note's data.culture names the note itself
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
The fourth comes from resolving cultures into the content index. A place or
|
|
242
|
+
affiliation with no culture of its own whose `data.parents` resolve to different
|
|
243
|
+
cultures is located at its `parents:` key, and names each culture with the
|
|
244
|
+
parent it came through:
|
|
245
|
+
|
|
246
|
+
```text
|
|
247
|
+
assets/content/Places/Causeway.md:8:3: error: data.parents resolve to different cultures (reedflats-note-lore-reedfolk via reedflats, reedflats-note-lore-hillfolk via stonecrest); state data.culture
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
A polity whose seat and governed places disagree is located at `seat:`, or at
|
|
251
|
+
`data:` when it states no seat. Because the index is read by every build, the
|
|
252
|
+
conflict fails the index and each command that reads it without collecting
|
|
253
|
+
problems, listing every conflict at once. Stating `data.culture` on the note
|
|
254
|
+
resolves it. The rules are under
|
|
255
|
+
[Culture in the index](reference/format-details.md#culture-in-the-index).
|
|
256
|
+
|
|
217
257
|
## Summary counts and prose are not findings
|
|
218
258
|
|
|
219
259
|
A run's progress and summary lines — `42 address(es) across 10 note(s).`,
|
|
@@ -256,18 +296,14 @@ all fails the run.
|
|
|
256
296
|
|
|
257
297
|
**A corpus problem always fails, regardless of severity or a `--strict`
|
|
258
298
|
flag.** When the content tree itself cannot be indexed — a note the walk
|
|
259
|
-
cannot record, most often a
|
|
299
|
+
cannot record, most often a declared `package:` key — the note is absent from
|
|
260
300
|
every other answer a command gives. Reporting it and still exiting `0` would
|
|
261
301
|
call the tree clean while silently omitting a note, so every command that
|
|
262
|
-
indexes a corpus (`lint`, `links`, `reachability`, `
|
|
263
|
-
`addresses diff`) fails on a corpus problem unconditionally, before it
|
|
302
|
+
indexes a corpus (`lint`, `links`, `reachability`, `addresses diff`) fails on a corpus problem unconditionally, before it
|
|
264
303
|
evaluates anything else.
|
|
265
304
|
|
|
266
305
|
**A few commands report advisory findings that never fail the run on their
|
|
267
|
-
own**, and say so where they emit them: `
|
|
268
|
-
content tree against the format specification as a progress report during a
|
|
269
|
-
migration, printing every finding as a `warning` and passing `--strict` to
|
|
270
|
-
promote a class to `error` only once that class has reached zero; `format`
|
|
306
|
+
own**, and say so where they emit them: `format`
|
|
271
307
|
reports where this repository's Prettier configuration diverges from the
|
|
272
308
|
shared convention as a `warning`, because a repository's own configuration
|
|
273
309
|
is allowed to win on purpose; `addresses diff` reports a withdrawn or renamed
|
|
@@ -283,7 +319,6 @@ over one would teach people to stop reading the report.
|
|
|
283
319
|
| command | fails when |
|
|
284
320
|
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
285
321
|
| `package-build lint [root]` | an address, frontmatter, schema, charset, icon or HTML finding is `error`-severity, or the corpus cannot be indexed |
|
|
286
|
-
| `package-build content-format notes [root]` | `--strict` was passed and it reported any finding (all findings are `error`-severity only under `--strict`), or the corpus cannot be indexed |
|
|
287
322
|
| `package-build content-format schema` | it reports any finding at all |
|
|
288
323
|
| `package-build content-format fields` | it reports any finding at all |
|
|
289
324
|
| `package-build links [root]` | it reports any finding at all, an index is unusable (a stale or unaddressable foreign manifest), or the corpus cannot be indexed |
|
package/docs/guides/book.md
CHANGED
|
@@ -9,7 +9,7 @@ subType: howto
|
|
|
9
9
|
|
|
10
10
|
`package-build pdf` selects notes from a content package and sets them as a
|
|
11
11
|
PDF. The website can publish the whole content tree; the book follows the
|
|
12
|
-
ordered document tree
|
|
12
|
+
ordered document tree each book declares. This makes the book's contents
|
|
13
13
|
an editorial choice. A note outside every selection remains in the content
|
|
14
14
|
package and on its site, but it has no book entry.
|
|
15
15
|
|
|
@@ -18,23 +18,36 @@ produce the PDF. Typst must be available on `PATH`, or named with `pdf.binary`.
|
|
|
18
18
|
The [command reference](../commands.md) lists the CLI options; the
|
|
19
19
|
[configuration reference](../configuration.md) lists the `pdf` keys.
|
|
20
20
|
|
|
21
|
-
## Declare the
|
|
21
|
+
## Declare the books
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
`pdf.books` lists one entry per PDF. A package that publishes one book lists
|
|
24
|
+
one; a package that publishes a world book and a book for each culture lists
|
|
25
|
+
them all, and `package-build pdf` builds every one. Each book needs an `id`, a
|
|
26
|
+
`title` and its tree of contents:
|
|
24
27
|
|
|
25
28
|
```yaml
|
|
26
29
|
pdf:
|
|
27
|
-
title: The Setting Guide
|
|
28
|
-
document: book.yaml
|
|
29
30
|
out: build/pdf
|
|
31
|
+
books:
|
|
32
|
+
- id: guide
|
|
33
|
+
title: The Setting Guide
|
|
34
|
+
subtitle: A Reader's Companion
|
|
35
|
+
document: book.yaml
|
|
36
|
+
out: setting
|
|
30
37
|
```
|
|
31
38
|
|
|
32
39
|
A tree containing only a homepage has no content pages for a book. With no
|
|
33
|
-
`pdf` block or no content tree, the command has nothing to build
|
|
34
|
-
and `pdf.document` are required together when `pdf` is declared.
|
|
40
|
+
`pdf` block or no content tree, the command has nothing to build and exits 0.
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
### The tree: `document` or `contents`
|
|
43
|
+
|
|
44
|
+
The tree is an ordered list of sections. Each section contains prose files,
|
|
45
|
+
note filters, or nested sections. A book gives its tree in exactly one of two
|
|
46
|
+
ways: `document` names a file that holds it, and `contents` writes it inline
|
|
47
|
+
in the configuration. A file suits a long tree; inline suits a short book that
|
|
48
|
+
reads best beside the other books it shares a package with.
|
|
49
|
+
|
|
50
|
+
`book.yaml` holds the tree under a `contents:` key:
|
|
38
51
|
|
|
39
52
|
```yaml
|
|
40
53
|
contents:
|
|
@@ -49,17 +62,299 @@ contents:
|
|
|
49
62
|
- filter: "type = 'place' AND subType = 'settlement'"
|
|
50
63
|
```
|
|
51
64
|
|
|
65
|
+
The same tree written inline sits under the book's own `contents`, without the
|
|
66
|
+
outer key:
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
pdf:
|
|
70
|
+
books:
|
|
71
|
+
- id: guide
|
|
72
|
+
title: The Setting Guide
|
|
73
|
+
contents:
|
|
74
|
+
- sectionName: Introduction
|
|
75
|
+
contents:
|
|
76
|
+
- file: prose/introduction.md
|
|
77
|
+
- sectionName: Places
|
|
78
|
+
contents:
|
|
79
|
+
- filter: "type = 'place'"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
A finding about an inline tree names `package-build.config.yaml` at the line
|
|
83
|
+
of the offending key; a finding about a tree file names that file.
|
|
84
|
+
|
|
52
85
|
The build keeps the order of prose and subsections as written. Notes selected
|
|
53
86
|
by a filter are ordered by their folded display name. The filter is a SQL
|
|
54
87
|
`WHERE` clause over this package's `notes` table; the build supplies
|
|
55
|
-
`SELECT * FROM notes`. A filter cannot choose another package's notes.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
88
|
+
`SELECT * FROM notes`. A filter cannot choose another package's notes. A
|
|
89
|
+
book's `front` lists Markdown files placed before its contents.
|
|
90
|
+
|
|
91
|
+
### The file stem and `--book`
|
|
92
|
+
|
|
93
|
+
A book's PDF is named `<out>-<version>.pdf`, where `out` is the book's **file
|
|
94
|
+
stem**. Without an `out`, the stem is `<package>-<id>`. A stem is one path
|
|
95
|
+
segment with no directory, and two books may not resolve to the same stem. The
|
|
96
|
+
version comes from `--book-version`; with none, the file is `<out>.pdf`. Every
|
|
97
|
+
book is written into the directory `pdf.out` names. A package that publishes
|
|
98
|
+
one book and keeps a file name of the form `<package>-<version>.pdf` declares
|
|
99
|
+
`out: <package>`.
|
|
100
|
+
|
|
101
|
+
`package-build pdf` builds every declared book in the order declared. `--book
|
|
102
|
+
<id>` builds the one book with that `id`:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
package-build pdf --book vedyara
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Coverage and home books, described below, are computed over every declared
|
|
109
|
+
book even when `--book` renders only one.
|
|
110
|
+
|
|
111
|
+
### Sections that select nothing
|
|
112
|
+
|
|
113
|
+
A section whose filters select no printable note is left out of the book
|
|
114
|
+
without a finding. A tree can therefore carry a section for a culture or a
|
|
115
|
+
period before any note belongs to it, and the book prints nothing for it.
|
|
116
|
+
|
|
117
|
+
A section that holds prose and no selected notes, such as a preface, prints
|
|
118
|
+
its prose. A **book** whose filters select no note at all, whatever prose it
|
|
119
|
+
holds, is an error at its `id`, and that book is not built while the others
|
|
120
|
+
are:
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
package-build.config.yaml:9:15: error: book `sinale` selects no note
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Coverage and home books
|
|
127
|
+
|
|
128
|
+
Several books draw on one content package, so the question "is every note in
|
|
129
|
+
some book?" belongs to the set of books, not to any one of them. After every
|
|
130
|
+
book's filters have run against the one corpus, the build reports each
|
|
131
|
+
printable note that no book selects. A **printable** note is a note that is
|
|
132
|
+
neither a stub nor tagged `gm`, and that `pdf.unprinted` does not name.
|
|
133
|
+
|
|
134
|
+
Two shared keys under `pdf` control the report:
|
|
135
|
+
|
|
136
|
+
- `pdf.unprinted` is a `WHERE` clause over `notes` that names notes belonging
|
|
137
|
+
in no book, such as folder notes: `unprinted: "type = 'folder'"`. Coverage
|
|
138
|
+
skips them. It has no default, so set it for any note type that has no place
|
|
139
|
+
in a book.
|
|
140
|
+
- `pdf.coverage` is `warning` (the default), `error` or `off`. A printable note
|
|
141
|
+
no book selects is reported at that severity, at the note's `type:` line.
|
|
142
|
+
`off` reports nothing. `error` makes the command exit 1.
|
|
143
|
+
|
|
144
|
+
The finding carries the standard shape, `file:line:column: severity: message`,
|
|
145
|
+
with the path of the note relative to the working directory:
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
assets/content/Guides/Fieldcraft.md:2:1: warning: no book selects this note; add it to a book's query or to `pdf.unprinted`
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
To clear the finding, add the note to a book's query or name it in
|
|
152
|
+
`pdf.unprinted`.
|
|
153
|
+
|
|
154
|
+
### A note several books select
|
|
155
|
+
|
|
156
|
+
A note may be selected by more than one book, and it prints in each. Its
|
|
157
|
+
**home book** is the first book in `pdf.books` that selects it. A note a book
|
|
158
|
+
selects twice counts as that one book's and prints at each position.
|
|
159
|
+
|
|
160
|
+
The home is a property of the order the books are listed in and the queries
|
|
161
|
+
they hold. To move a note's home, reorder the books, or narrow the query of the
|
|
162
|
+
book that currently holds it so that it does not select the note. Nothing
|
|
163
|
+
else sets a home.
|
|
164
|
+
|
|
165
|
+
### A reference to a note in another book
|
|
166
|
+
|
|
167
|
+
A PDF link cannot reach into another file, so a wikilink to a note that another
|
|
168
|
+
book is home to is not a link. It prints the words the link carried, then the
|
|
169
|
+
home book's title and the page the note's entry starts on there:
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
the Lyrebird Inn (The Tenebrae Volume, p. 214)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Which form a wikilink takes depends on where its target is printed:
|
|
176
|
+
|
|
177
|
+
| The target is | The link prints |
|
|
178
|
+
| ------------------------------------------------------------- | ----------------------------------------- |
|
|
179
|
+
| An entry of the same book, including a note the book reprints | An internal destination |
|
|
180
|
+
| An entry of another book, and not of this one | `Name (_Book title_, p. N)`, with no link |
|
|
181
|
+
| A note in no book | The web address of the note's page |
|
|
182
|
+
|
|
183
|
+
The page is the page the PDF itself numbers, which is the number printed in the
|
|
184
|
+
footer and used by the contents and the index, so the printed `p. N` is the
|
|
185
|
+
physical page of the PDF. A note the book reprints, or prints in two places,
|
|
186
|
+
has one page in its home book: a reference from a third book names the home
|
|
187
|
+
book and the page of the home book's first entry for it. Infobox links and
|
|
188
|
+
generated sections follow the same table.
|
|
189
|
+
|
|
190
|
+
The page is read from the laid-out book, so the build makes two passes:
|
|
191
|
+
|
|
192
|
+
1. **Pass one** renders every declared book, with `p. ?` in place of each
|
|
193
|
+
cross-book page, lays each out with `typst eval`, and writes
|
|
194
|
+
`pages.json` beside the books in `pdf.out`:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"sohl-thalorna-place-lyrebird-inn": { "book": "tenebrae", "page": 214 }
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The keys are the notes' canonical addresses in sorted order; the file is
|
|
203
|
+
identical across builds of unchanged sources.
|
|
204
|
+
|
|
205
|
+
2. **Pass two** renders every book again with those pages and lays them out
|
|
206
|
+
again. The words `(The Tenebrae Volume, p. 214)` are wider than `p. ?`, so a
|
|
207
|
+
page can move. When no page moved, pass two is the output. When one did, the
|
|
208
|
+
build renders once more with the new pages and reports every note whose page
|
|
209
|
+
still differs from the page printed for it, as a warning at the note's file.
|
|
59
210
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
211
|
+
A build that prints no cross-book reference, such as a package with one book,
|
|
212
|
+
is laid out once. Rendering and laying out every book happens for each build
|
|
213
|
+
with `--book` too, because a page in one book is read from another; only the
|
|
214
|
+
requested books are compiled. `--no-compile` runs neither pass: the source
|
|
215
|
+
prints `p. ?` for each cross-book reference and no `pages.json` is written.
|
|
216
|
+
|
|
217
|
+
Two builds produce identical PDFs only when Typst embeds the same creation
|
|
218
|
+
time. Set `SOURCE_DATE_EPOCH` for a reproducible build.
|
|
219
|
+
|
|
220
|
+
### Worked example: two culture books and a World book
|
|
221
|
+
|
|
222
|
+
A package publishes a book for each of two cultures and a World book that
|
|
223
|
+
gathers every region:
|
|
224
|
+
|
|
225
|
+
```yaml
|
|
226
|
+
pdf:
|
|
227
|
+
out: build/pdf
|
|
228
|
+
unprinted: "type = 'folder'"
|
|
229
|
+
books:
|
|
230
|
+
- id: vedyara
|
|
231
|
+
title: Vedyara
|
|
232
|
+
contents:
|
|
233
|
+
- sectionName: Vedyara
|
|
234
|
+
contents:
|
|
235
|
+
- filter: "data.culture = 'thalorna-note-lore-vedyariclt'"
|
|
236
|
+
- id: okharin
|
|
237
|
+
title: Okharin
|
|
238
|
+
contents:
|
|
239
|
+
- sectionName: Okharin
|
|
240
|
+
contents:
|
|
241
|
+
- filter: "data.culture = 'thalorna-note-lore-okharinclt'"
|
|
242
|
+
- id: world
|
|
243
|
+
title: The World of Thalorna
|
|
244
|
+
contents:
|
|
245
|
+
- sectionName: Regions
|
|
246
|
+
contents:
|
|
247
|
+
- filter: "type = 'place' AND subType = 'region'"
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The content tree holds these notes:
|
|
251
|
+
|
|
252
|
+
| Note | Type and subtype | Culture | Selected by |
|
|
253
|
+
| ---------------------- | ----------------- | ------- | ---------------- |
|
|
254
|
+
| `Places/Ashmere.md` | place, region | Vedyara | `vedyara`, world |
|
|
255
|
+
| `Places/Fordholm.md` | place, settlement | Vedyara | `vedyara` |
|
|
256
|
+
| `Places/Stormhaven.md` | place, settlement | Okharin | `okharin` |
|
|
257
|
+
| `Places/The Reach.md` | place, region | none | `world` |
|
|
258
|
+
| `Guides/Fieldcraft.md` | doc, howto | none | no book |
|
|
259
|
+
| `Folders/Places.md` | folder | none | `pdf.unprinted` |
|
|
260
|
+
|
|
261
|
+
`Ashmere` is a region of the Vedyara culture, so both the `vedyara` book and
|
|
262
|
+
the `world` book select it. `vedyara` is listed first, so it is Ashmere's home.
|
|
263
|
+
`Fieldcraft` matches no filter, so it is the one coverage finding. The folder
|
|
264
|
+
note is named by `pdf.unprinted` and is not a candidate at all.
|
|
265
|
+
|
|
266
|
+
Running `package-build pdf` first reports one finding on stderr:
|
|
267
|
+
|
|
268
|
+
```text
|
|
269
|
+
assets/content/Guides/Fieldcraft.md:2:1: warning: no book selects this note; add it to a book's query or to `pdf.unprinted`
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
then, for each book, a line counting its entries, prose files and sections and
|
|
273
|
+
the path of its Typst source (and of its PDF when Typst compiles it), and then
|
|
274
|
+
the summary:
|
|
275
|
+
|
|
276
|
+
```text
|
|
277
|
+
vedyara: 2 entries, 2 notes, 0 without a culture
|
|
278
|
+
okharin: 1 entry, 1 note, 0 without a culture
|
|
279
|
+
world: 2 entries, 2 notes, 1 without a culture
|
|
280
|
+
5 printable notes, 1 in no book, 1 in pdf.unprinted
|
|
281
|
+
Ashmere (Places/Ashmere.md) is printed by vedyara, world; home: vedyara
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Each book line gives its entries (a note printed at two positions is two
|
|
285
|
+
entries), its distinct notes, and how many of those carry no `data.culture`.
|
|
286
|
+
The `world` book's count of one is `The Reach`. The note path in the summary is
|
|
287
|
+
relative to the content root, while a finding's path is relative to the working
|
|
288
|
+
directory. The totals line counts the
|
|
289
|
+
printable notes that are not in `pdf.unprinted`, the ones among them that no
|
|
290
|
+
book selects, and the notes `pdf.unprinted` names. A final line appears for
|
|
291
|
+
every note that several books select, in book order and then path order,
|
|
292
|
+
naming the books that print it and its home.
|
|
293
|
+
|
|
294
|
+
To make `world` the home of Ashmere, list it before `vedyara`. To keep
|
|
295
|
+
`vedyara` first and still have `world` own the region, narrow the `vedyara`
|
|
296
|
+
filter with `AND NOT (type = 'place' AND subType = 'region')`; Ashmere is then
|
|
297
|
+
selected by `world` alone, its home is `world`, and its summary line
|
|
298
|
+
disappears.
|
|
299
|
+
|
|
300
|
+
## The cover page and the title page
|
|
301
|
+
|
|
302
|
+
A book opens on a **cover page** when it declares a `coverImage`, a path
|
|
303
|
+
resolved against the directory the configuration sits in:
|
|
304
|
+
|
|
305
|
+
```yaml
|
|
306
|
+
books:
|
|
307
|
+
- id: world
|
|
308
|
+
title: The World of Thalorna
|
|
309
|
+
subtitle: A Song of Heroic Lands Sourcebook
|
|
310
|
+
coverImage: assets/images/covers/world.webp
|
|
311
|
+
document: world.yaml
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
The image fills the page, cropped to fit, and is page 1. The book's title and
|
|
315
|
+
subtitle are centred in white in the upper third, over a translucent dark band
|
|
316
|
+
so they read over any art. The cover carries no running footer and no page
|
|
317
|
+
number. A book without `coverImage` begins on its title page.
|
|
318
|
+
|
|
319
|
+
The **title page** shows the book's title, subtitle and version, then the
|
|
320
|
+
package's people, one per line. The people come from the top-level `authors`
|
|
321
|
+
list, shared by every book, each entry a `name` and an optional `role`:
|
|
322
|
+
|
|
323
|
+
```yaml
|
|
324
|
+
authors:
|
|
325
|
+
- name: Tom Rodriguez
|
|
326
|
+
role: author
|
|
327
|
+
- name: Tom Rodriguez
|
|
328
|
+
role: artist
|
|
329
|
+
- name: Ada Quill
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
A person with a role prints as `Name, Role` with the role in title case, and
|
|
333
|
+
one without prints as `Name`. The role is one of `author`, `designer`,
|
|
334
|
+
`developer`, `editor`, `proofreader`, `artist`, `cartographer`, `layout`,
|
|
335
|
+
`playtester` and `translator`. A person who holds two roles is listed twice.
|
|
336
|
+
|
|
337
|
+
```text
|
|
338
|
+
Tom Rodriguez, Author
|
|
339
|
+
Tom Rodriguez, Artist
|
|
340
|
+
Ada Quill
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
At the foot of the title page sit the copyright and licence statements, set
|
|
344
|
+
under `pdf` and shared by every book:
|
|
345
|
+
|
|
346
|
+
```yaml
|
|
347
|
+
pdf:
|
|
348
|
+
copyright: © 2026 Tom Rodriguez
|
|
349
|
+
license: |
|
|
350
|
+
Text is licensed under CC BY-SA 4.0.
|
|
351
|
+
Code is licensed under GPL-3.0-or-later.
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Both are optional, and the foot prints whichever is given. `copyright` is one
|
|
355
|
+
line; `license` may run to several. The [configuration
|
|
356
|
+
reference](../configuration.md#authors) lists the `authors` keys and the
|
|
357
|
+
closed role list.
|
|
63
358
|
|
|
64
359
|
## Control a section's page
|
|
65
360
|
|
|
@@ -123,6 +418,25 @@ the book prints adds the page it appears on. A term mentioned several times on
|
|
|
123
418
|
one page lists that page once, and a note printed under more than one section
|
|
124
419
|
is listed once, with every page it occupies.
|
|
125
420
|
|
|
421
|
+
**An index lists the notes its own book is home to.** A note's home is the
|
|
422
|
+
first book in `pdf.books` that selects it. In a package of several books:
|
|
423
|
+
|
|
424
|
+
- A note a book reprints from another book's home has no entry in the
|
|
425
|
+
reprinting book. Its term, with its aliases and event names, is in its home
|
|
426
|
+
book's index, and a link to it from the reprinting book adds nothing there.
|
|
427
|
+
- The pages an index lists are those of its own book, taken from the same table
|
|
428
|
+
as the cross-book references (`pages.json`), so the page a reference prints
|
|
429
|
+
for a note is the page its home book's index lists for the note's own entry.
|
|
430
|
+
- A mention of a note another book prints is not a term of the mentioning
|
|
431
|
+
book. The mention reads `Name (_Book title_, p. N)` in the text, and the note's
|
|
432
|
+
entry and its page are in the other book's index.
|
|
433
|
+
|
|
434
|
+
Set [`pdf.indexSeeAlso`](../configuration.md) to `true` to list those mentions
|
|
435
|
+
too. Each note another book prints that this book mentions in authored prose
|
|
436
|
+
then has a line, filed under its name:
|
|
437
|
+
|
|
438
|
+
> Sword: _Book A_, p. 12
|
|
439
|
+
|
|
126
440
|
Two kinds of link add nothing:
|
|
127
441
|
|
|
128
442
|
- **Links in generated sections** such as "Within" or "Governed by". They name
|
|
@@ -155,8 +469,10 @@ for them. A package can choose families and add a font directory:
|
|
|
155
469
|
|
|
156
470
|
```yaml
|
|
157
471
|
pdf:
|
|
158
|
-
|
|
159
|
-
|
|
472
|
+
books:
|
|
473
|
+
- id: guide
|
|
474
|
+
title: The Setting Guide
|
|
475
|
+
document: book.yaml
|
|
160
476
|
fonts:
|
|
161
477
|
serif: Libertinus Serif
|
|
162
478
|
sans: Libertinus Sans
|
|
@@ -181,10 +497,11 @@ the font registry.
|
|
|
181
497
|
package-build pdf
|
|
182
498
|
package-build pdf --no-compile
|
|
183
499
|
package-build pdf --out build/book
|
|
500
|
+
package-build pdf --book vedyara
|
|
184
501
|
```
|
|
185
502
|
|
|
186
503
|
`--no-compile` emits the Typst source and staged images without invoking
|
|
187
|
-
Typst. The source and assets sit under the output directory, because Typst
|
|
504
|
+
Typst, and so without measuring pages. The source and assets sit under the output directory, because Typst
|
|
188
505
|
reads paths relative to its compilation root. An authored image from this
|
|
189
506
|
package can be staged into the book. A remote image or one owned by another
|
|
190
507
|
package cannot be read by this build; the build reports that limitation.
|
|
@@ -203,7 +520,10 @@ so their links follow their own rule, because a book is often a selection:
|
|
|
203
520
|
- A name whose note is in the book is an internal link followed by the page
|
|
204
521
|
that note's entry starts on, printed as the contents prints it:
|
|
205
522
|
`Ford (p. 12)`. The number is Typst's own, read after layout.
|
|
206
|
-
- A name whose note is
|
|
207
|
-
|
|
523
|
+
- A name whose note is printed by another book is followed by that book and
|
|
524
|
+
page, `Ford (_The Tenebrae Volume_, p. 12)`, with no link; see
|
|
525
|
+
[a reference to a note in another book](#a-reference-to-a-note-in-another-book).
|
|
526
|
+
- A name whose note is in no book is printed as plain text, with no link, no
|
|
527
|
+
page and no finding.
|
|
208
528
|
|
|
209
529
|
Links an author wrote keep the rules above and carry no page number.
|
package/docs/guides/e2e.md
CHANGED
|
@@ -57,6 +57,9 @@ this harness and a Foundry license available to the test container:
|
|
|
57
57
|
FOUNDRYVTT_TEST_DATA=/path/to/isolated-foundry-test-data
|
|
58
58
|
FOUNDRYVTT_TEST_LICENSE_KEY=replace-with-test-license-key
|
|
59
59
|
FOUNDRYVTT_TEST_PORT=30003
|
|
60
|
+
FOUNDRYVTT_CACHE=/path/to/foundry-release-cache
|
|
61
|
+
FOUNDRY_USERNAME=your-foundryvtt-com-account
|
|
62
|
+
FOUNDRY_PASSWORD=replace-with-account-password
|
|
60
63
|
# FOUNDRYVTT_TEST_VERSION=14.367
|
|
61
64
|
```
|
|
62
65
|
|
|
@@ -82,8 +85,16 @@ own `.env.local` because that ignored file is not copied with the branch.
|
|
|
82
85
|
The test data path is a Foundry data root, beneath which the harness creates
|
|
83
86
|
`Data/worlds/` and installs the package. Use an absolute path; `~` and shell
|
|
84
87
|
variables are not expanded in `.env.local`. Set `FOUNDRYVTT_TEST_VERSION` to
|
|
85
|
-
select a specific Foundry build for routine runs
|
|
86
|
-
|
|
88
|
+
select a specific Foundry build for routine runs; the container then runs the
|
|
89
|
+
image made for that build. The first run downloads the release, which needs
|
|
90
|
+
`FOUNDRY_USERNAME` and `FOUNDRY_PASSWORD`, and the image keeps the archive in
|
|
91
|
+
`FOUNDRYVTT_CACHE`, or in `container_cache` beneath the data root when that is
|
|
92
|
+
unset. Once the archive is cached and the stage has a licence, later runs
|
|
93
|
+
start without signing in to foundryvtt.com, so its rate limit never stops a
|
|
94
|
+
run. Under rootless Docker, set
|
|
95
|
+
`FOUNDRYVTT_CONTAINER_USER=0:0`: container root is then the host user, so every
|
|
96
|
+
file under the data root belongs to them, where the image would otherwise run
|
|
97
|
+
Foundry as user 1000. With the local settings in place, seed the world:
|
|
87
98
|
|
|
88
99
|
```bash
|
|
89
100
|
package-build e2e seed
|
package/docs/guides/icons.md
CHANGED
|
@@ -49,6 +49,11 @@ slots. A pathname with slashes or an extension is not an art-slot address.
|
|
|
49
49
|
| `data.tokenIcon` | Actor token art; follows `data.icon` when unset |
|
|
50
50
|
| `data.banner` | Page hero image for the site |
|
|
51
51
|
|
|
52
|
+
A map's picture in Foundry's Scene lists is not an art slot: a `map` note names
|
|
53
|
+
it with `data.thumbnail`, an `image` Address the build writes into the Scene's
|
|
54
|
+
`thumb`. The [map reference](../reference/format-details.md#the-thumbnail)
|
|
55
|
+
describes it.
|
|
56
|
+
|
|
52
57
|
An Item without `data.icon` uses its builder's configured default art. An
|
|
53
58
|
Actor without `data.icon` uses its compiled default art. Write `data.icon`
|
|
54
59
|
when the note needs a particular image. A portrait within the prose is an
|
|
@@ -58,7 +63,10 @@ it does not set a document's profile art. The
|
|
|
58
63
|
slot's type and document destination.
|
|
59
64
|
|
|
60
65
|
A being's `subType` selects its compiled default art: `character` and `npc`
|
|
61
|
-
use person art, and `creature` uses creature art.
|
|
66
|
+
use person art, and `creature` uses creature art. HM3's built-in Actor and Item
|
|
67
|
+
defaults point into the system's `assets/images/` and `assets/icons/` trees,
|
|
68
|
+
introduced by [HM3's asset-path migration](https://git.pupluppy.org/HeroicLands/HarnMaster-3-FoundryVTT/pulls/60).
|
|
69
|
+
Use these defaults with an HM3 release that includes those assets.
|
|
62
70
|
|
|
63
71
|
## Write an inline icon in prose
|
|
64
72
|
|
|
@@ -98,8 +106,10 @@ book:
|
|
|
98
106
|
|
|
99
107
|
```yaml
|
|
100
108
|
pdf:
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
books:
|
|
110
|
+
- id: guide
|
|
111
|
+
title: The Setting Guide
|
|
112
|
+
document: book.yaml
|
|
103
113
|
iconFonts:
|
|
104
114
|
fontawesome: assets/fonts/fa-solid-900.ttf
|
|
105
115
|
```
|
|
@@ -123,6 +133,6 @@ The content index assigns addresses to image assets. The lint reports unknown
|
|
|
123
133
|
inline names and invalid art addresses. A documentation package has no packs,
|
|
124
134
|
so it skips `package compile`. Inspect a compiled Actor or Item's
|
|
125
135
|
`img`, an Actor's `prototypeToken.texture.src`, and a map's `background.src`
|
|
126
|
-
when checking document art. Inspect the site page and emitted Typst source for
|
|
136
|
+
and `thumb` when checking document art. Inspect the site page and emitted Typst source for
|
|
127
137
|
inline icons and banners. The [command reference](../commands.md) gives the
|
|
128
138
|
available build and lint options.
|
|
@@ -366,7 +366,9 @@ order.
|
|
|
366
366
|
gives a usable overview of areas, peoples, institutions, and daily life, then
|
|
367
367
|
links to the detailed notes. Use `subType: settingguide` for that entry point;
|
|
368
368
|
`concept` explains one subject, `reference` serves lookup, and `userguide`
|
|
369
|
-
explains the Foundry controls.
|
|
369
|
+
explains the Foundry controls. A setting guide is a culture's guide to the
|
|
370
|
+
setting, so it names its culture in `data.culture`, the Address of a `lore` note
|
|
371
|
+
of `subType: culture`; a setting guide without one is an error. For example, a guide at
|
|
370
372
|
`assets/content/Guides/Reed_Flats.md` can begin:
|
|
371
373
|
|
|
372
374
|
```markdown
|
|
@@ -376,6 +378,8 @@ name: { full: The Reed Flats Guide }
|
|
|
376
378
|
type: doc
|
|
377
379
|
subType: settingguide
|
|
378
380
|
description: A starting point for adventures in the Reed Flats.
|
|
381
|
+
data:
|
|
382
|
+
culture: lore-reedfolk
|
|
379
383
|
---
|
|
380
384
|
|
|
381
385
|
The river trade links the settlements of the Reed Flats. Their routes and
|
|
@@ -630,9 +634,7 @@ packageBuild:
|
|
|
630
634
|
|
|
631
635
|
manifest:
|
|
632
636
|
title: Acme Bestiary
|
|
633
|
-
|
|
634
|
-
authors:
|
|
635
|
-
- name: Acme
|
|
637
|
+
descriptionHtml: Creatures of the reed flats, as compendium journals.
|
|
636
638
|
license: LICENSE.md
|
|
637
639
|
readme: README.md
|
|
638
640
|
languages:
|
|
@@ -649,14 +651,21 @@ packageBuild:
|
|
|
649
651
|
`assets:` is a copy list, from the repository into the stage. `manifest:` is
|
|
650
652
|
everything about the manifest that cannot be derived from `package.json` or from
|
|
651
653
|
the keys above — the human-facing identity, and the files Foundry links to.
|
|
652
|
-
`title` is required by Foundry and has no derivation; supply it.
|
|
654
|
+
`title` is required by Foundry and has no derivation; supply it. The manifest's
|
|
655
|
+
`authors` is derived too, from the top-level `authors` list, which names the
|
|
656
|
+
package's people once for the manifest, the site and the book:
|
|
657
|
+
|
|
658
|
+
```yaml
|
|
659
|
+
authors:
|
|
660
|
+
- name: Acme
|
|
661
|
+
```
|
|
653
662
|
|
|
654
663
|
`packFolders` may name only packs this package ships, and the build compares the
|
|
655
664
|
two lists rather than trusting them to agree:
|
|
656
665
|
|
|
657
666
|
```console
|
|
658
667
|
$ npx package-build manifest
|
|
659
|
-
package-build.config.yaml:
|
|
668
|
+
package-build.config.yaml:34:21: error: packFolders: folder "Acme Bestiary" names pack "items", which this package does not ship (packs: journals)
|
|
660
669
|
package-build: packFolders names 1 pack this package does not ship (reported above). Foundry skips a name it cannot resolve, so the folder would ship missing those packs — correct `packageBuild.manifest.packFolders`.
|
|
661
670
|
```
|
|
662
671
|
|
|
@@ -862,8 +871,9 @@ None of them is needed to build a package.
|
|
|
862
871
|
|
|
863
872
|
**A website.** Every package publishes one — at the least, the homepage note
|
|
864
873
|
from step 5 — at `https://www.heroiclands.org/<contentPackage>/`. Add that
|
|
865
|
-
address to `package.json` as `homepage`, with a `description`
|
|
866
|
-
|
|
874
|
+
address to `package.json` as `homepage`, with a `description` beside it, list
|
|
875
|
+
the package's people in `authors` in `package-build.config.yaml`, and add a
|
|
876
|
+
`packageBuild.manifest.title`. The theme the site renders
|
|
867
877
|
through ships with this package, so nothing else is installed. Then `package-build deps fetch` caches the
|
|
868
878
|
organisation's navigation, and `package-build site` writes the whole Hugo
|
|
869
879
|
source tree under `build/hugo/` — the configuration generated from those
|