@heroiclands/package-build 25.5.3 → 25.5.5
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 +28 -0
- package/README.md +7 -0
- package/bin/content-commands.mjs +32 -8
- package/docs/api.md +57 -16
- package/docs/authoring/links-and-markup.md +51 -3
- package/docs/commands.md +60 -17
- package/docs/configuration.md +3 -2
- package/docs/content-format.md +10 -0
- package/docs/diagnostics.md +17 -0
- package/docs/guides/module-project.md +11 -3
- package/docs/guides/site.md +12 -2
- package/docs/guides/writing-in-invented-scripts.md +5 -2
- package/docs/reference/format-details.md +61 -11
- package/docs/reference/note-types.md +32 -32
- package/e2e.mjs +1 -1
- package/engine/base-compiler.mjs +2 -0
- package/engine/compile-corpus.mjs +6 -2
- package/engine/content-charset.mjs +1 -1
- package/engine/content-render.mjs +14 -2
- package/engine/content-scripts.mjs +44 -6
- package/engine/content-session.mjs +57 -20
- package/engine/content-spans.mjs +3 -4
- package/engine/content-verse.mjs +52 -10
- package/engine/core-report.mjs +27 -18
- package/engine/language-names.mjs +53 -23
- package/engine/markdownlint-run.mjs +1 -1
- package/engine/markup-validation.mjs +2 -0
- package/engine/note-vocabulary.mjs +10 -5
- package/engine/npc-generate.mjs +52 -7
- package/engine/page-breaks.mjs +115 -0
- package/engine/pdf-build.mjs +12 -4
- package/engine/pdf-render.mjs +10 -1
- package/engine/preview-index.mjs +4 -2
- package/engine/site-build.mjs +12 -3
- package/engine/site-preview.mjs +3 -0
- package/engine/site-render.mjs +18 -4
- package/engine/site-root.mjs +10 -1
- package/engine/site-serve-http.mjs +151 -0
- package/engine/site-serve.mjs +196 -126
- package/engine/sql-tables.mjs +379 -214
- package/engine/verse-metre.mjs +50 -5
- package/engine/verse-regions.mjs +16 -0
- package/package.json +3 -3
- package/types/e2e.d.mts +1 -1
- package/types/engine/content-scripts.d.mts +9 -1
- package/types/engine/content-session.d.mts +1 -1
- package/types/engine/content-verse.d.mts +11 -2
- package/types/engine/core-report.d.mts +6 -2
- package/types/engine/language-names.d.mts +18 -6
- package/types/engine/npc-generate.d.mts +3 -0
- package/types/engine/page-breaks.d.mts +30 -0
- package/types/engine/pdf-render.d.mts +2 -0
- package/types/engine/site-build.d.mts +3 -1
- package/types/engine/site-render.d.mts +6 -2
- package/types/engine/site-root.d.mts +3 -1
- package/types/engine/site-serve-http.d.mts +1 -0
- package/types/engine/site-serve.d.mts +12 -6
- package/types/engine/sql-tables.d.mts +37 -8
- package/types/engine/verse-metre.d.mts +2 -1
- package/types/engine/verse-regions.d.mts +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @heroiclands/package-build
|
|
2
2
|
|
|
3
|
+
## 25.5.5
|
|
4
|
+
|
|
5
|
+
**Languages and scripts**
|
|
6
|
+
|
|
7
|
+
- Ch'alish P'ilam Ceremonial text passes character checks and is recognized as native script alongside Common.
|
|
8
|
+
- Core vocabulary reports name the languages left unmeasured, including when no language opts into coverage.
|
|
9
|
+
- Generated NPC names capitalize their name words for English prose while keeping connecting words as written.
|
|
10
|
+
- Distinct source names keep their authored spelling under the culture's language code, except when the selected pattern draws English words.
|
|
11
|
+
- The language reference explains that Roman inventories list language additions and refuse shared punctuation and whitespace in the list.
|
|
12
|
+
- A language can supply one list of given names for everyone; NPC generation draws from it for every gender.
|
|
13
|
+
|
|
14
|
+
**Verse**
|
|
15
|
+
|
|
16
|
+
- Metre checks allow multi-syllable function words to go unstressed, so lines can scan without placing a beat on every particle or pronoun.
|
|
17
|
+
- Verse inside blockquotes and nested lists keeps its line breaks, stanza boundaries and indentation, with findings located at the authored text.
|
|
18
|
+
- Verse metre checks count a linked name's visible words without adding beats from its address.
|
|
19
|
+
|
|
20
|
+
**Rendering and sites**
|
|
21
|
+
|
|
22
|
+
- A book can break the page at a chosen point with `--- {.page-break}`.
|
|
23
|
+
- Website previews start immediately, keep the last successful pages available during rebuilds, and report progress while building pages and search.
|
|
24
|
+
|
|
25
|
+
## 25.5.4
|
|
26
|
+
|
|
27
|
+
**Builds and commands**
|
|
28
|
+
|
|
29
|
+
- Content builds use less memory when preparing, checking and compiling notes.
|
|
30
|
+
|
|
3
31
|
## 25.5.3
|
|
4
32
|
|
|
5
33
|
**Verse**
|
package/README.md
CHANGED
|
@@ -53,6 +53,13 @@ repository’s setup installs the two canonical shell hooks; it installs no
|
|
|
53
53
|
pre-push hook. Run `npm test` and the other checks directly, or use
|
|
54
54
|
`package-build ci` for a container run.
|
|
55
55
|
|
|
56
|
+
The repository's `vitest.config.ts` limits both `npm test` and `npm run
|
|
57
|
+
test:watch` to two workers, with Vitest's isolated fork pool. CI runs the same
|
|
58
|
+
`npm test` command. This bounds concurrent test files on the shared runner,
|
|
59
|
+
including files that start CLI subprocesses, load SQL databases, or emit
|
|
60
|
+
TypeScript declarations. Keep this bound when reproducing CI failures locally;
|
|
61
|
+
a percentage of the host's CPUs does not reserve resources for other jobs.
|
|
62
|
+
|
|
56
63
|
## Documentation
|
|
57
64
|
|
|
58
65
|
The documentation lives in the Markdown files in this repository. Start with [the documentation home](docs/index.md). This toolchain does not build its own site or book.
|
package/bin/content-commands.mjs
CHANGED
|
@@ -1289,7 +1289,12 @@ function lintCommand() {
|
|
|
1289
1289
|
// Text marked with a language, a font or a map, checked against
|
|
1290
1290
|
// the languages this package declares, the faces it installed
|
|
1291
1291
|
// and the maps its notes declare.
|
|
1292
|
-
const runs = runContext(config, records
|
|
1292
|
+
const runs = runContext(config, records, {
|
|
1293
|
+
referenceName: (target) => {
|
|
1294
|
+
const hit = index.resolveAddress(target) ?? index.manifestHit(target);
|
|
1295
|
+
return hit?.fm?.name?.full ?? hit?.name;
|
|
1296
|
+
},
|
|
1297
|
+
});
|
|
1293
1298
|
const loaderLocations = new Set(
|
|
1294
1299
|
(runs.encodingFindings ?? []).map((one) =>
|
|
1295
1300
|
JSON.stringify([one.file, one.line, one.column, one.message]),
|
|
@@ -2346,7 +2351,11 @@ function siteBuildCommand() {
|
|
|
2346
2351
|
const config = argv[CONTENT_CONFIG] ?? loadPackConfig();
|
|
2347
2352
|
const root = path.resolve(config.rootDir, argv.out ?? DEPLOY_ROOT);
|
|
2348
2353
|
const out = siteDirectory(config, root);
|
|
2349
|
-
const result = await buildPackageSite({
|
|
2354
|
+
const result = await buildPackageSite({
|
|
2355
|
+
config,
|
|
2356
|
+
out,
|
|
2357
|
+
progress: (message) => log.info(message),
|
|
2358
|
+
});
|
|
2350
2359
|
// A note in error is written as its page shows it, and the
|
|
2351
2360
|
// build fails without indexing a site that is not to be
|
|
2352
2361
|
// deployed.
|
|
@@ -2374,6 +2383,7 @@ function siteBuildCommand() {
|
|
|
2374
2383
|
base: siteBase(config),
|
|
2375
2384
|
out: root,
|
|
2376
2385
|
search: config.site.search,
|
|
2386
|
+
progress: (message) => log.info(message),
|
|
2377
2387
|
});
|
|
2378
2388
|
if (search) {
|
|
2379
2389
|
log.info(
|
|
@@ -2429,8 +2439,10 @@ function siteServeCommand() {
|
|
|
2429
2439
|
host: argv.host,
|
|
2430
2440
|
port: argv.port,
|
|
2431
2441
|
report: (event) => {
|
|
2432
|
-
if (event.kind === "
|
|
2433
|
-
else if (event.kind === "
|
|
2442
|
+
if (event.kind === "progress") log.info(event.message);
|
|
2443
|
+
else if (event.kind === "error") {
|
|
2444
|
+
if (!event.fatal) reportFailure(event.error);
|
|
2445
|
+
} else if (event.kind === "failed") {
|
|
2434
2446
|
if (event.built) reportSiteBuild(event.built);
|
|
2435
2447
|
for (const finding of event.findings ?? []) emitDiagnostic(finding);
|
|
2436
2448
|
} else {
|
|
@@ -2444,11 +2456,22 @@ function siteServeCommand() {
|
|
|
2444
2456
|
},
|
|
2445
2457
|
});
|
|
2446
2458
|
log.info(`serving ${served.url} — interrupt to stop`);
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2459
|
+
let interrupt;
|
|
2460
|
+
const interrupted = new Promise((resolve) => {
|
|
2461
|
+
interrupt = resolve;
|
|
2462
|
+
process.once("SIGINT", interrupt);
|
|
2463
|
+
process.once("SIGTERM", interrupt);
|
|
2450
2464
|
});
|
|
2451
|
-
|
|
2465
|
+
try {
|
|
2466
|
+
await Promise.race([interrupted, served.done]);
|
|
2467
|
+
} catch (err) {
|
|
2468
|
+
reportFailure(err);
|
|
2469
|
+
process.exitCode = 1;
|
|
2470
|
+
} finally {
|
|
2471
|
+
process.removeListener("SIGINT", interrupt);
|
|
2472
|
+
process.removeListener("SIGTERM", interrupt);
|
|
2473
|
+
await served.close();
|
|
2474
|
+
}
|
|
2452
2475
|
} catch (err) {
|
|
2453
2476
|
reportFailure(err);
|
|
2454
2477
|
process.exitCode = 1;
|
|
@@ -3467,6 +3490,7 @@ function newNpc(config, argv) {
|
|
|
3467
3490
|
profile,
|
|
3468
3491
|
names,
|
|
3469
3492
|
language: languageKey,
|
|
3493
|
+
languageCode: code,
|
|
3470
3494
|
seed: argv.seed,
|
|
3471
3495
|
currentDate: config.currentDate,
|
|
3472
3496
|
dateContext: reckoningContext(index),
|
package/docs/api.md
CHANGED
|
@@ -1329,12 +1329,30 @@ content tree can also compile into Foundry compendium packs.
|
|
|
1329
1329
|
| `renderPages` | `function renderPages(pages, options)` | `{{written: number, byKind: Record<string, number>, tableErrors: object[], wikiErrors: object[]}}` | Renders every page. |
|
|
1330
1330
|
| `resolveSitePass` | `function resolveSitePass(name, options)` | `{{beforeLinks?: Function}}` The bundle. | Resolves `site.pass` to its bundle. |
|
|
1331
1331
|
| `sitePageDecorator` | `sitePageDecorator(config, index)` | Function | Add the site's infobox and being metadata to a rendered page. |
|
|
1332
|
-
| `buildSite` | `buildSite({ config, sqlTables })`
|
|
1332
|
+
| `buildSite` | `buildSite({ config, sqlTables, progress })` | `{{gates: object, stats: object\|null, tableErrors: object[], wikiErrors: object[], mapFindings: object[], manifests: object\|null, site?: object}}` | Collects, checks and renders a content tree's pages, and reports what it found; returns each page for the site's renderer. |
|
|
1333
1333
|
|
|
1334
1334
|
`siteGates` takes `{ config, records, sqlTables? }`. Pass the prepared
|
|
1335
1335
|
`sqlTables` map so anchors emitted by automatic dictionary sections are present in the
|
|
1336
1336
|
index for checking page links.
|
|
1337
1337
|
|
|
1338
|
+
`buildSite`, `engine/site-render.mjs`'s `buildPackageSite` and `writeSite`, and
|
|
1339
|
+
`engine/site-root.mjs`'s `writeSiteRoot` accept an optional `progress(message)`
|
|
1340
|
+
callback for phase summaries. It receives prose, independently of findings.
|
|
1341
|
+
|
|
1342
|
+
`engine/site-serve.mjs`'s `serveSite({ config, out, root?, host?, port?, search?,
|
|
1343
|
+
year?, report? })` resolves with `{ url, settled, close, done }` when HTTP listens,
|
|
1344
|
+
before the initial build. Await `settled()` to wait for that build and queued
|
|
1345
|
+
edits, and `close()` to stop watching and serving. `done` resolves on close;
|
|
1346
|
+
an unexpected HTTP failure rejects it and stops the watchers. Its `report` callback
|
|
1347
|
+
receives `progress` events with a `message`, alongside `built`, `page`,
|
|
1348
|
+
`theme`, `failed` and `error` events; a fatal HTTP error has `fatal: true`.
|
|
1349
|
+
Failed builds are reported through that
|
|
1350
|
+
callback and leave the previous output in service. HTTP runs in a separate
|
|
1351
|
+
thread so synchronous rendering does not stall requests; the resolved
|
|
1352
|
+
configuration and incremental render state stay in the calling thread. Every
|
|
1353
|
+
update is prepared in a separate output tree, then installed between HTTP
|
|
1354
|
+
requests so readers receive complete files.
|
|
1355
|
+
|
|
1338
1356
|
### `engine.contentRender`
|
|
1339
1357
|
|
|
1340
1358
|
`createRenderer(target, options?)` builds the one markdown-it configuration every target renders through. `target` is `"foundry"`, `"web"`, `"preview"` or `"book"`. The renderer holds the configured parser (`md`), the names of the plugins installed (`plugins`), and three functions: `prepare` writes the constructs markdown-it has no syntax for — marked text, captioned items, named blocks, verse and alerts — as HTML between blank lines; `render` prepares and renders to HTML; `renderInline` renders one inline run. The `book` target parses only, and its Typst stage reads the tokens.
|
|
@@ -1362,6 +1380,16 @@ complete source. Reference-only positions contribute no work shape. A wholly
|
|
|
1362
1380
|
reference-only body carries its references in `model.notes`, rendered once
|
|
1363
1381
|
outside native-font wrappers without a verse row or label.
|
|
1364
1382
|
|
|
1383
|
+
Verse regions retain the authored `body` and its absolute `bodyStart` and
|
|
1384
|
+
`bodyEnd`. Their `logicalBody` excludes Markdown list and blockquote prefixes;
|
|
1385
|
+
`bodyOffsets` maps each logical UTF-16 position, including the exclusive end,
|
|
1386
|
+
back to an authored body offset. `parseVerse(logicalBody, {sourceOffsets:
|
|
1387
|
+
bodyOffsets, footnotes})` returns the whole model in authored body coordinates:
|
|
1388
|
+
line bounds and character offsets, stanza and canto bounds, boundaries, layout
|
|
1389
|
+
ranges and findings all use that map. Omitted prefixes are layout ranges, so
|
|
1390
|
+
Roman and native projections exclude them. Add `bodyStart` to a model offset to
|
|
1391
|
+
locate it in the complete source. LF and CRLF retain their authored lengths.
|
|
1392
|
+
|
|
1365
1393
|
| Export | Signature | Returns | Use it when |
|
|
1366
1394
|
| ---------------- | ---------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
|
|
1367
1395
|
| `createRenderer` | `createRenderer(target, options?)` | `{ target, md, plugins, prepare, render, renderInline }` | Rendering a note body for one target with the rules every target shares. |
|
|
@@ -1446,17 +1474,17 @@ The charset authored content is held to, so a book can choose its face. The pack
|
|
|
1446
1474
|
|
|
1447
1475
|
### `engine.romanCharacters`
|
|
1448
1476
|
|
|
1449
|
-
|
|
1450
|
-
encoding. Inventories come from `data.roman` on each language's own note.
|
|
1477
|
+
A configured language's Roman additions to the shared punctuation standard,
|
|
1478
|
+
before script encoding. Inventories come from `data.roman` on each language's own note.
|
|
1451
1479
|
|
|
1452
|
-
| Export | Signature | Returns | Use it when
|
|
1453
|
-
| ------------------------- | -------------------------------------------- | ----------------------------- |
|
|
1454
|
-
| `isRomanWhitespace` | `isRomanWhitespace(char)` | `boolean` | recognizing standard spaces and ASCII tab or line whitespace
|
|
1455
|
-
| `romanInventoryProblems` | `romanInventoryProblems(value)` | `string[]` | checking NFC,
|
|
1456
|
-
| `romanInventoriesOf` | `romanInventoriesOf(records, languages)` | `Map<string, RomanInventory>` | looking up a configured language's own inventory by name or BCP 47 tag
|
|
1457
|
-
| `romanTextProblems` | `romanTextProblems(text, inventory, stream)` | `{offset, message}[]` | validating standard Roman punctuation and language additions with exact UTF-16 offsets; pass a `stream` state to continue sentences and quotations from earlier runs
|
|
1458
|
-
| `romanPunctuationState` | `romanPunctuationState()` | `{sentenceStart, quotes}` | starting a stream of runs whose sentences and quotations continue from one run to the next
|
|
1459
|
-
| `romanUnclosedQuotations` | `romanUnclosedQuotations(quotes)` | `{offset, message}[]` | reporting the quotations still open where a stream of runs ends
|
|
1480
|
+
| Export | Signature | Returns | Use it when |
|
|
1481
|
+
| ------------------------- | -------------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1482
|
+
| `isRomanWhitespace` | `isRomanWhitespace(char)` | `boolean` | recognizing standard spaces and ASCII tab or line whitespace |
|
|
1483
|
+
| `romanInventoryProblems` | `romanInventoryProblems(value)` | `string[]` | checking NFC, repeats and forbidden whitespace, controls, standard punctuation, literal markers, semicolons, colons, English double quotes and setting-script characters |
|
|
1484
|
+
| `romanInventoriesOf` | `romanInventoriesOf(records, languages)` | `Map<string, RomanInventory>` | looking up a configured language's own inventory by name or BCP 47 tag |
|
|
1485
|
+
| `romanTextProblems` | `romanTextProblems(text, inventory, stream)` | `{offset, message}[]` | validating standard Roman punctuation and language additions with exact UTF-16 offsets; pass a `stream` state to continue sentences and quotations from earlier runs |
|
|
1486
|
+
| `romanPunctuationState` | `romanPunctuationState()` | `{sentenceStart, quotes}` | starting a stream of runs whose sentences and quotations continue from one run to the next |
|
|
1487
|
+
| `romanUnclosedQuotations` | `romanUnclosedQuotations(quotes)` | `{offset, message}[]` | reporting the quotations still open where a stream of runs ends |
|
|
1460
1488
|
|
|
1461
1489
|
### `engine.pathCharset`
|
|
1462
1490
|
|
|
@@ -2573,6 +2601,16 @@ points derive their own inputs. Generation and pack compilation accept
|
|
|
2573
2601
|
`reportPreparation` (default true); a coordinating caller may set it false
|
|
2574
2602
|
only after reporting the shared source findings itself.
|
|
2575
2603
|
|
|
2604
|
+
`engine/content-scripts` exposes `runContext(config, records?, {referenceName}?)`.
|
|
2605
|
+
It returns the language, encoding and metre context used by run scanning.
|
|
2606
|
+
`referenceName(target)` supplies the rendering or validation index's current
|
|
2607
|
+
name for an Address, including dependency targets, or `undefined` when none
|
|
2608
|
+
resolves. This lookup takes precedence over the local-record fallback and
|
|
2609
|
+
belongs only to the returned context; shared cached lexical data does not
|
|
2610
|
+
share a lookup between page or audience views. A metre line whose empty link
|
|
2611
|
+
label has no resolved spoken text stays unscanned, while the link validator
|
|
2612
|
+
reports invalid targets independently.
|
|
2613
|
+
|
|
2576
2614
|
`buildLinkIndex` and `buildContentLinkIndex` accept an optional `foreign` view
|
|
2577
2615
|
from the same session; their diagnostic and routed resolver contracts remain
|
|
2578
2616
|
distinct. `collectAnchors`, `markupAnchorFindings`, `markupFindings`, journal
|
|
@@ -2922,10 +2960,13 @@ const inferred = encode(data, null, "say", { enc: "aelwsemaronenc" });
|
|
|
2922
2960
|
|
|
2923
2961
|
Both functions take `(data, language, text, options?)` and return
|
|
2924
2962
|
`{text, findings}`; encoding with a language also returns source-positioned
|
|
2925
|
-
`pieces`.
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2963
|
+
`pieces`. `options.enc` selects a consumer-authored encoding document, which
|
|
2964
|
+
supplies its language and font. An explicit language must agree with that
|
|
2965
|
+
document; a null or omitted language infers it and uses its lexical inputs.
|
|
2966
|
+
`options.font` must agree with the encoding's font; `options.verse` asks the
|
|
2967
|
+
encoder to interpret verse structure. An omitted `enc`, or `enc: "default"`,
|
|
2968
|
+
preserves the Roman text. Bare conversion without lexical inputs uses the
|
|
2969
|
+
pure `encodeText` and `decodeText` functions in `engine/encoding.mjs`.
|
|
2929
2970
|
|
|
2930
2971
|
Language conversion uses the same pure `encodeWithLanguage` and
|
|
2931
2972
|
`decodeWithLanguage` functions as the build. Recorded native writings and
|
|
@@ -2933,7 +2974,7 @@ parts precede encoding rows, and decoding can recover an unmarked word from
|
|
|
2933
2974
|
the lexicon. An unknown word gives a positioned finding. A bare refusal
|
|
2934
2975
|
returns empty text and an error finding. Findings carry `severity`, `message`,
|
|
2935
2976
|
`offset` (UTF-16), and one-based Unicode-code-point `line` and `column`.
|
|
2936
|
-
Invalid data, unknown languages and
|
|
2977
|
+
Invalid data, unknown languages and unknown encoding selections throw an
|
|
2937
2978
|
error before conversion. `validateData(data)` returns the validated data or
|
|
2938
2979
|
throws; it opens no files.
|
|
2939
2980
|
|
|
@@ -237,6 +237,30 @@ A captioned item inside the section is withheld with it: in Foundry the item's o
|
|
|
237
237
|
|
|
238
238
|
The special Actor anchors `{#appearance}` and `{#dossier}` feed the same authored sections to each system's Actor fields, and take an H1 only — not the lower-level heading a journal page may otherwise start from. The section runs to the next H1, nested headings included. An anchor declared on a lower heading is still found, and is a build error rather than a quietly empty field: move the heading to the top level, or drop the anchor if the section is meant to stay unaddressed prose.
|
|
239
239
|
|
|
240
|
+
## Book page breaks
|
|
241
|
+
|
|
242
|
+
Write `--- {.page-break}` on its own line between blocks, with blank lines around it:
|
|
243
|
+
|
|
244
|
+
```markdown
|
|
245
|
+
The first passage ends here.
|
|
246
|
+
|
|
247
|
+
--- {.page-break}
|
|
248
|
+
|
|
249
|
+
The next passage starts on a fresh book page.
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The book starts a fresh page without drawing a rule. If the marker already
|
|
253
|
+
falls at the top of a page, it adds no blank page. The website, Foundry and
|
|
254
|
+
both editor preview views omit the marker. Plain `---`, `***` and `___` keep
|
|
255
|
+
their ordinary horizontal rules. Code blocks and verse divs keep the marker
|
|
256
|
+
as literal text.
|
|
257
|
+
|
|
258
|
+
Only `---` accepts `.page-break`; `*** {.page-break}` and `___ {.page-break}`
|
|
259
|
+
are findings. Other classes, ids and attributes on an attributed `---` line
|
|
260
|
+
are findings too. A page break stands between blocks at the top level of a
|
|
261
|
+
note: putting one inside a list, block quote, alert, secret block or fenced
|
|
262
|
+
div is a finding at the marker's line and column.
|
|
263
|
+
|
|
240
264
|
## Captions and numbered references
|
|
241
265
|
|
|
242
266
|
Write a caption on its own line **before** the item it describes, with a blank line before and after the caption. `:` produces an unnumbered caption; `:@` produces a numbered caption. One or more spaces separate the marker from its text. An optional attribute block at the end accepts an identifier, classes and named attributes:
|
|
@@ -424,6 +448,20 @@ Periods inside the first inline span can set indentation; periods in later spans
|
|
|
424
448
|
are literal. Tabs inside a verse div are errors. The div body is opaque to Markdown block syntax:
|
|
425
449
|
lines beginning `- `, `1. `, `# `, `> ` or four spaces stay verse text.
|
|
426
450
|
|
|
451
|
+
A verse div may sit inside a blockquote, a list item, or nested combinations of
|
|
452
|
+
both. Write the surrounding container prefix on each line, including blank
|
|
453
|
+
stanza lines. Container markers stay outside the verse text; logical lines,
|
|
454
|
+
indentation and stanza boundaries follow the same rules as a standalone div.
|
|
455
|
+
Findings point to the authored line and column, including its container prefix.
|
|
456
|
+
|
|
457
|
+
```markdown
|
|
458
|
+
> ::: {.verse}
|
|
459
|
+
> One/..Two
|
|
460
|
+
>
|
|
461
|
+
> Three
|
|
462
|
+
> :::
|
|
463
|
+
```
|
|
464
|
+
|
|
427
465
|
These two bodies have the same lines and indentation:
|
|
428
466
|
|
|
429
467
|
```markdown
|
|
@@ -491,13 +529,23 @@ language's stress rules; it reports an error at the line:
|
|
|
491
529
|
Speaker labels and stage directions (`.speaker` and `.direction`) are presentation
|
|
492
530
|
only: their text is not scanned, and a line containing only those spans is skipped.
|
|
493
531
|
|
|
532
|
+
Wikilinks contribute only their visible labels to the beat count. An empty label
|
|
533
|
+
(`[[place-ashkarad|]]`) contributes the indexed target's name, including a name
|
|
534
|
+
from a dependency. Address segments, anchors and link attributes contribute no
|
|
535
|
+
beats. If an empty label has no resolved spoken text, the line is not scanned;
|
|
536
|
+
the link check reports invalid targets separately. Empty same-page caption
|
|
537
|
+
references depend on page or book numbering and leave the line unscanned when
|
|
538
|
+
that display text is unavailable.
|
|
539
|
+
|
|
494
540
|
Beats are counted this way:
|
|
495
541
|
|
|
496
542
|
- **Syllables** are vowel groups. A vowel is a letter whose base is `a`, `e`,
|
|
497
543
|
`i`, `o` or `u`, and a pair the language lists in
|
|
498
544
|
`data.sounds.syllables.vowelPairs` is one syllable.
|
|
499
|
-
- **
|
|
500
|
-
syllable
|
|
545
|
+
- **A word of two or more syllables has one beat**, on its stressed
|
|
546
|
+
syllable, but may go unstressed when every lexicon class is a function class:
|
|
547
|
+
any base other than `n`, `v`, `adj`, `num` or `name`. A word with any content
|
|
548
|
+
class, or no lexicon entry, keeps its beat. The language's stress rule places it: `two` for a word of two
|
|
501
549
|
syllables, `longer` for a word of three or more, and a vowel carrying the
|
|
502
550
|
rule's `mark` is stressed wherever it sits.
|
|
503
551
|
- **A one-syllable noun, verb, adjective, numeral or name has a beat.** A
|
|
@@ -506,7 +554,7 @@ Beats are counted this way:
|
|
|
506
554
|
through `lang=` as it is for the word check, including words inherited from
|
|
507
555
|
its family. All entries for a spelling in the nearest lexicon supply their
|
|
508
556
|
classes. A form the
|
|
509
|
-
language's own rules derive takes its word's class. A word
|
|
557
|
+
language's own rules derive takes its word's class. A one-syllable word with both content and function classes has a
|
|
510
558
|
beat that may be left out.
|
|
511
559
|
- **A one-syllable word the lexicon does not hold is a content word** and has a
|
|
512
560
|
beat. The word check reports the word separately.
|
package/docs/commands.md
CHANGED
|
@@ -2255,11 +2255,12 @@ dependencies; exact Item UUID validation remains part of compilation. Reads
|
|
|
2255
2255
|
the content tree named by `root`, defaulting to
|
|
2256
2256
|
`paths.content`; writes nothing.
|
|
2257
2257
|
|
|
2258
|
-
Every configured language note declares `data.roman`,
|
|
2259
|
-
|
|
2258
|
+
Every configured language note declares `data.roman`, the NFC Roman characters
|
|
2259
|
+
the language adds to the shared standard: letters in accepted cases, accents,
|
|
2260
|
+
catch signs and digits. Lint checks language-tagged text before mapping, using the
|
|
2260
2261
|
same inventory for a configured name and its BCP 47 tag. Visible linked labels
|
|
2261
2262
|
are checked; destinations, attributes and verse structure are excluded. An
|
|
2262
|
-
explicit empty inventory declares no
|
|
2263
|
+
explicit empty inventory declares no additions. External tags without
|
|
2263
2264
|
a language-note association retain their ordinary behavior. Standalone
|
|
2264
2265
|
`package-build markdown` does not load these inventories.
|
|
2265
2266
|
|
|
@@ -2698,6 +2699,11 @@ links, tables, expressions, generated sections, maps — and rendered by the
|
|
|
2698
2699
|
same renderer the Foundry journals and the editor preview use, then drawn by
|
|
2699
2700
|
the site theme's layouts.
|
|
2700
2701
|
|
|
2702
|
+
Progress goes to stdout as each phase starts: indexing content, rendering
|
|
2703
|
+
pages, writing pages, and building the search index. Rendering and writing
|
|
2704
|
+
include page counts; the search summary gives the number indexed. Diagnostics
|
|
2705
|
+
remain on stderr in `file:line:column: severity: message` form.
|
|
2706
|
+
|
|
2701
2707
|
**A site is its homepage and its pages.** The `type: homepage` note is the
|
|
2702
2708
|
package's front page at `/<contentPackage>/`; every other note is one page at
|
|
2703
2709
|
`/<contentPackage>/<type>-<shortcode>/`. Nothing is generated between them
|
|
@@ -2770,8 +2776,12 @@ findings of severity `warning` included.
|
|
|
2770
2776
|
|
|
2771
2777
|
```
|
|
2772
2778
|
$ package-build site build
|
|
2779
|
+
[…] indexing content
|
|
2780
|
+
[…] rendering 4306 page(s)
|
|
2781
|
+
[…] writing 4306 page(s)
|
|
2773
2782
|
package-build.config.yaml:38:24: warning: the page-not-found links to /thalorna/polity/, which the site does not publish, so the link is left out
|
|
2774
2783
|
[…] wrote 4306 page(s) to build/site/thalorna
|
|
2784
|
+
[…] building the search index
|
|
2775
2785
|
[…] indexed 4307 page(s) for search into build/site/thalorna/pagefind
|
|
2776
2786
|
```
|
|
2777
2787
|
|
|
@@ -2794,13 +2804,25 @@ package-build site serve [--port <port>] [--host <address>] [--out <dir>]
|
|
|
2794
2804
|
|
|
2795
2805
|
**DESCRIPTION**
|
|
2796
2806
|
|
|
2797
|
-
|
|
2798
|
-
|
|
2807
|
+
Starts HTTP and prints the listening address before the first build begins.
|
|
2808
|
+
Builds the site as `package-build site build` does and indexes it for search,
|
|
2809
|
+
while serving the deployed directory, so every page is at the address it
|
|
2799
2810
|
is deployed at: `http://127.0.0.1:1313/<contentPackage>/`, or the path
|
|
2800
2811
|
`site.base` states. An address the site does not publish is answered with its
|
|
2801
2812
|
`404.html`. A search index `site.mergeIndexes` names is not served, since it is
|
|
2802
2813
|
another site's; the site's own index is.
|
|
2803
2814
|
|
|
2815
|
+
Existing output stays available while a whole build runs. Incremental page and
|
|
2816
|
+
theme updates also prepare their files separately before replacing the served
|
|
2817
|
+
tree, so requests receive complete pages and styles. The new pages and
|
|
2818
|
+
search index replace it together after a successful build. A failed render,
|
|
2819
|
+
font delivery or search build leaves the previous site available. Without
|
|
2820
|
+
existing output, requests receive HTTP 503 with a message pointing to the
|
|
2821
|
+
terminal until a build succeeds; reload the page after the build completes.
|
|
2822
|
+
The build's indexing, rendering, writing and search phases print to stdout,
|
|
2823
|
+
with page counts where available. Diagnostics keep their located format on
|
|
2824
|
+
stderr. Whole rebuilds also refresh the search index.
|
|
2825
|
+
|
|
2804
2826
|
The content tree and the theme are watched. A change to a note's body or
|
|
2805
2827
|
frontmatter writes that note's page again; a note whose name, type or
|
|
2806
2828
|
shortcode changed, a new or removed note, a note holding an `sql` table, and
|
|
@@ -2825,15 +2847,21 @@ running. Interrupt it to stop.
|
|
|
2825
2847
|
|
|
2826
2848
|
**EXIT STATUS**
|
|
2827
2849
|
|
|
2828
|
-
1 when the site's settings or its cached menu cannot be read
|
|
2829
|
-
|
|
2850
|
+
1 when the site's settings or its cached menu cannot be read, or HTTP cannot
|
|
2851
|
+
start or stops unexpectedly. Build failures are reported while the server keeps running. Otherwise
|
|
2852
|
+
0 once interrupted.
|
|
2830
2853
|
|
|
2831
2854
|
**EXAMPLES**
|
|
2832
2855
|
|
|
2833
2856
|
```
|
|
2834
2857
|
$ package-build site serve
|
|
2835
|
-
[…] built the site
|
|
2836
2858
|
[…] serving http://127.0.0.1:1313/thalorna/ — interrupt to stop
|
|
2859
|
+
[…] indexing content
|
|
2860
|
+
[…] rendering 4306 page(s)
|
|
2861
|
+
[…] writing 4306 page(s)
|
|
2862
|
+
[…] building the search index
|
|
2863
|
+
[…] indexed 4307 page(s) for search
|
|
2864
|
+
[…] built the site
|
|
2837
2865
|
[…] wrote build/site/thalorna/place-vedyara/index.html
|
|
2838
2866
|
```
|
|
2839
2867
|
|
|
@@ -3389,17 +3417,20 @@ reads the words of its `data.family` chain as its own. The languages are listed
|
|
|
3389
3417
|
by name; each block gives the number missing, then the missing concepts under
|
|
3390
3418
|
their groups in list order, each group with its count, each concept as its `id`
|
|
3391
3419
|
and `gloss` separated by a tab. A language with no concept missing is reported as
|
|
3392
|
-
covering them all.
|
|
3420
|
+
covering them all. The default report ends with `Not covered (no data.core): …`,
|
|
3421
|
+
naming language notes without `data.core: true` in name order, when any exist.
|
|
3422
|
+
An explicit `--language` measures only the requested language and prints no
|
|
3423
|
+
skip line. Writes nothing.
|
|
3393
3424
|
|
|
3394
3425
|
A missing concept is a fact to work through, never a finding, so the report does
|
|
3395
3426
|
not change the exit status.
|
|
3396
3427
|
|
|
3397
3428
|
**OPTIONS**
|
|
3398
3429
|
|
|
3399
|
-
| Option | Type | Default | Description
|
|
3400
|
-
| ------------ | ------- | ------- |
|
|
3401
|
-
| `--language` | string | — | Report this language alone, by its name, its shortcode or its reference, whether or not it states `data.core`.
|
|
3402
|
-
| `--json` | boolean | `false` | Print `{ concepts, languages }` instead, each language `{ name, language, core, total, covered, missing }` and each missing group `{ group, count, total, concepts }`. |
|
|
3430
|
+
| Option | Type | Default | Description |
|
|
3431
|
+
| ------------ | ------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
3432
|
+
| `--language` | string | — | Report this language alone, by its name, its shortcode or its reference, whether or not it states `data.core`. |
|
|
3433
|
+
| `--json` | boolean | `false` | Print `{ concepts, notCovered, languages }` instead; `notCovered` lists unmeasured language names (empty with `--language`), each language `{ name, language, core, total, covered, missing }` and each missing group `{ group, count, total, concepts }`. |
|
|
3403
3434
|
|
|
3404
3435
|
**EXIT STATUS**
|
|
3405
3436
|
|
|
@@ -3505,7 +3536,7 @@ exactly as given, at every depth, and every field it leaves out is generated:
|
|
|
3505
3536
|
|
|
3506
3537
|
| Field | Generated value |
|
|
3507
3538
|
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
3508
|
-
| `name.full` | Drawn
|
|
3539
|
+
| `name.full` | Drawn by a pattern for `data.gender`; given names use the shared or gendered list, and drawn words start with capitals. |
|
|
3509
3540
|
| `shortcode` | The name transliterated to lowercase letters and digits and cut to twelve characters; a counter replaces its tail where a being holds it. |
|
|
3510
3541
|
| `type`, `subType`, `tags` | `being`, `npc`, `[generated, draft]`. |
|
|
3511
3542
|
| `data.icon`, `data.species`, `data.packFolder` | The commonest value among the package's npcs of the same culture, else among all its npcs; left out where none states one. |
|
|
@@ -3549,13 +3580,25 @@ cycle. See [culture parents](reference/format-details.md#culture-parents-and-inh
|
|
|
3549
3580
|
|
|
3550
3581
|
A profile or name lists with problems are refused with a finding at each.
|
|
3551
3582
|
|
|
3583
|
+
Generated `name.full` is the English display form: each word drawn from a name
|
|
3584
|
+
list starts with a capital, while its remaining letters and the pattern's
|
|
3585
|
+
connecting words keep their authored case. A caseless tongue can therefore
|
|
3586
|
+
supply `lumawesa` and `simi manik` to produce `Lumawesa of the Simi Manik`.
|
|
3587
|
+
The distinct source form keeps its authored spelling under the culture's language code,
|
|
3588
|
+
such as `name: {full: Lumawesa of the Simi Manik, teyu: [lumawesa of the simi manik]}`.
|
|
3589
|
+
If the selected pattern draws any English `{en.*}` part, the command omits
|
|
3590
|
+
the generated native alias. An unused English pattern does not affect a name
|
|
3591
|
+
drawn from another pattern.
|
|
3592
|
+
Supplied names and language forms keep their exact spelling and case.
|
|
3593
|
+
|
|
3552
3594
|
A spec that states `name.full` keeps it, and the name must fit the language's
|
|
3553
|
-
lists: one of the patterns for `data.gender`, with every placeholder filled by
|
|
3595
|
+
source or English display lists: one of the patterns for `data.gender`, with every placeholder filled by
|
|
3554
3596
|
a name of its list, the given name from the list for `data.gender`. A name that does not fit is an
|
|
3555
3597
|
error naming the part that fails and the language it was checked against; from
|
|
3556
3598
|
a `--specfile`, the error is located at the name in the file. Where the
|
|
3557
|
-
|
|
3558
|
-
|
|
3599
|
+
language states one shared `given` list, every gender draws from and is checked
|
|
3600
|
+
against it. With a gender map, a gender with no list of its own draws from and
|
|
3601
|
+
is checked against every given list together.
|
|
3559
3602
|
|
|
3560
3603
|
Two top-level spec keys are section bodies rather than frontmatter.
|
|
3561
3604
|
`appearance` is the Appearance section's markdown, written verbatim with its
|
package/docs/configuration.md
CHANGED
|
@@ -2307,8 +2307,9 @@ the source directory:
|
|
|
2307
2307
|
|
|
2308
2308
|
Optional path for a browser converter's JSON data, relative to
|
|
2309
2309
|
`packageBuild.stageDir`. `package-build manifest` writes it during the module
|
|
2310
|
-
build from the same
|
|
2311
|
-
native text. The path must stay
|
|
2310
|
+
build from the same consumer-authored encoding notes, selected fonts' glyph
|
|
2311
|
+
metadata and language vocabulary that render native text. The path must stay
|
|
2312
|
+
within the stage, end in `.json`, and name an
|
|
2312
2313
|
artifact other than `module.json`, `system.json` or `package.json`. Absolute
|
|
2313
2314
|
paths and parent traversal are refused. Omission writes no converter file.
|
|
2314
2315
|
|
package/docs/content-format.md
CHANGED
|
@@ -27,10 +27,20 @@ Start with [your first note](authoring/first-note.md). It explains the smallest
|
|
|
27
27
|
|
|
28
28
|
A nonempty note body creates one system-agnostic Foundry JournalEntry. Content before the first H1 becomes an introduction page; every H1 starts another JournalEntryPage. A lower-level heading with an explicit `{#anchor}` starts a page too, so a link can address it. Each page name is its heading's visible text: spans, links and emphasis contribute their text without their markup. The same prose becomes a web page and can be selected for a book. The content index records the note and its frontmatter for queries and navigation.
|
|
29
29
|
|
|
30
|
+
A top-level `--- {.page-break}` line between blank lines starts a fresh book page
|
|
31
|
+
without drawing a rule, and adds no blank page when it already falls at a page
|
|
32
|
+
top. Foundry, the website and both editor preview views omit it. Plain thematic
|
|
33
|
+
breaks remain rules; code and verse keep the marker literally. Other
|
|
34
|
+
attributes, star or underscore markers, and markers inside containers are
|
|
35
|
+
findings. See [book page breaks](authoring/links-and-markup.md#book-page-breaks).
|
|
36
|
+
|
|
30
37
|
Leading `:` captions describe the next supported block; `:@` captions also number it. The optional type accepts `figure`, `table`, `verse`, `code`, `prose`, and `example`. Captions support identifiers, classes and named attributes; unsupported following blocks are errors. See [captions and numbered references](authoring/links-and-markup.md#captions-and-numbered-references).
|
|
31
38
|
|
|
32
39
|
A `.verse` div (`::: {.verse ...}` or `:::verse {...}`) sets poetry or prose. `/` ends a logical line; source newlines
|
|
33
40
|
otherwise join. Blank lines or `//` end stanzas, and a standalone `--- {.canto}` after a blank line ends a canto.
|
|
41
|
+
Blockquotes and list items may contain verse divs, including nested combinations.
|
|
42
|
+
Their container prefixes are excluded from verse text, while findings retain
|
|
43
|
+
authored line and column positions with either LF or CRLF endings.
|
|
34
44
|
Leading periods indent a logical line, including after `/` within a source line;
|
|
35
45
|
a period on a joined continuation line is text. `\/` writes a literal slash.
|
|
36
46
|
A concrete `enc=` on a div sets the original once in two presentations, script on the left
|
package/docs/diagnostics.md
CHANGED
|
@@ -297,6 +297,23 @@ Like a culture conflict, each fails the index and every command that reads it
|
|
|
297
297
|
without collecting problems. The rules are under
|
|
298
298
|
[a note's language](reference/format-details.md#a-notes-language).
|
|
299
299
|
|
|
300
|
+
## Book page-break findings
|
|
301
|
+
|
|
302
|
+
The optional [book page break](authoring/links-and-markup.md#book-page-breaks)
|
|
303
|
+
uses only `--- {.page-break}` between blocks at the note's top level.
|
|
304
|
+
Other classes, ids or attributes on an attributed `---` line receive findings
|
|
305
|
+
at their opening brace. A `.page-break` on `***` or `___` receives a finding
|
|
306
|
+
at the marker. A marker inside a list, block quote, alert, secret block or
|
|
307
|
+
fenced div receives `a page break stands between blocks at the top level of a
|
|
308
|
+
note`, at that marker's line and column. Missing surrounding blank lines
|
|
309
|
+
receive the same placement finding. Code blocks and complete verse divs are
|
|
310
|
+
literal and receive no page-break findings.
|
|
311
|
+
|
|
312
|
+
The author lint, pack compiler, site build, both preview views and book source
|
|
313
|
+
generation report these errors from the same scanner. A valid marker is
|
|
314
|
+
omitted on screens and emits a weak page break in the book, avoiding an extra
|
|
315
|
+
blank page at a page top.
|
|
316
|
+
|
|
300
317
|
## A worked case: versions of a work
|
|
301
318
|
|
|
302
319
|
[Versions of a work](authoring/links-and-markup.md#versions-and-stanza-labels)
|
|
@@ -716,13 +716,21 @@ packageBuild:
|
|
|
716
716
|
```
|
|
717
717
|
|
|
718
718
|
`package-build manifest` writes the JSON beneath the build stage, so the
|
|
719
|
-
release includes the data alongside the module's other files. It embeds
|
|
720
|
-
|
|
719
|
+
release includes the data alongside the module's other files. It embeds the
|
|
720
|
+
consumer's authored encoding definitions, the selected fonts' glyph-code
|
|
721
|
+
snapshots, and the language names and lexical inputs used by the build.
|
|
722
|
+
Conversion rules belong to the consumer's encoding notes; fonts supply the
|
|
723
|
+
glyphs and their metadata.
|
|
721
724
|
|
|
722
725
|
Bundle `@heroiclands/package-build/convert` into the module's browser code,
|
|
723
726
|
fetch `modules/<module-id>/data/converter.json` once, and pass the parsed data
|
|
724
727
|
to `encode` or `decode`. A picker can list `Object.entries(data.languages)`
|
|
725
|
-
using each entry's `name
|
|
728
|
+
using each entry's `name`. Offer the encoding documents in `data.encodings`
|
|
729
|
+
whose `data.language` matches the selected language, and pass the selected
|
|
730
|
+
document Address as `options.enc`. That document supplies its font; language
|
|
731
|
+
entries carry no default encoding or face. Omitting `options.enc`, or choosing
|
|
732
|
+
`default`, preserves Roman text. The JSON includes all conversion inputs, so
|
|
733
|
+
the browser fetches no separate encoding or font metadata files.
|
|
726
734
|
Show the returned findings alongside the text when a word cannot be recovered.
|
|
727
735
|
See the [API](../api.md#browser-conversion) and
|
|
728
736
|
[data format](../reference/format-details.md#converter-data-format).
|
package/docs/guides/site.md
CHANGED
|
@@ -302,12 +302,22 @@ index inside it. Nothing else renders the pages: the body of each is the same
|
|
|
302
302
|
HTML the Foundry journals and the editor preview read, drawn into the site
|
|
303
303
|
theme's layouts and minified.
|
|
304
304
|
|
|
305
|
+
The terminal reports indexing, rendering, writing and search indexing as they
|
|
306
|
+
start, including page counts where available. Progress is on stdout;
|
|
307
|
+
diagnostics retain their file, line and column on stderr.
|
|
308
|
+
|
|
305
309
|
```bash
|
|
306
310
|
package-build site serve
|
|
307
311
|
```
|
|
308
312
|
|
|
309
|
-
`package-build site serve`
|
|
310
|
-
`http://127.0.0.1:1313/<contentPackage>/`.
|
|
313
|
+
`package-build site serve` prints its address as soon as HTTP starts, before
|
|
314
|
+
building the site: `http://127.0.0.1:1313/<contentPackage>/`. Existing output
|
|
315
|
+
remains available during the build. Successful whole builds replace the pages
|
|
316
|
+
and search index together; failed builds leave the last successful output in
|
|
317
|
+
place. A first run with no output answers HTTP 503 until a build succeeds, with
|
|
318
|
+
a message pointing to progress and diagnostics in the terminal.
|
|
319
|
+
|
|
320
|
+
Edit a note and its page is written
|
|
311
321
|
again and the browser reloads; edit the theme and every page is drawn again.
|
|
312
322
|
A change that moves, renames or adds a note builds the whole site again. See
|
|
313
323
|
[`site serve`](../commands.md#package-build-site-serve) for the whole table.
|