@heroiclands/package-build 25.5.4 → 25.6.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 +40 -0
- package/README.md +7 -0
- package/assets/styles/content-base.css +1 -1
- package/bin/content-commands.mjs +32 -8
- package/docs/api.md +81 -32
- package/docs/authoring/frontmatter.md +1 -1
- package/docs/authoring/links-and-markup.md +59 -10
- package/docs/commands.md +60 -17
- package/docs/configuration.md +3 -2
- package/docs/content-format.md +50 -1
- package/docs/diagnostics.md +17 -0
- package/docs/guides/module-project.md +11 -3
- package/docs/guides/reference-pages.md +4 -1
- package/docs/guides/site.md +13 -3
- package/docs/guides/writing-in-invented-scripts.md +5 -2
- package/docs/reference/format-details.md +233 -138
- package/docs/reference/note-types.md +165 -152
- package/docs/reference/theme-pages.md +1 -0
- 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-format.yaml +9 -7
- package/engine/content-html.mjs +3 -2
- package/engine/content-index.mjs +23 -0
- package/engine/content-links.mjs +8 -0
- package/engine/content-render.mjs +14 -2
- package/engine/content-scripts.mjs +44 -6
- package/engine/content-session.mjs +11 -7
- package/engine/content-spans.mjs +3 -4
- package/engine/content-tables.mjs +12 -5
- package/engine/content-verse.mjs +52 -10
- package/engine/core-report.mjs +27 -18
- package/engine/culture-reach.mjs +3 -0
- package/engine/declared-sections.mjs +100 -0
- package/engine/derived-sections.mjs +36 -2
- package/engine/dictionary-rows.mjs +2 -1
- package/engine/generated-sections.mjs +2 -0
- package/engine/holdings.mjs +107 -3
- package/engine/index-records.mjs +3 -1
- package/engine/index.mjs +1 -1
- package/engine/language-data.mjs +0 -1
- package/engine/language-names.mjs +53 -23
- package/engine/language-rows.mjs +1 -3
- package/engine/language-terms.mjs +7 -10
- package/engine/map-dot.mjs +22 -0
- package/engine/markdown-blocks.mjs +23 -8
- package/engine/markdownlint-run.mjs +1 -1
- package/engine/markup-validation.mjs +2 -0
- package/engine/metadata-index.mjs +1 -0
- package/engine/note-addresses.mjs +16 -0
- package/engine/note-vocabulary.mjs +29 -13
- package/engine/npc-generate.mjs +52 -7
- package/engine/office-holders.mjs +76 -0
- package/engine/page-breaks.mjs +143 -0
- package/engine/pdf-build.mjs +12 -4
- package/engine/pdf-render.mjs +12 -2
- package/engine/place-kinds.mjs +106 -0
- package/engine/preview-index.mjs +4 -2
- package/engine/settlement-tables.mjs +410 -675
- package/engine/settlement-terms.mjs +118 -0
- package/engine/site-build.mjs +14 -7
- 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 +101 -7
- package/engine/standing-terms.mjs +9 -5
- package/engine/standings.mjs +83 -31
- package/engine/unique-items.mjs +85 -0
- package/engine/verse-metre.mjs +50 -5
- package/engine/verse-regions.mjs +16 -0
- package/package.json +9 -4
- package/site-theme/data/banner-kinds.yaml +2 -0
- package/sohl/actors.mjs +4 -3
- package/types/e2e.d.mts +1 -1
- package/types/engine/content-html.d.mts +2 -1
- package/types/engine/content-scripts.d.mts +9 -1
- package/types/engine/content-verse.d.mts +11 -2
- package/types/engine/core-report.d.mts +6 -2
- package/types/engine/culture-reach.d.mts +3 -0
- package/types/engine/declared-sections.d.mts +30 -0
- package/types/engine/derived-sections.d.mts +5 -1
- package/types/engine/holdings.d.mts +34 -2
- package/types/engine/index-records.d.mts +2 -1
- package/types/engine/language-names.d.mts +18 -6
- package/types/engine/language-terms.d.mts +5 -1
- package/types/engine/markdown-blocks.d.mts +5 -1
- package/types/engine/npc-generate.d.mts +3 -0
- package/types/engine/office-holders.d.mts +33 -0
- package/types/engine/page-breaks.d.mts +38 -0
- package/types/engine/pdf-render.d.mts +2 -0
- package/types/engine/place-kinds.d.mts +18 -0
- package/types/engine/settlement-tables.d.mts +25 -158
- package/types/engine/settlement-terms.d.mts +53 -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 +35 -3
- package/types/engine/standing-terms.d.mts +3 -2
- package/types/engine/standings.d.mts +14 -2
- package/types/engine/unique-items.d.mts +12 -0
- package/types/engine/verse-metre.d.mts +2 -1
- package/types/engine/verse-regions.d.mts +8 -0
- package/vendor/markdownlint.mjs +855 -569
|
@@ -47,13 +47,45 @@ export function foreignHoldingsNodes(foreignIndex: Map<string, object> | undefin
|
|
|
47
47
|
export function holdingsPages(nodes: Iterable<HoldingsNode | null>, { governmentNodes }?: {
|
|
48
48
|
governmentNodes?: Iterable<HoldingsNode | null> | undefined;
|
|
49
49
|
}): Map<string, Holdings>;
|
|
50
|
+
/**
|
|
51
|
+
* Whether a record's `data.government` came from a parent rather than its own
|
|
52
|
+
* note.
|
|
53
|
+
*
|
|
54
|
+
* @param {object} record - An index record.
|
|
55
|
+
* @returns {boolean} True for a district that inherited its government.
|
|
56
|
+
*/
|
|
57
|
+
export function governmentInherited(record: object): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Give each district that states no government its parent's.
|
|
60
|
+
*
|
|
61
|
+
* A `place/district` falls under the government of the place it stands
|
|
62
|
+
* within. One stating no `data.government` key takes the value of its nearest
|
|
63
|
+
* parent that states the key, walking `data.parents` breadth first, in the
|
|
64
|
+
* order written, through any parent that states none, and never visiting a
|
|
65
|
+
* place twice. An explicit value on the district, `null` (complete anarchy)
|
|
66
|
+
* included, is its own and is kept; a parent's explicit `null` is inherited as
|
|
67
|
+
* anarchy. Every reader of the index — the Governed by and Governed places
|
|
68
|
+
* sections, the "missing government" advisory, a consumer of the published
|
|
69
|
+
* index — then reads the effective government at `data.government`.
|
|
70
|
+
*
|
|
71
|
+
* @param {object[]} records - Content-index records, edited in place.
|
|
72
|
+
* @param {object} [opts]
|
|
73
|
+
* @param {(key: string) => object|undefined} [opts.foreignRecord] - A fetched
|
|
74
|
+
* index's record by canonical Address, for a parent in a dependency.
|
|
75
|
+
* @returns {void}
|
|
76
|
+
*/
|
|
77
|
+
export function inheritDistrictGovernments(records: object[], { foreignRecord }?: {
|
|
78
|
+
foreignRecord?: ((key: string) => object | undefined) | undefined;
|
|
79
|
+
}): void;
|
|
50
80
|
/**
|
|
51
81
|
* Advise when a place with an authored positive population omits government.
|
|
52
82
|
* Missing, null or zero population establishes no inhabited population.
|
|
53
83
|
* Property presence distinguishes omitted government from explicit null,
|
|
54
84
|
* which means complete anarchy. Non-null values are validated by the declared
|
|
55
|
-
* affiliation reference field.
|
|
56
|
-
* supplies
|
|
85
|
+
* affiliation reference field. Tenure never supplies this fact, and
|
|
86
|
+
* containment supplies it only to a district, which the content index gives
|
|
87
|
+
* its nearest parent's government (see {@link inheritDistrictGovernments}), so
|
|
88
|
+
* a district under a governed place is never advised.
|
|
57
89
|
*
|
|
58
90
|
* @param {object} note - The note with parsed frontmatter and raw source.
|
|
59
91
|
* @returns {object[]} Located warning findings.
|
|
@@ -122,7 +122,8 @@ export function recordPath(record: Record<string, any>): string;
|
|
|
122
122
|
* since a note declaring its own is a hard error — and it matches what
|
|
123
123
|
* the content-table expander puts on the same field, so a query reads the same
|
|
124
124
|
* value from either. `file` namespaces the note's place in the tree, again
|
|
125
|
-
* matching the expander's `file.*`.
|
|
125
|
+
* matching the expander's `file.*`. `officeHolders` lists, on a body, the
|
|
126
|
+
* living beings whose own standing names each of its offices.
|
|
126
127
|
*
|
|
127
128
|
* Both are checked rather than assumed: `folder` is real frontmatter on most
|
|
128
129
|
* notes, so the neighbouring names are close enough to a real key that a silent
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The genders
|
|
2
|
+
* The genders a mapped `data.names.given` states a list for.
|
|
3
3
|
*
|
|
4
4
|
* A function rather than a `const`: `note-vocabulary.mjs` reads it while the
|
|
5
5
|
* module graph is still evaluating.
|
|
@@ -47,7 +47,7 @@ export function namesProblems(names: unknown, lookVocabulary: Readonly<Record<st
|
|
|
47
47
|
* keys cannot: a pattern that does not parse, a placeholder naming no list, a
|
|
48
48
|
* list no pattern names, a list name a placeholder cannot spell, an empty list
|
|
49
49
|
* of patterns or of names, an empty name, a pattern or given list keyed by no
|
|
50
|
-
* gender, and a missing `female` or `male` list. Each is located at the pattern, list, entry or key at fault.
|
|
50
|
+
* gender, and a missing `female` or `male` list in a gender map. Each is located at the pattern, list, entry or key at fault.
|
|
51
51
|
*
|
|
52
52
|
* @param {object} note - The note: `file`, `raw` and parsed `fm`.
|
|
53
53
|
* @param {Readonly<Record<string, readonly {value: string}[]>>} lookVocabulary -
|
|
@@ -70,8 +70,8 @@ export function namesFindings(note: object, lookVocabulary: Readonly<Record<stri
|
|
|
70
70
|
value: string;
|
|
71
71
|
}[]>>): object[];
|
|
72
72
|
/**
|
|
73
|
-
* The given names a gender draws from: its own list, or
|
|
74
|
-
* together where it has none.
|
|
73
|
+
* The given names a gender draws from: the shared list, its own list, or
|
|
74
|
+
* every given list together where it has none.
|
|
75
75
|
*
|
|
76
76
|
* @param {object} names - Checked `data.names`.
|
|
77
77
|
* @param {string} gender - A gender word.
|
|
@@ -79,8 +79,20 @@ export function namesFindings(note: object, lookVocabulary: Readonly<Record<stri
|
|
|
79
79
|
*/
|
|
80
80
|
export function givenNames(names: object, gender: string): string[];
|
|
81
81
|
/**
|
|
82
|
-
* A name
|
|
83
|
-
*
|
|
82
|
+
* A name's selected literal and placeholder parts. One of the gender's
|
|
83
|
+
* patterns is selected first, then each placeholder is an even draw from its
|
|
84
|
+
* source list.
|
|
85
|
+
*
|
|
86
|
+
* @param {object} names - Checked `data.names`.
|
|
87
|
+
* @param {string} gender - A gender word.
|
|
88
|
+
* @param {() => number} next - A stream of numbers in `[0, 1)`.
|
|
89
|
+
* @returns {(PatternPart & {text: string})[]} The selected parts in pattern order.
|
|
90
|
+
*/
|
|
91
|
+
export function drawNameParts(names: object, gender: string, next: () => number): (PatternPart & {
|
|
92
|
+
text: string;
|
|
93
|
+
})[];
|
|
94
|
+
/**
|
|
95
|
+
* A name drawn from a language's lists.
|
|
84
96
|
*
|
|
85
97
|
* @param {object} names - Checked `data.names`.
|
|
86
98
|
* @param {string} gender - A gender word.
|
|
@@ -94,7 +94,11 @@ export const JOIN_MEETINGS: readonly string[];
|
|
|
94
94
|
* letters between, `drop` loses the first, `double` doubles the consonant.
|
|
95
95
|
*/
|
|
96
96
|
export const JOIN_RULES: readonly string[];
|
|
97
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* What a written mark says of its letter: `stress` falls on it, `length` holds
|
|
99
|
+
* it longer, `apart` says it apart from its neighbour, and `quality` changes
|
|
100
|
+
* which vowel is said.
|
|
101
|
+
*/
|
|
98
102
|
export const MARK_KINDS: readonly string[];
|
|
99
103
|
/** How many of a mark a word may carry: `one` at most, or `any` number. */
|
|
100
104
|
export const MARK_LIMITS: readonly string[];
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
* and must not be modified; an `inline` token carries no `children`.
|
|
4
4
|
*
|
|
5
5
|
* @param {unknown} source - Markdown.
|
|
6
|
+
* @param {object} [options] - Optional block projection.
|
|
7
|
+
* @param {boolean} [options.footnotes=false] - Include footnote definition containers.
|
|
6
8
|
* @returns {readonly import("markdown-it").Token[]} The block tokens, in order.
|
|
7
9
|
*/
|
|
8
|
-
export function blockTokens(source: unknown
|
|
10
|
+
export function blockTokens(source: unknown, { footnotes }?: {
|
|
11
|
+
footnotes?: boolean | undefined;
|
|
12
|
+
}): readonly import("markdown-it").Token[];
|
|
@@ -57,6 +57,8 @@ export function appearanceParagraph({ name, age, gender, height, frame, appearan
|
|
|
57
57
|
* by `namesProblems`.
|
|
58
58
|
* @param {string} [context.language] - The language's Address, for an error
|
|
59
59
|
* about a name that does not fit.
|
|
60
|
+
* @param {string} [context.languageCode] - The language code under which a
|
|
61
|
+
* generated name's distinct source form is retained.
|
|
60
62
|
* @param {string} [context.seed] - Text joined to the spec's own seed, to draw a
|
|
61
63
|
* different person from the same spec.
|
|
62
64
|
* @param {unknown} [context.currentDate] - The setting's neutral current date, defaulting to "720.1".
|
|
@@ -74,6 +76,7 @@ export function generateNpc(spec: object, context: {
|
|
|
74
76
|
profile: object;
|
|
75
77
|
names: object;
|
|
76
78
|
language?: string | undefined;
|
|
79
|
+
languageCode?: string | undefined;
|
|
77
80
|
seed?: string | undefined;
|
|
78
81
|
currentDate?: unknown;
|
|
79
82
|
dateContext?: object | undefined;
|
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A note's identity across its systems: `package-type-shortcode`, lowercased.
|
|
3
|
+
*
|
|
4
|
+
* A body's Item and its journal carry one page, and a being names the body by
|
|
5
|
+
* its `note` Address, so the system is left out.
|
|
6
|
+
*
|
|
7
|
+
* @param {{package?: string, type?: string, shortcode?: string}} tuple
|
|
8
|
+
* @returns {string} The key, or `""` where a part is missing.
|
|
9
|
+
*/
|
|
10
|
+
export function officeBodyKey(tuple: {
|
|
11
|
+
package?: string;
|
|
12
|
+
type?: string;
|
|
13
|
+
shortcode?: string;
|
|
14
|
+
}): string;
|
|
15
|
+
/**
|
|
16
|
+
* Each body's offices with the living beings that hold them.
|
|
17
|
+
*
|
|
18
|
+
* Nothing is authored on the office for this: a being states the post it holds
|
|
19
|
+
* in its own `data.affiliations.<body>.office`, and this collects, for every
|
|
20
|
+
* office in a body's `governance.offices`, each being naming it. A being whose
|
|
21
|
+
* `data.died` is set holds nothing, so a former holder drops out and a vacant
|
|
22
|
+
* office lists no one. A post the body does not declare is the standing check's
|
|
23
|
+
* finding and is listed nowhere.
|
|
24
|
+
*
|
|
25
|
+
* Offices keep the body's declared order; holders are ordered by name.
|
|
26
|
+
*
|
|
27
|
+
* @param {object[]} records - Content-index records; only note records are
|
|
28
|
+
* read.
|
|
29
|
+
* @returns {Map<string, Map<string, object[]>>} Body identity
|
|
30
|
+
* (`package-type-shortcode`) → office → the holding beings' records, for every
|
|
31
|
+
* body with at least one held office.
|
|
32
|
+
*/
|
|
33
|
+
export function officeHolders(records: object[]): Map<string, Map<string, object[]>>;
|
|
1
34
|
/**
|
|
2
35
|
* Validate one affiliation's office roster against dated beings in the corpus.
|
|
3
36
|
* @param {object} note
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read page-break markers before any surface rewrites their source.
|
|
3
|
+
* Code, HTML examples and entire verse divs remain literal. Parser ranges
|
|
4
|
+
* retain list and quote membership, including lazy continuation lines.
|
|
5
|
+
* @param {string} source - Authored Markdown body.
|
|
6
|
+
* @returns {{breaks: Array<{line: number, column: number}>, errors: Array<{line: number, column: number, message: string}>}}
|
|
7
|
+
*/
|
|
8
|
+
export function scanPageBreaks(source: string): {
|
|
9
|
+
breaks: Array<{
|
|
10
|
+
line: number;
|
|
11
|
+
column: number;
|
|
12
|
+
}>;
|
|
13
|
+
errors: Array<{
|
|
14
|
+
line: number;
|
|
15
|
+
column: number;
|
|
16
|
+
message: string;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Omit valid page breaks on a screen, preserving the surrounding block boundaries.
|
|
21
|
+
* @param {string} source - Markdown body.
|
|
22
|
+
* @returns {string} Markdown without valid page-break lines.
|
|
23
|
+
*/
|
|
24
|
+
export function omitPageBreaks(source: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Preserve refused markers as literal Markdown before the book slices blocks.
|
|
27
|
+
* A slice must not make a marker eligible by discarding its original neighbour.
|
|
28
|
+
* Findings are collected from the original source before this rewrite.
|
|
29
|
+
* @param {string} source - Complete Markdown body, before splitting containers.
|
|
30
|
+
* @returns {string} Markdown with invalid markers escaped for literal rendering.
|
|
31
|
+
*/
|
|
32
|
+
export function escapeInvalidPageBreaks(source: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Produce the book's page-break token, leaving ordinary thematic breaks alone.
|
|
35
|
+
* @param {import("markdown-it")} md - The book parser.
|
|
36
|
+
* @returns {void}
|
|
37
|
+
*/
|
|
38
|
+
export function pageBreakPlugin(md: typeof import("markdown-it")): void;
|
|
@@ -98,6 +98,7 @@ export function stripHtmlComments(markdown: string): string;
|
|
|
98
98
|
* @param {Array<{line: number, generated: boolean}>} [opts.lineMap] - From
|
|
99
99
|
* table expansion, mapping each line handed in back to the line an author
|
|
100
100
|
* wrote.
|
|
101
|
+
* @param {boolean} [opts.pageBreaks] - Internal: whether this slice remains at the note top level.
|
|
101
102
|
* @param {boolean} [opts.prepared] - Whether this body has been through the
|
|
102
103
|
* passes that resolve a wikilink, an embed and an inline expression. A note's
|
|
103
104
|
* has; a front-matter file's and a prose file's have not, and markup of theirs
|
|
@@ -138,6 +139,7 @@ export function markdownToTypst(markdown: string, opts?: {
|
|
|
138
139
|
line: number;
|
|
139
140
|
generated: boolean;
|
|
140
141
|
}[] | undefined;
|
|
142
|
+
pageBreaks?: boolean | undefined;
|
|
141
143
|
prepared?: boolean | undefined;
|
|
142
144
|
url?: string | undefined;
|
|
143
145
|
elsewhere?: {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check a district's parent and a route's journeys.
|
|
3
|
+
*
|
|
4
|
+
* A district naming no parent is reported at its `subType`; one whose parents
|
|
5
|
+
* all resolve and none is a settlement or a region is reported at `parents`.
|
|
6
|
+
* A parent that does not resolve is the Address check's finding, so a district
|
|
7
|
+
* whose only parents are unresolved earns nothing more here. A route stating no
|
|
8
|
+
* `data.routes` entry is reported at its `subType`.
|
|
9
|
+
*
|
|
10
|
+
* @param {object} note - The note: `file`, `raw` and parsed `fm`.
|
|
11
|
+
* @param {{index?: object}} [options] - The lint's options.
|
|
12
|
+
* @returns {object[]} Located findings.
|
|
13
|
+
*/
|
|
14
|
+
export function checkPlaceKind(note: object, { index }?: {
|
|
15
|
+
index?: object;
|
|
16
|
+
}): object[];
|
|
17
|
+
/** The place kinds a district may stand within. */
|
|
18
|
+
export const DISTRICT_PARENT_KINDS: readonly string[];
|
|
@@ -1,164 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @param {
|
|
6
|
-
* @returns {
|
|
7
|
-
* heading's line, 0 when there is none, and its tables.
|
|
8
|
-
*/
|
|
9
|
-
export function findSettlementTables(raw: string): {
|
|
10
|
-
heading: number;
|
|
11
|
-
tables: SettlementTable[];
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Check a place note's settlements tables.
|
|
15
|
-
*
|
|
16
|
-
* Declared as part of the `place` vocabulary's whole-note check, so the lint
|
|
17
|
-
* runs it with the index every reference resolves through. Without an index
|
|
18
|
-
* nothing is reported.
|
|
19
|
-
*
|
|
20
|
-
* @param {object} note - The note, as the link index hands it over.
|
|
21
|
-
* @param {object} [opts]
|
|
22
|
-
* @param {object} [opts.index] - The link index, holding the whole corpus.
|
|
23
|
-
* @returns {object[]} Findings.
|
|
2
|
+
* Check indexed rows, locating each finding in its original YAML.
|
|
3
|
+
* @param {object} note - Indexed note and original locator text.
|
|
4
|
+
* @param {object} [opts] - Captured context.
|
|
5
|
+
* @param {object} [opts.index] - Complete local and dependency reference index.
|
|
6
|
+
* @returns {object[]} Located findings.
|
|
24
7
|
*/
|
|
25
8
|
export function checkSettlementTables(note: object, { index }?: {
|
|
26
9
|
index?: object | undefined;
|
|
27
10
|
}): object[];
|
|
28
|
-
/** The heading text a settlements table stands under, at level two. */
|
|
29
|
-
export const SETTLEMENTS_HEADING: "Settlements";
|
|
30
|
-
/**
|
|
31
|
-
* How a region's countryside is held, each the tag a region carries to say so.
|
|
32
|
-
*
|
|
33
|
-
* `holder` is what the `Held by` cell names under that model. `person` says
|
|
34
|
-
* whether that holder may be a person: only where land is held by a person or
|
|
35
|
-
* a house may the cell link a `being`.
|
|
36
|
-
*
|
|
37
|
-
* **The tags stay open.** They are not a declared tag group: a group would
|
|
38
|
-
* report every tag within a typo's distance of one — a region tagged `hellad`
|
|
39
|
-
* reads as a near miss of `held` — and a misspelled model on a note with a
|
|
40
|
-
* table is already reported, because the note then names no model at all.
|
|
41
|
-
*
|
|
42
|
-
* @type {ReadonlyArray<Readonly<{tag: string, holder: string, person: boolean}>>}
|
|
43
|
-
*/
|
|
44
|
-
export const HOLDING_MODELS: ReadonlyArray<Readonly<{
|
|
45
|
-
tag: string;
|
|
46
|
-
holder: string;
|
|
47
|
-
person: boolean;
|
|
48
|
-
}>>;
|
|
49
|
-
/**
|
|
50
|
-
* The table's columns, in the order the header states them. An optional
|
|
51
|
-
* column may be left out; the header carries no other column, and keeps this
|
|
52
|
-
* order.
|
|
53
|
-
*
|
|
54
|
-
* @type {ReadonlyArray<Readonly<{name: string, required: boolean}>>}
|
|
55
|
-
*/
|
|
56
|
-
export const SETTLEMENT_COLUMNS: ReadonlyArray<Readonly<{
|
|
57
|
-
name: string;
|
|
58
|
-
required: boolean;
|
|
59
|
-
}>>;
|
|
60
|
-
/**
|
|
61
|
-
* The rules this module enforces, each `name` the prefix its findings carry.
|
|
62
|
-
*
|
|
63
|
-
* @type {ReadonlyArray<Readonly<{name: string, describe: string}>>}
|
|
64
|
-
*/
|
|
65
|
-
export const SETTLEMENT_TABLE_RULES: ReadonlyArray<Readonly<{
|
|
66
|
-
name: string;
|
|
67
|
-
describe: string;
|
|
68
|
-
}>>;
|
|
69
11
|
/**
|
|
70
|
-
*
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* - The header cells.
|
|
92
|
-
*/
|
|
93
|
-
header: string[];
|
|
94
|
-
/**
|
|
95
|
-
* - Whether the header is the declared columns.
|
|
96
|
-
*/
|
|
97
|
-
wellFormed: boolean;
|
|
98
|
-
/**
|
|
99
|
-
* - Each
|
|
100
|
-
* row's cells keyed by column name; empty when the header is not well formed.
|
|
101
|
-
*/
|
|
102
|
-
rows: Array<{
|
|
103
|
-
line: number;
|
|
104
|
-
cells: Record<string, Cell>;
|
|
105
|
-
}>;
|
|
106
|
-
/**
|
|
107
|
-
* - The 1-based line of its last row.
|
|
108
|
-
*/
|
|
109
|
-
last: number;
|
|
110
|
-
/**
|
|
111
|
-
* - Whether prose follows it before the next heading.
|
|
112
|
-
*/
|
|
113
|
-
tailed: boolean;
|
|
114
|
-
};
|
|
115
|
-
/**
|
|
116
|
-
* One place note, as the rules read it.
|
|
117
|
-
*/
|
|
118
|
-
export type PlaceNode = {
|
|
119
|
-
/**
|
|
120
|
-
* - The note.
|
|
121
|
-
*/
|
|
122
|
-
note: object;
|
|
123
|
-
/**
|
|
124
|
-
* - Lower case.
|
|
125
|
-
*/
|
|
126
|
-
shortcode: string;
|
|
127
|
-
subType: string;
|
|
128
|
-
title: string;
|
|
129
|
-
/**
|
|
130
|
-
* - Its name and listed forms, lower case.
|
|
131
|
-
*/
|
|
132
|
-
names: Set<string>;
|
|
133
|
-
/**
|
|
134
|
-
* - Enclosing places' shortcodes.
|
|
135
|
-
*/
|
|
136
|
-
parents: string[];
|
|
137
|
-
section: {
|
|
138
|
-
heading: number;
|
|
139
|
-
tables: SettlementTable[];
|
|
140
|
-
};
|
|
141
|
-
};
|
|
142
|
-
/**
|
|
143
|
-
* Everything the rules ask of the whole tree.
|
|
144
|
-
*/
|
|
145
|
-
export type Corpus = {
|
|
146
|
-
/**
|
|
147
|
-
* - By shortcode.
|
|
148
|
-
*/
|
|
149
|
-
places: Map<string, PlaceNode>;
|
|
150
|
-
/**
|
|
151
|
-
* - By note.
|
|
152
|
-
*/
|
|
153
|
-
byNote: Map<object, PlaceNode>;
|
|
154
|
-
/**
|
|
155
|
-
* - Region shortcode → the
|
|
156
|
-
* settlement notes its table covers.
|
|
157
|
-
*/
|
|
158
|
-
covers: Map<string, PlaceNode[]>;
|
|
159
|
-
/**
|
|
160
|
-
* - Settlement note → the region
|
|
161
|
-
* notes whose tables link it, in path order.
|
|
162
|
-
*/
|
|
163
|
-
rowedIn: Map<object, object[]>;
|
|
164
|
-
};
|
|
12
|
+
* Fail every publishing surface before it writes invalid settlement output.
|
|
13
|
+
* @param {object[]} records - Indexed records, including documentation projections.
|
|
14
|
+
* @param {object} opts - Captured context.
|
|
15
|
+
* @param {(record: object) => string} opts.fileOf - Source filename for a record.
|
|
16
|
+
* @param {Map<string,object>} [opts.foreignIndex] - Dependency reference targets.
|
|
17
|
+
* @param {(file: string) => string|undefined} [opts.rawOf] - Captured locator text.
|
|
18
|
+
* @returns {void}
|
|
19
|
+
*/
|
|
20
|
+
export function assertSettlementRecords(records: object[], { fileOf, foreignIndex, rawOf }?: {
|
|
21
|
+
fileOf: (record: object) => string;
|
|
22
|
+
foreignIndex?: Map<string, object> | undefined;
|
|
23
|
+
rawOf?: ((file: string) => string | undefined) | undefined;
|
|
24
|
+
}): void;
|
|
25
|
+
/**
|
|
26
|
+
* Render rows once as shared Markdown; all surfaces consume the same table.
|
|
27
|
+
* @param {object} record - Indexed region.
|
|
28
|
+
* @returns {string} Generated table and its closing sentence.
|
|
29
|
+
*/
|
|
30
|
+
export function settlementMarkdown(record: object): string;
|
|
31
|
+
export { SETTLEMENTS_HEADING, SETTLEMENT_COLUMNS, SETTLEMENT_ROW_FIELDS, SETTLEMENTS_FIELD, SETTLEMENT_TABLE_RULES } from "./settlement-terms.mjs";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Dependency-free settlement row declarations. @module */
|
|
2
|
+
/** The generated heading. */
|
|
3
|
+
export const SETTLEMENTS_HEADING: "Settlements";
|
|
4
|
+
/** Rendered columns, in their fixed order; Held by and For appear when a row states them. */
|
|
5
|
+
export const SETTLEMENT_COLUMNS: readonly (Readonly<{
|
|
6
|
+
name: "Name";
|
|
7
|
+
required: true;
|
|
8
|
+
}> | Readonly<{
|
|
9
|
+
name: "Market";
|
|
10
|
+
required: true;
|
|
11
|
+
}> | Readonly<{
|
|
12
|
+
name: "People";
|
|
13
|
+
required: true;
|
|
14
|
+
}> | Readonly<{
|
|
15
|
+
name: "Held by";
|
|
16
|
+
required: false;
|
|
17
|
+
}> | Readonly<{
|
|
18
|
+
name: "For";
|
|
19
|
+
required: false;
|
|
20
|
+
}>)[];
|
|
21
|
+
/** The closed row fields; existing subjects use native Addresses. */
|
|
22
|
+
export const SETTLEMENT_ROW_FIELDS: readonly Readonly<unknown>[];
|
|
23
|
+
/** The place vocabulary's single settlement declaration. */
|
|
24
|
+
export const SETTLEMENTS_FIELD: Readonly<{
|
|
25
|
+
name: "settlements";
|
|
26
|
+
kind: "map";
|
|
27
|
+
shape: "{ rows, tail }";
|
|
28
|
+
fields: readonly ({
|
|
29
|
+
name: string;
|
|
30
|
+
kind: string;
|
|
31
|
+
required: boolean;
|
|
32
|
+
shape: string;
|
|
33
|
+
entries: {
|
|
34
|
+
kind: string;
|
|
35
|
+
shape: string;
|
|
36
|
+
fields: readonly Readonly<unknown>[];
|
|
37
|
+
};
|
|
38
|
+
describe: string;
|
|
39
|
+
} | {
|
|
40
|
+
name: string;
|
|
41
|
+
kind: string;
|
|
42
|
+
required: boolean;
|
|
43
|
+
shape: string;
|
|
44
|
+
describe: string;
|
|
45
|
+
entries?: undefined;
|
|
46
|
+
})[];
|
|
47
|
+
describe: "A region's settlement rows and the sentence stating what they leave out; the table is generated from this declaration.";
|
|
48
|
+
}>;
|
|
49
|
+
/** Every semantic finding, named once for the reference and its guards. */
|
|
50
|
+
export const SETTLEMENT_TABLE_RULES: readonly Readonly<{
|
|
51
|
+
name: string;
|
|
52
|
+
describe: string;
|
|
53
|
+
}>[];
|
|
@@ -306,6 +306,7 @@ export function sitePageDecorator(config: any, index: any): (data: any, page: an
|
|
|
306
306
|
* @param {object} [options] - Options.
|
|
307
307
|
* @param {object} [options.config] - A resolved configuration; loaded when
|
|
308
308
|
* omitted.
|
|
309
|
+
* @param {(message: string) => void} [options.progress] - Build phase summaries.
|
|
309
310
|
* @param {Map<string, object[]>} [options.sqlTables] - Prepared `sql` results,
|
|
310
311
|
* keyed by the note's absolute file, from
|
|
311
312
|
* {@link module:engine/sql-tables.prepareSqlTables}. A page authoring an
|
|
@@ -322,8 +323,9 @@ export function sitePageDecorator(config: any, index: any): (data: any, page: an
|
|
|
322
323
|
* against the rest of the build, or returns `null` when its address, name
|
|
323
324
|
* or type changed and the whole site must be built again.
|
|
324
325
|
*/
|
|
325
|
-
export function buildSite({ config, sqlTables }?: {
|
|
326
|
+
export function buildSite({ config, sqlTables, progress }?: {
|
|
326
327
|
config?: object | undefined;
|
|
328
|
+
progress?: ((message: string) => void) | undefined;
|
|
327
329
|
sqlTables?: Map<string, object[]> | undefined;
|
|
328
330
|
}): {
|
|
329
331
|
gates: object;
|
|
@@ -50,19 +50,21 @@ export function writeThemeFiles(out: string, staticDir?: string): string[];
|
|
|
50
50
|
* @param {string} [options.staticDir] - The theme's own files, copied first.
|
|
51
51
|
* @param {ReadonlySet<string>} [options.only] - The addresses of the pages to
|
|
52
52
|
* draw again into a site already written. Nothing else is touched.
|
|
53
|
+
* @param {(message: string) => void} [options.progress] - Build phase summaries.
|
|
53
54
|
* @returns {{files: string[], pages: string[], reachable: string[],
|
|
54
55
|
* findings: object[]}} Every file written, the address of every page, the
|
|
55
56
|
* address of each page reachable from the homepage, and the layouts' findings.
|
|
56
57
|
* @throws {Error} When a page's address is outside the site, or a site served
|
|
57
58
|
* under a path asks for a sitemap index.
|
|
58
59
|
*/
|
|
59
|
-
export function writeSite({ site, pages, out, report, staticDir, only }: {
|
|
60
|
+
export function writeSite({ site, pages, out, report, staticDir, only, progress, }: {
|
|
60
61
|
site: object;
|
|
61
62
|
pages: readonly object[];
|
|
62
63
|
out: string;
|
|
63
64
|
report?: ((finding: import("./site-theme.mjs").Finding) => void) | undefined;
|
|
64
65
|
staticDir?: string | undefined;
|
|
65
66
|
only?: ReadonlySet<string> | undefined;
|
|
67
|
+
progress?: ((message: string) => void) | undefined;
|
|
66
68
|
}): {
|
|
67
69
|
files: string[];
|
|
68
70
|
pages: string[];
|
|
@@ -147,6 +149,7 @@ export function deliverSiteFonts(config: object, out: string): {
|
|
|
147
149
|
* @param {string} options.out - The directory the site is written to, which
|
|
148
150
|
* is the package's own directory under the deployed root.
|
|
149
151
|
* @param {number} [options.year] - The year the footer states.
|
|
152
|
+
* @param {(message: string) => void} [options.progress] - Build phase summaries.
|
|
150
153
|
* @returns {Promise<{built: object, written: object|null, fonts: object|null,
|
|
151
154
|
* site?: object, pages?: object[], pageOf?: (entry: object) => object}>}
|
|
152
155
|
* What the build found, and, when it found nothing that stops it, what was
|
|
@@ -154,10 +157,11 @@ export function deliverSiteFonts(config: object, out: string): {
|
|
|
154
157
|
* becomes its page. `written` is `null` when a gate fired.
|
|
155
158
|
* @throws {Error} When the site's settings or its cached menu cannot be read.
|
|
156
159
|
*/
|
|
157
|
-
export function buildPackageSite({ config, out, year }: {
|
|
160
|
+
export function buildPackageSite({ config, out, year, progress }: {
|
|
158
161
|
config: object;
|
|
159
162
|
out: string;
|
|
160
163
|
year?: number | undefined;
|
|
164
|
+
progress?: ((message: string) => void) | undefined;
|
|
161
165
|
}): Promise<{
|
|
162
166
|
built: object;
|
|
163
167
|
written: object | null;
|
|
@@ -73,6 +73,7 @@ export function indexSite(where: {
|
|
|
73
73
|
* `site.search` in the configuration. Default `true`.
|
|
74
74
|
* @param {SiteIndexer} [options.indexer] - What builds it. Default
|
|
75
75
|
* {@link indexSite}.
|
|
76
|
+
* @param {(message: string) => void} [options.progress] - Build phase summaries.
|
|
76
77
|
* @returns {Promise<{files: string[], search: {dir: string, pages: number}|null}>}
|
|
77
78
|
* The files written, and the index — where it is and how many pages it
|
|
78
79
|
* holds — or `null` when none was built.
|
|
@@ -81,12 +82,13 @@ export function indexSite(where: {
|
|
|
81
82
|
* under the prefix; or, located at the rendered site, when the indexer
|
|
82
83
|
* fails.
|
|
83
84
|
*/
|
|
84
|
-
export function writeSiteRoot({ pkg, base, out, search, indexer }: {
|
|
85
|
+
export function writeSiteRoot({ pkg, base, out, search, indexer, progress, }: {
|
|
85
86
|
pkg: string;
|
|
86
87
|
base?: string | undefined;
|
|
87
88
|
out: string;
|
|
88
89
|
search?: boolean | undefined;
|
|
89
90
|
indexer?: SiteIndexer | undefined;
|
|
91
|
+
progress?: ((message: string) => void) | undefined;
|
|
90
92
|
}): Promise<{
|
|
91
93
|
files: string[];
|
|
92
94
|
search: {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -9,16 +9,19 @@
|
|
|
9
9
|
* directory above `out` by default; `out` itself for a site served at `/`.
|
|
10
10
|
* @param {string} [options.host] - The address to listen on.
|
|
11
11
|
* @param {number} [options.port] - The port; `0` takes any free one.
|
|
12
|
-
* @param {boolean} [options.search] - Build the search index
|
|
12
|
+
* @param {boolean} [options.search] - Build the search index with each whole
|
|
13
13
|
* build, where the site has one.
|
|
14
14
|
* @param {number} [options.year] - The year the footer states.
|
|
15
|
-
* @param {(event: {kind: string, built?: object, files?: string[], findings?: object[], error?: unknown}) => void} [options.report] -
|
|
16
|
-
* Told of each build: `built` for a whole build, `page` for one note's page,
|
|
15
|
+
* @param {(event: {kind: string, built?: object, files?: string[], findings?: object[], error?: unknown, message?: string, fatal?: boolean}) => void} [options.report] -
|
|
16
|
+
* Told of progress (`message`) and each build: `built` for a whole build, `page` for one note's page,
|
|
17
17
|
* `theme` for the theme, `failed` with what the build found, `error` with
|
|
18
18
|
* what it threw.
|
|
19
|
-
* @returns {Promise<{url: string, close: () => Promise<void>, settled: () => Promise<void>}>}
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* @returns {Promise<{url: string, close: () => Promise<void>, settled: () => Promise<void>, done: Promise<void>}>}
|
|
20
|
+
* Resolves as soon as HTTP listens, before the first build. The address of
|
|
21
|
+
* the site's home page, how to stop serving, and a promise for the initial
|
|
22
|
+
* build and every change seen so far to finish. Failed builds are reported
|
|
23
|
+
* through `report` and leave the last successful site in service. `done`
|
|
24
|
+
* resolves on close and rejects if HTTP stops unexpectedly.
|
|
22
25
|
*/
|
|
23
26
|
export function serveSite({ config, out, root, host, port, search, year, report, }: {
|
|
24
27
|
config: object;
|
|
@@ -34,11 +37,14 @@ export function serveSite({ config, out, root, host, port, search, year, report,
|
|
|
34
37
|
files?: string[];
|
|
35
38
|
findings?: object[];
|
|
36
39
|
error?: unknown;
|
|
40
|
+
message?: string;
|
|
41
|
+
fatal?: boolean;
|
|
37
42
|
}) => void) | undefined;
|
|
38
43
|
}): Promise<{
|
|
39
44
|
url: string;
|
|
40
45
|
close: () => Promise<void>;
|
|
41
46
|
settled: () => Promise<void>;
|
|
47
|
+
done: Promise<void>;
|
|
42
48
|
}>;
|
|
43
49
|
/** The address a served page listens on for the server's reloads. */
|
|
44
50
|
export const RELOAD_PATH: "/__package-build/reload";
|