@heroiclands/package-build 23.9.0 → 23.11.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 +33 -0
- package/README.md +2 -0
- package/bin/content-commands.mjs +197 -68
- package/docs/api.md +365 -70
- package/docs/authoring/first-note.md +10 -0
- package/docs/authoring/frontmatter.md +1 -1
- package/docs/authoring/links-and-markup.md +186 -49
- package/docs/commands.md +92 -3
- package/docs/content-format.md +10 -3
- package/docs/design.md +18 -0
- package/docs/guides/book.md +7 -0
- package/docs/guides/site.md +7 -0
- package/docs/reference/format-details.md +186 -15
- package/docs/reference/note-types.md +4 -4
- package/engine/anchors.mjs +43 -9
- package/engine/base-compiler.mjs +6 -4
- package/engine/changelog-group.mjs +58 -34
- package/engine/changelog-lint.mjs +6 -2
- package/engine/compendiums.mjs +15 -1
- package/engine/compile-corpus.mjs +14 -1
- package/engine/content-charset.mjs +13 -1
- package/engine/content-html.mjs +18 -4
- package/engine/content-icons.mjs +15 -1
- package/engine/content-images.mjs +28 -9
- package/engine/content-index.mjs +102 -23
- package/engine/content-links.mjs +68 -30
- package/engine/content-session.mjs +247 -0
- package/engine/content-sources.mjs +110 -0
- package/engine/content-spans.mjs +118 -14
- package/engine/content-tables.mjs +1 -0
- package/engine/content-tasklists.mjs +20 -4
- package/engine/diagnostics.mjs +17 -6
- package/engine/extension-attributes.mjs +28 -5
- package/engine/first-use.mjs +371 -0
- package/engine/foundry-entries.mjs +12 -9
- package/engine/generate.mjs +13 -4
- package/engine/helpers.mjs +47 -16
- package/engine/index-records.mjs +1 -0
- package/engine/index.mjs +3 -0
- package/engine/journals.mjs +9 -5
- package/engine/language-data.mjs +2 -2
- package/engine/language-rows.mjs +4 -4
- package/engine/language-terms.mjs +4 -4
- package/engine/lexical-sections.mjs +5 -5
- package/engine/markup-validation.mjs +7 -2
- package/engine/metadata-index.mjs +1 -0
- package/engine/name-markup.mjs +114 -0
- package/engine/name-rows.mjs +70 -0
- package/engine/names.mjs +460 -0
- package/engine/note-addresses.mjs +25 -4
- package/engine/path-charset.mjs +24 -1
- package/engine/pdf-render.mjs +15 -1
- package/engine/site-index.mjs +25 -2
- package/engine/sql-tables.mjs +76 -15
- package/engine/stub-lint.mjs +4 -3
- package/engine/web-wikilinks.mjs +33 -12
- package/engine/wikilink-syntax.mjs +65 -8
- package/engine/wikilinks.mjs +29 -11
- package/engine/yaml-lint.mjs +3 -5
- package/hugo-theme/layouts/partials/footer.html +2 -0
- package/hugo-theme/static/css/style.css +20 -0
- package/hugo-theme/static/js/inline-spoilers.js +23 -0
- package/package.json +1 -1
- package/types/engine/anchors.d.mts +6 -3
- package/types/engine/compendiums.d.mts +5 -1
- package/types/engine/compile-corpus.d.mts +5 -2
- package/types/engine/content-charset.d.mts +5 -1
- package/types/engine/content-html.d.mts +5 -1
- package/types/engine/content-icons.d.mts +5 -1
- package/types/engine/content-images.d.mts +5 -1
- package/types/engine/content-index.d.mts +39 -19
- package/types/engine/content-links.d.mts +22 -8
- package/types/engine/content-session.d.mts +108 -0
- package/types/engine/content-sources.d.mts +32 -0
- package/types/engine/content-spans.d.mts +8 -6
- package/types/engine/content-tasklists.d.mts +5 -1
- package/types/engine/diagnostics.d.mts +10 -0
- package/types/engine/extension-attributes.d.mts +16 -2
- package/types/engine/first-use.d.mts +31 -0
- package/types/engine/foundry-entries.d.mts +11 -4
- package/types/engine/generate.d.mts +5 -1
- package/types/engine/helpers.d.mts +30 -7
- package/types/engine/index.d.mts +1 -0
- package/types/engine/journals.d.mts +5 -2
- package/types/engine/lexical-sections.d.mts +3 -2
- package/types/engine/markup-validation.d.mts +2 -1
- package/types/engine/name-markup.d.mts +176 -0
- package/types/engine/name-rows.d.mts +35 -0
- package/types/engine/names.d.mts +356 -0
- package/types/engine/note-addresses.d.mts +3 -3
- package/types/engine/path-charset.d.mts +16 -1
- package/types/engine/site-build.d.mts +2 -2
- package/types/engine/site-index.d.mts +3 -1
- package/types/engine/sql-tables.d.mts +7 -2
- package/types/engine/stub-lint.d.mts +3 -1
- package/types/engine/wikilink-syntax.d.mts +40 -3
|
@@ -41,6 +41,16 @@ For optional writing suggestions, run `npx package-build prose lint assets/conte
|
|
|
41
41
|
|
|
42
42
|
The full Address is `<package>-note-lore-harbor`; `<package>` comes from `contentPackage` in `package-build.config.yaml`. In another note, `[[lore-harbor|Harbor]]` links to it. `[[lore-harbor|]]` asks the renderer to use the target's current name. The pipe is required.
|
|
43
43
|
|
|
44
|
+
Use another subject's full canonical name at its first prose mention, then
|
|
45
|
+
plain text for later mentions and aliases. Keep a note's own subject in plain
|
|
46
|
+
text. Link indexed subjects even when they are private: the destination's
|
|
47
|
+
audience automatically makes the whole reference a spoiler. Add `.show` only
|
|
48
|
+
to intentionally reveal the reference; it grants no access to the destination.
|
|
49
|
+
For an unwritten subject, use a typed span such as
|
|
50
|
+
`[Aldric Venn]{.name data-type="being/npc"}`. The
|
|
51
|
+
[links and markup guide](links-and-markup.md#marking-names-in-prose) covers
|
|
52
|
+
these rules and separate `[text]{.secret}` spoilers.
|
|
53
|
+
|
|
44
54
|
## Grow the note only when needed
|
|
45
55
|
|
|
46
56
|
Add `description` for a short page summary, `tags: [draft]` to mark unfinished prose, or `data` for fields the note's type permits. A system block such as `sohl:` or `hm3:` adds mechanics and can produce a Foundry Actor or Item. It does not replace the shared prose or make another JournalEntry. [Frontmatter](frontmatter.md) explains the allowed keys, and the [note-type reference](../reference/note-types.md) lists every type-specific field.
|
|
@@ -25,7 +25,7 @@ data: {}
|
|
|
25
25
|
|
|
26
26
|
`description` is the short page summary. `tags` hold draft state and descriptive labels. The note type's classification belongs in `subType` where it is declared. `data` holds facts about the subject shared by systems. A YAML comment is the place for an author-only note: commented values remain valid YAML but do not enter the content index or generated documents.
|
|
27
27
|
|
|
28
|
-
Use `tags: [gm]` for a note intended only for the GM. It is absent from the public website and book. Foundry includes it only when its document routes to a pack with `private: true`. A note with `gm` that also creates a prose JournalEntry needs a private JournalEntry pack.
|
|
28
|
+
Use `tags: [gm]` for a note intended only for the GM. It is absent from the public website and book. Foundry includes it only when its document routes to a pack with `private: true`. A note with `gm` that also creates a prose JournalEntry needs a private JournalEntry pack. Any note can reference a GM note with an ordinary wikilink. The whole reference is automatically a spoiler; `.show` reveals only that reference, without changing the target's audience or permissions. See [references to secret subjects](links-and-markup.md#references-to-secret-subjects).
|
|
29
29
|
|
|
30
30
|
The formatter keeps a collection on one line when the full line is under 100 characters. Longer collections use full YAML block form. Run `package-build format --write` to apply key order and collection formatting.
|
|
31
31
|
|
|
@@ -23,6 +23,107 @@ A link to a note tagged `draft` retains its target and carries a visible draft c
|
|
|
23
23
|
|
|
24
24
|
An HTML comment is an aside to whoever reads the note next, and no surface shows one — the packs and the website emit it into the HTML, where it stays a comment, and a book leaves it out. Write a `markdownlint` pragma or a note about a quoted passage freely. A comment inside a fence or a code span is an example and is printed as written, and a comment that is never closed is an error.
|
|
25
25
|
|
|
26
|
+
## References to secret subjects
|
|
27
|
+
|
|
28
|
+
Use an ordinary wikilink for an indexed subject, including a GM-only note:
|
|
29
|
+
|
|
30
|
+
```markdown
|
|
31
|
+
[[doc-divineactn|The Truth of Divine Action]]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The renderer reads the destination's audience and conceals the entire reference,
|
|
35
|
+
including its label, as a spoiler. Authors do not repeat that audience at each
|
|
36
|
+
reference. A reference to a public subject stays visible. A link to an anchor inside secret content
|
|
37
|
+
conceals its reference too, including a same-note `[[#anchor|label]]`.
|
|
38
|
+
Linking to the public note as a whole does not inherit a section's secrecy.
|
|
39
|
+
|
|
40
|
+
| Surface | Reference to a secret destination |
|
|
41
|
+
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
42
|
+
| Website | An inline show/hide spoiler conceals its label. An omitted GM-only destination produces text without an unusable link. A published secret heading can still be linked. |
|
|
43
|
+
| Foundry | A visible inline spoiler labelled **Secret:** contains the reference. Private pack and page permissions govern whether its destination can be opened. |
|
|
44
|
+
| Book | The reference prints with secret styling and a **Secret:** label. An omitted GM-only destination produces text without a link. |
|
|
45
|
+
|
|
46
|
+
`.show` removes that automatic spoiler presentation on every surface. Where
|
|
47
|
+
the target is unavailable it still produces text without a link.
|
|
48
|
+
|
|
49
|
+
To intentionally reveal this reference, add `.show` immediately after the link:
|
|
50
|
+
|
|
51
|
+
```markdown
|
|
52
|
+
[[doc-divineactn|The Truth of Divine Action]]{.show}
|
|
53
|
+
[[doc-magictruth|The Truth of Magic]]{.show}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`.show` reveals only this reference. It does not publish the destination, change
|
|
57
|
+
its audience or grant Foundry access. It is redundant for a public target.
|
|
58
|
+
Use `[text]{.secret}` when the text itself is a spoiler, independently of any
|
|
59
|
+
destination; see [inline spoilers](#inline-spoilers).
|
|
60
|
+
|
|
61
|
+
## Marking names in prose
|
|
62
|
+
|
|
63
|
+
Use `[Name]{.name}` for a name that has no indexed note. Link a name that has
|
|
64
|
+
one, including a private subject; an empty link label uses the indexed full
|
|
65
|
+
name. Introduce another subject with its full canonical name at its first prose
|
|
66
|
+
use. Keep the note's own subject in plain text, and use plain text for later
|
|
67
|
+
mentions and aliases. Bold is emphasis.
|
|
68
|
+
Plain text, including capitalized words, is not searched for names.
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
[[place-arden|Arden Vale]] stands beside the river. Arden Vale has two gates.
|
|
72
|
+
[Hidden Hand]{.name} keeps watch over the crossing.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
To name something that has no note yet, mark it with its type instead of
|
|
76
|
+
creating a placeholder note:
|
|
77
|
+
|
|
78
|
+
```markdown
|
|
79
|
+
[Ravenmoor]{.name data-type="place/settlement"}
|
|
80
|
+
[Aldric Venn]{.name data-type="being/npc"}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`data-type` is optional. It names a declared [note type and
|
|
84
|
+
subtype](../reference/note-types.md), written as `type` or `type/subType`.
|
|
85
|
+
Enumerated subtypes must belong to that type's list; an open declaration
|
|
86
|
+
accepts a well-formed note subtype, and a type without a subtype declaration
|
|
87
|
+
takes only the bare type. An invalid supplied value is an error at the
|
|
88
|
+
attribute. Site and Foundry spans retain the classes and attribute values;
|
|
89
|
+
the attribute adds no book presentation.
|
|
90
|
+
|
|
91
|
+
`package-build lint` warns when an indexed name or alias uses `.name`
|
|
92
|
+
instead of a link, when the same name is marked or linked again, or when a
|
|
93
|
+
short form appears before its full name. Only marked names and authored link
|
|
94
|
+
labels count toward these rules. Introduce the full name before an alias such
|
|
95
|
+
as `Arden`, then use plain text for later mentions. Full names and their
|
|
96
|
+
declared aliases count as the same name, including in links to different
|
|
97
|
+
headings. Different labels do not become the same name just because they link
|
|
98
|
+
to the same page.
|
|
99
|
+
|
|
100
|
+
A name span can sit inside emphasis:
|
|
101
|
+
|
|
102
|
+
```markdown
|
|
103
|
+
**This is a phrase with [Joe Blow]{.name} in it**
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The marked name is `Joe Blow`. Sites and books display `.name` text in bold, including
|
|
107
|
+
inside an emphasized phrase. A whole bold span matching an indexed name or
|
|
108
|
+
alias receives an advisory to mark or link that name; bold containing an
|
|
109
|
+
explicit name span or link needs no such advisory.
|
|
110
|
+
|
|
111
|
+
These are warnings at each occurrence's `file:line:column`; they do not make
|
|
112
|
+
a valid package fail. The check reads authored prose outside headings,
|
|
113
|
+
tables, infoboxes, code, frontmatter, comments and embeds. See the
|
|
114
|
+
[complete name-marking rules](../reference/format-details.md#marking-names-in-prose).
|
|
115
|
+
|
|
116
|
+
The index records every actual `.name` span in the authored body, including
|
|
117
|
+
headings, tables, verse and spans inside links. The `names` SQL relation holds
|
|
118
|
+
its visible text, optional type/subtype and source location. Plain prose, bold,
|
|
119
|
+
unmarked link labels and generated content add no rows.
|
|
120
|
+
|
|
121
|
+
Lint also gives one grouped package advisory for names without a matching
|
|
122
|
+
indexed full name or alias, and for conflicting supplied classifications. It
|
|
123
|
+
lists every use and starts at the earliest reported span. Untyped uses do not
|
|
124
|
+
conflict, and `place` agrees with `place/settlement`; different supplied types
|
|
125
|
+
or different supplied subtypes conflict. These advisories do not fail lint.
|
|
126
|
+
|
|
26
127
|
## Journal pages and anchors
|
|
27
128
|
|
|
28
129
|
Every H1 starts a JournalEntryPage. A lower-level heading with an explicit anchor starts a page too. Use `{#slug}` to make a stable target:
|
|
@@ -128,8 +229,43 @@ An attribute-bearing opener allows a nested div to be distinguished from the bar
|
|
|
128
229
|
The watch wears [a _blue_ sash]{#watch-sash .uniform lang=en}.
|
|
129
230
|
```
|
|
130
231
|
|
|
232
|
+
Use `[Ravenmoor]{.name data-type="place/settlement"}` to mark a name with its
|
|
233
|
+
optional declared type; see [marking names](#marking-names-in-prose).
|
|
234
|
+
|
|
131
235
|
Inline Markdown remains active inside the span. Bracket spans have lower priority than URL links, image links, reference links, footnotes and wikilinks. A bracketed form immediately preceded by `!`, followed by `(` or another `[`, or beginning with `[[` is not a span, even when the link is unresolved. Ordinary links retain their existing syntax. Escape a bracket when it should be literal, or put examples inside a code span or fence. A span identifier addresses that point in the note; it does not start a journal page.
|
|
132
236
|
|
|
237
|
+
### Inline spoilers
|
|
238
|
+
|
|
239
|
+
Mark text itself as a spoiler with `.secret`. It can contain inline Markdown or
|
|
240
|
+
combine with a typed name for an unwritten subject:
|
|
241
|
+
|
|
242
|
+
```markdown
|
|
243
|
+
The key is [under the **third** stair]{.secret}.
|
|
244
|
+
The informant is [Aldric Venn]{.name .secret data-type="being/npc"}.
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
This marks only the enclosed text; it does not declare a target's audience.
|
|
248
|
+
For indexed subjects, use the ordinary wikilink and let the destination decide
|
|
249
|
+
whether the reference needs a spoiler. `.show` on a wikilink bypasses automatic
|
|
250
|
+
reference concealment; an enclosing authored `.secret` still marks its text.
|
|
251
|
+
|
|
252
|
+
On the website an inline spoiler has a button to show or hide its content.
|
|
253
|
+
It stays within the surrounding sentence, and links inside it can be followed
|
|
254
|
+
after revealing it. Foundry prints a visible inline `secret` span labelled
|
|
255
|
+
**Secret:**; this span does not withhold its text from players. The book prints
|
|
256
|
+
the text with secret styling and a **Secret:** label; printed text cannot be
|
|
257
|
+
interactively concealed.
|
|
258
|
+
These presentations preserve inline emphasis and the `.name` classification.
|
|
259
|
+
|
|
260
|
+
Published web HTML contains the spoiler's text. Revealing the spoiler or reading
|
|
261
|
+
the page source exposes it; this is presentation, not access control. GM-only
|
|
262
|
+
destination notes remain absent from public site and book output.
|
|
263
|
+
|
|
264
|
+
A `.secret` span does not start a journal page or change surrounding text.
|
|
265
|
+
Use a [secret heading](#a-section-players-must-not-read) to withhold a whole
|
|
266
|
+
Foundry page or a [secret block](#secret-blocks) for a passage in a labelled
|
|
267
|
+
section; those retain their own scope and presentation.
|
|
268
|
+
|
|
133
269
|
### Alerts
|
|
134
270
|
|
|
135
271
|
Alerts replace the former `:::info` and `:::warn` fences. Start with a special blockquote marker, optionally followed by an attribute block, then write the alert body as a standard blockquote:
|
|
@@ -323,50 +459,51 @@ A column's heading is its SQL alias, so `AS "Name"` is what a reader sees. A cel
|
|
|
323
459
|
|
|
324
460
|
### What a query can read
|
|
325
461
|
|
|
326
|
-
| Relation | What it holds
|
|
327
|
-
| ------------------ |
|
|
328
|
-
| `notes` | Every note except a stub. This is the one to use unless a stub is wanted.
|
|
329
|
-
| `entries` | Every note, stubs included.
|
|
330
|
-
| `events` | One row per event a `lore`, `place` or `affiliation` note writes in `data.events`, with `whenSort` to order them by date.
|
|
331
|
-
| `
|
|
332
|
-
| `
|
|
333
|
-
| `
|
|
334
|
-
| `
|
|
335
|
-
| `
|
|
336
|
-
| `
|
|
337
|
-
| `
|
|
338
|
-
| `
|
|
339
|
-
| `
|
|
340
|
-
| `
|
|
341
|
-
| `
|
|
342
|
-
| `
|
|
343
|
-
| `
|
|
344
|
-
| `
|
|
345
|
-
| `
|
|
346
|
-
| `
|
|
347
|
-
| `
|
|
348
|
-
| `
|
|
349
|
-
| `
|
|
350
|
-
| `
|
|
351
|
-
| `
|
|
352
|
-
| `
|
|
353
|
-
| `
|
|
354
|
-
| `
|
|
355
|
-
| `
|
|
356
|
-
| `
|
|
357
|
-
| `
|
|
358
|
-
| `
|
|
359
|
-
| `
|
|
360
|
-
| `
|
|
361
|
-
| `
|
|
362
|
-
| `
|
|
363
|
-
| `
|
|
364
|
-
| `
|
|
365
|
-
| `
|
|
366
|
-
| `
|
|
367
|
-
| `
|
|
368
|
-
| `
|
|
369
|
-
|
|
|
462
|
+
| Relation | What it holds |
|
|
463
|
+
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
464
|
+
| `notes` | Every note except a stub. This is the one to use unless a stub is wanted. |
|
|
465
|
+
| `entries` | Every note, stubs included. |
|
|
466
|
+
| `events` | One row per event a `lore`, `place` or `affiliation` note writes in `data.events`, with `whenSort` to order them by date. |
|
|
467
|
+
| `names` | Each authored `.name` span, with its containing NOTE Address, visible text, optional type/subtype and source line/column. |
|
|
468
|
+
| `words` | One row per word a language note writes in `data.words`, with that note as its `language`, its `position` and what it is built from. |
|
|
469
|
+
| `affixes` | One row per affix a language note writes in `data.affixes`, with that note as its `language`, its `position`, and each key the affix states: `form` (`NULL` on a zero affix), `zero`, `kind`, `given`, `"where"`, `gloss`, `attaches`, `replaces`, `lengthens`, `front`, `examples`, `barredAfter` and `tones`, then `written`, the form as a table prints it, `∅` for a zero affix. |
|
|
470
|
+
| `fields` | One row per field a language note writes in `data.fields`, with that note as its `language`, its `position`, and the field's `name` and what it `holds`. |
|
|
471
|
+
| `glossary` | One row per entry a culture or an affiliation writes in `data.glossary`, with the `note` it belongs to and the `language` it resolves to. |
|
|
472
|
+
| `language_lineage` | One row per language note and each language it inherits words from through `data.family`, itself included at `depth` 0. Join it to `words` for a language's words with inherited ones. |
|
|
473
|
+
| `dictionary` | One row per word per language it is listed under, inherited words included, with its `depth`. See [dictionaries and glossaries](#dictionaries-and-glossaries). |
|
|
474
|
+
| `terms` | One row per glossary entry, rank or office per note that owns it, with its `cultures` associations. See [dictionaries and glossaries](#dictionaries-and-glossaries). |
|
|
475
|
+
| `register` | One row per name a language note writes in `data.register`, with its `tongue`, `kind`, `gloss` and `why`, its pieces as `built_text`, and the `notes` carrying the name, derived from the index. |
|
|
476
|
+
| `tongues` | One row per tag a language note writes in `data.tongues`: `tag`, `meaning` and `tongue_language`. |
|
|
477
|
+
| `retired` | One row per form a language note writes in `data.retired`: `form`, `instead` as a list, and `why`. |
|
|
478
|
+
| `scope` | One row per value of a language note's `data.scope`: the `kind` it is under and the `value`. |
|
|
479
|
+
| `letters` | One row per entry of a language note's `data.sounds.letters`: `letters` as a list, `kind`, `like`, `place` and `tongue`. |
|
|
480
|
+
| `edges` | One row per entry of a language note's `data.sounds.edges`: the `edge` and its `sounds` as a list. |
|
|
481
|
+
| `clusters` | One row per language note stating `data.sounds.clusters`, with its `max`. |
|
|
482
|
+
| `cluster_groups` | One row per group of a language note's `data.sounds.clusters.groups`: `what`, `clusters` as a list, and `use`. |
|
|
483
|
+
| `stress` | One row per language note stating `data.sounds.stress`, with its `stress`. |
|
|
484
|
+
| `finals` | One row per entry of a language note's `data.sounds.finals`: `final` and `like`. |
|
|
485
|
+
| `syllables` | One row per language note stating `data.sounds.syllables`: each rule a column, the harmony as `harmony_back`, `harmony_front`, `harmony_neutral`, `harmony_neutralAs` and `harmony_partners`, a list of `{ vowel, partner }`. |
|
|
486
|
+
| `joining` | One row per entry of a language note's `data.sounds.joining`: `first`, `second`, `written` and `example`. |
|
|
487
|
+
| `joins` | One row per entry of a language note's `data.sounds.joins`: `meeting`, `rule`, `letters` and `"where"`. |
|
|
488
|
+
| `marks` | One row per entry of a language note's `data.sounds.marks`: `mark`, `letters`, `kind` and `"limit"`. |
|
|
489
|
+
| `skeleton` | One row per entry of a language note's `data.sounds.skeleton`: `second` and `between`. |
|
|
490
|
+
| `frames` | One row per frame of a language note's `data.sounds.frames`: `frame`, `shape`, `class`, `makes` and `examples` as `{ root, form }`. |
|
|
491
|
+
| `read_past` | One row per entry of a language note's `data.sounds.readPast`: `written`, `readAs` and `what`. |
|
|
492
|
+
| `mutations` | One row per entry of a language note's `data.sounds.mutations`: `mutation`, `sound`, `becomes` and `example`. |
|
|
493
|
+
| `sound_changes` | One row per step of each set in a language note's `data.soundChanges`: the set's `position`, `name`, `from_language`, `to_language` and `takes`, then `step_position`, `step`, `change` and `"where"`. |
|
|
494
|
+
| `elements` | One row per element of a language note's `data.elements`: `form`, `variants`, `element_position`, `kind`, `sense`, `examples`, `word` and `joining`. |
|
|
495
|
+
| `roots` | One row per root of a language note's `data.roots`: `root`, `sense` and `field`. |
|
|
496
|
+
| `cognates` | One row per form of each set in a language note's `data.cognates`: the set's `position`, `gloss` and `proto`, the `form_language` and the `form`. |
|
|
497
|
+
| `calling_names` | One row per closing of a language note's `data.callingNames`: `form`, `doubled`, `usual` and the language's `min_syllables`. |
|
|
498
|
+
| `older` | One row per form of a language note's `data.older`: `form`, `gloss` and `layer`. |
|
|
499
|
+
| `negation` | One row per language note stating `data.negation`: its `particle` and `mutation`. |
|
|
500
|
+
| `name_shapes` | One row per entry of a language note's `data.naming.shapes`: `of`, `syllables_min`, `syllables_max`, `per_vowel_min` and `per_vowel_max`. |
|
|
501
|
+
| `name_edges` | One row per entry of a language note's `data.naming.edges`: `edge`, `sounds` as a list, `vowel` and `of`. |
|
|
502
|
+
| `name_draws` | One row per entry of a language note's `data.naming.draws`: `kind` and `elements` as a list. |
|
|
503
|
+
| `held_from` | One row per entry of a language note's `data.naming.heldFrom`: `source`, `takes`, `clip`, and `joining` and `elements` as lists. |
|
|
504
|
+
| `near_names` | One row per worked example of a language note's `data.naming.nearName`: `near`, `given` and the language's `min_syllables`. |
|
|
505
|
+
| `market` | The market scale as three columns — `value`, `name`, `trade` — so a table can print `village` beside the number a note wrote. |
|
|
506
|
+
| `<package>.notes` | The same relations — `notes`, `entries`, `events`, `names`, `words`, `affixes`, `fields`, `glossary`, `language_lineage`, `dictionary`, `terms`, `register`, `tongues`, `retired`, `scope`, `letters`, `edges`, `clusters`, `stress`, `finals`, `syllables`, `joining`, `joins`, `marks`, `skeleton`, `frames`, `read_past`, `mutations`, `cluster_groups`, `sound_changes`, `elements`, `roots`, `cognates`, `calling_names`, `older`, `negation`, `name_shapes`, `name_edges`, `name_draws`, `held_from` and `near_names` — for each package this one declares a dependency on, in a schema named for it. |
|
|
370
507
|
|
|
371
508
|
Nested frontmatter is addressed exactly as a note writes it: `name.full`, `sohl.weight`, `data.born`. Every Address is a string — the full canonical Address, as in `list_contains(data.parents, 'thalorna-note-place-xerathia')` — whichever package published it. Every note carries a computed `state` column of `full`, `draft` or `stub`. Notes tagged `gm` are absent from the relations on public surfaces.
|
|
372
509
|
|
|
@@ -747,11 +884,11 @@ GROUP BY position, gloss ORDER BY position
|
|
|
747
884
|
```
|
|
748
885
|
````
|
|
749
886
|
|
|
750
|
-
An element's `kind` keeps one set of elements apart from another, and a place's generic gives its `
|
|
887
|
+
An element's `kind` keeps one set of elements apart from another, and a place's generic gives its `joining` form:
|
|
751
888
|
|
|
752
889
|
````markdown
|
|
753
890
|
```sql
|
|
754
|
-
SELECT '`' || form || '`' AS "Generic", sense AS "What it names", coalesce('`' ||
|
|
891
|
+
SELECT '`' || form || '`' AS "Generic", sense AS "What it names", coalesce('`' || joining || '`', '—') AS "Joining form"
|
|
755
892
|
FROM elements WHERE language = 'thalorna-note-skill-nordmalng' AND kind = 'place' ORDER BY position
|
|
756
893
|
```
|
|
757
894
|
````
|
|
@@ -809,7 +946,7 @@ SELECT source AS "held from",
|
|
|
809
946
|
WHEN 'element' THEN array_to_string(list_transform(elements, x -> '`' || x || '`'), ', ')
|
|
810
947
|
ELSE (CASE takes WHEN 'godName' THEN 'that god''s name' ELSE 'that founder''s given name' END)
|
|
811
948
|
|| coalesce(', clipped to its ' || clip || ' element', '')
|
|
812
|
-
|| coalesce(', with a
|
|
949
|
+
|| coalesce(', with a joining ending ' || array_to_string(list_transform(joining, x -> '`' || x || '`'), ' or '), '')
|
|
813
950
|
END AS "what stands first"
|
|
814
951
|
FROM held_from WHERE language = 'thalorna-note-skill-nordmalng' ORDER BY position
|
|
815
952
|
```
|
|
@@ -930,8 +1067,8 @@ common.
|
|
|
930
1067
|
|
|
931
1068
|
Public dictionaries omit citations to GM-only notes. `links` checks generated
|
|
932
1069
|
tables in the source note's audience: public notes use public rows, and GM
|
|
933
|
-
notes retain GM citations. An authored
|
|
934
|
-
note is
|
|
1070
|
+
notes retain GM citations. An authored wikilink from a public note to a GM-only
|
|
1071
|
+
note is valid and follows the [secret-reference rules](#references-to-secret-subjects).
|
|
935
1072
|
|
|
936
1073
|
#### Custom views
|
|
937
1074
|
|
package/docs/commands.md
CHANGED
|
@@ -1004,9 +1004,11 @@ scattered entries instead of one.
|
|
|
1004
1004
|
|
|
1005
1005
|
`group` rewrites the first `## <version>` section of `CHANGELOG.md` in
|
|
1006
1006
|
place. Within each `### <Bump> Changes` body, every block sharing one bold
|
|
1007
|
-
label is merged into a single block for that label
|
|
1008
|
-
|
|
1009
|
-
|
|
1007
|
+
label is merged into a single block for that label. Prose and bullets are
|
|
1008
|
+
retained, with exact duplicate items kept once. Opening paragraphs from
|
|
1009
|
+
merged labels combine in source order before their items. Wrapped
|
|
1010
|
+
paragraphs, nested item content and literal code stay intact. The merged
|
|
1011
|
+
blocks are reordered: the unlabelled lead paragraph a
|
|
1010
1012
|
changeset writes with no category first, then every label
|
|
1011
1013
|
[`changelog.labels`](configuration.md#changelog) declares, in the order
|
|
1012
1014
|
given, then any label absent from that list last, in the order it first
|
|
@@ -1501,6 +1503,73 @@ package-build: This repository declares no end-to-end suite to `run`. Name one u
|
|
|
1501
1503
|
|
|
1502
1504
|
## Content operations
|
|
1503
1505
|
|
|
1506
|
+
### `package-build content run <targets..>`
|
|
1507
|
+
|
|
1508
|
+
**NAME**
|
|
1509
|
+
|
|
1510
|
+
Run selected content checks and outputs from one captured source tree.
|
|
1511
|
+
|
|
1512
|
+
**SYNOPSIS**
|
|
1513
|
+
|
|
1514
|
+
```text
|
|
1515
|
+
package-build content run <targets..> [--no-references] [--pack <name>] [--out <dir>]
|
|
1516
|
+
```
|
|
1517
|
+
|
|
1518
|
+
**DESCRIPTION**
|
|
1519
|
+
|
|
1520
|
+
Choose one or more of `index`, `lint`, `links` and `compile`. The command runs
|
|
1521
|
+
each selected target once, in that order, regardless of the argument order.
|
|
1522
|
+
They perform the same operations as `content-index`, `lint`, `links` and
|
|
1523
|
+
`package compile`. The standalone commands remain available.
|
|
1524
|
+
|
|
1525
|
+
The selected operations share captured files, parsed frontmatter, content
|
|
1526
|
+
records and exact-source markup scans. Public and complete SQL preparations
|
|
1527
|
+
remain separate, as do prose-link checking and native document resolution.
|
|
1528
|
+
Each invocation starts a fresh in-memory session; independent commands do
|
|
1529
|
+
their own work. Finish dependency fetching, source generation and asset
|
|
1530
|
+
preparation before running this command, and start a new invocation after
|
|
1531
|
+
changing any input.
|
|
1532
|
+
|
|
1533
|
+
All selected preparations finish before the first output is written. If
|
|
1534
|
+
source or writer preparation fails, `index` and `compile` leave existing
|
|
1535
|
+
index, intermediate JSON and staged packs untouched. Read-only targets still
|
|
1536
|
+
report the findings they can produce. An ordinary lint error does not block
|
|
1537
|
+
an otherwise successful index or compile target. The command writes no
|
|
1538
|
+
persistent source cache.
|
|
1539
|
+
|
|
1540
|
+
Selecting `compile` applies the package command's existing package-kind rule
|
|
1541
|
+
before any writer. A documentation package can select `index` alone; selecting
|
|
1542
|
+
`index compile` reports the compile refusal and leaves its index untouched.
|
|
1543
|
+
|
|
1544
|
+
**OPTIONS**
|
|
1545
|
+
|
|
1546
|
+
| Option | Type | Default | Description |
|
|
1547
|
+
| ----------------- | ------- | ------------------------ | ------------------------------------------- |
|
|
1548
|
+
| `--references` | boolean | true | Check frontmatter references during `lint`. |
|
|
1549
|
+
| `--pack` `<name>` | string | all configured packs | Restrict `compile` to this pack. |
|
|
1550
|
+
| `--out` `<dir>` | string | configured content index | Set the `index` output directory. |
|
|
1551
|
+
|
|
1552
|
+
**EXIT STATUS**
|
|
1553
|
+
|
|
1554
|
+
0 when every selected target succeeds, including advisory warnings. 1 when
|
|
1555
|
+
arguments or preparation fail, or any selected target reports an error.
|
|
1556
|
+
|
|
1557
|
+
**EXAMPLES**
|
|
1558
|
+
|
|
1559
|
+
```bash
|
|
1560
|
+
package-build content run lint links
|
|
1561
|
+
package-build content run index compile
|
|
1562
|
+
package-build content run index lint links compile
|
|
1563
|
+
```
|
|
1564
|
+
|
|
1565
|
+
**SEE ALSO**
|
|
1566
|
+
|
|
1567
|
+
`package-build content-index`, `package-build lint`, `package-build links`,
|
|
1568
|
+
`package-build package compile`, [Configuration](configuration.md),
|
|
1569
|
+
[Programmatic sessions](api.md#enginecontentsession).
|
|
1570
|
+
|
|
1571
|
+
---
|
|
1572
|
+
|
|
1504
1573
|
### `package-build package <action> [pack] [entry]`
|
|
1505
1574
|
|
|
1506
1575
|
**NAME**
|
|
@@ -2012,6 +2081,21 @@ dependencies; exact Item UUID validation remains part of compilation. Reads
|
|
|
2012
2081
|
the content tree named by `root`, defaulting to
|
|
2013
2082
|
`paths.content`; writes nothing.
|
|
2014
2083
|
|
|
2084
|
+
Name marking is advisory: lint checks explicit `.name` spans and authored link
|
|
2085
|
+
labels against the [name-marking
|
|
2086
|
+
conventions](authoring/links-and-markup.md#marking-names-in-prose). Plain prose
|
|
2087
|
+
is not searched for names. It builds one matcher from the current local and
|
|
2088
|
+
dependency names, then
|
|
2089
|
+
reports each affected occurrence at its exact source location. These warnings
|
|
2090
|
+
also appear when `lint` is selected in `content run`; they do not fail the run.
|
|
2091
|
+
|
|
2092
|
+
Lint also emits one grouped package advisory for marked names without an
|
|
2093
|
+
indexed full-name or alias match, and for conflicting supplied classifications.
|
|
2094
|
+
It lists every source use and is located at the earliest reported span.
|
|
2095
|
+
Untyped uses and compatible type/subtype refinements do not conflict.
|
|
2096
|
+
An invalid supplied `.name` `data-type` is a located preparation error and
|
|
2097
|
+
prevents selected writers. See the same name-marking guide for typed examples.
|
|
2098
|
+
|
|
2015
2099
|
Content lint computes source positions when it emits findings and shares each
|
|
2016
2100
|
note's YAML position document across consecutive lookups.
|
|
2017
2101
|
|
|
@@ -2352,6 +2436,11 @@ content tree named by `root`, defaulting to `paths.content`; writes
|
|
|
2352
2436
|
`<contentPackage>-terms.jsonl` into `--out`, defaulting to the configured
|
|
2353
2437
|
`paths.contentIndex`.
|
|
2354
2438
|
|
|
2439
|
+
Metadata includes each own note's authored `.name` occurrences under `names`,
|
|
2440
|
+
with visible text, nullable type/subtype and original source line/column.
|
|
2441
|
+
Local and dependency SQL schemas expose them through `names`; they travel in
|
|
2442
|
+
the metadata artifact.
|
|
2443
|
+
|
|
2355
2444
|
The command prepares SQL tables, page lists, automatic sections and scalar
|
|
2356
2445
|
expressions before publishing their prose targets. Each source uses its own
|
|
2357
2446
|
audience for prose declarations: public notes use public providers and usage,
|
package/docs/content-format.md
CHANGED
|
@@ -31,6 +31,11 @@ Leading `:` captions describe the next supported block; `:@` captions also numbe
|
|
|
31
31
|
|
|
32
32
|
A code fence with language `poetry` keeps verse lines, stanza breaks and relative indentation. Its numbered caption uses the **Poem** label. Generic `:::` divs and `[inline spans]{.class}` accept attributes. See [poetry](authoring/links-and-markup.md#poetry), [fenced divs](authoring/links-and-markup.md#fenced-divs) and [inline spans](authoring/links-and-markup.md#inline-spans).
|
|
33
33
|
|
|
34
|
+
Mark a name without a note as `[Name]{.name data-type="being"}`; the optional
|
|
35
|
+
classification uses the declared note vocabulary. The [name-marking
|
|
36
|
+
guide](authoring/links-and-markup.md#marking-names-in-prose) explains its syntax,
|
|
37
|
+
index and grouped lint advice.
|
|
38
|
+
|
|
34
39
|
Body extensions use braces with space-separated `key=value` attributes:
|
|
35
40
|
`![[icon-harbor|Harbor]]{float=top-left size=medium}` and an SQL fence with
|
|
36
41
|
`{allow-empty=true}` are examples. Inline font glyphs use the package's icon
|
|
@@ -47,8 +52,10 @@ for examples and placement in journals, web pages, and books.
|
|
|
47
52
|
An inline `{{sql "SELECT COUNT(*) FROM notes"}}` expression inserts one scalar query result. Use `{{words (sql "SELECT COUNT(*) FROM notes")}}` for a count in running prose, or `{{digits (sql "SELECT COUNT(*) FROM entries")}}` for grouped numerals. The query must return exactly one row and one column with a nonempty value; a mismatch is a located build error. Prefix `\{{` to show the syntax literally. The [expression reference](reference/format-details.md#dates-and-calendars) describes the helpers and the available SQL relations.
|
|
48
53
|
|
|
49
54
|
Add `gm` to `tags` for a GM-only note. Public site and book builds omit it;
|
|
50
|
-
Foundry compiles it only into private compendiums.
|
|
51
|
-
|
|
55
|
+
Foundry compiles it only into private compendiums. Ordinary wikilinks to it
|
|
56
|
+
conceal the whole reference as a spoiler; `.show` reveals just the reference.
|
|
57
|
+
`[text]{.secret}` marks text itself as a spoiler. Neither changes the target's
|
|
58
|
+
access permissions. The [frontmatter guide](authoring/frontmatter.md#frontmatter-and-system-blocks)
|
|
52
59
|
explains routing for documents and their prose journals.
|
|
53
60
|
|
|
54
61
|
A note can also produce a system document: an Actor, Item, Scene, or Macro according to its type and system blocks. The `sohl:` and `hm3:` blocks supply game-specific mechanics and overrides; they do not create separate prose. The JournalEntry is shared between systems.
|
|
@@ -166,6 +173,6 @@ Places, affiliations, lore and beings may name their culture in `data.culture`,
|
|
|
166
173
|
|
|
167
174
|
An affiliation may name the trade, temple or order tongue it keeps in its own `data.language`. An affiliation that reaches no culture is a warning, in a tree holding a culture note. A language needs no culture and no affiliation. See [type: affiliation](reference/format-details.md#type-affiliation).
|
|
168
175
|
|
|
169
|
-
A language note (`type: skill`, `subType: language`) states its words in frontmatter: `data.words` states each word as a map of its form, class, field and gloss — one sense or a list of them, which a dictionary numbers — with its source, its variant forms, the pieces it is built from and a note, beside `data.classModifiers`, `data.fields` and `data.affixes`, each affix with the `kind` it makes, for a given name's ending who the name is `given` to, and the stem closes it is barred after; a zero affix states `zero: true` and no form. The notes a word is cited from are derived, not written: a note cites a word by marking it in italics in its prose, matched by form or a variant with diacritics and case set aside. The language of a word is the note it sits on, and none of it reaches the compiled Item. A daughter language names its parent in `data.family` and reads the parent's words as its own; the `language_lineage` relation joins a language to its ancestors. Classes come from the [master word classes](reference/format-details.md#word-classes). A culture or an affiliation states its own glossary entries in `data.glossary`: common words in its core vocabulary, dictionary words with a context meaning, or phrases, compounds and terms of art outside the dictionary with their own gloss. An entry naming a word of its resolved language takes the word's senses and class and links to its language entry; a `definition` supplies the entry's meaning instead. Common marks belong to the glossary's owner. A language note with nonempty `data.words` receives its full Dictionary section automatically: one alphabetical list with field tags and one key. A culture or affiliation with nonempty `data.glossary` receives only its explicitly declared entries in its Glossary section; ranks and offices stand in the affiliation's own sections. A note without the relevant frontmatter receives no such section. All surfaces show these sections after the authored text, or under an existing `{#dictionary}`, `{#lexicon}` or `{#glossary}` heading after its introduction. There are no setting-wide dictionary or glossary pages. Every entry resolves to a language — its own `language`, else the affiliation's, its parents' or its culture's, else the culture's — or is an error at the entry. The `words`, `affixes`, `fields`, `glossary` and `language_lineage` relations hold them for `sql` fences, the `dictionary` relation lists each word under every language that has it, inherited words included, and the `terms` relation each glossary entry, rank and office with its culture associations; a fence sets custom views with `layout=dictionary` or `layout=glossary`. A language note names the tag a dictionary prints for it in `data.abbreviation`. Every fact a check reads about a language's names, sounds and history is frontmatter too: `data.tongues` and `data.register` (every name the setting gives in the language's reach, the notes carrying each derived from the index), `data.retired`, `data.scope`, `data.sounds` (letters with their place, word edges from a closed list, the cluster limit and the groups of clusters inside a word, the stress rule, syllable finals, syllable rules and vowel harmony with each vowel's front partner, the joining of parts, written marks, a root's skeleton vowel and frames, the spellings read past, and named mutations such as wearing and voicing), `data.soundChanges` (named sets of ordered steps), `data.elements` (each standing `opening`, `closing`, `either` or `link`, for one kind of name, with the word it is the stem of and its
|
|
176
|
+
A language note (`type: skill`, `subType: language`) states its words in frontmatter: `data.words` states each word as a map of its form, class, field and gloss — one sense or a list of them, which a dictionary numbers — with its source, its variant forms, the pieces it is built from and a note, beside `data.classModifiers`, `data.fields` and `data.affixes`, each affix with the `kind` it makes, for a given name's ending who the name is `given` to, and the stem closes it is barred after; a zero affix states `zero: true` and no form. The notes a word is cited from are derived, not written: a note cites a word by marking it in italics in its prose, matched by form or a variant with diacritics and case set aside. The language of a word is the note it sits on, and none of it reaches the compiled Item. A daughter language names its parent in `data.family` and reads the parent's words as its own; the `language_lineage` relation joins a language to its ancestors. Classes come from the [master word classes](reference/format-details.md#word-classes). A culture or an affiliation states its own glossary entries in `data.glossary`: common words in its core vocabulary, dictionary words with a context meaning, or phrases, compounds and terms of art outside the dictionary with their own gloss. An entry naming a word of its resolved language takes the word's senses and class and links to its language entry; a `definition` supplies the entry's meaning instead. Common marks belong to the glossary's owner. A language note with nonempty `data.words` receives its full Dictionary section automatically: one alphabetical list with field tags and one key. A culture or affiliation with nonempty `data.glossary` receives only its explicitly declared entries in its Glossary section; ranks and offices stand in the affiliation's own sections. A note without the relevant frontmatter receives no such section. All surfaces show these sections after the authored text, or under an existing `{#dictionary}`, `{#lexicon}` or `{#glossary}` heading after its introduction. There are no setting-wide dictionary or glossary pages. Every entry resolves to a language — its own `language`, else the affiliation's, its parents' or its culture's, else the culture's — or is an error at the entry. The `words`, `affixes`, `fields`, `glossary` and `language_lineage` relations hold them for `sql` fences, the `dictionary` relation lists each word under every language that has it, inherited words included, and the `terms` relation each glossary entry, rank and office with its culture associations; a fence sets custom views with `layout=dictionary` or `layout=glossary`. A language note names the tag a dictionary prints for it in `data.abbreviation`. Every fact a check reads about a language's names, sounds and history is frontmatter too: `data.tongues` and `data.register` (every name the setting gives in the language's reach, the notes carrying each derived from the index), `data.retired`, `data.scope`, `data.sounds` (letters with their place, word edges from a closed list, the cluster limit and the groups of clusters inside a word, the stress rule, syllable finals, syllable rules and vowel harmony with each vowel's front partner, the joining of parts, written marks, a root's skeleton vowel and frames, the spellings read past, and named mutations such as wearing and voicing), `data.soundChanges` (named sets of ordered steps), `data.elements` (each standing `opening`, `closing`, `either` or `link`, for one kind of name, with the word it is the stem of and its joining form), `data.roots`, `data.cognates` (with a reconstructed `proto` form), `data.callingNames`, `data.older` (the forms older than the rules), `data.negation` (the negative particle and the mutation it brings) and `data.naming` (how long each class of name runs, the edges names keep that words do not, the element kinds each kind of name draws on, what a place name takes from what it is held from, and the near name), each a relation — `sounds` as `letters`, `edges`, `clusters`, `cluster_groups`, `stress`, `finals`, `syllables`, `joining`, `joins`, `marks`, `skeleton`, `frames`, `read_past` and `mutations`, `soundChanges` as `sound_changes`, `callingNames` as `calling_names` — that a fence sets back on the page. A word's citations also come from a note whose name, alias or rank or office title spells it whole. See [a language's words](reference/format-details.md#a-languages-words), [a language's register, sounds and history](reference/format-details.md#a-languages-register-sounds-and-history), [glossary terms](reference/format-details.md#glossary-terms) and [dictionaries and glossaries](reference/format-details.md#dictionaries-and-glossaries).
|
|
170
177
|
|
|
171
178
|
Blockquote alerts use `[!NOTE]`, `[!TIP]`, `[!IMPORTANT]`, `[!WARNING]`, or `[!]`, with optional attributes after the marker. They replace the former info and warn div fences; secret blocks remain supported. See [alerts](authoring/links-and-markup.md#alerts).
|