@heroiclands/package-build 22.14.4 → 22.15.1
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 +34 -0
- package/CONTENT.md +25 -1
- package/bin/content-build.mjs +3 -7
- package/bin/package-build.mjs +25 -0
- package/docs/api.md +61 -34
- package/docs/commands.md +65 -9
- package/docs/configuration.md +6 -3
- package/docs/content-format.md +165 -121
- package/docs/diagnostics.md +1 -1
- package/docs/getting-started.md +23 -0
- package/engine/base-compiler.mjs +3 -1
- package/engine/being-age.mjs +16 -24
- package/engine/calendar-artifacts.mjs +153 -0
- package/engine/calendar-notes.mjs +64 -16
- package/engine/calendars.mjs +129 -0
- package/engine/content-index.mjs +3 -1
- package/engine/exported-scene.mjs +230 -0
- package/engine/generate.mjs +1 -0
- package/engine/ids.mjs +1 -1
- package/engine/index.mjs +6 -0
- package/engine/infobox.mjs +4 -0
- package/engine/itinerary-scenes.mjs +172 -0
- package/engine/map-build.mjs +10 -45
- package/engine/map-dot.mjs +6 -3
- package/engine/map-graphviz.mjs +50 -131
- package/engine/map-notes.mjs +26 -3
- package/engine/map-places.mjs +12 -6
- package/engine/map-raster.mjs +51 -0
- package/engine/note-dates.mjs +125 -85
- package/engine/note-vocabulary.mjs +22 -6
- package/engine/pdf-build.mjs +57 -1
- package/engine/pdf-render.mjs +18 -0
- package/engine/reckoning-markers.mjs +207 -0
- package/engine/scenes.mjs +113 -26
- package/engine/site-build.mjs +11 -13
- package/engine/site-maps.mjs +5 -35
- package/engine/site-preview.mjs +6 -1
- package/engine/social-tie-terms.mjs +3 -0
- package/engine/social-ties.mjs +30 -19
- package/package.json +3 -1
- package/types/engine/being-age.d.mts +2 -2
- package/types/engine/calendar-artifacts.d.mts +16 -0
- package/types/engine/calendar-notes.d.mts +1 -1
- package/types/engine/calendars.d.mts +65 -0
- package/types/engine/exported-scene.d.mts +12 -0
- package/types/engine/index.d.mts +2 -0
- package/types/engine/itinerary-scenes.d.mts +29 -0
- package/types/engine/map-build.d.mts +4 -13
- package/types/engine/map-graphviz.d.mts +17 -59
- package/types/engine/map-places.d.mts +5 -1
- package/types/engine/map-raster.d.mts +8 -0
- package/types/engine/note-dates.d.mts +6 -0
- package/types/engine/note-vocabulary.d.mts +3 -3
- package/types/engine/pdf-render.d.mts +7 -1
- package/types/engine/reckoning-markers.d.mts +27 -0
- package/types/engine/scenes.d.mts +9 -2
- package/types/engine/site-build.d.mts +1 -5
- package/types/engine/site-maps.d.mts +2 -7
- package/types/engine/social-tie-terms.d.mts +2 -0
- package/types/engine/social-ties.d.mts +2 -1
package/engine/site-maps.mjs
CHANGED
|
@@ -23,10 +23,8 @@
|
|
|
23
23
|
* and every `href` in it composes `<base><slug>/` the way every other href
|
|
24
24
|
* the build renders does.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* would without maps. `site.maps: false` says the site carries none and asks
|
|
29
|
-
* nothing of GraphViz.
|
|
26
|
+
* The npm Graphviz runtime draws each map. `site.maps: false` says the site
|
|
27
|
+
* carries none and skips map rendering.
|
|
30
28
|
*
|
|
31
29
|
* The drawings land under `build/map/site/` — beside the author's own
|
|
32
30
|
* drawings under `build/map/`, and apart from them, because the site's
|
|
@@ -40,7 +38,6 @@ import fs from "node:fs";
|
|
|
40
38
|
import path from "node:path";
|
|
41
39
|
|
|
42
40
|
import { buildMaps, relatedPlaces } from "./map-build.mjs";
|
|
43
|
-
import { GRAPHVIZ_INSTALL, findGraphviz } from "./map-graphviz.mjs";
|
|
44
41
|
import { mapWorld } from "./map-places.mjs";
|
|
45
42
|
|
|
46
43
|
/**
|
|
@@ -50,13 +47,6 @@ import { mapWorld } from "./map-places.mjs";
|
|
|
50
47
|
*/
|
|
51
48
|
export const SITE_MAP_DIR = "build/map/site";
|
|
52
49
|
|
|
53
|
-
/**
|
|
54
|
-
* The engine the map from a place is drawn with.
|
|
55
|
-
*
|
|
56
|
-
* @type {string}
|
|
57
|
-
*/
|
|
58
|
-
const ENGINE = "neato";
|
|
59
|
-
|
|
60
50
|
/**
|
|
61
51
|
* A drawing as the page writer receives it.
|
|
62
52
|
*
|
|
@@ -106,16 +96,12 @@ export function inlineSvg(svg) {
|
|
|
106
96
|
* @param {object} opts.config - The resolved configuration.
|
|
107
97
|
* @param {string} opts.base - The site base every page is served under,
|
|
108
98
|
* ending in a slash: what every name in a drawing links through.
|
|
109
|
-
* @param {(engine: string) => string|undefined} [opts.locate] - How the
|
|
110
|
-
* engine's binary is found; the real lookup by default.
|
|
111
99
|
* @returns {{maps: Map<string, SiteMap>, findings: Array<{file: string,
|
|
112
100
|
* line?: number, column?: number, severity: "error"|"warning",
|
|
113
101
|
* message: string}>}} The drawings, keyed by the URL of the page each
|
|
114
|
-
* belongs to, and
|
|
115
|
-
* install when GraphViz is absent, and a warning for each relation that
|
|
116
|
-
* names no place.
|
|
102
|
+
* belongs to, and warnings for relations that name no place.
|
|
117
103
|
*/
|
|
118
|
-
export function drawSiteMaps({ records, foreignIndex, config, base
|
|
104
|
+
export function drawSiteMaps({ records, foreignIndex, config, base }) {
|
|
119
105
|
/** @type {Map<string, SiteMap>} */
|
|
120
106
|
const maps = new Map();
|
|
121
107
|
const outDir = path.join(config.rootDir, ...SITE_MAP_DIR.split("/"));
|
|
@@ -123,22 +109,6 @@ export function drawSiteMaps({ records, foreignIndex, config, base, locate = fin
|
|
|
123
109
|
// the map an earlier run drew.
|
|
124
110
|
fs.rmSync(outDir, { recursive: true, force: true });
|
|
125
111
|
|
|
126
|
-
if (!locate(ENGINE)) {
|
|
127
|
-
return {
|
|
128
|
-
maps,
|
|
129
|
-
findings: [
|
|
130
|
-
{
|
|
131
|
-
file: config.rootDir,
|
|
132
|
-
severity: "warning",
|
|
133
|
-
message:
|
|
134
|
-
`GraphViz's \`${ENGINE}\` is not installed, so no place page carries ` +
|
|
135
|
-
`the map from that place; ${GRAPHVIZ_INSTALL} to draw them, or set ` +
|
|
136
|
-
"`site.maps: false` to say the site carries none",
|
|
137
|
-
},
|
|
138
|
-
],
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
112
|
const world = mapWorld({
|
|
143
113
|
records,
|
|
144
114
|
foreignIndex,
|
|
@@ -152,7 +122,7 @@ export function drawSiteMaps({ records, foreignIndex, config, base, locate = fin
|
|
|
152
122
|
const centres = relatedPlaces(world.places).filter((s) => world.places.get(s)?.local);
|
|
153
123
|
if (centres.length === 0) return { maps, findings: [] };
|
|
154
124
|
|
|
155
|
-
const { findings } = buildMaps({ world, outDir, from: centres
|
|
125
|
+
const { findings } = buildMaps({ world, outDir, from: centres });
|
|
156
126
|
for (const centre of centres) {
|
|
157
127
|
const place = world.places.get(centre);
|
|
158
128
|
if (!place?.url) continue;
|
package/engine/site-preview.mjs
CHANGED
|
@@ -14,6 +14,7 @@ import { noteAddressContext, decodeNoteAddresses, encodeAddresses } from "./note
|
|
|
14
14
|
import { noteFile } from "./index-records.mjs";
|
|
15
15
|
import { foundryIdentities } from "./foundry-entries.mjs";
|
|
16
16
|
import { applyComputedBeingAge, presentAmongRecords } from "./being-age.mjs";
|
|
17
|
+
import { reckoningContext } from "./reckoning-markers.mjs";
|
|
17
18
|
import { cachedMetadataIndexes, noContentIndexPackages } from "./metadata-index.mjs";
|
|
18
19
|
import { buildSiteIndex } from "./site-index.mjs";
|
|
19
20
|
import { openNotesDatabase, prepareSqlTables, findSqlBlocks } from "./sql-tables.mjs";
|
|
@@ -133,7 +134,11 @@ export async function prepareSitePreview({ config = loadPackConfig() } = {}) {
|
|
|
133
134
|
...noteAddressContext(config),
|
|
134
135
|
package: config.contentPackage,
|
|
135
136
|
});
|
|
136
|
-
applyComputedBeingAge(
|
|
137
|
+
applyComputedBeingAge(
|
|
138
|
+
fm,
|
|
139
|
+
presentAmongRecords(snapshot.records),
|
|
140
|
+
reckoningContext({ notes: snapshot.records }),
|
|
141
|
+
);
|
|
137
142
|
} catch (error) {
|
|
138
143
|
return {
|
|
139
144
|
ok: false,
|
|
@@ -9,3 +9,6 @@ export const SOCIAL_TIES = Object.freeze([
|
|
|
9
9
|
{ term: "rival", meaning: "Opposes the subject without implacable hostility." },
|
|
10
10
|
{ term: "nemesis", meaning: "Opposes the subject personally and implacably." },
|
|
11
11
|
]);
|
|
12
|
+
|
|
13
|
+
/** The note types a being can name as a social tie. */
|
|
14
|
+
export const SOCIAL_TIE_TARGET_TYPES = Object.freeze(["being", "affiliation"]);
|
package/engine/social-ties.mjs
CHANGED
|
@@ -8,14 +8,13 @@
|
|
|
8
8
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { parseAddress, renderAddress } from "./address.mjs";
|
|
11
|
+
import { acceptsType, parseAddress, renderAddress } from "./address.mjs";
|
|
12
12
|
import { positionOfFrontmatterPath } from "./diagnostics.mjs";
|
|
13
|
-
import { SOCIAL_TIES } from "./social-tie-terms.mjs";
|
|
13
|
+
import { SOCIAL_TIES, SOCIAL_TIE_TARGET_TYPES } from "./social-tie-terms.mjs";
|
|
14
14
|
|
|
15
|
-
export { SOCIAL_TIES };
|
|
15
|
+
export { SOCIAL_TIES, SOCIAL_TIE_TARGET_TYPES };
|
|
16
16
|
|
|
17
17
|
const TERMS = new Set(SOCIAL_TIES.map(({ term }) => term));
|
|
18
|
-
const ACCEPTED = new Set(["being", "affiliation"]);
|
|
19
18
|
|
|
20
19
|
/** Validate a being's map of defining relationships. */
|
|
21
20
|
export function checkSocialTies(note, { index } = {}) {
|
|
@@ -38,6 +37,7 @@ export function checkSocialTies(note, { index } = {}) {
|
|
|
38
37
|
},
|
|
39
38
|
];
|
|
40
39
|
const findings = [];
|
|
40
|
+
const seen = new Map();
|
|
41
41
|
for (const [key, term] of Object.entries(ties)) {
|
|
42
42
|
const tuple = parseAddress(
|
|
43
43
|
key,
|
|
@@ -54,25 +54,36 @@ export function checkSocialTies(note, { index } = {}) {
|
|
|
54
54
|
...at(key),
|
|
55
55
|
message: `data.socialTies key ${JSON.stringify(key)} is not a complete Address (${tuple.reason}); write being or affiliation as its type`,
|
|
56
56
|
});
|
|
57
|
-
} else if (!
|
|
57
|
+
} else if (!acceptsType(tuple, SOCIAL_TIE_TARGET_TYPES)) {
|
|
58
58
|
findings.push({
|
|
59
59
|
...at(key),
|
|
60
60
|
message: `data.socialTies accepts being or affiliation, not ${tuple.type}`,
|
|
61
61
|
});
|
|
62
|
-
} else
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
62
|
+
} else {
|
|
63
|
+
const target = renderAddress(tuple);
|
|
64
|
+
if (seen.has(target)) {
|
|
65
|
+
findings.push({
|
|
66
|
+
...at(key),
|
|
67
|
+
message: `data.socialTies names the same target ${target} as ${JSON.stringify(seen.get(target))}; keep one tie per target`,
|
|
68
|
+
});
|
|
69
|
+
} else {
|
|
70
|
+
seen.set(target, key);
|
|
71
|
+
}
|
|
72
|
+
if (
|
|
73
|
+
tuple.package === (index?.contentPackage ?? note.fm?.package) &&
|
|
74
|
+
tuple.type === "being" &&
|
|
75
|
+
tuple.shortcode === note.fm?.shortcode
|
|
76
|
+
) {
|
|
77
|
+
findings.push({
|
|
78
|
+
...at(key),
|
|
79
|
+
message: `data.socialTies cannot address this being itself`,
|
|
80
|
+
});
|
|
81
|
+
} else if (index?.addressHit && !index.addressHit(target)) {
|
|
82
|
+
findings.push({
|
|
83
|
+
...at(key),
|
|
84
|
+
message: `data.socialTies target ${target} does not resolve`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
76
87
|
}
|
|
77
88
|
if (!TERMS.has(term))
|
|
78
89
|
findings.push({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heroiclands/package-build",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.15.1",
|
|
4
4
|
"description": "Shared toolchain for building and shipping a HeroicLands Foundry VTT package — content compilation, manifest, localization, staging, bundle, release and deployment.",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -134,6 +134,8 @@
|
|
|
134
134
|
"dependencies": {
|
|
135
135
|
"@duckdb/node-api": "^1.5.5-r.4",
|
|
136
136
|
"@foundryvtt/foundryvtt-cli": "^3.0.4",
|
|
137
|
+
"@resvg/resvg-js": "^2.6.2",
|
|
138
|
+
"@viz-js/viz": "^3.30.0",
|
|
137
139
|
"acorn": "^8.18.0",
|
|
138
140
|
"archiver": "^8.0.0",
|
|
139
141
|
"classic-level": "^3.0.0",
|
|
@@ -21,7 +21,7 @@ export function parseAgeMagnitude(raw: unknown): {
|
|
|
21
21
|
* @returns {number|null} The age, or `null` where `born` is `unknown` or
|
|
22
22
|
* absent, where no present is declared, or where either date fails to parse.
|
|
23
23
|
*/
|
|
24
|
-
export function computeAge(bornRaw: unknown, presentRaw: unknown): number | null;
|
|
24
|
+
export function computeAge(bornRaw: unknown, presentRaw: unknown, dateContext?: {}): number | null;
|
|
25
25
|
/**
|
|
26
26
|
* Fill in a being's computed `age`, and the numeric companion an estimate
|
|
27
27
|
* carries beside it — mutating the frontmatter object handed in, never a file
|
|
@@ -39,7 +39,7 @@ export function computeAge(bornRaw: unknown, presentRaw: unknown): number | null
|
|
|
39
39
|
* `undefined`/`null` where it states none.
|
|
40
40
|
* @returns {void}
|
|
41
41
|
*/
|
|
42
|
-
export function applyComputedBeingAge(fm: object, presentRaw: unknown): void;
|
|
42
|
+
export function applyComputedBeingAge(fm: object, presentRaw: unknown, dateContext?: {}): void;
|
|
43
43
|
/**
|
|
44
44
|
* A being's `data.present`, read from every `place` note a batch of records or
|
|
45
45
|
* frontmatter objects carries.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emit calendar definitions and import envelopes from the package's index.
|
|
3
|
+
*
|
|
4
|
+
* @param {object} opts
|
|
5
|
+
* @param {object} opts.config - Resolved content configuration.
|
|
6
|
+
* @param {string} opts.calendariaVersion - Version whose import format is targeted.
|
|
7
|
+
* @returns {{directory: string, calendars: number, files: number}}
|
|
8
|
+
*/
|
|
9
|
+
export function emitCalendarArtifacts({ config, calendariaVersion }?: {
|
|
10
|
+
config: object;
|
|
11
|
+
calendariaVersion: string;
|
|
12
|
+
}): {
|
|
13
|
+
directory: string;
|
|
14
|
+
calendars: number;
|
|
15
|
+
files: number;
|
|
16
|
+
};
|
|
@@ -103,7 +103,7 @@ export function quarterDays(daysPerYear: number): number[];
|
|
|
103
103
|
* its own package.
|
|
104
104
|
* @returns {object} The definition.
|
|
105
105
|
*/
|
|
106
|
-
export function compileCalendar({ note, invariants, contentPackage }: {
|
|
106
|
+
export function compileCalendar({ note, invariants, contentPackage, dateContext }: {
|
|
107
107
|
note: object;
|
|
108
108
|
invariants: object;
|
|
109
109
|
contentPackage?: string | undefined;
|
|
@@ -35,6 +35,60 @@ export function canonicalYear(year: number, epoch?: number): number;
|
|
|
35
35
|
* @returns {number} The sort key.
|
|
36
36
|
*/
|
|
37
37
|
export function dateSortKey(year: number, month: number | null, day: number | null): number;
|
|
38
|
+
/**
|
|
39
|
+
* Days from an arbitrary canonical origin to a canonical year and day.
|
|
40
|
+
*
|
|
41
|
+
* Canonical years form a continuous integer line. Day one opens each year;
|
|
42
|
+
* calendar month divisions play no part in this count.
|
|
43
|
+
*
|
|
44
|
+
* @param {number} year - Canonical year.
|
|
45
|
+
* @param {number} day - Day of that year, starting at one.
|
|
46
|
+
* @param {number} originYear - Canonical year whose first day is offset zero.
|
|
47
|
+
* @param {number} daysPerYear - The world's authored year length.
|
|
48
|
+
* @returns {number} Signed whole-day offset.
|
|
49
|
+
*/
|
|
50
|
+
export function canonicalDayOffset(year: number, day: number, originYear: number, daysPerYear: number): number;
|
|
51
|
+
/**
|
|
52
|
+
* The canonical year and day at a signed offset from an arbitrary origin.
|
|
53
|
+
* Flooring the division keeps the day within the year before the origin.
|
|
54
|
+
*
|
|
55
|
+
* @param {number} offset - Whole days from the origin.
|
|
56
|
+
* @param {number} originYear - Canonical year whose first day is offset zero.
|
|
57
|
+
* @param {number} daysPerYear - The world's authored year length.
|
|
58
|
+
* @returns {{year: number, day: number}} Canonical year and day.
|
|
59
|
+
*/
|
|
60
|
+
export function canonicalDateFromOffset(offset: number, originYear: number, daysPerYear: number): {
|
|
61
|
+
year: number;
|
|
62
|
+
day: number;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Print a calendar-neutral date as `<year>.<day>[:HHMMSS]`.
|
|
66
|
+
*
|
|
67
|
+
* @param {{year: number, day: number, seconds?: number}} date - Canonical date.
|
|
68
|
+
* @param {number} daysPerYear - The world's authored year length.
|
|
69
|
+
* @returns {string} The canonical spelling.
|
|
70
|
+
*/
|
|
71
|
+
export function formatCanonicalDate(date: {
|
|
72
|
+
year: number;
|
|
73
|
+
day: number;
|
|
74
|
+
seconds?: number;
|
|
75
|
+
}, daysPerYear: number): string;
|
|
76
|
+
/**
|
|
77
|
+
* Read the calendar-neutral `<year>.<day>[:HHMMSS]` spelling.
|
|
78
|
+
*
|
|
79
|
+
* This is distinct from an authored month date such as `720/6`; no calendar
|
|
80
|
+
* month list is consulted to read a canonical day of year.
|
|
81
|
+
*
|
|
82
|
+
* @param {unknown} value - Canonical date text.
|
|
83
|
+
* @param {number} daysPerYear - The world's authored year length.
|
|
84
|
+
* @returns {{year: number, day: number, seconds?: number}|null} The date, or
|
|
85
|
+
* `null` when the spelling or a component is invalid.
|
|
86
|
+
*/
|
|
87
|
+
export function parseCanonicalDate(value: unknown, daysPerYear: number): {
|
|
88
|
+
year: number;
|
|
89
|
+
day: number;
|
|
90
|
+
seconds?: number;
|
|
91
|
+
} | null;
|
|
38
92
|
/**
|
|
39
93
|
* One month of a calendar, as the note declares it.
|
|
40
94
|
*
|
|
@@ -101,6 +155,17 @@ export function monthStarts(months: readonly CalendarMonth[]): number[];
|
|
|
101
155
|
* @returns {number} The day of the year.
|
|
102
156
|
*/
|
|
103
157
|
export function dayOfYear(months: readonly CalendarMonth[], month: number, day: number): number;
|
|
158
|
+
/**
|
|
159
|
+
* Recover a calendar's month and day from an ordinal day of its year.
|
|
160
|
+
*
|
|
161
|
+
* @param {readonly CalendarMonth[]} months - The ordered month list.
|
|
162
|
+
* @param {number} ordinal - Day of year, starting at one.
|
|
163
|
+
* @returns {{month: number, day: number}|null} The named day, or `null` outside the year.
|
|
164
|
+
*/
|
|
165
|
+
export function monthDayOfYear(months: readonly CalendarMonth[], ordinal: number): {
|
|
166
|
+
month: number;
|
|
167
|
+
day: number;
|
|
168
|
+
} | null;
|
|
104
169
|
/**
|
|
105
170
|
* How far into its cycle a moon is on a given day.
|
|
106
171
|
*
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile a Foundry Scene export into a pack document.
|
|
3
|
+
*
|
|
4
|
+
* Only the note-derived Scene ID, compendium metadata, and pins marked
|
|
5
|
+
* `#anchor` change. Every other authored Scene field passes through.
|
|
6
|
+
*
|
|
7
|
+
* @param {object} fm - The map note's frontmatter.
|
|
8
|
+
* @param {string} markdown - Its converted Markdown body.
|
|
9
|
+
* @param {object} [opts] - Pack metadata, derived JournalEntry ID, and asset resolver.
|
|
10
|
+
* @returns {object} The keyed Scene document.
|
|
11
|
+
*/
|
|
12
|
+
export function buildExportedScene(fm: object, markdown: string, { journalEntryId, stats, resolveAddress }?: object): object;
|
package/types/engine/index.d.mts
CHANGED
|
@@ -31,7 +31,9 @@ export * as siteMaps from "./site-maps.mjs";
|
|
|
31
31
|
export * as systems from "./systems.mjs";
|
|
32
32
|
export * as calendars from "./calendars.mjs";
|
|
33
33
|
export * as noteDates from "./note-dates.mjs";
|
|
34
|
+
export * as reckoningMarkers from "./reckoning-markers.mjs";
|
|
34
35
|
export * as calendarNotes from "./calendar-notes.mjs";
|
|
36
|
+
export * as calendarArtifacts from "./calendar-artifacts.mjs";
|
|
35
37
|
export * as beingAge from "./being-age.mjs";
|
|
36
38
|
export * as contentSlug from "./content-slug.mjs";
|
|
37
39
|
export * as contentAddress from "./content-address.mjs";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** GraphViz's plain coordinates, converted to pixel positions on its PNG. */
|
|
2
|
+
export function pinPositions(plain: any, width: any, height: any): Map<any, any>;
|
|
3
|
+
/**
|
|
4
|
+
* Emit backgrounds into the staged package and return Scenes and the journals
|
|
5
|
+
* their pins need. The caller writes them into its Scene and Adventure packs.
|
|
6
|
+
*/
|
|
7
|
+
export function buildItineraryScenes({ config, records, contentBase, journalSourceDirs, stats, foreign, }: {
|
|
8
|
+
config: any;
|
|
9
|
+
records: any;
|
|
10
|
+
contentBase: any;
|
|
11
|
+
journalSourceDirs?: never[] | undefined;
|
|
12
|
+
stats: any;
|
|
13
|
+
foreign?: {
|
|
14
|
+
index: Map<string, object>;
|
|
15
|
+
packages: Set<string>;
|
|
16
|
+
stale: Array<{
|
|
17
|
+
package: string;
|
|
18
|
+
reason: string;
|
|
19
|
+
}>;
|
|
20
|
+
} | undefined;
|
|
21
|
+
}): {
|
|
22
|
+
scenes: object[];
|
|
23
|
+
journal: any[];
|
|
24
|
+
findings: {
|
|
25
|
+
file: any;
|
|
26
|
+
severity: string;
|
|
27
|
+
message: string;
|
|
28
|
+
}[];
|
|
29
|
+
};
|
|
@@ -30,19 +30,13 @@ export function relatedPlaces(places: Map<string, import("./map-places.mjs").Map
|
|
|
30
30
|
* @param {number} [opts.ranksep] - The tree's `ranksep`, inches.
|
|
31
31
|
* @param {number} [opts.scale=1] - Multiplies every node's size and font.
|
|
32
32
|
* @param {boolean} [opts.polities=true] - Whether the tree draws polities.
|
|
33
|
-
* @param {(engine: string) => string|undefined} [opts.locate] - How a GraphViz
|
|
34
|
-
* engine's binary is found; the real lookup by default.
|
|
35
|
-
* @param {boolean} [opts.requireGraphviz=true] - Whether a missing engine is
|
|
36
|
-
* an error. False, the `.dot` files are written, the renderings skipped,
|
|
37
|
-
* and one warning returned.
|
|
38
33
|
* @returns {{written: string[], findings: Array<{file: string, line?: number,
|
|
39
|
-
* column?: number, severity: "error"|"warning", message: string}
|
|
40
|
-
*
|
|
41
|
-
* rendering was skipped for want of GraphViz.
|
|
34
|
+
* column?: number, severity: "error"|"warning", message: string}>}} What was
|
|
35
|
+
* written and what was found.
|
|
42
36
|
* @throws {Error} When no mode is asked for, a named place is not one, the
|
|
43
|
-
* horizon is not a marker of the scale
|
|
37
|
+
* horizon is not a marker of the scale.
|
|
44
38
|
*/
|
|
45
|
-
export function buildMaps({ world, outDir, tree, root, from, chart, horizon, travel, engine, rankdir, nodesep, ranksep, scale, polities,
|
|
39
|
+
export function buildMaps({ world, outDir, tree, root, from, chart, horizon, travel, engine, rankdir, nodesep, ranksep, scale, polities, }: {
|
|
46
40
|
world: import("./map-places.mjs").MapWorld;
|
|
47
41
|
outDir: string;
|
|
48
42
|
tree?: boolean | undefined;
|
|
@@ -57,8 +51,6 @@ export function buildMaps({ world, outDir, tree, root, from, chart, horizon, tra
|
|
|
57
51
|
ranksep?: number | undefined;
|
|
58
52
|
scale?: number | undefined;
|
|
59
53
|
polities?: boolean | undefined;
|
|
60
|
-
locate?: ((engine: string) => string | undefined) | undefined;
|
|
61
|
-
requireGraphviz?: boolean | undefined;
|
|
62
54
|
}): {
|
|
63
55
|
written: string[];
|
|
64
56
|
findings: Array<{
|
|
@@ -68,7 +60,6 @@ export function buildMaps({ world, outDir, tree, root, from, chart, horizon, tra
|
|
|
68
60
|
severity: "error" | "warning";
|
|
69
61
|
message: string;
|
|
70
62
|
}>;
|
|
71
|
-
skipped: boolean;
|
|
72
63
|
};
|
|
73
64
|
/**
|
|
74
65
|
* The directory the maps land in, below a package's root.
|
|
@@ -1,68 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Render a DOT source file to SVG, plain positions, or a PNG background.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* business.
|
|
4
|
+
* A PNG uses the same Graphviz SVG layout as the vector map. SVG dimensions
|
|
5
|
+
* are in points; resvg starts at 96 pixels per inch, so the zoom converts
|
|
6
|
+
* the requested DPI to the same physical size as Graphviz's PNG output.
|
|
8
7
|
*
|
|
9
|
-
* @param {string}
|
|
10
|
-
* @param {
|
|
11
|
-
* @param {Record<string, string|undefined>} [opts.env] - The environment to
|
|
12
|
-
* read `PATH` from, defaulting to the process's.
|
|
13
|
-
* @param {readonly string[]} [opts.fallbacks] - The directories tried after
|
|
14
|
-
* `PATH`, defaulting to the package managers' ones.
|
|
15
|
-
* @returns {string|undefined} The binary, or `undefined` when none is found.
|
|
16
|
-
* @throws {Error} When `engine` is not a GraphViz engine this command uses.
|
|
17
|
-
*/
|
|
18
|
-
export function findGraphviz(engine: string, { env, fallbacks }?: {
|
|
19
|
-
env?: Record<string, string | undefined> | undefined;
|
|
20
|
-
fallbacks?: readonly string[] | undefined;
|
|
21
|
-
}): string | undefined;
|
|
22
|
-
/**
|
|
23
|
-
* What to say when an engine is not installed: the name, and what installs
|
|
24
|
-
* it.
|
|
25
|
-
*
|
|
26
|
-
* @param {string} engine - The engine that was wanted.
|
|
27
|
-
* @returns {string} The message.
|
|
28
|
-
*/
|
|
29
|
-
export function graphvizMissingMessage(engine: string): string;
|
|
30
|
-
/**
|
|
31
|
-
* Render a `.dot` file with a GraphViz engine.
|
|
32
|
-
*
|
|
33
|
-
* The engine is run over the file rather than fed the text, so the file the
|
|
34
|
-
* command keeps is exactly what was drawn. Warnings GraphViz prints — an
|
|
35
|
-
* unknown font, an overlapping label — are returned rather than swallowed,
|
|
36
|
-
* and a non-zero exit is an error naming the file.
|
|
37
|
-
*
|
|
38
|
-
* @param {string} dotPath - The `.dot` file.
|
|
39
|
-
* @param {string} outPath - Where to write the rendering.
|
|
8
|
+
* @param {string} dotPath - The saved DOT source.
|
|
9
|
+
* @param {string} outPath - The output file.
|
|
40
10
|
* @param {object} opts
|
|
41
|
-
* @param {
|
|
42
|
-
* @param {
|
|
43
|
-
* @param {
|
|
44
|
-
* @
|
|
45
|
-
* @
|
|
11
|
+
* @param {"dot"|"twopi"|"neato"} opts.engine - Layout engine.
|
|
12
|
+
* @param {"svg"|"plain"|"png"} [opts.format="svg"] - Output format.
|
|
13
|
+
* @param {2} [opts.nop] - Preserve positioned nodes as `neato -n2` does.
|
|
14
|
+
* @param {number} [opts.dpi=96] - PNG resolution.
|
|
15
|
+
* @returns {{warnings: string}} Renderer warnings.
|
|
46
16
|
*/
|
|
47
|
-
export function renderDot(dotPath: string, outPath: string, {
|
|
48
|
-
|
|
49
|
-
format?:
|
|
50
|
-
|
|
17
|
+
export function renderDot(dotPath: string, outPath: string, { engine, format, nop, dpi }: {
|
|
18
|
+
engine: "dot" | "twopi" | "neato";
|
|
19
|
+
format?: "svg" | "plain" | "png" | undefined;
|
|
20
|
+
nop?: 2 | undefined;
|
|
21
|
+
dpi?: number | undefined;
|
|
51
22
|
}): {
|
|
52
23
|
warnings: string;
|
|
53
24
|
};
|
|
54
|
-
/**
|
|
55
|
-
* The layout engines the map command may ask for. `dot` draws a tree by
|
|
56
|
-
* rank, `twopi` the same tree radially, `neato` a graph by its edge lengths —
|
|
57
|
-
* and, with every node pinned, the map from a place.
|
|
58
|
-
*
|
|
59
|
-
* @type {readonly string[]}
|
|
60
|
-
*/
|
|
25
|
+
/** The layout engines accepted by the map command. */
|
|
61
26
|
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;
|
|
@@ -214,9 +214,13 @@ export type MapWorld = {
|
|
|
214
214
|
*/
|
|
215
215
|
export type Containment = {
|
|
216
216
|
/**
|
|
217
|
-
* - The one
|
|
217
|
+
* - The world when exactly one is present.
|
|
218
218
|
*/
|
|
219
219
|
world: string | undefined;
|
|
220
|
+
/**
|
|
221
|
+
* - Every `subType: world` place, sorted.
|
|
222
|
+
*/
|
|
223
|
+
worlds: string[];
|
|
220
224
|
/**
|
|
221
225
|
* - Regions parented directly on the world,
|
|
222
226
|
* in name order.
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
* the value is written in, as its note declares it. Its ordered month list
|
|
19
19
|
* bounds a written month and a written day, the day against the length of
|
|
20
20
|
* the month it names. A calendar that declares no list bounds nothing.
|
|
21
|
+
* @param {Map<string, object>} [options.markers] - Resolved era markers from
|
|
22
|
+
* the corpus, each carrying its calendar and canonical start.
|
|
23
|
+
* @param {number} [options.daysPerYear] - The world's year length, required for
|
|
24
|
+
* canonical days and marked dates.
|
|
21
25
|
* @param {string} [options.field] - The key that carried it, named in every
|
|
22
26
|
* message. Omitted, a message names the value alone.
|
|
23
27
|
* @param {boolean} [options.allowUnknown=true] - Whether `"unknown"` is a
|
|
@@ -34,6 +38,8 @@ export function parseNoteDate(value: unknown, options?: {
|
|
|
34
38
|
calendar?: {
|
|
35
39
|
months?: readonly object[] | null;
|
|
36
40
|
} | undefined;
|
|
41
|
+
markers?: Map<string, object> | undefined;
|
|
42
|
+
daysPerYear?: number | undefined;
|
|
37
43
|
field?: string | undefined;
|
|
38
44
|
allowUnknown?: boolean | undefined;
|
|
39
45
|
file?: string | undefined;
|
|
@@ -278,15 +278,15 @@ export type DataFieldSpec = {
|
|
|
278
278
|
* value — which is the honest answer wherever the specification's stated
|
|
279
279
|
* shape and the shape notes are authored in today disagree.
|
|
280
280
|
*/
|
|
281
|
-
kind?: "string" | "number" | "boolean" | "map" | "list" | "shortcode" | "scalar-or-map" |
|
|
281
|
+
kind?: "string" | "number" | "boolean" | "map" | "address" | "list" | "shortcode" | "scalar-or-map" | undefined;
|
|
282
282
|
/**
|
|
283
283
|
* - Type of each list or pack-map value.
|
|
284
284
|
*/
|
|
285
|
-
entryKind?: "
|
|
285
|
+
entryKind?: "address" | "shortcode" | undefined;
|
|
286
286
|
/**
|
|
287
287
|
* - Type of each map key.
|
|
288
288
|
*/
|
|
289
|
-
keyKind?: "
|
|
289
|
+
keyKind?: "address" | "shortcode" | undefined;
|
|
290
290
|
/**
|
|
291
291
|
* - An alternative `subType:<skill-subtype>` key.
|
|
292
292
|
*/
|
|
@@ -209,9 +209,11 @@ export function bookTypstPreamble(): string;
|
|
|
209
209
|
* declared it → the staged file's path, relative to the `.typ`. A declared
|
|
210
210
|
* banner this map does not carry has no file the compiler can open, so the
|
|
211
211
|
* plate draws without a picture.
|
|
212
|
+
* @param {Map<string, {path: string, title: string}>} [opts.maps] - An entry
|
|
213
|
+
* anchor to its SVG path and page heading. Each map takes a page after its entry.
|
|
212
214
|
* @returns {string} A complete `.typ` document.
|
|
213
215
|
*/
|
|
214
|
-
export function renderBook({ plan, bodies, title, subtitle, front, fonts, version, preamble, banners, }?: {
|
|
216
|
+
export function renderBook({ plan, bodies, title, subtitle, front, fonts, version, preamble, banners, maps, }?: {
|
|
215
217
|
plan: object;
|
|
216
218
|
bodies: Map<string, string>;
|
|
217
219
|
title: string;
|
|
@@ -221,6 +223,10 @@ export function renderBook({ plan, bodies, title, subtitle, front, fonts, versio
|
|
|
221
223
|
version?: string | undefined;
|
|
222
224
|
preamble?: string | undefined;
|
|
223
225
|
banners?: Map<string, string> | undefined;
|
|
226
|
+
maps?: Map<string, {
|
|
227
|
+
path: string;
|
|
228
|
+
title: string;
|
|
229
|
+
}> | undefined;
|
|
224
230
|
}): string;
|
|
225
231
|
/**
|
|
226
232
|
* Point every internal link at a label the document actually declares.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve every declared reckoning marker against its calendar and era start.
|
|
3
|
+
* The marker names one era, while the calendar supplies the month layout.
|
|
4
|
+
*
|
|
5
|
+
* @param {{notes?: readonly object[]}} index - The corpus link index.
|
|
6
|
+
* @param {number} daysPerYear - The world's year length.
|
|
7
|
+
* @returns {{markers: Map<string, object>, findings: object[]}} Resolved markers and errors.
|
|
8
|
+
*/
|
|
9
|
+
export function resolveReckoningMarkers(index: {
|
|
10
|
+
notes?: readonly object[];
|
|
11
|
+
}, daysPerYear: number): {
|
|
12
|
+
markers: Map<string, object>;
|
|
13
|
+
findings: object[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Read the world's year length and its era markers from one corpus index.
|
|
17
|
+
*
|
|
18
|
+
* @param {{notes?: readonly object[]}|undefined} index - The corpus index.
|
|
19
|
+
* @returns {{markers: Map<string, object>, daysPerYear: number|undefined, findings: object[]}}
|
|
20
|
+
*/
|
|
21
|
+
export function reckoningContext(index: {
|
|
22
|
+
notes?: readonly object[];
|
|
23
|
+
} | undefined): {
|
|
24
|
+
markers: Map<string, object>;
|
|
25
|
+
daysPerYear: number | undefined;
|
|
26
|
+
findings: object[];
|
|
27
|
+
};
|