@heroiclands/package-build 23.11.0 → 23.12.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 +21 -0
- package/README.md +1 -0
- package/assets/preview/check-sanitizer.go +68 -0
- package/assets/preview/gitea-theme.js +36 -0
- package/assets/preview/gitea.ini +127 -0
- package/assets/styles/content-base.css +119 -16
- package/bin/content-commands.mjs +2 -2
- package/bin/package-build-preview.mjs +75 -0
- package/content-config.mjs +11 -0
- package/docs/api.md +105 -46
- package/docs/authoring/links-and-markup.md +46 -11
- package/docs/commands.md +46 -2
- package/docs/configuration.md +21 -4
- package/docs/design.md +4 -3
- package/docs/guides/book.md +10 -6
- package/docs/reference/format-details.md +33 -34
- package/docs/reference/note-types.md +0 -1
- package/docs/reference/theme-pages.md +1 -1
- package/docs/source-preview.md +172 -0
- package/engine/base-compiler.mjs +7 -8
- package/engine/being-age.mjs +19 -105
- package/engine/calendar-notes.mjs +3 -25
- package/engine/compile-corpus.mjs +2 -1
- package/engine/content-format.yaml +0 -1
- package/engine/content-index.mjs +9 -9
- package/engine/content-spans.mjs +28 -6
- package/engine/current-date.mjs +37 -0
- package/engine/definition-list.mjs +58 -0
- package/engine/frontmatter-lint.mjs +7 -2
- package/engine/helpers.mjs +2 -0
- package/engine/index.mjs +2 -0
- package/engine/infobox.mjs +1 -5
- package/engine/note-vocabulary.mjs +2 -2
- package/engine/npc-generate.mjs +7 -6
- package/engine/pdf-render.mjs +37 -4
- package/engine/preview-current-date.mjs +60 -0
- package/engine/site-build.mjs +5 -5
- package/engine/site-index.mjs +5 -2
- package/engine/site-preview.mjs +641 -325
- package/hugo-theme/layouts/_default/list.html +1 -1
- package/hugo-theme/layouts/blog/list.html +1 -1
- package/hugo-theme/layouts/blog-post/single.html +1 -1
- package/hugo-theme/layouts/partials/dictionary-lists.html +53 -0
- package/hugo-theme/layouts/partials/page-body.html +1 -1
- package/hugo-theme/static/css/style.css +22 -8
- package/package.json +8 -2
- package/types/content-config.d.mts +8 -0
- package/types/engine/base-compiler.d.mts +1 -1
- package/types/engine/being-age.d.mts +10 -44
- package/types/engine/calendar-notes.d.mts +2 -6
- package/types/engine/compile-corpus.d.mts +2 -1
- package/types/engine/content-index.d.mts +3 -1
- package/types/engine/content-spans.d.mts +4 -2
- package/types/engine/current-date.d.mts +9 -0
- package/types/engine/definition-list.d.mts +8 -0
- package/types/engine/frontmatter-lint.d.mts +6 -2
- package/types/engine/index.d.mts +2 -0
- package/types/engine/npc-generate.d.mts +2 -2
- package/types/engine/preview-current-date.d.mts +8 -0
- package/types/engine/site-index.d.mts +5 -1
- package/types/engine/site-preview.d.mts +40 -33
package/docs/api.md
CHANGED
|
@@ -744,23 +744,23 @@ The corpus registry anchors each calendar's year 1, day 1 to its canonical `data
|
|
|
744
744
|
|
|
745
745
|
A calendar is a `lore` note with `subType: calendar`, declaring the months it keeps, the weekdays it names, the seasons it marks and the eras it counts years in. How long the year is, how the day divides and how the moon moves are facts about the **world**, written on its `place` note and its moon's, and no calendar may restate them — which is why the months summing to the world's year is the only arithmetic a calendar note is held to. One definition is emitted per calendar, in array shape: Foundry core prunes the keys outside its schema, and Calendaria converts the arrays to its own keyed collections.
|
|
746
746
|
|
|
747
|
-
| Export | Signature | Returns
|
|
748
|
-
| --------------------------- | ----------------------------------------------------- |
|
|
749
|
-
| `CALENDAR_SUBTYPE` | `const CALENDAR_SUBTYPE` | —
|
|
750
|
-
| `INVARIANT_SUBTYPES` | `const INVARIANT_SUBTYPES` | —
|
|
751
|
-
| `CALENDAR_FIELDS` | `const CALENDAR_FIELDS` | —
|
|
752
|
-
| `CALENDAR_ENTRY_FIELDS` | `const CALENDAR_ENTRY_FIELDS` | —
|
|
753
|
-
| `CALENDAR_DATE_FORMAT_KEYS` | `const CALENDAR_DATE_FORMAT_KEYS` | —
|
|
754
|
-
| `CALENDAR_FORMAT_TOKENS` | `const CALENDAR_FORMAT_TOKENS` | —
|
|
755
|
-
| `INVARIANT_FIELDS` | `const INVARIANT_FIELDS` | —
|
|
756
|
-
| `checkCalendarNote` | `checkCalendarNote(note, opts)` | `object[]` — findings
|
|
757
|
-
| `checkCalendarDateFormats` | `checkCalendarDateFormats(note)` | `object[]` — findings
|
|
758
|
-
| `checkWorldFacts` | `checkWorldFacts(note, opts)` | `object[]` — findings
|
|
759
|
-
| `worldInvariants` | `worldInvariants(index)` | `{year,
|
|
760
|
-
| `quarterDays` | `quarterDays(daysPerYear)` | `number[]` — four days of the year
|
|
761
|
-
| `compileCalendar` | `compileCalendar({note, invariants, contentPackage})` | `object` — the definition
|
|
762
|
-
| `compileCalendars` | `compileCalendars(index, opts)` | `{calendars, invariants}`
|
|
763
|
-
| `calendariaEnvelope` | `calendariaEnvelope(definition, opts)` | `object` — the import envelope
|
|
747
|
+
| Export | Signature | Returns | Use it when |
|
|
748
|
+
| --------------------------- | ----------------------------------------------------- | ---------------------------------- | --------------------------------------------------------------------------------- |
|
|
749
|
+
| `CALENDAR_SUBTYPE` | `const CALENDAR_SUBTYPE` | — | naming the `lore` subType whose notes are calendars |
|
|
750
|
+
| `INVARIANT_SUBTYPES` | `const INVARIANT_SUBTYPES` | — | naming the `place` subTypes a world fact may be written on |
|
|
751
|
+
| `CALENDAR_FIELDS` | `const CALENDAR_FIELDS` | — | reading the closed list of what a calendar note may declare |
|
|
752
|
+
| `CALENDAR_ENTRY_FIELDS` | `const CALENDAR_ENTRY_FIELDS` | — | reading the keys one entry of each calendar list takes, as inner-key declarations |
|
|
753
|
+
| `CALENDAR_DATE_FORMAT_KEYS` | `const CALENDAR_DATE_FORMAT_KEYS` | — | reading the supported Calendaria display slots |
|
|
754
|
+
| `CALENDAR_FORMAT_TOKENS` | `const CALENDAR_FORMAT_TOKENS` | — | checking bare date tokens in a format string |
|
|
755
|
+
| `INVARIANT_FIELDS` | `const INVARIANT_FIELDS` | — | reading the closed list of what a body may declare about itself |
|
|
756
|
+
| `checkCalendarNote` | `checkCalendarNote(note, opts)` | `object[]` — findings | holding a `lore` note to the family and to the year the world keeps |
|
|
757
|
+
| `checkCalendarDateFormats` | `checkCalendarDateFormats(note)` | `object[]` — findings | checking named patterns and the readable default |
|
|
758
|
+
| `checkWorldFacts` | `checkWorldFacts(note, opts)` | `object[]` — findings | holding a `place` note's world facts to one body, one year and one moon |
|
|
759
|
+
| `worldInvariants` | `worldInvariants(index)` | `{year, moon, body, moonName, …}` | reading the year and moon a package's own notes state |
|
|
760
|
+
| `quarterDays` | `quarterDays(daysPerYear)` | `number[]` — four days of the year | asking which days the year turns on |
|
|
761
|
+
| `compileCalendar` | `compileCalendar({note, invariants, contentPackage})` | `object` — the definition | building the one object both a core consumer and Calendaria read |
|
|
762
|
+
| `compileCalendars` | `compileCalendars(index, opts)` | `{calendars, invariants}` | building every calendar a package declares, or none where it states no year |
|
|
763
|
+
| `calendariaEnvelope` | `calendariaEnvelope(definition, opts)` | `object` — the import envelope | wrapping a definition for a hand import through Calendaria's settings |
|
|
764
764
|
|
|
765
765
|
### `engine.calendarArtifacts`
|
|
766
766
|
|
|
@@ -776,18 +776,45 @@ identical bytes.
|
|
|
776
776
|
| ----------------------- | ---------------------------------------------------- | ------------------------------- | ---------------------------------------------------- |
|
|
777
777
|
| `emitCalendarArtifacts` | `emitCalendarArtifacts({config, calendariaVersion})` | `{directory, calendars, files}` | writing calendar files for a package's Foundry stage |
|
|
778
778
|
|
|
779
|
+
### `engine.definitionList`
|
|
780
|
+
|
|
781
|
+
HTML definition lists use semantic dictionary rows. The plugin groups each term
|
|
782
|
+
and all its definitions inside one `div` under `dl.dictionary`, preserving
|
|
783
|
+
nested blocks, inline formatting and document footnotes. Register it after
|
|
784
|
+
`markdown-it-deflist`.
|
|
785
|
+
|
|
786
|
+
| Export | Signature | Returns | Use it when |
|
|
787
|
+
| ---------------------- | -------------------------- | ------- | --------------------------------------------------------------- |
|
|
788
|
+
| `dictionaryListPlugin` | `dictionaryListPlugin(md)` | `void` | Giving an HTML Markdown parser the shared dictionary structure. |
|
|
789
|
+
|
|
790
|
+
The website groups Goldmark's final HTML through the `dictionary-lists.html`
|
|
791
|
+
partial, retaining its headings, TOC and footnotes. Shared content styles use a
|
|
792
|
+
150px hanging indent, a `.75em` term gap and `.5em` space between entries. At
|
|
793
|
+
viewport widths of 600px or less the indent is 100px. Terms are bold and stay on
|
|
794
|
+
one line. A long term pushes the first definition farther right; continuation
|
|
795
|
+
lines return to the common indent. Profile infobox grids keep their own layout.
|
|
796
|
+
|
|
797
|
+
### `engine.currentDate`
|
|
798
|
+
|
|
799
|
+
The shared current-date setting is a neutral string and requires no calendar or
|
|
800
|
+
configuration loading. Undefined selects the default; invalid explicit values
|
|
801
|
+
throw `TypeError`. Day digits remain exactly as authored.
|
|
802
|
+
|
|
803
|
+
| Export | Signature | Returns | Use it when |
|
|
804
|
+
| ---------------------- | ------------------------------ | --------- | ----------------------------------------------- |
|
|
805
|
+
| `DEFAULT_CURRENT_DATE` | Constant | `"720.1"` | Selecting the setting-wide default. |
|
|
806
|
+
| `normalizeCurrentDate` | `normalizeCurrentDate(value?)` | `string` | Validating a configuration or adapter override. |
|
|
807
|
+
|
|
779
808
|
### `engine.beingAge`
|
|
780
809
|
|
|
781
|
-
The middle state of a being's `age`: absent beside a dated `born`, it is computed against the
|
|
810
|
+
The middle state of a being's `age`: absent beside a dated `born`, it is computed against the configured `currentDate` (default `"720.1"`) — the two dates compared, not the two years subtracted, so a birthday later in the year than the present counts one less. `applyComputedBeingAge` fills it in on the frontmatter object a pass already holds, never on the note; `checkBeingAge` is `being`'s `NOTE_VOCABULARY` check, raising a warning where an authored `age` disagrees with what a dated `born` computes to. An estimate's `~` is read the way a date's is: the authored string stays verbatim, and `ageYears` carries the magnitude beside it.
|
|
782
811
|
|
|
783
|
-
| Export
|
|
784
|
-
|
|
|
785
|
-
| `computeAge`
|
|
786
|
-
| `parseAgeMagnitude`
|
|
787
|
-
| `applyComputedBeingAge`
|
|
788
|
-
| `
|
|
789
|
-
| `presentAmongFrontmatters` | `presentAmongFrontmatters(frontmatters)` | the present, or `null` | reading the declared present from a batch of raw frontmatter objects |
|
|
790
|
-
| `checkBeingAge` | `checkBeingAge(note, opts)` | `object[]` — findings | holding a being's authored `age` to what `born` and the present compute |
|
|
812
|
+
| Export | Signature | Returns | Use it when |
|
|
813
|
+
| ----------------------- | --------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------- |
|
|
814
|
+
| `computeAge` | `computeAge(bornRaw, presentRaw)` | `number \| null` | reading the age two dates imply, in whole years |
|
|
815
|
+
| `parseAgeMagnitude` | `parseAgeMagnitude(raw)` | `{approximate, value} \| null` | reading an authored `age`'s `~` mark and its magnitude |
|
|
816
|
+
| `applyComputedBeingAge` | `applyComputedBeingAge(fm, presentRaw)` | `void` — mutates `fm.data` | filling in a being's computed `age`, or the `ageYears` beside an estimate |
|
|
817
|
+
| `checkBeingAge` | `checkBeingAge(note, { index, currentDate })` | `object[]` — findings | holding a being's authored `age` to what `born` and the present compute |
|
|
791
818
|
|
|
792
819
|
### `engine.contentAddress`
|
|
793
820
|
|
|
@@ -1290,30 +1317,33 @@ index for checking page links.
|
|
|
1290
1317
|
|
|
1291
1318
|
### `engine.sitePreview`
|
|
1292
1319
|
|
|
1293
|
-
`
|
|
1320
|
+
`renderPreview(text, { dark = false, infobox = true, file = "", currentDate = "720.1" })` renders the current Markdown buffer directly to HTML. Frontmatter is optional. It needs no package configuration, saved note, content tree, dependency cache, database or Pandoc installation. The result is `{ ok, html, frontmatter, findings }`; `file` only labels diagnostics. Malformed frontmatter produces a warning and remains visible without preventing a preview update.
|
|
1294
1321
|
|
|
1295
|
-
| Export
|
|
1296
|
-
|
|
|
1297
|
-
| `
|
|
1322
|
+
| Export | Signature | Returns | Use it when |
|
|
1323
|
+
| ------------------------ | ------------------------------- | ------------------------------------- | ---------------------------------------------------------------------- |
|
|
1324
|
+
| `renderPreview` | `renderPreview(text, options?)` | `{ ok, html, frontmatter, findings }` | An editor or external renderer needs a preview from one buffer. |
|
|
1325
|
+
| `previewStyles` | `previewStyles()` | CSS string | A host needs the shared, scoped light and dark palettes. |
|
|
1326
|
+
| `readPreviewCurrentDate` | `readPreviewCurrentDate(root)` | `Promise<string>` | Opting into the nearest project's validated root current-date setting. |
|
|
1327
|
+
| `PREVIEW_HELPERS` | Constant | Helper dependency policy | Checking preview coverage when adding an expression helper. |
|
|
1298
1328
|
|
|
1299
|
-
The
|
|
1329
|
+
The returned HTML includes an `.hl-preview` wrapper with exactly one explicit mode class, `.hl-preview-light` or `.hl-preview-dark`. Include `previewStyles()` once in the host document. The stylesheet colors only the preview container, including its backgrounds, source tokens, alerts and optional local infobox. Set `dark` from the host's selected theme; browser preference does not override it.
|
|
1300
1330
|
|
|
1301
1331
|
```js
|
|
1302
|
-
import {
|
|
1332
|
+
import { renderPreview, previewStyles } from "@heroiclands/package-build/engine/site-preview";
|
|
1303
1333
|
|
|
1304
|
-
const
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
if (result.ok) {
|
|
1308
|
-
// Convert result.markdown and result.frontmatter to the editor's HTML preview.
|
|
1309
|
-
} else {
|
|
1310
|
-
showDiagnostics(result.findings);
|
|
1311
|
-
}
|
|
1312
|
-
} finally {
|
|
1313
|
-
await preview.close();
|
|
1314
|
-
}
|
|
1334
|
+
const result = renderPreview(currentBufferText, { dark: true });
|
|
1335
|
+
// Include previewStyles() in a stylesheet and result.html in the preview document.
|
|
1336
|
+
showDiagnostics(result.findings);
|
|
1315
1337
|
```
|
|
1316
1338
|
|
|
1339
|
+
Ordinary Markdown, definition lists, footnotes, alert boxes, poetry, captions, local figures and container blocks render locally. Alerts reuse the four shared icons and titles, accept custom titles and nested alerts, and have opaque tinted backgrounds in both modes. Definition terms are bold; definitions retain ordinary Markdown styling. Wikilinks and image embeds retain their entire authored source: blue opening markers (including all of `, with
|
|
2051
|
+
the same explicit palette, local infobox, source-preservation and diagnostics
|
|
2052
|
+
contract. See [Source preview](source-preview.md) for the standalone command and
|
|
2053
|
+
Gitea installation.
|
|
2054
|
+
|
|
2002
2055
|
## `./content-config`
|
|
2003
2056
|
|
|
2004
2057
|
The per-repository configuration contract: what `package-build.config.yaml` (or an `.mjs` config calling `defineConfig` directly) must satisfy. `defineConfig` validates and normalizes the whole thing, returning a deeply frozen copy, and performs no I/O — `engine.packConfig` is what locates and reads a repository's file, deriving the three fields absent from authored YAML (`rootDir`, `stats.systemVersion`, the resolved `itemBuilders` table). See `docs/configuration.md` for the full key-by-key reference; this section covers the module's own exported shape.
|
|
@@ -2391,9 +2444,15 @@ The engine wildcard subpath also exposes the body parsers below. Their figure ex
|
|
|
2391
2444
|
|
|
2392
2445
|
Inline `.secret` spans preserve their inline content, name classes and
|
|
2393
2446
|
attributes. Site rendering uses a separate show/hide button and content span,
|
|
2394
|
-
so a link inside the content does not become a nested control. Foundry
|
|
2395
|
-
|
|
2396
|
-
|
|
2447
|
+
so a link inside the content does not become a nested control. Foundry emits a
|
|
2448
|
+
focusable inline spoiler: scoped content CSS redacts its text and descendants
|
|
2449
|
+
until pointer hover or keyboard focus reveals them. Its focus outline and
|
|
2450
|
+
accessible cue identify the reveal interaction. Native Foundry secret sections
|
|
2451
|
+
keep their separate controls. Book rendering discards inline `.secret` classes
|
|
2452
|
+
and prints their content normally, retaining emphasis, links, anchors and `.name`
|
|
2453
|
+
bold styling. Book secret sections and fences retain their visible labelled
|
|
2454
|
+
boxes. The span parser's opaque source tokens retain a `secret` boolean from
|
|
2455
|
+
their parsed classes for preview presentation.
|
|
2397
2456
|
`collectAnchors` includes `secret: true` on secret anchors for destination
|
|
2398
2457
|
presentation. Block and heading secrecy retain their separate scope and
|
|
2399
2458
|
Foundry permission handling.
|
|
@@ -40,11 +40,12 @@ Linking to the public note as a whole does not inherit a section's secrecy.
|
|
|
40
40
|
| Surface | Reference to a secret destination |
|
|
41
41
|
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
42
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
|
|
44
|
-
| Book | The reference prints
|
|
43
|
+
| Foundry | A CSS-redacted inline spoiler reveals the reference on hover or keyboard focus. Private pack and page permissions govern whether its destination can be opened. |
|
|
44
|
+
| Book | The reference prints normally, preserving emphasis and name styling. An omitted GM-only destination produces text without a link. |
|
|
45
45
|
|
|
46
|
-
`.show` removes
|
|
47
|
-
|
|
46
|
+
`.show` removes automatic spoiler presentation on the website and in Foundry.
|
|
47
|
+
Book references already print normally. Where the target is unavailable the
|
|
48
|
+
reference still produces text without a link.
|
|
48
49
|
|
|
49
50
|
To intentionally reveal this reference, add `.show` immediately after the link:
|
|
50
51
|
|
|
@@ -251,11 +252,13 @@ reference concealment; an enclosing authored `.secret` still marks its text.
|
|
|
251
252
|
|
|
252
253
|
On the website an inline spoiler has a button to show or hide its content.
|
|
253
254
|
It stays within the surrounding sentence, and links inside it can be followed
|
|
254
|
-
after revealing it. Foundry
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
255
|
+
after revealing it. Foundry redacts inline `secret` spans with a solid cover;
|
|
256
|
+
hover the span or focus it with the keyboard to reveal its text, links and
|
|
257
|
+
images. A visible focus outline and a spoiler cue identify the interaction.
|
|
258
|
+
This does not change native Foundry secret-section controls. The book ignores
|
|
259
|
+
`.secret` on inline spans and prints their text normally, preserving emphasis,
|
|
260
|
+
links, anchors and `.name` bold styling. Secret sections and `:::secret` fences
|
|
261
|
+
retain their visible labelled boxes.
|
|
259
262
|
|
|
260
263
|
Published web HTML contains the spoiler's text. Revealing the spoiler or reading
|
|
261
264
|
the page source exposes it; this is presentation, not access control. GM-only
|
|
@@ -432,8 +435,40 @@ Janapada
|
|
|
432
435
|
: Also the land associated with that community.
|
|
433
436
|
```
|
|
434
437
|
|
|
435
|
-
|
|
436
|
-
|
|
438
|
+
To continue the same definition, leave a blank line and indent the next
|
|
439
|
+
paragraph or block by four spaces. For a fenced code block, indent both fences
|
|
440
|
+
and its contents:
|
|
441
|
+
|
|
442
|
+
````markdown
|
|
443
|
+
Harbour due
|
|
444
|
+
: A toll on every hull that ties up.
|
|
445
|
+
|
|
446
|
+
The harbourmaster collects it before unloading begins.
|
|
447
|
+
|
|
448
|
+
```text
|
|
449
|
+
One hull: two silver pieces.
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Anchorage
|
|
453
|
+
: A sheltered place where a ship can lie at anchor.
|
|
454
|
+
````
|
|
455
|
+
|
|
456
|
+
The continuation paragraph and code block belong to the same definition.
|
|
457
|
+
Repeat `:` only when starting a separate definition for the same term, as in
|
|
458
|
+
the first example. The next unindented term starts a new entry.
|
|
459
|
+
|
|
460
|
+
Definition lists use a dictionary hanging indent in the website, Foundry,
|
|
461
|
+
preview and book. A bold term begins the row, followed by its normally styled
|
|
462
|
+
definition. Short terms share a definition column 150px from the row's left
|
|
463
|
+
edge; browser viewports of 600px or less use 100px. The gap after a term is
|
|
464
|
+
`.75em`, with `.5em` between entries. A long term stays on one line and pushes
|
|
465
|
+
the first definition farther right; wrapped lines return to the common column.
|
|
466
|
+
The book uses the equivalent print dimensions.
|
|
467
|
+
|
|
468
|
+
HTML surfaces preserve the semantic `<dl class="dictionary">`, `<dt>` and `<dd>`
|
|
469
|
+
elements, with one grouping `<div>` for each term and all its definitions.
|
|
470
|
+
Multiple definitions, continuation paragraphs, nested lists and footnotes keep
|
|
471
|
+
their normal Markdown meaning. Infobox profiles retain their own layout.
|
|
437
472
|
|
|
438
473
|
## Lists
|
|
439
474
|
|
package/docs/commands.md
CHANGED
|
@@ -66,6 +66,50 @@ behaviour where they appear below; read the command, not the name.
|
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
|
69
|
+
## Standalone source preview
|
|
70
|
+
|
|
71
|
+
### `package-build-preview`
|
|
72
|
+
|
|
73
|
+
**NAME**
|
|
74
|
+
|
|
75
|
+
Render a Markdown buffer without a content index.
|
|
76
|
+
|
|
77
|
+
**SYNOPSIS**
|
|
78
|
+
|
|
79
|
+
`package-build-preview [--dark] [--current-date DATE] [--css] < note.md`
|
|
80
|
+
|
|
81
|
+
**DESCRIPTION**
|
|
82
|
+
|
|
83
|
+
Reads Markdown from stdin and writes an HTML fragment. Requires no package
|
|
84
|
+
configuration. Local Markdown and extensions render; constructs needing other
|
|
85
|
+
notes remain highlighted source. Shared CSS is supplied separately.
|
|
86
|
+
|
|
87
|
+
**OPTIONS**
|
|
88
|
+
|
|
89
|
+
- `--dark` — select dark mode; light is the default.
|
|
90
|
+
- `--current-date DATE` — override the setting-wide neutral current date; otherwise
|
|
91
|
+
read the nearest root configuration setting, defaulting to `"720.1"`.
|
|
92
|
+
- `--css` — emit the shared scoped stylesheet without reading stdin.
|
|
93
|
+
- `--help`, `-h` — show usage.
|
|
94
|
+
|
|
95
|
+
**EXIT STATUS**
|
|
96
|
+
|
|
97
|
+
0 on success, 1 for an invalid argument or rendering error. Findings go to
|
|
98
|
+
stderr; stdout contains only HTML (or CSS with `--css`).
|
|
99
|
+
|
|
100
|
+
**EXAMPLES**
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
package-build-preview --dark < note.md > preview.html
|
|
104
|
+
package-build-preview --css > preview.css
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**SEE ALSO**
|
|
108
|
+
|
|
109
|
+
[Source preview and Gitea renderer](source-preview.md), [API](api.md).
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
69
113
|
## Package and release operations
|
|
70
114
|
|
|
71
115
|
### `package-build ci`
|
|
@@ -3017,7 +3061,7 @@ exactly as given, at every depth, and every field it leaves out is generated:
|
|
|
3017
3061
|
| `data.templatePriority`, `data.occupation`, `data.died` | `null`. |
|
|
3018
3062
|
| `data.lore`, `data.homes` | `[]`. |
|
|
3019
3063
|
| `data.affiliations` | `{}`. |
|
|
3020
|
-
| `data.born` | An adult age of 18 to 60 years before the
|
|
3064
|
+
| `data.born` | An adult age of 18 to 60 years before the configured `currentDate` (default `"720.1"`), as a `<year>.<day>` date. |
|
|
3021
3065
|
| `data.frame`, `data.appearance.*` | Weighted draws from the culture's appearance profile; `extra_features` is `[]`. |
|
|
3022
3066
|
| `data.height` | From the profile's range for the gender, in feet and inches. |
|
|
3023
3067
|
| `data.weight` | From the height and the frame's body-mass band, in pounds. A spec giving height and weight but no frame gets the frame they imply. |
|
|
@@ -3105,7 +3149,7 @@ dossier: |
|
|
|
3105
3149
|
record rather than of reputation.
|
|
3106
3150
|
```
|
|
3107
3151
|
|
|
3108
|
-
Run against a package
|
|
3152
|
+
Run against a package configured with `currentDate: "720.300"`, whose
|
|
3109
3153
|
`khelathi` culture carries the profile in
|
|
3110
3154
|
[appearance profiles](reference/format-details.md#appearance-profiles) and
|
|
3111
3155
|
names `language: skill-khelathilng`, and whose language carries the lists in
|
package/docs/configuration.md
CHANGED
|
@@ -54,7 +54,7 @@ around its own evaluation.
|
|
|
54
54
|
|
|
55
55
|
### Quick reference
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
24 top-level keys. `rootDir` is not one of them — a data configuration never
|
|
58
58
|
writes it — and is documented under [Derived values](#derived-values) instead,
|
|
59
59
|
alongside `foundryPackage`, `homepage`, `author` and `itemBuilders`, whose
|
|
60
60
|
data-configuration behaviour is also derivation rather than ordinary
|
|
@@ -62,6 +62,7 @@ authoring.
|
|
|
62
62
|
|
|
63
63
|
| Key | Type | Required | Default |
|
|
64
64
|
| ------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------- |
|
|
65
|
+
| [`currentDate`](#currentdate) | quoted neutral date string | no | `"720.1"` |
|
|
65
66
|
| [`contentPackage`](#contentpackage) | string | yes | — |
|
|
66
67
|
| [`foundryPackage`](#foundrypackage) | string | yes (`.mjs` only — derived in YAML); refused in a `documentation` package | — |
|
|
67
68
|
| [`homepage`](#homepage) | string | no (`.mjs` only — derived in YAML) | `null` |
|
|
@@ -87,7 +88,7 @@ authoring.
|
|
|
87
88
|
|
|
88
89
|
Any key outside this list is refused:
|
|
89
90
|
|
|
90
|
-
> `` `<key>` is not a recognized option (expected one of: rootDir, contentPackage, foundryPackage, homepage, authors, packageKind, stats, itemBuilders, paths, skipDirectories, forbidGeneratedArt, icons, packs, docs, site, pdf, compatibility, relationships, systems, requiresSystem, packageBuild, publish, changelog). ``
|
|
91
|
+
> `` `<key>` is not a recognized option (expected one of: rootDir, contentPackage, currentDate, foundryPackage, homepage, authors, packageKind, stats, itemBuilders, paths, skipDirectories, forbidGeneratedArt, icons, packs, docs, site, pdf, compatibility, relationships, systems, requiresSystem, packageBuild, publish, changelog). ``
|
|
91
92
|
|
|
92
93
|
(`rootDir` appears in that list because it is a key `defineConfig` itself
|
|
93
94
|
accepts — an `.mjs` configuration authors it directly. A YAML configuration
|
|
@@ -194,7 +195,7 @@ build writes its `name` as `params.author`. `null` when `authors` is empty.
|
|
|
194
195
|
as an unknown key, at the key's own line, because `authors` is the one list a
|
|
195
196
|
package names its people in:
|
|
196
197
|
|
|
197
|
-
> ``package-build config: `author` is not a recognized option (expected one of: rootDir, contentPackage, foundryPackage, homepage, authors, packageKind, stats, itemBuilders, paths, skipDirectories, forbidGeneratedArt, icons, packs, docs, site, pdf, compatibility, relationships, systems, requiresSystem, packageBuild, publish, changelog).``
|
|
198
|
+
> ``package-build config: `author` is not a recognized option (expected one of: rootDir, contentPackage, currentDate, foundryPackage, homepage, authors, packageKind, stats, itemBuilders, paths, skipDirectories, forbidGeneratedArt, icons, packs, docs, site, pdf, compatibility, relationships, systems, requiresSystem, packageBuild, publish, changelog).``
|
|
198
199
|
|
|
199
200
|
`package.json`'s own `author` is npm's and is not read.
|
|
200
201
|
|
|
@@ -294,7 +295,23 @@ Unlike the first three, authoring `itemBuilders` is not an error — it is
|
|
|
294
295
|
|
|
295
296
|
---
|
|
296
297
|
|
|
297
|
-
##
|
|
298
|
+
## Configuration keys
|
|
299
|
+
|
|
300
|
+
### `currentDate`
|
|
301
|
+
|
|
302
|
+
The setting-wide date used for computed ages, age lint, content-index dates,
|
|
303
|
+
Foundry and website output, NPC generation and editor preview. It defaults to
|
|
304
|
+
`"720.1"`. Quote the value so YAML preserves the exact ordinal day digits:
|
|
305
|
+
|
|
306
|
+
```yaml
|
|
307
|
+
contentPackage: thalorna
|
|
308
|
+
currentDate: "720.130"
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Use a neutral `<year>[.<day>[:HHMMSS]]` string. A bare quoted year means its first
|
|
312
|
+
day. Named calendars, `unknown`, numeric YAML values and malformed dates are
|
|
313
|
+
configuration errors located at `currentDate`. Birth dates can still use named
|
|
314
|
+
calendars when the output has the relevant calendar context.
|
|
298
315
|
|
|
299
316
|
### `contentPackage`
|
|
300
317
|
|
package/docs/design.md
CHANGED
|
@@ -33,9 +33,10 @@ Concealment and access remain separate decisions. Public site and book builds
|
|
|
33
33
|
omit GM-only notes; a reference to an omitted destination carries no unusable
|
|
34
34
|
link. Foundry's private packs and page permissions govern destination access.
|
|
35
35
|
Web inline spoilers use a separate show/hide control beside their content, so
|
|
36
|
-
a revealed link is independently usable. Foundry
|
|
37
|
-
|
|
38
|
-
permission behavior.
|
|
36
|
+
a revealed link is independently usable. Foundry inline spoilers use a CSS
|
|
37
|
+
redaction revealed on hover or keyboard focus; they have no native secret-section
|
|
38
|
+
permission behavior. Books ignore inline `.secret` and preserve normal text
|
|
39
|
+
formatting. A spoiler in published HTML remains readable in the source. See the
|
|
39
40
|
[authoring contract](authoring/links-and-markup.md#references-to-secret-subjects)
|
|
40
41
|
for syntax and surface presentation.
|
|
41
42
|
|
package/docs/guides/book.md
CHANGED
|
@@ -522,12 +522,16 @@ Anchors on headings are scoped to their entries, so two entries can use the
|
|
|
522
522
|
same heading anchor. The build reports an unresolved destination while
|
|
523
523
|
keeping the source available for inspection.
|
|
524
524
|
|
|
525
|
-
A reference to a GM-only note or secret heading prints
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
525
|
+
A reference to a GM-only note or secret heading prints normally. GM-only notes
|
|
526
|
+
remain omitted, and references to them print as text without a link. `.show`
|
|
527
|
+
does not add an omitted destination to the book. Inline `[text]{.secret}` spans
|
|
528
|
+
print as ordinary text, preserving emphasis, links, anchors and `.name` bold
|
|
529
|
+
styling; the book ignores their `.secret` class.
|
|
530
|
+
|
|
531
|
+
Secret sections and `:::secret` fences keep their visible contents in pale
|
|
532
|
+
lavender boxes (`#f2eefb`) with a purple left border and title (`#5c4b8a`). The
|
|
533
|
+
default title is **! Secret**; a fence can supply its own title. See
|
|
534
|
+
[secret references](../authoring/links-and-markup.md#references-to-secret-subjects).
|
|
531
535
|
|
|
532
536
|
The [generated sections](../reference/format-details.md#generated-sections)
|
|
533
537
|
an entry carries — **Within**, **Governed by**, **In song and story**, the
|
|
@@ -1822,11 +1822,12 @@ link to the whole public note does not inherit a section's secrecy.
|
|
|
1822
1822
|
|
|
1823
1823
|
The website renders an inline show/hide spoiler; an omitted GM-only target
|
|
1824
1824
|
retains its reference as text without a dead link. A published secret section
|
|
1825
|
-
retains its link. Foundry renders a
|
|
1826
|
-
|
|
1827
|
-
permissions. Books
|
|
1828
|
-
without a link when the GM-only destination
|
|
1829
|
-
automatic spoiler presentation on
|
|
1825
|
+
retains its link. Foundry renders a CSS-redacted inline spoiler, revealed on
|
|
1826
|
+
hover or keyboard focus, with destination access controlled by private packs
|
|
1827
|
+
and page permissions. Books ignore inline `.secret` presentation and print
|
|
1828
|
+
references normally, retaining text without a link when the GM-only destination
|
|
1829
|
+
is omitted. `.show` bypasses automatic spoiler presentation on the website and
|
|
1830
|
+
in Foundry; book references already print normally. An unavailable destination
|
|
1830
1831
|
still has no link.
|
|
1831
1832
|
|
|
1832
1833
|
An immediately following `.show` attribute explicitly reveals the reference:
|
|
@@ -2667,7 +2668,13 @@ local to a note; rendered markers are sequential numbers. A Foundry page
|
|
|
2667
2668
|
collects its referenced footnotes in a Footnotes section at the bottom of that
|
|
2668
2669
|
JournalEntryPage, while a book places them at the bottom of the page of
|
|
2669
2670
|
reference. A term followed by `: definition` lines creates a definition list.
|
|
2670
|
-
|
|
2671
|
+
After a blank line, indent continuation paragraphs and blocks by four spaces
|
|
2672
|
+
to keep them in the same definition; indent a code block's opening fence,
|
|
2673
|
+
contents and closing fence. Another `:` starts a separate definition for the
|
|
2674
|
+
same term. See the [authoring examples](../authoring/links-and-markup.md#footnotes-and-definition-lists). Definition lists use dictionary hanging indents: bold, nonwrapping terms,
|
|
2675
|
+
normal definitions, a 150px shared column (100px at browser widths up to 600px),
|
|
2676
|
+
a `.75em` term gap and `.5em` entry spacing. A long term pushes only the first
|
|
2677
|
+
definition line beyond the shared column; continuation lines return to it.
|
|
2671
2678
|
|
|
2672
2679
|
```
|
|
2673
2680
|
# Heading {#id .class1 .class2 attr="value"}
|
|
@@ -3528,11 +3535,13 @@ The exact `.secret` class marks the enclosed text as an inline spoiler:
|
|
|
3528
3535
|
```
|
|
3529
3536
|
|
|
3530
3537
|
The website provides an inline show/hide button and preserves interactive links
|
|
3531
|
-
inside the revealed content. Foundry
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3538
|
+
inside the revealed content. Foundry renders a focusable, CSS-redacted inline
|
|
3539
|
+
span that reveals its text and nested content on hover or keyboard focus.
|
|
3540
|
+
Native Foundry secret sections retain their own controls. Books ignore `.secret`
|
|
3541
|
+
on inline spans, preserving their text, emphasis, links, anchors and `.name`
|
|
3542
|
+
bold styling. Secret sections and `:::secret` fences keep their visible labelled
|
|
3543
|
+
boxes. Published HTML retains the text, so opening the spoiler or inspecting the
|
|
3544
|
+
source reveals it.
|
|
3536
3545
|
|
|
3537
3546
|
This span has no effect on a destination's audience. Ordinary wikilinks derive
|
|
3538
3547
|
spoilers from their resolved destinations; `.show` bypasses that automatic
|
|
@@ -4555,7 +4564,7 @@ three fields are built around.
|
|
|
4555
4564
|
unrecorded. Both spellings of `died` mean dead.
|
|
4556
4565
|
- **`age` is optional and is an override.** Written, it wins over anything the
|
|
4557
4566
|
dates say. Unwritten beside a dated `born`, it is the age that follows from
|
|
4558
|
-
the date and the
|
|
4567
|
+
the date and the configured current date — see below. Unwritten beside
|
|
4559
4568
|
`born: unknown` or an absent `born`, the age is unknown.
|
|
4560
4569
|
|
|
4561
4570
|
Most people in a setting do not know their own birth date, so an age beside
|
|
@@ -4568,22 +4577,15 @@ read it.
|
|
|
4568
4577
|
|
|
4569
4578
|
#### The age a dated `born` computes to
|
|
4570
4579
|
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
**An authored `age` beside a dated `born` is expected to agree with what the
|
|
4581
|
-
date computes.** Where it does not, `package-build lint` raises a warning
|
|
4582
|
-
naming both values, so a stale age left behind after a `born` was corrected
|
|
4583
|
-
does not go unnoticed. The warning is silent beside `born: unknown` or an
|
|
4584
|
-
absent `born` — there is nothing there to disagree with — and silent wherever
|
|
4585
|
-
the package declares no present, for the same reason no age is computed at
|
|
4586
|
-
all.
|
|
4580
|
+
The root configuration's `currentDate` states the setting's neutral current
|
|
4581
|
+
date, defaulting to `"720.1"`. A being with a dated `born` and no authored `age`
|
|
4582
|
+
compiles the age implied by those dates. A birthday later in the year counts one
|
|
4583
|
+
less than the difference between the years. A year-only birth date uses day one.
|
|
4584
|
+
Unknown and absent birth dates supply no computed age.
|
|
4585
|
+
|
|
4586
|
+
An authored `age` beside a dated `born` is expected to agree with the configured
|
|
4587
|
+
current date. `package-build lint` warns when the values disagree. Authored ages,
|
|
4588
|
+
including zero and estimates such as `~34`, remain unchanged in built output.
|
|
4587
4589
|
|
|
4588
4590
|
Use `born:` for a being's birth date.
|
|
4589
4591
|
|
|
@@ -6989,7 +6991,6 @@ level with no background prints nothing.
|
|
|
6989
6991
|
| `year.hoursPerDay` | `number` | How many hours the day divides into |
|
|
6990
6992
|
| `year.minutesPerHour` | `number` | How many minutes the hour divides into |
|
|
6991
6993
|
| `year.secondsPerMinute` | `number` | How many seconds the minute divides into |
|
|
6992
|
-
| `present` | `date` | The day the setting stops and play begins |
|
|
6993
6994
|
| `body.diameterKm` | `number` | The body's diameter, in kilometres |
|
|
6994
6995
|
| `body.orbitalRadiusKm` | `number` | How far it orbits from the body it circles, in kilometres |
|
|
6995
6996
|
| `body.orbit` | `string` | The orbit's shape — `circular` means the cycle never varies |
|
|
@@ -7021,7 +7022,6 @@ about the world's year.
|
|
|
7021
7022
|
data:
|
|
7022
7023
|
world: { equatorialCircumferenceKm: 40000, surfaceGravityG: 1.0, axialTiltDegrees: 23.5 }
|
|
7023
7024
|
year: { days: 365, hoursPerDay: 24, minutesPerHour: 60, secondsPerMinute: 60 }
|
|
7024
|
-
present: 720
|
|
7025
7025
|
|
|
7026
7026
|
# its moon — a note of its own, because a moon is a body and not a property
|
|
7027
7027
|
data:
|
|
@@ -7039,14 +7039,13 @@ else wrote down.
|
|
|
7039
7039
|
can say which one a calendar divides; a `moon` with no `year` anywhere is
|
|
7040
7040
|
refused, because a cycle counted in days has no year to be measured against.
|
|
7041
7041
|
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
says it that way.
|
|
7042
|
+
The root configuration's `currentDate` supplies the neutral date used for age
|
|
7043
|
+
calculations throughout the setting. Its default is `"720.1"`.
|
|
7045
7044
|
|
|
7046
7045
|
**`world.axialTiltDegrees`, the circumference, the gravity, the moon's diameter
|
|
7047
7046
|
and its orbital radius are read by nobody.** They are there so a reader knows
|
|
7048
7047
|
what kind of world this is. What the build consumes is the year, the day's
|
|
7049
|
-
divisions, the
|
|
7048
|
+
divisions, the moon's cycle and epoch, and whether its orbit is
|
|
7050
7049
|
circular and inclined.
|
|
7051
7050
|
|
|
7052
7051
|
#### What a settlement's market supports
|
|
@@ -885,7 +885,6 @@ Lore records in-world knowledge. A `culture` describes a people; a `custom` desc
|
|
|
885
885
|
| `data.year.hoursPerDay` | number | How many hours the day divides into. |
|
|
886
886
|
| `data.year.minutesPerHour` | number | How many minutes the hour divides into. |
|
|
887
887
|
| `data.year.secondsPerMinute` | number | How many seconds the minute divides into. |
|
|
888
|
-
| `data.present` | a date | The day the setting stops and play begins — what an age is computed against. |
|
|
889
888
|
| `data.body.diameterKm` | number | The body's diameter, in kilometres. |
|
|
890
889
|
| `data.body.orbitalRadiusKm` | number | How far the body orbits from the one it circles, in kilometres. |
|
|
891
890
|
| `data.body.orbit` | string | The orbit's shape — `circular` means the cycle never varies. |
|