@heroiclands/package-build 22.4.5 → 22.4.7
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 +16 -0
- package/CONTENT.md +109 -0
- package/bin/content-build.mjs +36 -8
- package/content-config.mjs +8 -3
- package/docs/api.md +86 -46
- package/docs/commands.md +64 -24
- package/docs/configuration.md +20 -1
- package/docs/content-format.md +71 -0
- package/engine/frontmatter-lint.mjs +2 -0
- package/engine/holdings.mjs +391 -0
- package/engine/index.mjs +9 -0
- package/engine/map-build.mjs +41 -11
- package/engine/map-dot.mjs +84 -24
- package/engine/map-graphviz.mjs +12 -3
- package/engine/map-layout.mjs +283 -101
- package/engine/map-places.mjs +33 -3
- package/engine/market-class.mjs +178 -0
- package/engine/metadata-index.mjs +7 -4
- package/engine/note-vocabulary.mjs +19 -0
- package/engine/site-build.mjs +88 -10
- package/engine/site-maps.mjs +165 -0
- package/package.json +1 -1
- package/types/engine/holdings.d.mts +146 -0
- package/types/engine/index.d.mts +3 -0
- package/types/engine/map-build.d.mts +13 -7
- package/types/engine/map-dot.d.mts +22 -9
- package/types/engine/map-graphviz.d.mts +8 -1
- package/types/engine/map-layout.d.mts +117 -49
- package/types/engine/map-places.d.mts +26 -0
- package/types/engine/market-class.d.mts +62 -0
- package/types/engine/note-vocabulary.d.mts +10 -0
- package/types/engine/site-build.d.mts +37 -6
- package/types/engine/site-maps.d.mts +81 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read a local note into a node, or `null` for a note that takes no part.
|
|
3
|
+
*
|
|
4
|
+
* @param {object} fm - The note's frontmatter.
|
|
5
|
+
* @param {object} page - The page it publishes as.
|
|
6
|
+
* @param {string} page.title - Its published title.
|
|
7
|
+
* @param {string} page.url - Its URL.
|
|
8
|
+
* @returns {HoldingsNode|null} The node, or `null` for a note that is neither
|
|
9
|
+
* a place nor an affiliation, or that declares no shortcode.
|
|
10
|
+
*/
|
|
11
|
+
export function holdingsNode(fm: object, { title, url }: {
|
|
12
|
+
title: string;
|
|
13
|
+
url: string;
|
|
14
|
+
}): HoldingsNode | null;
|
|
15
|
+
/**
|
|
16
|
+
* Read a fetched index's places and affiliations as nodes.
|
|
17
|
+
*
|
|
18
|
+
* An entry carries what the producer's record stated — its name, `subType`,
|
|
19
|
+
* `parents` and `domains` — and its page URL where the package publishes one.
|
|
20
|
+
*
|
|
21
|
+
* @param {Map<string, object>|undefined} foreignIndex - As
|
|
22
|
+
* {@link module:engine/metadata-index.loadForeignIndexes} returns it.
|
|
23
|
+
* @returns {HoldingsNode[]} The nodes, in index order.
|
|
24
|
+
*/
|
|
25
|
+
export function foreignHoldingsNodes(foreignIndex: Map<string, object> | undefined): HoldingsNode[];
|
|
26
|
+
/**
|
|
27
|
+
* Invert `parents` and `domains` into each page's lists.
|
|
28
|
+
*
|
|
29
|
+
* A shortcode is declared once per type: the first node declaring it wins,
|
|
30
|
+
* so local nodes handed in ahead of fetched ones shadow a dependency's, the
|
|
31
|
+
* way the link resolver answers. A node with no URL is nobody's entry and
|
|
32
|
+
* carries no lists of its own, since there is no page to write them on. A
|
|
33
|
+
* name no node declares is dropped: a `parents` naming nowhere is the map's
|
|
34
|
+
* finding, a `domains` naming nowhere the reference check's.
|
|
35
|
+
*
|
|
36
|
+
* The result holds only pages with at least one entry on at least one list,
|
|
37
|
+
* and a page's block carries only the keys it has entries for — the theme's
|
|
38
|
+
* silent-disappear convention, kept at the source.
|
|
39
|
+
*
|
|
40
|
+
* @param {Iterable<HoldingsNode|null>} nodes - Every place and affiliation,
|
|
41
|
+
* local first. `parents` and `domains` are read as written, so a node
|
|
42
|
+
* built by hand may carry them as the note spells them.
|
|
43
|
+
* @returns {Map<string, Holdings>} URL → the page's lists, sorted.
|
|
44
|
+
*/
|
|
45
|
+
export function holdingsPages(nodes: Iterable<HoldingsNode | null>): Map<string, Holdings>;
|
|
46
|
+
/**
|
|
47
|
+
* Check a place note's tenure: a settlement, a site or a structure that no
|
|
48
|
+
* affiliation's `domains` names is unheld land, reported as a warning at the
|
|
49
|
+
* note's `type:` line.
|
|
50
|
+
*
|
|
51
|
+
* Declared on the `place` vocabulary as its type-level check, so the lint
|
|
52
|
+
* runs it beside the field checks with the same index. Without an index the
|
|
53
|
+
* question cannot be asked and nothing is reported.
|
|
54
|
+
*
|
|
55
|
+
* @param {object} note - The note, as the link index hands it over.
|
|
56
|
+
* @param {object} [opts]
|
|
57
|
+
* @param {object} [opts.index] - The link index, holding every affiliation.
|
|
58
|
+
* @returns {object[]} Findings.
|
|
59
|
+
*/
|
|
60
|
+
export function checkHeld(note: object, { index }?: {
|
|
61
|
+
index?: object | undefined;
|
|
62
|
+
}): object[];
|
|
63
|
+
/**
|
|
64
|
+
* The keys this module writes, and which a note cannot author: `contains`
|
|
65
|
+
* and `held_by` on a place, `holdings` on an affiliation.
|
|
66
|
+
*
|
|
67
|
+
* @type {readonly string[]}
|
|
68
|
+
*/
|
|
69
|
+
export const HOLDINGS_KEYS: readonly string[];
|
|
70
|
+
/**
|
|
71
|
+
* The place subTypes tenure is checked on. A region is held through its
|
|
72
|
+
* polity's `domains`, a world by nobody, a feature by nobody — a river has no
|
|
73
|
+
* lord — so the rest are the kinds of place a body holds directly.
|
|
74
|
+
*
|
|
75
|
+
* @type {readonly string[]}
|
|
76
|
+
*/
|
|
77
|
+
export const HELD_SUBTYPES: readonly string[];
|
|
78
|
+
/**
|
|
79
|
+
* One entry of a holdings list — a page a reader is pointed at.
|
|
80
|
+
*/
|
|
81
|
+
export type HoldingsEntry = {
|
|
82
|
+
/**
|
|
83
|
+
* The page's published title.
|
|
84
|
+
*/
|
|
85
|
+
title: string;
|
|
86
|
+
/**
|
|
87
|
+
* `<base><slug>/` — the page's address as every
|
|
88
|
+
* href this build renders composes it.
|
|
89
|
+
*/
|
|
90
|
+
url: string;
|
|
91
|
+
/**
|
|
92
|
+
* The note's `type` — `place` or `affiliation`.
|
|
93
|
+
*/
|
|
94
|
+
type: string;
|
|
95
|
+
/**
|
|
96
|
+
* The note's `subType`, where it declares one.
|
|
97
|
+
*/
|
|
98
|
+
subType?: string | undefined;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* One place or affiliation, as the derivation reads it — a local page or a
|
|
102
|
+
* fetched index entry through one shape.
|
|
103
|
+
*/
|
|
104
|
+
export type HoldingsNode = {
|
|
105
|
+
/**
|
|
106
|
+
* Lower case.
|
|
107
|
+
*/
|
|
108
|
+
shortcode: string;
|
|
109
|
+
type: "place" | "affiliation";
|
|
110
|
+
subType?: string | undefined;
|
|
111
|
+
/**
|
|
112
|
+
* The page's published title.
|
|
113
|
+
*/
|
|
114
|
+
title: string;
|
|
115
|
+
/**
|
|
116
|
+
* The page's URL; absent where the package
|
|
117
|
+
* publishes no page for it.
|
|
118
|
+
*/
|
|
119
|
+
url?: string | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* What a place sits within, as written.
|
|
122
|
+
*/
|
|
123
|
+
parents: string[];
|
|
124
|
+
/**
|
|
125
|
+
* What an affiliation holds, as written.
|
|
126
|
+
*/
|
|
127
|
+
domains: string[];
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* The lists one page carries. Every key is optional, and a key present holds
|
|
131
|
+
* at least one entry.
|
|
132
|
+
*/
|
|
133
|
+
export type Holdings = {
|
|
134
|
+
/**
|
|
135
|
+
* Places whose `parents` name this one.
|
|
136
|
+
*/
|
|
137
|
+
contains?: HoldingsEntry[] | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Affiliations whose `domains` name this one.
|
|
140
|
+
*/
|
|
141
|
+
held_by?: HoldingsEntry[] | undefined;
|
|
142
|
+
/**
|
|
143
|
+
* Places this affiliation's `domains` name.
|
|
144
|
+
*/
|
|
145
|
+
holdings?: HoldingsEntry[] | undefined;
|
|
146
|
+
};
|
package/types/engine/index.d.mts
CHANGED
|
@@ -16,11 +16,14 @@ export * as homepage from "./homepage.mjs";
|
|
|
16
16
|
export * as noteSchemas from "./note-schemas.mjs";
|
|
17
17
|
export * as noteVocabulary from "./note-vocabulary.mjs";
|
|
18
18
|
export * as placeRelations from "./place-relations.mjs";
|
|
19
|
+
export * as holdings from "./holdings.mjs";
|
|
20
|
+
export * as marketClass from "./market-class.mjs";
|
|
19
21
|
export * as mapPlaces from "./map-places.mjs";
|
|
20
22
|
export * as mapLayout from "./map-layout.mjs";
|
|
21
23
|
export * as mapDot from "./map-dot.mjs";
|
|
22
24
|
export * as mapGraphviz from "./map-graphviz.mjs";
|
|
23
25
|
export * as mapBuild from "./map-build.mjs";
|
|
26
|
+
export * as siteMaps from "./site-maps.mjs";
|
|
24
27
|
export * as systems from "./systems.mjs";
|
|
25
28
|
export * as contentSlug from "./content-slug.mjs";
|
|
26
29
|
export * as contentAddress from "./content-address.mjs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Every place that states, or is named in, a border or a route — the places
|
|
3
|
-
* `--from all`
|
|
3
|
+
* `--from all` and `--chart all` draw.
|
|
4
4
|
*
|
|
5
5
|
* @param {Map<string, import("./map-places.mjs").MapPlace>} places - Every place.
|
|
6
6
|
* @returns {string[]} Shortcodes, sorted.
|
|
@@ -17,10 +17,14 @@ export function relatedPlaces(places: Map<string, import("./map-places.mjs").Map
|
|
|
17
17
|
* @param {string} [opts.root] - With `tree`, the subtree beneath this place.
|
|
18
18
|
* @param {string[]} [opts.from] - Draw the map from each of these places, or
|
|
19
19
|
* from every related place for {@link FROM_ALL}.
|
|
20
|
+
* @param {string[]} [opts.chart] - Draw the chart from each of these places,
|
|
21
|
+
* or from every related place for {@link FROM_ALL}.
|
|
22
|
+
* @param {number} [opts.horizon] - The charts' horizon in days, a marker of
|
|
23
|
+
* the scale; the end of the scale by default.
|
|
20
24
|
* @param {boolean} [opts.travel] - Draw the whole route graph.
|
|
21
25
|
* @param {string} [opts.engine="dot"] - The tree's engine: `dot`, `twopi` or
|
|
22
|
-
* `neato`. The map from a place
|
|
23
|
-
* and the route graph always `neato`.
|
|
26
|
+
* `neato`. The map and the chart from a place are always `neato` with
|
|
27
|
+
* every node pinned, and the route graph always `neato`.
|
|
24
28
|
* @param {string} [opts.rankdir="TB"] - The tree's rank direction, `dot` only.
|
|
25
29
|
* @param {number} [opts.nodesep] - The tree's `nodesep`, inches.
|
|
26
30
|
* @param {number} [opts.ranksep] - The tree's `ranksep`, inches.
|
|
@@ -35,15 +39,17 @@ export function relatedPlaces(places: Map<string, import("./map-places.mjs").Map
|
|
|
35
39
|
* column?: number, severity: "error"|"warning", message: string}>,
|
|
36
40
|
* skipped: boolean}} What was written, what was found, and whether the
|
|
37
41
|
* rendering was skipped for want of GraphViz.
|
|
38
|
-
* @throws {Error} When no mode is asked for, a named place is not one,
|
|
39
|
-
* GraphViz is required and absent.
|
|
42
|
+
* @throws {Error} When no mode is asked for, a named place is not one, the
|
|
43
|
+
* horizon is not a marker of the scale, or GraphViz is required and absent.
|
|
40
44
|
*/
|
|
41
|
-
export function buildMaps({ world, outDir, tree, root, from, travel, engine, rankdir, nodesep, ranksep, scale, polities, locate, requireGraphviz, }: {
|
|
45
|
+
export function buildMaps({ world, outDir, tree, root, from, chart, horizon, travel, engine, rankdir, nodesep, ranksep, scale, polities, locate, requireGraphviz, }: {
|
|
42
46
|
world: import("./map-places.mjs").MapWorld;
|
|
43
47
|
outDir: string;
|
|
44
48
|
tree?: boolean | undefined;
|
|
45
49
|
root?: string | undefined;
|
|
46
50
|
from?: string[] | undefined;
|
|
51
|
+
chart?: string[] | undefined;
|
|
52
|
+
horizon?: number | undefined;
|
|
47
53
|
travel?: boolean | undefined;
|
|
48
54
|
engine?: string | undefined;
|
|
49
55
|
rankdir?: string | undefined;
|
|
@@ -71,7 +77,7 @@ export function buildMaps({ world, outDir, tree, root, from, travel, engine, ran
|
|
|
71
77
|
*/
|
|
72
78
|
export const MAP_DIR: string;
|
|
73
79
|
/**
|
|
74
|
-
* The value of `--from` that means every place with a relation.
|
|
80
|
+
* The value of `--from` or `--chart` that means every place with a relation.
|
|
75
81
|
*
|
|
76
82
|
* @type {string}
|
|
77
83
|
*/
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The opacity of a place by its hop count: the neighbours and the second hop
|
|
3
|
+
* are drawn full — the second in the dim palette — and each hop beyond
|
|
4
|
+
* steps down, never below the floor.
|
|
5
|
+
*
|
|
6
|
+
* @param {number} hop - 1 for a neighbour, 2 and up beyond.
|
|
7
|
+
* @returns {number} 0 to 1.
|
|
8
|
+
*/
|
|
9
|
+
export function hopOpacity(hop: number): number;
|
|
1
10
|
/**
|
|
2
11
|
* A DOT double-quoted string.
|
|
3
12
|
*
|
|
@@ -45,24 +54,28 @@ export function treeDot({ places, polities, analysis, root, title, engine, rankd
|
|
|
45
54
|
drawPolities?: boolean | undefined;
|
|
46
55
|
}): string;
|
|
47
56
|
/**
|
|
48
|
-
* The map from a place as DOT
|
|
57
|
+
* The map from a place, or the chart from one, as DOT for `neato -n2`.
|
|
49
58
|
*
|
|
50
59
|
* Every node is pinned at the position the layout computed, so the engine
|
|
51
60
|
* only draws. The rings are circles pinned at the origin, drawn faintly,
|
|
52
|
-
* each labelled with its days marker at the top; the rim is one more
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
61
|
+
* each labelled with its days marker at the top; the rim is one more,
|
|
62
|
+
* labelled `beyond` where the layout names what lies past the horizon there
|
|
63
|
+
* and `unknown` where it holds only the places whose days nobody stated.
|
|
64
|
+
* The centre is drawn in its `subType` style at full size, a neighbour at
|
|
65
|
+
* the layout's scale, a second hop dimmer, and each hop beyond fainter
|
|
66
|
+
* still, down to a floor. A place at the rim is a name, its label carrying
|
|
67
|
+
* its days or `?`. A border edge is dashed; every edge is labelled with its
|
|
68
|
+
* bearing and days, and dimmed with its far end.
|
|
57
69
|
*
|
|
58
|
-
* @param {
|
|
70
|
+
* @param {import("./map-layout.mjs").FromLayout} layout - The layout.
|
|
59
71
|
* @param {Map<string, import("./map-places.mjs").MapPlace>} places - Every place.
|
|
60
72
|
* @param {object} [opts]
|
|
61
73
|
* @param {number} [opts.scale=1] - Multiplies every size.
|
|
62
|
-
* @param {string} [opts.title] - Defaults to `From <name
|
|
74
|
+
* @param {string} [opts.title] - Defaults to `From <name>`, or to
|
|
75
|
+
* `Chart from <name>` for a layout with no rim beyond the horizon.
|
|
63
76
|
* @returns {string} The DOT text.
|
|
64
77
|
*/
|
|
65
|
-
export function fromDot(layout:
|
|
78
|
+
export function fromDot(layout: import("./map-layout.mjs").FromLayout, places: Map<string, import("./map-places.mjs").MapPlace>, { scale, title }?: {
|
|
66
79
|
scale?: number | undefined;
|
|
67
80
|
title?: string | undefined;
|
|
68
81
|
}): string;
|
|
@@ -21,7 +21,7 @@ export function findGraphviz(engine: string, { env, fallbacks }?: {
|
|
|
21
21
|
}): string | undefined;
|
|
22
22
|
/**
|
|
23
23
|
* What to say when an engine is not installed: the name, and what installs
|
|
24
|
-
* it
|
|
24
|
+
* it.
|
|
25
25
|
*
|
|
26
26
|
* @param {string} engine - The engine that was wanted.
|
|
27
27
|
* @returns {string} The message.
|
|
@@ -59,3 +59,10 @@ export function renderDot(dotPath: string, outPath: string, { binary, format, ar
|
|
|
59
59
|
* @type {readonly string[]}
|
|
60
60
|
*/
|
|
61
61
|
export const GRAPHVIZ_ENGINES: readonly string[];
|
|
62
|
+
/**
|
|
63
|
+
* What installs GraphViz on the two platforms a contributor is likely to be
|
|
64
|
+
* on, as the clause every "not installed" message ends with.
|
|
65
|
+
*
|
|
66
|
+
* @type {string}
|
|
67
|
+
*/
|
|
68
|
+
export const GRAPHVIZ_INSTALL: string;
|
|
@@ -34,26 +34,32 @@ export function bearingSteps(a: unknown, b: unknown): number | undefined;
|
|
|
34
34
|
* days nobody stated, is named. One log step beyond the horizon, so the rim
|
|
35
35
|
* reads as the next ring rather than a margin.
|
|
36
36
|
*
|
|
37
|
+
* @param {number} [horizon] - The horizon in days; the map from a place's
|
|
38
|
+
* by default.
|
|
37
39
|
* @returns {number} Points.
|
|
38
40
|
*/
|
|
39
|
-
export function rimRadius(): number;
|
|
41
|
+
export function rimRadius(horizon?: number): number;
|
|
40
42
|
/**
|
|
41
43
|
* The radius of the ring a days value sits on.
|
|
42
44
|
*
|
|
43
45
|
* Logarithmic in days, so equal ratios of days are equal steps of radius: a
|
|
44
|
-
* day to two days is the same step as five to ten
|
|
45
|
-
* horizon, and no value at all, is the rim.
|
|
46
|
+
* day to two days is the same step as five to ten, whatever the horizon. Any
|
|
47
|
+
* value beyond the horizon, and no value at all, is the rim.
|
|
46
48
|
*
|
|
47
49
|
* @param {number|undefined} days - A days value, on the scale or not.
|
|
50
|
+
* @param {number} [horizon] - The horizon in days; the map from a place's
|
|
51
|
+
* by default.
|
|
48
52
|
* @returns {number} Points.
|
|
49
53
|
*/
|
|
50
|
-
export function ringRadius(days: number | undefined): number;
|
|
54
|
+
export function ringRadius(days: number | undefined, horizon?: number): number;
|
|
51
55
|
/**
|
|
52
56
|
* The rings, inside out — one per marker up to the horizon.
|
|
53
57
|
*
|
|
58
|
+
* @param {number} [horizon] - The horizon in days; the map from a place's
|
|
59
|
+
* by default.
|
|
54
60
|
* @returns {Array<{days: number, radius: number}>} Each marker and its radius.
|
|
55
61
|
*/
|
|
56
|
-
export function rings(): Array<{
|
|
62
|
+
export function rings(horizon?: number): Array<{
|
|
57
63
|
days: number;
|
|
58
64
|
radius: number;
|
|
59
65
|
}>;
|
|
@@ -79,24 +85,37 @@ export function daysMarker(total: number | undefined): number | undefined;
|
|
|
79
85
|
*/
|
|
80
86
|
export function edgeLength(days: number | undefined): number;
|
|
81
87
|
/**
|
|
82
|
-
*
|
|
88
|
+
* A chain of hops composed into one bearing and one total, or nothing where
|
|
89
|
+
* a hop turns back.
|
|
90
|
+
*
|
|
91
|
+
* The composed direction is that of the hops added as vectors weighted by
|
|
92
|
+
* their days, and the total is their sum. Each hop after the first is
|
|
93
|
+
* checked against the running direction of the chain before it — not
|
|
94
|
+
* against the previous hop — and composes only where it lies within one
|
|
95
|
+
* octant of that direction, so a path may bend a little at every hop and
|
|
96
|
+
* drift past an octant of where it began, but a hop that turns back ends
|
|
97
|
+
* the chain: a place east and then north of here is not in any one
|
|
98
|
+
* direction, and the drawing omits it rather than guess. A hop with no days
|
|
99
|
+
* — a border — makes the total unknown, because a frontier states no
|
|
100
|
+
* distance, and then every hop weighs the same, because nothing says which
|
|
101
|
+
* is the longer.
|
|
83
102
|
*
|
|
84
|
-
* @
|
|
85
|
-
* @
|
|
86
|
-
*
|
|
103
|
+
* @param {Hop[]} hops - The hops, from the centre outward.
|
|
104
|
+
* @returns {{angle: number, days: number|undefined}|undefined} The composed
|
|
105
|
+
* bearing in degrees and the total days, or `undefined` where a hop turns
|
|
106
|
+
* back, a bearing is not one, or there are no hops.
|
|
87
107
|
*/
|
|
108
|
+
export function composeChain(hops: Hop[]): {
|
|
109
|
+
angle: number;
|
|
110
|
+
days: number | undefined;
|
|
111
|
+
} | undefined;
|
|
88
112
|
/**
|
|
89
113
|
* Two hops composed into one bearing and one total, or nothing where they
|
|
90
114
|
* disagree.
|
|
91
115
|
*
|
|
92
|
-
* Two hops agree when their bearings are the same or adjacent
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* makes the total unknown, because a frontier states no distance, and then
|
|
96
|
-
* the two hops weigh the same, because nothing says which is the longer.
|
|
97
|
-
* Hops two or more steps apart do not compose:
|
|
98
|
-
* a place east and then north of here is not in any one direction, and the
|
|
99
|
-
* map omits it rather than guess.
|
|
116
|
+
* Two hops agree when their bearings are the same or adjacent — the
|
|
117
|
+
* two-hop case of {@link composeChain}: the second hop is checked against
|
|
118
|
+
* the first, which is the whole running direction at that point.
|
|
100
119
|
*
|
|
101
120
|
* @param {Hop} first - The hop from the centre.
|
|
102
121
|
* @param {Hop} second - The hop onward.
|
|
@@ -133,7 +152,8 @@ export function relationsOf(places: Map<string, MapPlace>, shortcode: string): {
|
|
|
133
152
|
}>;
|
|
134
153
|
};
|
|
135
154
|
/**
|
|
136
|
-
* Lay out the map from a place
|
|
155
|
+
* Lay out the map from a place: two hops, a horizon of 90 days, and a rim
|
|
156
|
+
* naming what lies beyond it.
|
|
137
157
|
*
|
|
138
158
|
* The centre at the origin. Every neighbour it states, or that states it, at
|
|
139
159
|
* the angle of its bearing and on the ring of its days — the innermost ring
|
|
@@ -147,25 +167,35 @@ export function relationsOf(places: Map<string, MapPlace>, shortcode: string): {
|
|
|
147
167
|
*
|
|
148
168
|
* @param {Map<string, MapPlace>} places - Every place, by shortcode.
|
|
149
169
|
* @param {string} centre - The place the map is from.
|
|
150
|
-
* @returns {
|
|
151
|
-
* rings: Array<{days: number, radius: number}>, rim: number,
|
|
152
|
-
* unresolved: Array<{from: string, to: string}>}} The layout, in points.
|
|
170
|
+
* @returns {FromLayout} The layout, in points.
|
|
153
171
|
* @throws {Error} When `centre` is not a place.
|
|
154
172
|
*/
|
|
155
|
-
export function layoutFrom(places: Map<string, MapPlace>, centre: string):
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
173
|
+
export function layoutFrom(places: Map<string, MapPlace>, centre: string): FromLayout;
|
|
174
|
+
/**
|
|
175
|
+
* Lay out the chart from a place: the map from it at a larger horizon.
|
|
176
|
+
*
|
|
177
|
+
* The neighbours as on the map from a place. Beyond them the hops chain on,
|
|
178
|
+
* each checked against the running direction of the chain so far and
|
|
179
|
+
* composing only within one octant of it, so a path bends but never turns
|
|
180
|
+
* back; a place is drawn at the composed bearing on the ring of the summed
|
|
181
|
+
* days, and where several chains reach it, by the one with the fewest. A
|
|
182
|
+
* border beyond the first hop makes the total unknown and sends the place to
|
|
183
|
+
* the rim, and nothing is drawn beyond it. A place whose total exceeds the
|
|
184
|
+
* horizon is left out — the chart is already the larger view — so the rim
|
|
185
|
+
* holds the unknown alone.
|
|
186
|
+
*
|
|
187
|
+
* @param {Map<string, MapPlace>} places - Every place, by shortcode.
|
|
188
|
+
* @param {string} centre - The place the chart is from.
|
|
189
|
+
* @param {object} [opts]
|
|
190
|
+
* @param {number} [opts.horizon] - The horizon in days, a marker of the
|
|
191
|
+
* scale; {@link CHART_HORIZON_DAYS} by default.
|
|
192
|
+
* @returns {FromLayout} The layout, in points.
|
|
193
|
+
* @throws {Error} When `centre` is not a place, or `horizon` is not a marker
|
|
194
|
+
* of the scale.
|
|
195
|
+
*/
|
|
196
|
+
export function layoutChart(places: Map<string, MapPlace>, centre: string, { horizon }?: {
|
|
197
|
+
horizon?: number | undefined;
|
|
198
|
+
}): FromLayout;
|
|
169
199
|
/**
|
|
170
200
|
* One edge of the whole route graph.
|
|
171
201
|
*
|
|
@@ -213,18 +243,12 @@ export const HORIZON_DAYS: number;
|
|
|
213
243
|
*/
|
|
214
244
|
export const RING_DAYS: readonly number[];
|
|
215
245
|
/**
|
|
216
|
-
*
|
|
246
|
+
* The horizon of the chart from a place when none is asked for, in days: the
|
|
247
|
+
* end of the scale, so the whole of what the notes state fits on the page.
|
|
248
|
+
*
|
|
249
|
+
* @type {number}
|
|
217
250
|
*/
|
|
218
|
-
export
|
|
219
|
-
/**
|
|
220
|
-
* - Where the far end lies from the near end.
|
|
221
|
-
*/
|
|
222
|
-
bearing: string;
|
|
223
|
-
/**
|
|
224
|
-
* - The route's marker; absent for a border.
|
|
225
|
-
*/
|
|
226
|
-
days?: number | undefined;
|
|
227
|
-
};
|
|
251
|
+
export const CHART_HORIZON_DAYS: number;
|
|
228
252
|
/**
|
|
229
253
|
* A place as the map reads it. The shape {@link module :engine/map-places}
|
|
230
254
|
* builds from the content index; only the relation fields matter here.
|
|
@@ -265,6 +289,35 @@ export type Relation = {
|
|
|
265
289
|
*/
|
|
266
290
|
stated: boolean;
|
|
267
291
|
};
|
|
292
|
+
/**
|
|
293
|
+
* The layout of the map from a place or of the chart from one.
|
|
294
|
+
*/
|
|
295
|
+
export type FromLayout = {
|
|
296
|
+
centre: string;
|
|
297
|
+
nodes: FromNode[];
|
|
298
|
+
edges: FromEdge[];
|
|
299
|
+
rings: Array<{
|
|
300
|
+
days: number;
|
|
301
|
+
radius: number;
|
|
302
|
+
}>;
|
|
303
|
+
/**
|
|
304
|
+
* - The rim's radius, in points.
|
|
305
|
+
*/
|
|
306
|
+
rim: number;
|
|
307
|
+
/**
|
|
308
|
+
* - The horizon, in days.
|
|
309
|
+
*/
|
|
310
|
+
horizon: number;
|
|
311
|
+
/**
|
|
312
|
+
* - Whether a place past the horizon is named at
|
|
313
|
+
* the rim; false, it is omitted and the rim holds only the unknown.
|
|
314
|
+
*/
|
|
315
|
+
beyond: boolean;
|
|
316
|
+
unresolved: Array<{
|
|
317
|
+
from: string;
|
|
318
|
+
to: string;
|
|
319
|
+
}>;
|
|
320
|
+
};
|
|
268
321
|
/**
|
|
269
322
|
* One edge of the whole route graph.
|
|
270
323
|
*/
|
|
@@ -283,13 +336,27 @@ export type TravelEdge = {
|
|
|
283
336
|
*/
|
|
284
337
|
len: number;
|
|
285
338
|
};
|
|
339
|
+
/**
|
|
340
|
+
* One hop of a journey: a bearing and, for a route, its days.
|
|
341
|
+
*/
|
|
342
|
+
export type Hop = {
|
|
343
|
+
/**
|
|
344
|
+
* - Where the far end lies from the near end.
|
|
345
|
+
*/
|
|
346
|
+
bearing: string;
|
|
347
|
+
/**
|
|
348
|
+
* - The route's marker; absent for a border.
|
|
349
|
+
*/
|
|
350
|
+
days?: number | undefined;
|
|
351
|
+
};
|
|
286
352
|
/**
|
|
287
353
|
* One place on the map from a place.
|
|
288
354
|
*/
|
|
289
355
|
export type FromNode = {
|
|
290
356
|
shortcode: string;
|
|
291
357
|
/**
|
|
292
|
-
* - 0 for the centre, 1 for a neighbour, 2
|
|
358
|
+
* - 0 for the centre, 1 for a neighbour, 2 and up
|
|
359
|
+
* beyond — the map from a place stops at 2, the chart goes on.
|
|
293
360
|
*/
|
|
294
361
|
hop: number;
|
|
295
362
|
/**
|
|
@@ -321,7 +388,8 @@ export type FromNode = {
|
|
|
321
388
|
*/
|
|
322
389
|
unknown: boolean;
|
|
323
390
|
/**
|
|
324
|
-
* - The
|
|
391
|
+
* - The place a hop beyond the neighbours is reached
|
|
392
|
+
* through.
|
|
325
393
|
*/
|
|
326
394
|
via?: string | undefined;
|
|
327
395
|
};
|
|
@@ -353,7 +421,7 @@ export type FromEdge = {
|
|
|
353
421
|
days: number | undefined;
|
|
354
422
|
}>;
|
|
355
423
|
/**
|
|
356
|
-
* - 1 from the centre, 2 onward.
|
|
424
|
+
* - 1 from the centre, 2 and up onward.
|
|
357
425
|
*/
|
|
358
426
|
hop: number;
|
|
359
427
|
};
|
|
@@ -34,6 +34,32 @@ export function loadMapWorld({ config, contentBase, base, problems }: {
|
|
|
34
34
|
base?: string | undefined;
|
|
35
35
|
problems?: object[] | undefined;
|
|
36
36
|
}): MapWorld;
|
|
37
|
+
/**
|
|
38
|
+
* The world a map is drawn from, out of records and indexes a caller already
|
|
39
|
+
* holds: this package's places from its index records, and every
|
|
40
|
+
* dependency's from the fetched indexes. The site build reads its corpus and
|
|
41
|
+
* its foreign indexes once for every surface it publishes, and hands them
|
|
42
|
+
* here rather than walking the tree a second time.
|
|
43
|
+
*
|
|
44
|
+
* @param {object} opts
|
|
45
|
+
* @param {Array<Record<string, any>>} opts.records - Index records, as
|
|
46
|
+
* {@link module:engine/content-index.indexRecordsFor} returns them.
|
|
47
|
+
* @param {Map<string, object>} opts.foreignIndex - The fetched indexes, as
|
|
48
|
+
* {@link module:engine/metadata-index.loadForeignIndexes} returns `index`.
|
|
49
|
+
* @param {string} opts.contentBase - The content root the records were read from.
|
|
50
|
+
* @param {string} [opts.base] - The site base this package's pages are served
|
|
51
|
+
* under. Absent, no local place carries a URL.
|
|
52
|
+
* @param {object} opts.config - The resolved configuration.
|
|
53
|
+
* @returns {MapWorld} The world, with nothing stale: the caller has already
|
|
54
|
+
* judged its indexes usable.
|
|
55
|
+
*/
|
|
56
|
+
export function mapWorld({ records, foreignIndex, contentBase, base, config }: {
|
|
57
|
+
records: Array<Record<string, any>>;
|
|
58
|
+
foreignIndex: Map<string, object>;
|
|
59
|
+
contentBase: string;
|
|
60
|
+
base?: string | undefined;
|
|
61
|
+
config: object;
|
|
62
|
+
}): MapWorld;
|
|
37
63
|
/**
|
|
38
64
|
* Analyse the containment tree.
|
|
39
65
|
*
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a value is one of the classes the scale states.
|
|
3
|
+
*
|
|
4
|
+
* A note may write the number quoted, which YAML hands over as a string, so
|
|
5
|
+
* the value is read as a number before it is compared — the same reading
|
|
6
|
+
* `matchesKind` gives a `number` field.
|
|
7
|
+
*
|
|
8
|
+
* @param {unknown} value - The authored value.
|
|
9
|
+
* @returns {boolean} Whether it names a class.
|
|
10
|
+
*/
|
|
11
|
+
export function isMarketClass(value: unknown): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* The class a value names, or `undefined` for a value that names none.
|
|
14
|
+
*
|
|
15
|
+
* @param {unknown} value - The authored value.
|
|
16
|
+
* @returns {MarketClass|undefined} The class.
|
|
17
|
+
*/
|
|
18
|
+
export function marketClass(value: unknown): MarketClass | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Check a place note's `data.market`.
|
|
21
|
+
*
|
|
22
|
+
* The value is one of the classes the scale states, or it is a finding located
|
|
23
|
+
* at the key's own line. A value that is not a number at all is left alone:
|
|
24
|
+
* the container's own shape check reports it, and saying so twice would make
|
|
25
|
+
* one slip read as two.
|
|
26
|
+
*
|
|
27
|
+
* @param {object} note - The note, as the link index hands it over.
|
|
28
|
+
* @returns {object[]} Findings.
|
|
29
|
+
*/
|
|
30
|
+
export function checkMarket(note: object): object[];
|
|
31
|
+
/**
|
|
32
|
+
* One step of the market scale.
|
|
33
|
+
*
|
|
34
|
+
* @typedef {object} MarketClass
|
|
35
|
+
* @property {number} value - The integer a note writes.
|
|
36
|
+
* @property {string} name - What a settlement of this class is called.
|
|
37
|
+
* @property {string} trade - What can be had there.
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* The market scale, in order, from the settlement with no market to the one
|
|
41
|
+
* other markets buy from.
|
|
42
|
+
*
|
|
43
|
+
* @type {readonly MarketClass[]}
|
|
44
|
+
*/
|
|
45
|
+
export const MARKET_CLASSES: readonly MarketClass[];
|
|
46
|
+
/**
|
|
47
|
+
* One step of the market scale.
|
|
48
|
+
*/
|
|
49
|
+
export type MarketClass = {
|
|
50
|
+
/**
|
|
51
|
+
* - The integer a note writes.
|
|
52
|
+
*/
|
|
53
|
+
value: number;
|
|
54
|
+
/**
|
|
55
|
+
* - What a settlement of this class is called.
|
|
56
|
+
*/
|
|
57
|
+
name: string;
|
|
58
|
+
/**
|
|
59
|
+
* - What can be had there.
|
|
60
|
+
*/
|
|
61
|
+
trade: string;
|
|
62
|
+
};
|
|
@@ -344,4 +344,14 @@ export type TypeVocabulary = {
|
|
|
344
344
|
* values, as above.
|
|
345
345
|
*/
|
|
346
346
|
subTypes?: readonly string[] | null | undefined;
|
|
347
|
+
/**
|
|
348
|
+
* - A
|
|
349
|
+
* check of the whole note, run by the frontmatter lint beside the field
|
|
350
|
+
* checks with the same index. For a rule that is about the note rather than
|
|
351
|
+
* one of its fields — a place's tenure is a fact about every affiliation's
|
|
352
|
+
* `domains`, and is located at the note's `type:` line.
|
|
353
|
+
*/
|
|
354
|
+
check?: ((note: object, opts: {
|
|
355
|
+
index?: object;
|
|
356
|
+
}) => object[]) | undefined;
|
|
347
357
|
};
|