@heroiclands/package-build 22.4.5 → 22.4.6
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 +6 -0
- package/bin/content-build.mjs +26 -6
- package/docs/api.md +36 -32
- package/docs/commands.md +64 -24
- package/engine/map-build.mjs +41 -11
- package/engine/map-dot.mjs +84 -24
- package/engine/map-layout.mjs +283 -101
- package/package.json +1 -1
- package/types/engine/map-build.d.mts +13 -7
- package/types/engine/map-dot.d.mts +22 -9
- package/types/engine/map-layout.d.mts +117 -49
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @heroiclands/package-build
|
|
2
2
|
|
|
3
|
+
## 22.4.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
`content-build map --chart <shortcode>` draws the chart from a place: the map from it at a larger horizon, north up, the hops chaining on as long as none turns back, each place on the ring of its summed days and each hop beyond the neighbours drawn fainter. `--horizon <days>` sets how far the rings reach, a year by default, and a place farther than that is left out.
|
|
8
|
+
|
|
3
9
|
## 22.4.5
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/bin/content-build.mjs
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
* npx content-build markdown [paths..] [--fix]
|
|
48
48
|
* npx content-build manifest [root] [--out <dir>]
|
|
49
49
|
* npx content-build site [--out <dir>]
|
|
50
|
-
* npx content-build map [--tree] [--from <shortcode>] [--travel] [--out <dir>]
|
|
50
|
+
* npx content-build map [--tree] [--from <shortcode>] [--chart <shortcode>] [--travel] [--out <dir>]
|
|
51
51
|
* npx content-build reachability <dir> [file] [--index <shortcode>]
|
|
52
52
|
* npx content-build addresses diff --from <zip|dir> [--strict]
|
|
53
53
|
*
|
|
@@ -146,6 +146,7 @@ import {
|
|
|
146
146
|
} from "../engine/address-diff.mjs";
|
|
147
147
|
import { emittedArtFor, itemPackJsonDirs } from "../engine/generate.mjs";
|
|
148
148
|
import { buildMaps, FROM_ALL, MAP_DIR } from "../engine/map-build.mjs";
|
|
149
|
+
import { CHART_HORIZON_DAYS } from "../engine/map-layout.mjs";
|
|
149
150
|
import { GRAPHVIZ_ENGINES } from "../engine/map-graphviz.mjs";
|
|
150
151
|
import { loadMapWorld } from "../engine/map-places.mjs";
|
|
151
152
|
|
|
@@ -1673,12 +1674,13 @@ function siteCommand() {
|
|
|
1673
1674
|
*
|
|
1674
1675
|
* Reads the content index — this package's and every declared dependency's —
|
|
1675
1676
|
* so a consumer's map draws its dependencies' places beside its own, and
|
|
1676
|
-
* writes under `build/map/`, always the `.dot` beside the `.svg`.
|
|
1677
|
+
* writes under `build/map/`, always the `.dot` beside the `.svg`. Four
|
|
1677
1678
|
* drawings: the containment tree from `parents` (`--tree`, the author's
|
|
1678
1679
|
* check, whose anomalies are reported as findings), the map from a place
|
|
1679
|
-
* from its `borders` and `routes` (`--from`),
|
|
1680
|
-
*
|
|
1681
|
-
*
|
|
1680
|
+
* from its `borders` and `routes` (`--from`), the chart from a place — the
|
|
1681
|
+
* same drawing at a larger horizon (`--chart`, `--horizon`) — and the whole
|
|
1682
|
+
* route graph (`--travel`). GraphViz draws; when it is absent the command
|
|
1683
|
+
* says what to install and stops.
|
|
1682
1684
|
*
|
|
1683
1685
|
* @returns {object} The yargs command module.
|
|
1684
1686
|
*/
|
|
@@ -1686,7 +1688,8 @@ function siteCommand() {
|
|
|
1686
1688
|
function mapCommand() {
|
|
1687
1689
|
return {
|
|
1688
1690
|
command: "map",
|
|
1689
|
-
describe:
|
|
1691
|
+
describe:
|
|
1692
|
+
"Draw the containment tree, the map or the chart from a place, or the route graph",
|
|
1690
1693
|
builder: (yargs) => {
|
|
1691
1694
|
yargs
|
|
1692
1695
|
.option("tree", {
|
|
@@ -1709,6 +1712,21 @@ function mapCommand() {
|
|
|
1709
1712
|
type: "string",
|
|
1710
1713
|
array: true,
|
|
1711
1714
|
})
|
|
1715
|
+
.option("chart", {
|
|
1716
|
+
describe:
|
|
1717
|
+
"Draw the chart from this place as `chart-<shortcode>.svg` — the map " +
|
|
1718
|
+
"from it at a larger horizon, the hops chaining on; repeatable, " +
|
|
1719
|
+
`or \`${FROM_ALL}\` for every place with a border or a route.`,
|
|
1720
|
+
type: "string",
|
|
1721
|
+
array: true,
|
|
1722
|
+
})
|
|
1723
|
+
.option("horizon", {
|
|
1724
|
+
describe:
|
|
1725
|
+
"The charts' horizon in days, a marker of the scale: rings are " +
|
|
1726
|
+
"drawn to it, and a place farther than it is left out.",
|
|
1727
|
+
type: "number",
|
|
1728
|
+
default: CHART_HORIZON_DAYS,
|
|
1729
|
+
})
|
|
1712
1730
|
.option("travel", {
|
|
1713
1731
|
describe: "Draw the whole route graph as `travel.svg`.",
|
|
1714
1732
|
type: "boolean",
|
|
@@ -1783,6 +1801,8 @@ function mapCommand() {
|
|
|
1783
1801
|
tree: argv.tree,
|
|
1784
1802
|
root: argv.root,
|
|
1785
1803
|
from: argv.from ?? [],
|
|
1804
|
+
chart: argv.chart ?? [],
|
|
1805
|
+
horizon: argv.horizon,
|
|
1786
1806
|
travel: argv.travel,
|
|
1787
1807
|
engine: argv.engine,
|
|
1788
1808
|
rankdir: argv.rankdir,
|
package/docs/api.md
CHANGED
|
@@ -443,36 +443,40 @@ The places a map is drawn from — this package's index records and every fetche
|
|
|
443
443
|
|
|
444
444
|
### `engine.mapLayout`
|
|
445
445
|
|
|
446
|
-
The geometry of the map from a place, as arithmetic over the place records: north up, east right, the angle from the bearing and the radius from the days marker on log-spaced rings,
|
|
447
|
-
|
|
448
|
-
| Export
|
|
449
|
-
|
|
|
450
|
-
| `HORIZON_DAYS`
|
|
451
|
-
| `
|
|
452
|
-
| `
|
|
453
|
-
| `
|
|
454
|
-
| `
|
|
455
|
-
| `
|
|
456
|
-
| `
|
|
457
|
-
| `
|
|
458
|
-
| `
|
|
459
|
-
| `
|
|
460
|
-
| `
|
|
461
|
-
| `
|
|
462
|
-
| `
|
|
463
|
-
| `
|
|
446
|
+
The geometry of the map from a place and of the chart from one, as arithmetic over the place records: north up, east right, the angle from the bearing and the radius from the days marker on log-spaced rings, hops composed into one bearing as long as none turns back. Nothing here touches a file or GraphViz.
|
|
447
|
+
|
|
448
|
+
| Export | Signature | Returns | Use it when |
|
|
449
|
+
| -------------------- | ------------------------------------------ | ------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
450
|
+
| `HORIZON_DAYS` | `const HORIZON_DAYS` | `number` | the horizon of the map from a place, 90 days; beyond it a place is a name at the rim |
|
|
451
|
+
| `CHART_HORIZON_DAYS` | `const CHART_HORIZON_DAYS` | `number` | the horizon of the chart from a place when none is asked for, 360 days — the end of the scale |
|
|
452
|
+
| `RING_DAYS` | `const RING_DAYS` | `readonly number[]` | the days markers that are rings on the map from a place — every marker up to its horizon |
|
|
453
|
+
| `bearingAngle` | `bearingAngle(bearing)` | `number\|undefined` | the angle of a bearing in degrees counter-clockwise from east — `N` is 90, `E` 0 |
|
|
454
|
+
| `bearingVector` | `bearingVector(bearing)` | `{x, y}\|undefined` | the unit vector of a bearing |
|
|
455
|
+
| `bearingSteps` | `bearingSteps(a, b)` | `number\|undefined` | how many steps around the compass separate two bearings, the shorter way |
|
|
456
|
+
| `rimRadius` | `rimRadius(horizon?)` | `number` | the radius of the rim, one log step beyond the horizon — the map from a place's by default |
|
|
457
|
+
| `ringRadius` | `ringRadius(days, horizon?)` | `number` | the radius of the ring a days value sits on — the rim for none, or for a value beyond the horizon |
|
|
458
|
+
| `rings` | `rings(horizon?)` | `object[]` | the rings inside out, each marker up to the horizon with its radius |
|
|
459
|
+
| `daysMarker` | `daysMarker(total)` | `number\|undefined` | the smallest marker of the scale that covers a total of days |
|
|
460
|
+
| `edgeLength` | `edgeLength(days)` | `number` | the length a route asks of `neato` in the route graph, inches, on the rings' log scale |
|
|
461
|
+
| `composeChain` | `composeChain(hops)` | `object\|undefined` | a chain of hops composed into one bearing and one total, each hop within an octant of the running direction, else `undefined` |
|
|
462
|
+
| `composeHops` | `composeHops(first, second)` | `object\|undefined` | two hops composed into one bearing and one total where they agree — the same bearing or adjacent — else `undefined` |
|
|
463
|
+
| `relationsOf` | `relationsOf(places, shortcode)` | `object` | every border and route touching one place, read from both ends, plus the targets that resolved to nothing |
|
|
464
|
+
| `layoutFrom` | `layoutFrom(places, centre)` | `object` | laying out the map from a place: every node pinned in points, every edge, the rings and the rim |
|
|
465
|
+
| `layoutChart` | `layoutChart(places, centre, { horizon })` | `object` | laying out the chart from a place: the map from it at a larger horizon, the hops chaining on as long as none turns back |
|
|
466
|
+
| `travelGraph` | `travelGraph(places)` | `object` | the whole route graph — one edge per pair, however many ends and modes state it, each with a length from its days |
|
|
464
467
|
|
|
465
468
|
### `engine.mapDot`
|
|
466
469
|
|
|
467
|
-
The
|
|
470
|
+
The drawings of `content-build map` as DOT text, sharing one style table: shape, colour and size by `subType`, an anomaly overriding colour alone, every label a `name.full`, every tooltip an address, and a `URL` where the place carries one so the SVG's names are links.
|
|
468
471
|
|
|
469
|
-
| Export
|
|
470
|
-
|
|
|
471
|
-
| `STYLE`
|
|
472
|
-
| `dotString`
|
|
473
|
-
| `treeDot`
|
|
474
|
-
| `
|
|
475
|
-
| `
|
|
472
|
+
| Export | Signature | Returns | Use it when |
|
|
473
|
+
| ------------ | -------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
474
|
+
| `STYLE` | `const STYLE` | — | the shape, colour and size of each `subType`, and of a polity |
|
|
475
|
+
| `dotString` | `dotString(value)` | `string` | quoting text for DOT |
|
|
476
|
+
| `treeDot` | `treeDot({ places, polities, analysis, root, … })` | `string` | the containment tree — the whole world clustered by continent, or the subtree beneath `root` |
|
|
477
|
+
| `hopOpacity` | `hopOpacity(hop)` | `number` | how faint a place is drawn by its hop count — full to the second hop, a step down each hop beyond, floored |
|
|
478
|
+
| `fromDot` | `fromDot(layout, places, { scale, title })` | `string` | the map or the chart from a place, every node pinned for `neato -n2`, the rings drawn faintly with their markers |
|
|
479
|
+
| `travelDot` | `travelDot(graph, places, { scale, title })` | `string` | the whole route graph for `neato`, each edge asking for a length from its days |
|
|
476
480
|
|
|
477
481
|
### `engine.mapGraphviz`
|
|
478
482
|
|
|
@@ -489,12 +493,12 @@ GraphViz, as the map command reaches it: a build-time tool of that command alone
|
|
|
489
493
|
|
|
490
494
|
`content-build map` as a function: the drawings written under an output directory, always the `.dot` beside the `.svg`, the tree's anomalies returned as findings, and a missing GraphViz either an error or — for a build that would rather skip — one warning.
|
|
491
495
|
|
|
492
|
-
| Export | Signature
|
|
493
|
-
| --------------- |
|
|
494
|
-
| `MAP_DIR` | `const MAP_DIR`
|
|
495
|
-
| `FROM_ALL` | `const FROM_ALL`
|
|
496
|
-
| `relatedPlaces` | `relatedPlaces(places)`
|
|
497
|
-
| `buildMaps` | `buildMaps({ world, outDir, tree, root, from, travel, engine, rankdir, nodesep, ranksep, scale, polities, locate, requireGraphviz })` | `{written, findings, skipped}` | drawing any of the
|
|
496
|
+
| Export | Signature | Returns | Use it when |
|
|
497
|
+
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | ----------------------------------------------------------------------------- |
|
|
498
|
+
| `MAP_DIR` | `const MAP_DIR` | `string` | where the maps land below a package's root, `build/map` |
|
|
499
|
+
| `FROM_ALL` | `const FROM_ALL` | `string` | the `--from` or `--chart` value that means every place with a relation, `all` |
|
|
500
|
+
| `relatedPlaces` | `relatedPlaces(places)` | `string[]` | every place that states, or is named in, a border or a route |
|
|
501
|
+
| `buildMaps` | `buildMaps({ world, outDir, tree, root, from, chart, horizon, travel, engine, rankdir, nodesep, ranksep, scale, polities, locate, requireGraphviz })` | `{written, findings, skipped}` | drawing any of the four from a loaded world |
|
|
498
502
|
|
|
499
503
|
### `engine.systems`
|
|
500
504
|
|
package/docs/commands.md
CHANGED
|
@@ -1864,7 +1864,8 @@ demo-book: error: the document tree named by `pdf.document` cannot be read
|
|
|
1864
1864
|
|
|
1865
1865
|
**NAME**
|
|
1866
1866
|
|
|
1867
|
-
Draw the containment tree, the map from a place, or the whole
|
|
1867
|
+
Draw the containment tree, the map or the chart from a place, or the whole
|
|
1868
|
+
route graph.
|
|
1868
1869
|
|
|
1869
1870
|
**SYNOPSIS**
|
|
1870
1871
|
|
|
@@ -1872,6 +1873,7 @@ Draw the containment tree, the map from a place, or the whole route graph.
|
|
|
1872
1873
|
content-build map --tree [--root <shortcode>] [--engine dot|twopi|neato] [--rankdir TB|LR|BT|RL]
|
|
1873
1874
|
[--nodesep <inches>] [--ranksep <inches>] [--no-polities]
|
|
1874
1875
|
content-build map --from <shortcode>.. | --from all
|
|
1876
|
+
content-build map --chart <shortcode>.. | --chart all [--horizon <days>]
|
|
1875
1877
|
content-build map --travel
|
|
1876
1878
|
content-build map [...] [--scale <factor>] [--base <url>] [--out <dir>]
|
|
1877
1879
|
```
|
|
@@ -1884,14 +1886,13 @@ index — so a consumer's map draws its dependencies' places beside its own
|
|
|
1884
1886
|
and no note is opened except to locate a finding. Everything lands under
|
|
1885
1887
|
`build/map/`, always the `.dot` beside the `.svg`, so a drawing can be
|
|
1886
1888
|
re-rendered, diffed or read without the index. GraphViz draws: `dot` (or
|
|
1887
|
-
`twopi`, `neato`) for the tree, `neato` for the
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
failing.
|
|
1889
|
+
`twopi`, `neato`) for the tree, `neato` for the others. It is a build-time
|
|
1890
|
+
tool of this command alone; when the engine a run needs is not installed
|
|
1891
|
+
the command says so, names what to install, and stops. A build that asks
|
|
1892
|
+
for maps as one step of a larger job — a site build — writes the `.dot`
|
|
1893
|
+
files, emits one warning and skips the renderings rather than failing.
|
|
1893
1894
|
|
|
1894
|
-
The
|
|
1895
|
+
The four drawings, any of which may be asked for in one run:
|
|
1895
1896
|
|
|
1896
1897
|
**`--tree`** — the author's check. The containment tree from `data.parents`,
|
|
1897
1898
|
edges running child → parent, clustered by continent — a `region` parented
|
|
@@ -1950,6 +1951,39 @@ sailor's chart, a tax survey, partial and from somewhere, whose prose says
|
|
|
1950
1951
|
whose it is — and never the survey. The two are two sources of the same
|
|
1951
1952
|
thing on a place's page.
|
|
1952
1953
|
|
|
1954
|
+
**`--chart <shortcode>`** — the chart from a place, `chart-<shortcode>.svg`:
|
|
1955
|
+
the world-scale drawing chosen by viewpoint rather than projection — the
|
|
1956
|
+
sea from a port, the eastern roads from a caravan city. It is the same
|
|
1957
|
+
graph from the same place with a larger horizon: the centre pinned, north
|
|
1958
|
+
up and east right, the neighbours exactly as `--from` draws them, and
|
|
1959
|
+
beyond them the hops chaining on. Hops compose as a running vector sum
|
|
1960
|
+
weighted by their days, and a hop is accepted when its bearing lies within
|
|
1961
|
+
one octant — 45° either way — of the **running composed direction** at
|
|
1962
|
+
that point, not of the previous hop; so a path may bend a little at every
|
|
1963
|
+
hop, but never turn back, and a place reached only through a hop that
|
|
1964
|
+
turns back is omitted. Where several chains reach one place, the one with
|
|
1965
|
+
the fewest total days is drawn. The total is the sum of the hops' days,
|
|
1966
|
+
placed on the ring of the smallest marker not less than it. A border
|
|
1967
|
+
carries no days: on the first hop it sits on the innermost ring, as on the
|
|
1968
|
+
map from a place; beyond the first hop it makes the total unknown, the
|
|
1969
|
+
place goes to the rim marked unknown, and the chart states nothing beyond
|
|
1970
|
+
it. `all` draws the chart from every place that states or is named in a
|
|
1971
|
+
border or a route.
|
|
1972
|
+
|
|
1973
|
+
_The horizon._ `--horizon <days>`, a marker of the scale, `360` by default:
|
|
1974
|
+
one ring per marker up to and including it, on the same log spacing as the
|
|
1975
|
+
map from a place, so a chart to a year's travel is simply a larger page
|
|
1976
|
+
with more rings. A place whose total exceeds the horizon is omitted — the
|
|
1977
|
+
chart is already the larger view, and there is no "beyond" rim, only the
|
|
1978
|
+
unknown one, a log step past the horizon. `--horizon` applies to charts
|
|
1979
|
+
alone; the map from a place keeps its horizon of 90 days and its rim.
|
|
1980
|
+
|
|
1981
|
+
_The dimming._ The neighbours are drawn full, the second hop as the map
|
|
1982
|
+
from a place draws it — grey border and label, pale fill, faint edge —
|
|
1983
|
+
and each hop beyond a step fainter, never below half opacity, so the
|
|
1984
|
+
farthest place still reads. An edge is dimmed with its far end, and
|
|
1985
|
+
labelled with its bearing and days like any other.
|
|
1986
|
+
|
|
1953
1987
|
**`--travel`** — the whole route graph, `travel.svg`, for the author: one
|
|
1954
1988
|
undirected edge per pair of places, a border dashed, each route asking
|
|
1955
1989
|
`neato` for a length on the same log scale as the rings so the god's-eye
|
|
@@ -1964,25 +1998,28 @@ page can inline the SVG. Without it the names are plain text.
|
|
|
1964
1998
|
|
|
1965
1999
|
**OPTIONS**
|
|
1966
2000
|
|
|
1967
|
-
| Option | Type | Default | Description
|
|
1968
|
-
| ------------ | ------- | ------------ |
|
|
1969
|
-
| `--tree` | boolean | `false` | Draw the containment tree: `tree.svg`, one `tree-<shortcode>.svg` per continent, and the findings.
|
|
1970
|
-
| `--root` | string | — | With `--tree`, draw the subtree beneath this place as `tree-<shortcode>.svg` and report nothing.
|
|
1971
|
-
| `--from` | string | — | Draw the map from this place as `from-<shortcode>.svg`; repeatable, or `all` for every place with a border or a route.
|
|
1972
|
-
| `--
|
|
1973
|
-
| `--
|
|
1974
|
-
| `--
|
|
1975
|
-
| `--
|
|
1976
|
-
| `--
|
|
1977
|
-
| `--
|
|
1978
|
-
| `--
|
|
1979
|
-
| `--
|
|
1980
|
-
| `--
|
|
2001
|
+
| Option | Type | Default | Description |
|
|
2002
|
+
| ------------ | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
2003
|
+
| `--tree` | boolean | `false` | Draw the containment tree: `tree.svg`, one `tree-<shortcode>.svg` per continent, and the findings. |
|
|
2004
|
+
| `--root` | string | — | With `--tree`, draw the subtree beneath this place as `tree-<shortcode>.svg` and report nothing. |
|
|
2005
|
+
| `--from` | string | — | Draw the map from this place as `from-<shortcode>.svg`; repeatable, or `all` for every place with a border or a route. |
|
|
2006
|
+
| `--chart` | string | — | Draw the chart from this place as `chart-<shortcode>.svg` — the map from it at a larger horizon; repeatable, or `all`. |
|
|
2007
|
+
| `--horizon` | number | `360` | The charts' horizon in days, a marker of the scale: rings are drawn to it, and a place farther than it is left out. |
|
|
2008
|
+
| `--travel` | boolean | `false` | Draw the whole route graph as `travel.svg`. |
|
|
2009
|
+
| `--engine` | choice | `dot` | The tree's layout engine — `dot`, `twopi` (radial, rooted on the world or the `--root`) or `neato`. The other drawings are always `neato`. |
|
|
2010
|
+
| `--rankdir` | choice | `TB` | The tree's rank direction — `TB`, `LR`, `BT` or `RL`; `dot` engine only. |
|
|
2011
|
+
| `--nodesep` | number | by `--scale` | The tree's GraphViz `nodesep`, in inches. |
|
|
2012
|
+
| `--ranksep` | number | by engine | The tree's GraphViz `ranksep`, in inches. |
|
|
2013
|
+
| `--scale` | number | `1` | Multiply every node's width, height, font size and border weight, the legend's included. |
|
|
2014
|
+
| `--polities` | boolean | `true` | Draw polities beside their regions in the tree. `--no-polities` drops them. |
|
|
2015
|
+
| `--base` | string | — | The site base this package's pages are served under, ending in a slash; given, every name is a link to its page. |
|
|
2016
|
+
| `--out` | string | `build/map` | Directory to write into, relative to the working directory. |
|
|
1981
2017
|
|
|
1982
2018
|
**EXIT STATUS**
|
|
1983
2019
|
|
|
1984
|
-
1 when no drawing is asked for, when a `--from` or `--root`
|
|
1985
|
-
place, when
|
|
2020
|
+
1 when no drawing is asked for, when a `--from`, `--chart` or `--root`
|
|
2021
|
+
names no place, when `--horizon` is not a marker of the days scale, when
|
|
2022
|
+
the GraphViz engine a drawing needs is not installed, when a
|
|
1986
2023
|
dependency's index cannot be read, when a note the index cannot record is
|
|
1987
2024
|
met, on any error finding from `--tree` (a place with no parent, a parent
|
|
1988
2025
|
that does not resolve, a cycle), or on any other thrown error. Otherwise 0
|
|
@@ -1999,6 +2036,9 @@ assets/content/Regions/Marches/Lost_Fort.md:9:14: error: place "lostfort" names
|
|
|
1999
2036
|
$ content-build map --from dunharargn --base /thalorna/
|
|
2000
2037
|
[…] 394 place(s) → 1 drawing(s) under build/map
|
|
2001
2038
|
|
|
2039
|
+
$ content-build map --chart takheperurgn --horizon 90
|
|
2040
|
+
[…] 394 place(s) → 1 drawing(s) under build/map
|
|
2041
|
+
|
|
2002
2042
|
$ content-build map --travel
|
|
2003
2043
|
[…] GraphViz's `neato` is not installed, and `content-build map` draws with it; install GraphViz (`brew install graphviz` on macOS, `apt-get install graphviz` on Debian or Ubuntu) and run the command again
|
|
2004
2044
|
```
|
package/engine/map-build.mjs
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
/**
|
|
15
15
|
* `content-build map`: the drawings, written under `build/map/`.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
17
|
+
* Four modes, each a function of the world the content index describes:
|
|
18
18
|
*
|
|
19
19
|
* - **`tree`** — the containment tree from `parents`, the author's check.
|
|
20
20
|
* `tree.svg` for the whole world and `tree-<continent>.svg` per continent,
|
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
* - **`from`** — the map from a place, `from-<shortcode>.svg`, for each
|
|
24
24
|
* place named, or for every place that takes part in a border or a route
|
|
25
25
|
* with `all`.
|
|
26
|
+
* - **`chart`** — the chart from a place, `chart-<shortcode>.svg`: the same
|
|
27
|
+
* drawing at a larger horizon, the hops chaining on as long as none turns
|
|
28
|
+
* back. `all` as for `from`.
|
|
26
29
|
* - **`travel`** — the whole route graph, `travel.svg`.
|
|
27
30
|
*
|
|
28
31
|
* Every rendering is written beside the `.dot` it was drawn from, and the
|
|
@@ -42,7 +45,8 @@ import path from "node:path";
|
|
|
42
45
|
|
|
43
46
|
import { fromDot, travelDot, treeDot } from "./map-dot.mjs";
|
|
44
47
|
import { findGraphviz, graphvizMissingMessage, renderDot } from "./map-graphviz.mjs";
|
|
45
|
-
import { layoutFrom, travelGraph } from "./map-layout.mjs";
|
|
48
|
+
import { CHART_HORIZON_DAYS, layoutChart, layoutFrom, travelGraph } from "./map-layout.mjs";
|
|
49
|
+
import { TRAVEL_DAYS } from "./place-relations.mjs";
|
|
46
50
|
import { analyzeContainment, containmentFindings } from "./map-places.mjs";
|
|
47
51
|
|
|
48
52
|
/**
|
|
@@ -53,7 +57,7 @@ import { analyzeContainment, containmentFindings } from "./map-places.mjs";
|
|
|
53
57
|
export const MAP_DIR = "build/map";
|
|
54
58
|
|
|
55
59
|
/**
|
|
56
|
-
* The value of `--from` that means every place with a relation.
|
|
60
|
+
* The value of `--from` or `--chart` that means every place with a relation.
|
|
57
61
|
*
|
|
58
62
|
* @type {string}
|
|
59
63
|
*/
|
|
@@ -61,7 +65,7 @@ export const FROM_ALL = "all";
|
|
|
61
65
|
|
|
62
66
|
/**
|
|
63
67
|
* Every place that states, or is named in, a border or a route — the places
|
|
64
|
-
* `--from all`
|
|
68
|
+
* `--from all` and `--chart all` draw.
|
|
65
69
|
*
|
|
66
70
|
* @param {Map<string, import("./map-places.mjs").MapPlace>} places - Every place.
|
|
67
71
|
* @returns {string[]} Shortcodes, sorted.
|
|
@@ -89,10 +93,14 @@ export function relatedPlaces(places) {
|
|
|
89
93
|
* @param {string} [opts.root] - With `tree`, the subtree beneath this place.
|
|
90
94
|
* @param {string[]} [opts.from] - Draw the map from each of these places, or
|
|
91
95
|
* from every related place for {@link FROM_ALL}.
|
|
96
|
+
* @param {string[]} [opts.chart] - Draw the chart from each of these places,
|
|
97
|
+
* or from every related place for {@link FROM_ALL}.
|
|
98
|
+
* @param {number} [opts.horizon] - The charts' horizon in days, a marker of
|
|
99
|
+
* the scale; the end of the scale by default.
|
|
92
100
|
* @param {boolean} [opts.travel] - Draw the whole route graph.
|
|
93
101
|
* @param {string} [opts.engine="dot"] - The tree's engine: `dot`, `twopi` or
|
|
94
|
-
* `neato`. The map from a place
|
|
95
|
-
* and the route graph always `neato`.
|
|
102
|
+
* `neato`. The map and the chart from a place are always `neato` with
|
|
103
|
+
* every node pinned, and the route graph always `neato`.
|
|
96
104
|
* @param {string} [opts.rankdir="TB"] - The tree's rank direction, `dot` only.
|
|
97
105
|
* @param {number} [opts.nodesep] - The tree's `nodesep`, inches.
|
|
98
106
|
* @param {number} [opts.ranksep] - The tree's `ranksep`, inches.
|
|
@@ -107,8 +115,8 @@ export function relatedPlaces(places) {
|
|
|
107
115
|
* column?: number, severity: "error"|"warning", message: string}>,
|
|
108
116
|
* skipped: boolean}} What was written, what was found, and whether the
|
|
109
117
|
* rendering was skipped for want of GraphViz.
|
|
110
|
-
* @throws {Error} When no mode is asked for, a named place is not one,
|
|
111
|
-
* GraphViz is required and absent.
|
|
118
|
+
* @throws {Error} When no mode is asked for, a named place is not one, the
|
|
119
|
+
* horizon is not a marker of the scale, or GraphViz is required and absent.
|
|
112
120
|
*/
|
|
113
121
|
export function buildMaps({
|
|
114
122
|
world,
|
|
@@ -116,6 +124,8 @@ export function buildMaps({
|
|
|
116
124
|
tree = false,
|
|
117
125
|
root,
|
|
118
126
|
from = [],
|
|
127
|
+
chart = [],
|
|
128
|
+
horizon = CHART_HORIZON_DAYS,
|
|
119
129
|
travel = false,
|
|
120
130
|
engine = "dot",
|
|
121
131
|
rankdir = "TB",
|
|
@@ -126,8 +136,15 @@ export function buildMaps({
|
|
|
126
136
|
locate = findGraphviz,
|
|
127
137
|
requireGraphviz = true,
|
|
128
138
|
}) {
|
|
129
|
-
if (!tree && from.length === 0 && !travel) {
|
|
130
|
-
throw new Error(
|
|
139
|
+
if (!tree && from.length === 0 && chart.length === 0 && !travel) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
"name a drawing: --tree, --from <shortcode>, --chart <shortcode> or --travel",
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
if (!TRAVEL_DAYS.includes(horizon)) {
|
|
145
|
+
throw new Error(
|
|
146
|
+
`--horizon must be a marker of the days scale — one of ${TRAVEL_DAYS.join(", ")} — and ${horizon} is not`,
|
|
147
|
+
);
|
|
131
148
|
}
|
|
132
149
|
const { places } = world;
|
|
133
150
|
|
|
@@ -135,7 +152,7 @@ export function buildMaps({
|
|
|
135
152
|
// so a missing one is reported before a directory is touched.
|
|
136
153
|
const engines = new Set();
|
|
137
154
|
if (tree) engines.add(engine);
|
|
138
|
-
if (from.length || travel) engines.add("neato");
|
|
155
|
+
if (from.length || chart.length || travel) engines.add("neato");
|
|
139
156
|
/** @type {Map<string, string>} */
|
|
140
157
|
const binaries = new Map();
|
|
141
158
|
const findings = [];
|
|
@@ -212,6 +229,19 @@ export function buildMaps({
|
|
|
212
229
|
emit(`from-${centre}`, fromDot(layout, places, { scale }), "neato", ["-n2"]);
|
|
213
230
|
}
|
|
214
231
|
|
|
232
|
+
const viewpoints = chart.includes(FROM_ALL) ? relatedPlaces(places) : chart;
|
|
233
|
+
for (const centre of viewpoints) {
|
|
234
|
+
const layout = layoutChart(places, centre, { horizon });
|
|
235
|
+
for (const { from: place, to } of layout.unresolved) {
|
|
236
|
+
findings.push({
|
|
237
|
+
file: unresolvedFile(world, place),
|
|
238
|
+
severity: "warning",
|
|
239
|
+
message: `place "${place}" names "${to}" in a border or a route, and no place declares that shortcode; the chart centred on "${centre}" leaves it out`,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
emit(`chart-${centre}`, fromDot(layout, places, { scale }), "neato", ["-n2"]);
|
|
243
|
+
}
|
|
244
|
+
|
|
215
245
|
if (travel) {
|
|
216
246
|
const graph = travelGraph(places);
|
|
217
247
|
for (const { from: place, to } of graph.unresolved) {
|