@heroiclands/package-build 22.12.3 → 22.13.1
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 +19 -0
- package/README.md +2 -2
- package/docs/api.md +42 -40
- package/docs/commands.md +0 -3
- package/docs/content-format.md +94 -84
- package/docs/getting-started.md +1 -3
- package/engine/address.mjs +39 -153
- package/engine/art-fields.mjs +1 -1
- package/engine/bundles.mjs +3 -2
- package/engine/content-address.mjs +6 -9
- package/engine/content-index.mjs +8 -10
- package/engine/content-links.mjs +9 -17
- package/engine/content-tables.mjs +1 -1
- package/engine/folder-notes.mjs +2 -1
- package/engine/foundry-entries.mjs +4 -8
- package/engine/frontmatter-lint.mjs +2 -2
- package/engine/frontmatter.mjs +2 -2
- package/engine/homepage.mjs +3 -3
- package/engine/item-compiler.mjs +7 -2
- package/engine/map-places.mjs +3 -1
- package/engine/metadata-index.mjs +23 -6
- package/engine/note-addresses.mjs +27 -9
- package/engine/note-ids.mjs +7 -2
- package/engine/note-vocabulary.mjs +24 -0
- package/engine/pack-router.mjs +7 -3
- package/engine/place-relations.mjs +4 -4
- package/engine/reference-targets.mjs +7 -7
- package/engine/shortcode-references.mjs +1 -1
- package/engine/site-index.mjs +8 -39
- package/engine/sql-tables.mjs +1 -1
- package/engine/system-block.mjs +19 -0
- package/engine/systems.mjs +4 -1
- package/engine/web-wikilinks.mjs +3 -3
- package/engine/wikilinks.mjs +31 -106
- package/hm3/actors.mjs +7 -2
- package/package.json +2 -3
- package/sohl/infobox.mjs +2 -2
- package/types/engine/address.d.mts +21 -88
- package/types/engine/content-address.d.mts +3 -6
- package/types/engine/content-links.d.mts +2 -6
- package/types/engine/frontmatter.d.mts +1 -1
- package/types/engine/homepage.d.mts +2 -2
- package/types/engine/note-addresses.d.mts +2 -0
- package/types/engine/system-block.d.mts +11 -0
- package/types/engine/systems.d.mts +2 -0
- package/bin/heroiclands-content-language-server.mjs +0 -8
- package/docs/content-language-server.md +0 -25
- package/engine/content-language-server.mjs +0 -439
- package/types/engine/content-language-server.d.mts +0 -64
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @heroiclands/package-build
|
|
2
2
|
|
|
3
|
+
## 22.13.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
Content authors can keep pinned document identities and compendium placement alongside shared note facts.
|
|
8
|
+
|
|
9
|
+
## 22.13.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
**Content links**
|
|
14
|
+
|
|
15
|
+
- Ordinary wikilinks open readable notes by default; image embeds and art fields resolve systemless assets.
|
|
16
|
+
- Readable notes use `note` addresses, while explicit game systems select Actors and Items and `none` selects systemless targets.
|
|
17
|
+
|
|
18
|
+
**Editor navigation**
|
|
19
|
+
|
|
20
|
+
- Install `@heroiclands/content-language-server` for content note search and navigation in an editor.
|
|
21
|
+
|
|
3
22
|
## 22.12.3
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -14,8 +14,8 @@ The content half is documented separately in **[CONTENT.md](CONTENT.md)** — th
|
|
|
14
14
|
note format, the pack pipeline, and the configuration contract a content tree
|
|
15
15
|
declares itself with.
|
|
16
16
|
|
|
17
|
-
Editor navigation
|
|
18
|
-
[content
|
|
17
|
+
Editor navigation for content projects is provided by
|
|
18
|
+
[`@heroiclands/content-language-server`](https://github.com/HeroicLands/content-language-server).
|
|
19
19
|
|
|
20
20
|
## Install
|
|
21
21
|
|
package/docs/api.md
CHANGED
|
@@ -119,28 +119,29 @@ Deterministic document ids, derived by hashing rather than stored, so compile pa
|
|
|
119
119
|
|
|
120
120
|
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.
|
|
121
121
|
|
|
122
|
-
| Export | Signature
|
|
123
|
-
| --------------------------- |
|
|
124
|
-
| `SYSTEM_DATA_KEY` | `const SYSTEM_DATA_KEY`
|
|
125
|
-
| `BLOCK_DOCUMENT_PROPERTIES` | `const BLOCK_DOCUMENT_PROPERTIES`
|
|
126
|
-
| `BLOCK_DIRECTIVES` | `const BLOCK_DIRECTIVES`
|
|
127
|
-
| `SYSTEM_BLOCK_KEYS` | `const SYSTEM_BLOCK_KEYS`
|
|
128
|
-
| `setPath` | `setPath(target, dotted, value)`
|
|
129
|
-
| `systemBlock` | `systemBlock(fm, block)`
|
|
130
|
-
| `carriesSystemBlock` | `carriesSystemBlock(fm, block)`
|
|
131
|
-
| `systemData` | `systemData(fm, block)`
|
|
132
|
-
| `blockField` | `blockField(fm, block, key, defaultValue)`
|
|
133
|
-
| `sharedProperty` | `sharedProperty(fm, source, defaultValue)`
|
|
134
|
-
| `blockProperty` | `blockProperty(fm, block, key, defaultValue)`
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
122
|
+
| Export | Signature | Returns | Use it when |
|
|
123
|
+
| --------------------------- | ------------------------------------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
124
|
+
| `SYSTEM_DATA_KEY` | `const SYSTEM_DATA_KEY` | — | naming the key inside a system block whose contents are the system's own vocabulary |
|
|
125
|
+
| `BLOCK_DOCUMENT_PROPERTIES` | `const BLOCK_DOCUMENT_PROPERTIES` | — | mapping a system-block key to the document property it becomes |
|
|
126
|
+
| `BLOCK_DIRECTIVES` | `const BLOCK_DIRECTIVES` | — | recognizing a build directive (e.g. `pack`) that names no document property |
|
|
127
|
+
| `SYSTEM_BLOCK_KEYS` | `const SYSTEM_BLOCK_KEYS` | — | enumerating every key any system block may carry |
|
|
128
|
+
| `setPath` | `setPath(target, dotted, value)` | `object` — `target`, for chaining | writing a value at a dotted path in a document's `system` block |
|
|
129
|
+
| `systemBlock` | `systemBlock(fm, block)` | `Record<string, unknown> \| undefined` | reading one system's whole block off a note, or nothing when it is absent or malformed |
|
|
130
|
+
| `carriesSystemBlock` | `carriesSystemBlock(fm, block)` | `boolean` | deciding whether a pack that declares a system should compile a note at all |
|
|
131
|
+
| `systemData` | `systemData(fm, block)` | `Record<string, unknown>` | reading a system block's `system` sub-block, `{}` when absent |
|
|
132
|
+
| `blockField` | `blockField(fm, block, key, defaultValue)` | the value | reading a key from one system's block, falling back to the top level |
|
|
133
|
+
| `sharedProperty` | `sharedProperty(fm, source, defaultValue)` | the value | reading a shared top-level property by a possibly-dotted path, blind to every system block |
|
|
134
|
+
| `blockProperty` | `blockProperty(fm, block, key, defaultValue)` | the value | reading a property a system block may override, else the shared top-level one |
|
|
135
|
+
| `blockDataProperty` | `blockDataProperty(fm, block, key, defaultValue)` | the value | reading a system override, then shared `data`, then a top-level value |
|
|
136
|
+
| `legacyKeyOf` | `legacyKeyOf(field)` | `string \| undefined` | finding the key a field is authored at inside a system block |
|
|
137
|
+
| `retiredTopLevelKey` | `retiredTopLevelKey(field)` | `string \| undefined` | finding the bare top-level key a `data:`-sourced field is being swept off |
|
|
138
|
+
| `authoredKey` | `authoredKey(name)` | `string` | reading a shared source as the key an author writes, without the `data:` container holding it |
|
|
139
|
+
| `resolveFieldValue` | `resolveFieldValue(field, fm, ...)` | `{value, from}` | resolving one declared field against a note, in the declared source order |
|
|
140
|
+
| `systemDataPaths` | `systemDataPaths(data, prefix)` | `string[]` | listing every path a note authors under `<system>.system`, containers included |
|
|
141
|
+
| `undeclaredPaths` | `undeclaredPaths(data, declared, prefix)` | `string[]` | finding authored paths a system's published schema does not declare |
|
|
142
|
+
| `unknownBlockKeys` | `unknownBlockKeys(fm, block, ...)` | `string[]` | finding keys directly under a system block that neither this format nor the system recognizes |
|
|
143
|
+
| `claimedPaths` | `claimedPaths(fields)` | `Set<string>` | listing the exact `system` paths a field declaration writes, for `mergeSystemData` |
|
|
144
|
+
| `mergeSystemData` | `mergeSystemData(built, fm, ...)` | `object` — `built`, for chaining | merging a note's `<system>.system` verbatim onto a built `system` block |
|
|
144
145
|
|
|
145
146
|
### `engine.codeFences`
|
|
146
147
|
|
|
@@ -596,16 +597,17 @@ The map from each place, drawn for the site: `content-build site` draws the map
|
|
|
596
597
|
|
|
597
598
|
The closed registry of system ids, and the `none` that stands for no system at all. An unknown system value is an error; adding a system is a data change to this registry rather than a hardcoded set scattered through the pipeline.
|
|
598
599
|
|
|
599
|
-
| Export | Signature | Returns | Use it when
|
|
600
|
-
| ---------------------- | -------------------------------------- | ------------------------------- |
|
|
601
|
-
| `NO_SYSTEM` | `const NO_SYSTEM` | — | naming
|
|
602
|
-
| `
|
|
603
|
-
| `
|
|
604
|
-
| `
|
|
605
|
-
| `
|
|
606
|
-
| `
|
|
607
|
-
| `
|
|
608
|
-
| `
|
|
600
|
+
| Export | Signature | Returns | Use it when |
|
|
601
|
+
| ---------------------- | -------------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------- |
|
|
602
|
+
| `NO_SYSTEM` | `const NO_SYSTEM` | — | naming a systemless asset or Foundry document |
|
|
603
|
+
| `NOTE_SYSTEM` | `const NOTE_SYSTEM` | — | naming readable note content across web, book and Foundry |
|
|
604
|
+
| `SYSTEM_IDS` | `const SYSTEM_IDS` | — | enumerating every game system this toolchain compiles for |
|
|
605
|
+
| `SYSTEM_SEGMENTS` | `const SYSTEM_SEGMENTS` | — | enumerating the game systems, `note` and `none` |
|
|
606
|
+
| `isSystemId` | `isSystemId(value)` | `boolean` | checking whether a value names a game system this toolchain knows (`none` is rejected) |
|
|
607
|
+
| `isSystemSegment` | `isSystemSegment(value)` | `boolean` | checking whether a value is something the `<system>` address segment may hold |
|
|
608
|
+
| `unknownSystemMessage` | `unknownSystemMessage(value, where)` | `string` | building the message for a caller that wrote an unknown system |
|
|
609
|
+
| `assertSystemSegment` | `assertSystemSegment(value, where)` | `string` — the value, unchanged | refusing a value the `<system>` segment may not hold, validating inline |
|
|
610
|
+
| `assertSystemCharset` | `assertSystemCharset(segments, where)` | throws | refusing a registry declaration whose id could not be an address segment |
|
|
609
611
|
|
|
610
612
|
### `engine.calendars`
|
|
611
613
|
|
|
@@ -675,7 +677,7 @@ Where a content note publishes on the web. One rule, in one place, because two b
|
|
|
675
677
|
| `addressSlug` | `function addressSlug(fm)` | {string} The address segment, e.g. | The single path segment a note is addressed by: `type-shortcode`. |
|
|
676
678
|
| `packageAddress` | `function packageAddress(fm)` | {string} The package-relative address, with a trailing slash and no leading one. | A note's address: `<type>-<shortcode>/`, e.g. |
|
|
677
679
|
| `canonicalKey` | `function canonicalKey(pkg, system, type, shortcode)` | {string} `package-system-type-shortcode`, lowercased. | The **canonical** address of a note: fully qualified, one spelling per document, and globally unique. |
|
|
678
|
-
| `blockSystem` | `function blockSystem(keyPath)` | {string} The system id, or `
|
|
680
|
+
| `blockSystem` | `function blockSystem(keyPath)` | {string} The game system id, or `note`. | Which system a frontmatter key path is written under. |
|
|
679
681
|
| `expandAddress` | `function expandAddress(read, where)` | {string} The canonical `package-system-type-shortcode`. | Expand a written address to the one canonical address it names. |
|
|
680
682
|
| `CANONICAL_KEY_SEGMENTS` | `const CANONICAL_KEY_SEGMENTS` | — | How many segments a canonical key has, and therefore how many the reader below counts. |
|
|
681
683
|
| `readCanonicalKey` | `function readCanonicalKey(key)` | {{package: string, system: string, type: string, shortcode: string} \|null\|undefined} The parts; `null` when there is a string that is not in canonical form; `undefined` when there is no key at all. | Reads a canonical key back into its parts. |
|
|
@@ -1062,12 +1064,12 @@ Shared helpers for the pack compilers in `packages/content-build/`. The HeroicLa
|
|
|
1062
1064
|
|
|
1063
1065
|
**Item docs** — an item's prose compiled as a JournalEntry, with the item keeping only a pointer to it. An item note's body describes what the thing _is_. That is documentation, and documentation belongs in the journals pack, so each item note compiles into a JournalEntry and the item's `system.docHtml` becomes nothing but a `@UUID` link to that entry's first page — the description-as-pointer convention, which {@link sohl.utils.descriptionLinkTarget} recognises and Display Description follows.
|
|
1064
1066
|
|
|
1065
|
-
| Export | Signature | Returns | Use it when
|
|
1066
|
-
| ---------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
1067
|
-
| `docEntryTypes` | `function docEntryTypes()` | {ReadonlySet<string>} The configured doc-carrying types. | Every content type whose **prose compiles into a JournalEntry of its own**, addressed by the
|
|
1068
|
-
| `hasDocEntry` | `function hasDocEntry(type)` | {boolean} True for an item type, for `macro` and for a map type; false for `doc` and for actors. | Whether a content note's type is one whose prose becomes a JournalEntry of its own.
|
|
1069
|
-
| `itemDocEntryId` | `function itemDocEntryId(itemId)` | {string} A 16-character Foundry id. | The id of the JournalEntry a note's prose compiles into — an item's, or a macro's.
|
|
1070
|
-
| `itemDocPointer` | `function itemDocPointer(packageId, itemId, name, firstPageId)` | {string} The pointer to store in `system.docHtml`. | The description an item carries in place of its prose: a `@UUID` link to the first page of its item doc, and nothing else.
|
|
1067
|
+
| Export | Signature | Returns | Use it when |
|
|
1068
|
+
| ---------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
|
|
1069
|
+
| `docEntryTypes` | `function docEntryTypes()` | {ReadonlySet<string>} The configured doc-carrying types. | Every content type whose **prose compiles into a JournalEntry of its own**, addressed by `note` with the authored type. |
|
|
1070
|
+
| `hasDocEntry` | `function hasDocEntry(type)` | {boolean} True for an item type, for `macro` and for a map type; false for `doc` and for actors. | Whether a content note's type is one whose prose becomes a JournalEntry of its own. |
|
|
1071
|
+
| `itemDocEntryId` | `function itemDocEntryId(itemId)` | {string} A 16-character Foundry id. | The id of the JournalEntry a note's prose compiles into — an item's, or a macro's. |
|
|
1072
|
+
| `itemDocPointer` | `function itemDocPointer(packageId, itemId, name, firstPageId)` | {string} The pointer to store in `system.docHtml`. | The description an item carries in place of its prose: a `@UUID` link to the first page of its item doc, and nothing else. |
|
|
1071
1073
|
|
|
1072
1074
|
- `itemTypes` — re-exported: Every content type that compiles into an item — and therefore into an item doc.
|
|
1073
1075
|
|
|
@@ -1077,7 +1079,7 @@ Wikilink resolution for the pack compilers. Content notes link to one another wi
|
|
|
1077
1079
|
|
|
1078
1080
|
| Export | Signature | Returns | Use it when |
|
|
1079
1081
|
| -------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1080
|
-
| `resolveItemDocType` | `function resolveItemDocType(qualifier, types)` | {string\|null} The underlying document type, or `null` when the qualifier is not a virtual one. | Reads
|
|
1082
|
+
| `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. |
|
|
1081
1083
|
| `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. |
|
|
1082
1084
|
| `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. |
|
|
1083
1085
|
| `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. |
|
package/docs/commands.md
CHANGED
|
@@ -6,9 +6,6 @@ container, drive the end-to-end suite. `content-build` is the content half —
|
|
|
6
6
|
compile a note tree into compendium packs, check it, publish it as a site or a
|
|
7
7
|
book, and manage the caches a build resolves other packages through.
|
|
8
8
|
|
|
9
|
-
The package also ships `heroiclands-content-language-server`, a stdio editor
|
|
10
|
-
service described in the [content language server guide](content-language-server.md).
|
|
11
|
-
|
|
12
9
|
Both read `package-build.config.yaml` from the repository root — see
|
|
13
10
|
[Configuration](configuration.md) for every key. Neither reads it for
|
|
14
11
|
`--version` or `--help`: those two answer in a directory with no
|
package/docs/content-format.md
CHANGED
|
@@ -96,7 +96,7 @@ column regardless.
|
|
|
96
96
|
|
|
97
97
|
**Embedded models link to documentation in an infobox.** The model Address
|
|
98
98
|
continues to identify the native Item used for compilation. Its displayed link
|
|
99
|
-
uses that same package, type and Shortcode under `
|
|
99
|
+
uses that same package, type and Shortcode under `note`, which names the
|
|
100
100
|
corresponding documentation journal. A model with no published documentation
|
|
101
101
|
keeps its known name as plain text; the infobox does not substitute an Actor or
|
|
102
102
|
Item link.
|
|
@@ -308,6 +308,12 @@ finding that names the key you meant; the same misspelling at top level would
|
|
|
308
308
|
silently become a theme parameter, which is exactly why these cannot live
|
|
309
309
|
together.
|
|
310
310
|
|
|
311
|
+
Every note type may put a pinned document id in `data.id`, a shared compendium
|
|
312
|
+
route in `data.pack`, a shared folder Address in `data.packFolder`, and source
|
|
313
|
+
details in `data.harnworld`. A system block's `pack` or `packFolder` overrides
|
|
314
|
+
the shared value for that system. A `being` may also describe its social profile
|
|
315
|
+
in `data.social`.
|
|
316
|
+
|
|
311
317
|
**Tags are open, except the ones that classify.** `tags:` shares the top level's
|
|
312
318
|
openness: a tag naming a theme or a region — `underworld`,
|
|
313
319
|
`byzaria`, `riverlands` — is the author's own and this build has no opinion about it.
|
|
@@ -569,8 +575,8 @@ type.
|
|
|
569
575
|
| ----------------------- | ------------------------- | ---------------------------- |
|
|
570
576
|
| `name.full` | `name` | `name` |
|
|
571
577
|
| `data.icon` | `img` | `img` |
|
|
572
|
-
| `id`
|
|
573
|
-
| `packFolder`
|
|
578
|
+
| `data.id` | `_id` | `_id` |
|
|
579
|
+
| `data.packFolder` | `folder` | `folder` |
|
|
574
580
|
| `shortcode` | `system.shortcode` | NA |
|
|
575
581
|
| `data.templatePriority` | `system.templatePriority` | `flags.hm3.templatePriority` |
|
|
576
582
|
| `actionDefs` | `system.actionDefs` | NA |
|
|
@@ -657,16 +663,20 @@ refused at all four slots: a sound is not art, and a value naming one — `icon:
|
|
|
657
663
|
audio-thunder`, say — is an error naming the set the slot accepts, never a
|
|
658
664
|
silent fall back to the note's default art.
|
|
659
665
|
|
|
660
|
-
**
|
|
666
|
+
**These properties are legal on _every_ note**, whatever its type. `data:` is a
|
|
661
667
|
closed container and the per-type vocabularies below are the only lists there
|
|
662
668
|
are, so a key legal everywhere is stated once here rather than repeated in
|
|
663
669
|
twenty-five tables where the one that was mistyped would be the one nobody
|
|
664
670
|
noticed:
|
|
665
671
|
|
|
666
|
-
| shared `data` property | Values
|
|
667
|
-
| ---------------------- |
|
|
668
|
-
| `
|
|
669
|
-
| `
|
|
672
|
+
| shared `data` property | Values | Description |
|
|
673
|
+
| ---------------------- | ---------------------- | -------------------------------------------------------------------- |
|
|
674
|
+
| `id` | `string` | A pinned document identity. |
|
|
675
|
+
| `pack` | `string` | The shared compendium route. |
|
|
676
|
+
| `packFolder` | `Address` or pack map | The shared compendium folder Address. |
|
|
677
|
+
| `harnworld` | `Map<string, unknown>` | HârnWorld source details. |
|
|
678
|
+
| `icon` | `Address` | The document's profile art — an `icon` address, resolved into `img`. |
|
|
679
|
+
| `banner` | `Address` | The page's hero image — an `image` address. |
|
|
670
680
|
|
|
671
681
|
`icon` is legal everywhere because most types compile into a document that
|
|
672
682
|
carries one; where a type's passes emit none, the lint says so and the value is
|
|
@@ -847,10 +857,11 @@ on any type, and the frontmatter lint never reports it.
|
|
|
847
857
|
|
|
848
858
|
#### The pack a note compiles into
|
|
849
859
|
|
|
850
|
-
`pack` names which configured compendium receives the note's document.
|
|
860
|
+
`data.pack` names which configured compendium receives the note's document.
|
|
851
861
|
|
|
852
862
|
```yaml
|
|
853
|
-
|
|
863
|
+
data:
|
|
864
|
+
pack: items-hm3
|
|
854
865
|
```
|
|
855
866
|
|
|
856
867
|
It is deliberately close to the retired `package:` and deliberately not the same
|
|
@@ -867,7 +878,8 @@ system: each block the note carries sends its own document where that block
|
|
|
867
878
|
says, and a note carrying two blocks may place them in two packs.
|
|
868
879
|
|
|
869
880
|
```yaml
|
|
870
|
-
|
|
881
|
+
data:
|
|
882
|
+
pack: items-sohl
|
|
871
883
|
hm3:
|
|
872
884
|
pack: items-hm3
|
|
873
885
|
```
|
|
@@ -898,10 +910,11 @@ and in no compendium — a page of developer documentation, a page about the
|
|
|
898
910
|
package itself:
|
|
899
911
|
|
|
900
912
|
```yaml
|
|
913
|
+
shortcode: architecture
|
|
901
914
|
type: doc
|
|
902
915
|
subType: concept
|
|
903
|
-
|
|
904
|
-
pack: none
|
|
916
|
+
data:
|
|
917
|
+
pack: none
|
|
905
918
|
```
|
|
906
919
|
|
|
907
920
|
A link to such a note resolves everywhere the note is addressable. On the web
|
|
@@ -1046,16 +1059,17 @@ none. It is the same principle that turned `folder: ONXsqZAIZr2qzxTb` into
|
|
|
1046
1059
|
`packFolder: <address>` above: an opaque derived identity does not belong in
|
|
1047
1060
|
authored content.
|
|
1048
1061
|
|
|
1049
|
-
**An authored `id`
|
|
1062
|
+
**An authored `data.id` wins**, and that is how a document's identity is
|
|
1050
1063
|
**pinned**:
|
|
1051
1064
|
|
|
1052
1065
|
```yaml
|
|
1053
|
-
type: miscgear
|
|
1054
1066
|
shortcode: bowlcer
|
|
1055
|
-
|
|
1067
|
+
type: miscgear
|
|
1068
|
+
data:
|
|
1069
|
+
id: plaiQQm2T5zVK5mO # pinned: this document keeps this id
|
|
1056
1070
|
```
|
|
1057
1071
|
|
|
1058
|
-
A blank `id:` is not a pin — it is a deleted value with the key left behind, and
|
|
1072
|
+
A blank `data.id:` is not a pin — it is a deleted value with the key left behind, and
|
|
1059
1073
|
is treated as absent.
|
|
1060
1074
|
|
|
1061
1075
|
**A rename moves the id, and that is the trade.** The address carries the
|
|
@@ -1144,7 +1158,8 @@ of the same entry is a warning; the declaration still works.
|
|
|
1144
1158
|
A note says which folder of its pack it lands in:
|
|
1145
1159
|
|
|
1146
1160
|
```yaml
|
|
1147
|
-
|
|
1161
|
+
data:
|
|
1162
|
+
packFolder: poisonsandtoxins # a folder note's address
|
|
1148
1163
|
```
|
|
1149
1164
|
|
|
1150
1165
|
**`packFolder` is a folder note's address** — an ordinary address, resolved the
|
|
@@ -1268,85 +1283,78 @@ below.
|
|
|
1268
1283
|
<package>-<system>-<note_type>-<shortcode>
|
|
1269
1284
|
```
|
|
1270
1285
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
it means.
|
|
1286
|
+
The final segment is the shortcode, preceded by the note type, the system and
|
|
1287
|
+
the package. Each segment has one position. The system says which kind of target
|
|
1288
|
+
is named:
|
|
1275
1289
|
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1290
|
+
| system | target |
|
|
1291
|
+
| ------------- | --------------------------------------------------------------------------- |
|
|
1292
|
+
| `note` | Readable note content: a web page, a book entry, or a Foundry JournalEntry. |
|
|
1293
|
+
| `none` | A systemless target such as an asset, Folder, Macro or Scene. |
|
|
1294
|
+
| `sohl`, `hm3` | A game system's Actor or Item document. |
|
|
1295
|
+
|
|
1296
|
+
A note can publish more than one Address. A `being` note, for example, publishes
|
|
1297
|
+
`thalorna-note-being-bctrncml` for its readable content and
|
|
1298
|
+
`thalorna-sohl-being-bctrncml` for its SoHL Actor. An item note follows the same
|
|
1299
|
+
pattern for its page and Item. The type segment remains the authored note type
|
|
1300
|
+
in each Address.
|
|
1279
1301
|
|
|
1280
1302
|
#### Shorter forms
|
|
1281
1303
|
|
|
1282
|
-
|
|
1283
|
-
12,056 links in the current trees. The rest rely on shorter forms, each dropping
|
|
1284
|
-
segments from the left:
|
|
1304
|
+
Authors may omit segments from the left. The complete Address states all four:
|
|
1285
1305
|
|
|
1286
1306
|
| form | expands to |
|
|
1287
1307
|
| ------------------------------- | -------------------------------------------------------- |
|
|
1288
1308
|
| `package-system-type-shortcode` | itself |
|
|
1289
1309
|
| `system-type-shortcode` | `<this package>-system-type-shortcode` |
|
|
1290
|
-
| `type-shortcode` | `<this package>-<this
|
|
1291
|
-
| `shortcode` | as above, with the type from the field's
|
|
1310
|
+
| `type-shortcode` | `<this package>-<this position's system>-type-shortcode` |
|
|
1311
|
+
| `shortcode` | as above, with the type from the field's declaration |
|
|
1292
1312
|
|
|
1293
|
-
There is no `package-type-shortcode
|
|
1294
|
-
|
|
1295
|
-
`kethira-place-tashal` is three segments, which reads as system `kethira`, and
|
|
1296
|
-
fails.
|
|
1313
|
+
There is no `package-type-shortcode` form. A reference to another package states
|
|
1314
|
+
its system as well as its package.
|
|
1297
1315
|
|
|
1298
1316
|
#### Authored references and generated references
|
|
1299
1317
|
|
|
1300
|
-
Authored notes may use any permitted suffix. Builds leave
|
|
1301
|
-
|
|
1302
|
-
Wikilinks contain
|
|
1303
|
-
`data.parents: [north]
|
|
1304
|
-
`data.parents: [thalorna-none-place-north]`.
|
|
1318
|
+
Authored notes may use any permitted suffix. Builds leave source bytes unchanged.
|
|
1319
|
+
Generated content indexes, SQL records, site frontmatter and generated
|
|
1320
|
+
Wikilinks contain complete Addresses. For example, `data.parents: [north]` in
|
|
1321
|
+
`thalorna` emits `data.parents: [thalorna-note-place-north]`.
|
|
1305
1322
|
|
|
1306
|
-
SQL queries compare Address-valued fields to
|
|
1307
|
-
is a distinct identity component, so it is not equal to an Address
|
|
1308
|
-
`data.parents`, `data.domains` or a governance rank's `lore`. Use the
|
|
1309
|
-
complete identity for that comparison
|
|
1310
|
-
|
|
1311
|
-
components and its Shortcode.
|
|
1323
|
+
SQL queries compare Address-valued fields to complete Addresses. A note's
|
|
1324
|
+
`shortcode` is a distinct identity component, so it is not equal to an Address
|
|
1325
|
+
stored in `data.parents`, `data.domains` or a governance rank's `lore`. Use the
|
|
1326
|
+
target's complete identity for that comparison. A stub has no published page
|
|
1327
|
+
address; its note identity still contains the package, system, type and shortcode.
|
|
1312
1328
|
|
|
1313
|
-
The toolchain holds parsed
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1329
|
+
The toolchain holds parsed Addresses as complete tuples internally. Address-keyed
|
|
1330
|
+
relation maps hold typed targets and standing values. Only generated output
|
|
1331
|
+
serializes these properties to Address strings. Runtime Shortcodes, Foundry
|
|
1332
|
+
UUIDs, file paths and URLs keep their own representations.
|
|
1317
1333
|
|
|
1318
1334
|
An Address-valued `data:` field must name a target in this package or a declared
|
|
1319
|
-
dependency index. `content-build lint` reports a missing target
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1335
|
+
dependency index. `content-build lint` reports a missing target at the value or
|
|
1336
|
+
map key that names it. A stub counts as a target for data even though it
|
|
1337
|
+
publishes no page. Art slots use their own missing-art warning and document
|
|
1338
|
+
fallback.
|
|
1323
1339
|
|
|
1324
1340
|
#### An omitted segment defaults from where the link is written
|
|
1325
1341
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
- **
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
`
|
|
1342
|
-
so a prose `[[affiliation-sirvadar|Sirvadar]]` names the page, which is what
|
|
1343
|
-
prose almost always means. A prose link that means the **Item** states the
|
|
1344
|
-
system: `[[sohl-affiliation-sirvadar|…]]`.
|
|
1345
|
-
|
|
1346
|
-
Only a type whose own document carries a system is redirected this way. A
|
|
1347
|
-
`macro` and the map types have documentation journals too, but their own
|
|
1348
|
-
documents are core ones already at `none`, so `macro-autoattack` names the Macro
|
|
1349
|
-
and `docmacro-autoattack` its journal — two live addresses.
|
|
1342
|
+
An omitted segment is a default, not a wildcard. Every short form expands to one
|
|
1343
|
+
complete Address before lookup.
|
|
1344
|
+
|
|
1345
|
+
- **Package:** the current package. A short address never falls through to a
|
|
1346
|
+
dependency.
|
|
1347
|
+
- **System in `[[link|text]]`:** `note`, for every note type. Use an explicit
|
|
1348
|
+
game system to name its Actor or Item, or `none` to name a systemless target.
|
|
1349
|
+
- **System in `![[link|text]]`:** `none`. An embed names an image or icon asset;
|
|
1350
|
+
it also supplies `image` as the type of a bare shortcode.
|
|
1351
|
+
- **System in frontmatter:** a system block such as `sohl:` or `hm3:` supplies
|
|
1352
|
+
its game system. Other Address fields default to `note`, except fields
|
|
1353
|
+
declared for images, icons or folders, which default to `none`.
|
|
1354
|
+
|
|
1355
|
+
For example, `[[macro-autoattack|Automated Attack]]` names the readable macro
|
|
1356
|
+
note, while `[[none-macro-autoattack|Automated Attack]]` names the Foundry Macro.
|
|
1357
|
+
`![[icon-anvil|Anvil]]` names the systemless icon asset.
|
|
1350
1358
|
|
|
1351
1359
|
**A complete Address is lowercase throughout.** Every segment — package,
|
|
1352
1360
|
system, type and shortcode alike — contains only lowercase ASCII letters and
|
|
@@ -1572,7 +1580,7 @@ A **`Wikilink`** is how body prose names something:
|
|
|
1572
1580
|
The brackets, the `#<anchor>` and the `|<text>` label are the Wikilink's own.
|
|
1573
1581
|
What sits inside them is an `Address` like any other — read by the same grammar,
|
|
1574
1582
|
written at any of its lengths, and taking each omitted segment from where the
|
|
1575
|
-
link is written, which for body prose is this package and system `
|
|
1583
|
+
link is written, which for body prose is this package and system `note`. So
|
|
1576
1584
|
nothing about resolution belongs to the bracketed form: a wikilink and a
|
|
1577
1585
|
frontmatter field ask the same question of the same value, and the findings above
|
|
1578
1586
|
are the answers either of them gets.
|
|
@@ -2054,10 +2062,10 @@ system a note might write. A package shipping for a second system declares
|
|
|
2054
2062
|
`system:` on a pack of each class it compiles.
|
|
2055
2063
|
|
|
2056
2064
|
That includes actors. A being producing its Actor and nothing else would be
|
|
2057
|
-
|
|
2065
|
+
a system-bearing note with readable content, giving a prose link
|
|
2058
2066
|
naming it nowhere to land. It carries a documentation journal like every other
|
|
2059
2067
|
such note, addressed
|
|
2060
|
-
`<package>-
|
|
2068
|
+
`<package>-note-being-<shortcode>` beside the Actor's
|
|
2061
2069
|
`<package>-<system>-being-<shortcode>`.
|
|
2062
2070
|
|
|
2063
2071
|
**A being keeps its prose inline as well.** `system.appearance` and
|
|
@@ -2488,6 +2496,7 @@ Generates a living (or undead, or spirit) being.
|
|
|
2488
2496
|
| `templatePriority` | `number` | Template priority, _null_ = not a template |
|
|
2489
2497
|
| `archetypes` | `Archetype[]` | What sort of character this is. **Always an array** — `[]` where none apply; `null` is an error. |
|
|
2490
2498
|
| `occupation` | `string` | Name of the character's occupation |
|
|
2499
|
+
| `social` | `Map<string, unknown>` | The being's social profile |
|
|
2491
2500
|
| `stations` | `Address[]` | Name of the stations the character belongs to |
|
|
2492
2501
|
| `lore` | `Address[]` | Lore concerning this being — the people it is of, the standing it holds, the law it lives under |
|
|
2493
2502
|
| `homes` | `Address[]` | Place the being calls home |
|
|
@@ -2750,7 +2759,8 @@ no Foundry document: it is a page and nothing else.
|
|
|
2750
2759
|
It declares a `shortcode` — conventionally `root` — because that is what a
|
|
2751
2760
|
link is written with: `[[homepage-root|Text]]` is an ordinary wikilink, and it
|
|
2752
2761
|
resolves to `/<package>/`. The shortcode names the page in links; its address
|
|
2753
|
-
is the package root. `
|
|
2762
|
+
is the package root. The page heading reads `name.full` and defaults to
|
|
2763
|
+
`packageBuild.manifest.title`; a
|
|
2754
2764
|
`description` and a `banner` are read by the theme's hero; any other
|
|
2755
2765
|
top-level key is passed through to the page as a theme parameter.
|
|
2756
2766
|
|
|
@@ -4065,7 +4075,7 @@ await CONFIG.SOHL.class.Utility.currentCombatantAttack();
|
|
|
4065
4075
|
|
|
4066
4076
|
Three rules follow, and each is deliberate. The anchor names the **page**, not
|
|
4067
4077
|
the heading text, so the heading may be worded freely and
|
|
4068
|
-
`[[
|
|
4078
|
+
`[[macro-autoattack#script]]` still opens exactly this page. The fence must
|
|
4069
4079
|
be **tagged** — an untagged fence is a code sample whose language nobody stated,
|
|
4070
4080
|
and treating it as executable would make an illustrative snippet the macro. And
|
|
4071
4081
|
only the **first** tagged fence counts, so a note may document its macro
|
|
@@ -4141,8 +4151,8 @@ persists in the pack.
|
|
|
4141
4151
|
**Each address names the note's own document.** That is the same rule `pack:`
|
|
4142
4152
|
follows, so there is one answer and not two. A note that compiles into _two_
|
|
4143
4153
|
documents — an item and the JournalEntry its prose became — puts the second in a
|
|
4144
|
-
bundle
|
|
4145
|
-
`miscgear-bowlcer` is the
|
|
4154
|
+
bundle when the bundle names its `note` Address:
|
|
4155
|
+
`sohl-miscgear-bowlcer` is the Item, `miscgear-bowlcer` its description page.
|
|
4146
4156
|
|
|
4147
4157
|
**An address that resolves to nothing fails the build.** A `folder` address is
|
|
4148
4158
|
refused with a message of its own: a folder materialises in every pack holding
|
package/docs/getting-started.md
CHANGED
|
@@ -133,9 +133,7 @@ npm install --save-dev @heroiclands/package-build
|
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
That installs `package-build`, the packaging half, and `content-build`, the
|
|
136
|
-
content half, into `node_modules/.bin`.
|
|
137
|
-
`heroiclands-content-language-server` for editor navigation. Every build command
|
|
138
|
-
below uses one of the first two binaries. Run them through `npx`, or wire them into npm scripts as
|
|
136
|
+
content half, into `node_modules/.bin`. Run them through `npx`, or wire them into npm scripts as
|
|
139
137
|
[`project-setup.md`](project-setup.md) describes.
|
|
140
138
|
|
|
141
139
|
**How it worked:** `npx package-build --version` prints the installed version.
|