@heroiclands/package-build 22.4.4 → 22.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/commands.md CHANGED
@@ -261,7 +261,8 @@ package-build: `packageKind: documentation` ships no Foundry package, so there i
261
261
 
262
262
  **NAME**
263
263
 
264
- `package-build site-root` — write the deployment's `_headers`.
264
+ `package-build site-root` — write the deployment's `_headers`, and index the
265
+ site for search.
265
266
 
266
267
  **SYNOPSIS**
267
268
 
@@ -294,6 +295,29 @@ it.
294
295
  The rules are scoped to those hostnames, so a site deployed under a domain of
295
296
  its own stays indexable.
296
297
 
298
+ With `_headers` written, the rendered site is indexed for search. Pagefind
299
+ reads every page under `<out>/<contentPackage>/` and writes the index into
300
+ `<out>/<contentPackage>/pagefind/`, so it is deployed with the pages and served
301
+ at `/<contentPackage>/pagefind/`; the theme loads `pagefind.js` from there,
302
+ relative to the site's base URL, and the browser bundle derives the prefix from
303
+ its own address, so nothing about the prefix is configured on either side. What
304
+ is indexed is the body of every page and the homepage; the theme marks its own
305
+ chrome — header, footer, breadcrumbs, infobox, the related-pages card —
306
+ `data-pagefind-ignore`, and carries `data-pagefind-filter` attributes for a
307
+ page's `type` and `package`, so a search can be narrowed to one kind of page.
308
+ This command's part is only to run the indexer over whatever the theme
309
+ rendered.
310
+
311
+ The indexer is the `pagefind` package this toolchain depends on, which installs
312
+ the binary for the platform as an optional dependency; nothing goes on a
313
+ `PATH`. Every failure of the step is an error located at the rendered site —
314
+ `build/site/<contentPackage>: error: search index: …` — and a binary that is
315
+ not installed names the platform package `npm ci` installs.
316
+
317
+ [`site.search: false`](configuration.md#site) skips the step, and removes a
318
+ `pagefind/` an earlier build left beside the pages, so a site that wants no
319
+ search deploys none.
320
+
297
321
  **OPTIONS**
298
322
 
299
323
  `--out <dir>` — the directory that is deployed. Defaults to `build/site`.
@@ -302,13 +326,20 @@ its own stays indexable.
302
326
 
303
327
  1 when `<out>/<contentPackage>/` holds no rendered site, which means the site
304
328
  build has not run and writing root files would publish a deployment with nothing
305
- under the prefix. Otherwise 0.
329
+ under the prefix; 1 when the index cannot be built. Otherwise 0.
306
330
 
307
331
  **EXAMPLES**
308
332
 
309
333
  ```
310
334
  $ package-build site-root
311
335
  ✅ Wrote build/site/_headers.
336
+ ✅ Indexed 412 pages for search into build/site/thalorna/pagefind/.
337
+ ```
338
+
339
+ ```
340
+ $ package-build site-root
341
+ ✅ Wrote build/site/_headers.
342
+ Search is off (`site.search: false`), so no index was written.
312
343
  ```
313
344
 
314
345
  **SEE ALSO**
@@ -1829,6 +1860,155 @@ demo-book: error: the document tree named by `pdf.document` cannot be read
1829
1860
  `content-build site`, `content-build package <action> [pack] [entry]`,
1830
1861
  [Diagnostics](diagnostics.md), [Configuration](configuration.md).
1831
1862
 
1863
+ ### `content-build map`
1864
+
1865
+ **NAME**
1866
+
1867
+ Draw the containment tree, the map from a place, or the whole route graph.
1868
+
1869
+ **SYNOPSIS**
1870
+
1871
+ ```
1872
+ content-build map --tree [--root <shortcode>] [--engine dot|twopi|neato] [--rankdir TB|LR|BT|RL]
1873
+ [--nodesep <inches>] [--ranksep <inches>] [--no-polities]
1874
+ content-build map --from <shortcode>.. | --from all
1875
+ content-build map --travel
1876
+ content-build map [...] [--scale <factor>] [--base <url>] [--out <dir>]
1877
+ ```
1878
+
1879
+ **DESCRIPTION**
1880
+
1881
+ Draws what the place notes state. Every drawing is read from the content
1882
+ index — this package's records and every declared dependency's fetched
1883
+ index — so a consumer's map draws its dependencies' places beside its own
1884
+ and no note is opened except to locate a finding. Everything lands under
1885
+ `build/map/`, always the `.dot` beside the `.svg`, so a drawing can be
1886
+ re-rendered, diffed or read without the index. GraphViz draws: `dot` (or
1887
+ `twopi`, `neato`) for the tree, `neato` for the other two. It is a
1888
+ build-time tool of this command alone; when the engine a run needs is not
1889
+ installed the command says so, names what to install, and stops. A build
1890
+ that asks for maps as one step of a larger job — a site build — writes
1891
+ the `.dot` files, emits one warning and skips the renderings rather than
1892
+ failing.
1893
+
1894
+ The three drawings, any of which may be asked for in one run:
1895
+
1896
+ **`--tree`** — the author's check. The containment tree from `data.parents`,
1897
+ edges running child → parent, clustered by continent — a `region` parented
1898
+ directly on the `world` note — with the places reaching no continent
1899
+ floating outside every cluster. Node shape, colour and size are by
1900
+ `subType` (a gold double circle for the world, a blue box for a region, a
1901
+ small green ellipse for a settlement, a purple diamond for a site, a teal
1902
+ hexagon for a feature, an orange house for a structure), and a legend
1903
+ drawn from the same style table sits on every drawing. A `polity`
1904
+ affiliation is drawn as a grey dashed cylinder beside every region note in
1905
+ its own directory. Anomalies are highlighted and reported as findings: a
1906
+ place with **no parent** and a **placeholder for a parent shortcode no
1907
+ place declares** are filled red (errors); a place on a **cycle** is
1908
+ outlined red (an error); a place with **more than one parent**, a region
1909
+ with **no `packFolder`** and a polity whose directory holds **no region
1910
+ note** are warnings. The world note has no parent by nature and is not a
1911
+ finding. Writes `tree.svg` for the whole world and `tree-<shortcode>.svg`
1912
+ for each continent; with `--root`, the subtree beneath that one place as
1913
+ `tree-<shortcode>.svg` — every place whose `parents` chain reaches it by
1914
+ any path — and no findings.
1915
+
1916
+ **`--from <shortcode>`** — the map from a place, `from-<shortcode>.svg`.
1917
+ Pre-modern maps were itineraries: partial, centred on their maker, exact
1918
+ about the next stage and vague about the tenth. A place's `borders` and
1919
+ `routes` are exactly that, so the reader's map is one map per place, from
1920
+ that place. The place sits at the centre, **north up, east right**. Every
1921
+ neighbour it states — or that states it, since a border or a route is one
1922
+ fact stated from each end — sits at the angle of its bearing and on the
1923
+ ring of its days, with an edge labelled by the bearing and days; a border
1924
+ is a dashed edge, and where several modes reach one place the label lists
1925
+ each. Beyond each neighbour, every place a second hop reaches is drawn
1926
+ dimmer at the composed bearing where the two hops agree — the same bearing
1927
+ or adjacent ones, added as vectors weighted by their days — on the ring of
1928
+ their total; where the hops disagree the place is omitted rather than
1929
+ guessed at. Nodes sharing a ring and a bearing are fanned apart. `all`
1930
+ draws the map from every place that states or is named in a border or a
1931
+ route. Positions are computed by the command and pinned, so `neato` only
1932
+ draws; nothing on the page is a solver's decision.
1933
+
1934
+ _The rings._ One faint dashed circle per marker of the days scale up to
1935
+ the horizon of 90 days — `1 2 3 5 10 20 30 45 60 90` — each labelled at
1936
+ its top, spaced logarithmically so that equal ratios of days are equal
1937
+ steps of radius: a day to two days is the same step as five to ten, and a
1938
+ day's ride and a month's voyage both fit on one page. A neighbour with a
1939
+ route sits on the ring of its shortest route's days. A neighbour reached by
1940
+ a border alone sits on the innermost ring, because a frontier states no
1941
+ distance. One more circle, the rim, lies a log step beyond the horizon:
1942
+ a place farther than 90 days, and a second hop whose days are unknown
1943
+ because either hop was a border, are a name at the rim carrying its days
1944
+ or `?` — beyond what the notes state, the map states nothing more.
1945
+
1946
+ _Two scales._ The generated map from a place is the default regional map:
1947
+ every place gets one at build time, from its `borders` and `routes`. An
1948
+ authored `regionalmap` note is an artefact of the setting — a road book, a
1949
+ sailor's chart, a tax survey, partial and from somewhere, whose prose says
1950
+ whose it is — and never the survey. The two are two sources of the same
1951
+ thing on a place's page.
1952
+
1953
+ **`--travel`** — the whole route graph, `travel.svg`, for the author: one
1954
+ undirected edge per pair of places, a border dashed, each route asking
1955
+ `neato` for a length on the same log scale as the rings so the god's-eye
1956
+ view and the itinerary agree about what a day and a month look like; the
1957
+ engine solves the positions.
1958
+
1959
+ Every node's label is the place's `name.full` and its tooltip the canonical
1960
+ address. With `--base`, every name is also a link — GraphViz writes an
1961
+ `<a href>` around it — to the page at `<base><slug>/` for this package's
1962
+ places and to the URL the fetched index resolved for a dependency's, so a
1963
+ page can inline the SVG. Without it the names are plain text.
1964
+
1965
+ **OPTIONS**
1966
+
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
+ | `--travel` | boolean | `false` | Draw the whole route graph as `travel.svg`. |
1973
+ | `--engine` | choice | `dot` | The tree's layout engine — `dot`, `twopi` (radial, rooted on the world or the `--root`) or `neato`. The other two drawings are always `neato`. |
1974
+ | `--rankdir` | choice | `TB` | The tree's rank direction — `TB`, `LR`, `BT` or `RL`; `dot` engine only. |
1975
+ | `--nodesep` | number | by `--scale` | The tree's GraphViz `nodesep`, in inches. |
1976
+ | `--ranksep` | number | by engine | The tree's GraphViz `ranksep`, in inches. |
1977
+ | `--scale` | number | `1` | Multiply every node's width, height, font size and border weight, the legend's included. |
1978
+ | `--polities` | boolean | `true` | Draw polities beside their regions in the tree. `--no-polities` drops them. |
1979
+ | `--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. |
1980
+ | `--out` | string | `build/map` | Directory to write into, relative to the working directory. |
1981
+
1982
+ **EXIT STATUS**
1983
+
1984
+ 1 when no drawing is asked for, when a `--from` or `--root` names no
1985
+ place, when the GraphViz engine a drawing needs is not installed, when a
1986
+ dependency's index cannot be read, when a note the index cannot record is
1987
+ met, on any error finding from `--tree` (a place with no parent, a parent
1988
+ that does not resolve, a cycle), or on any other thrown error. Otherwise 0
1989
+ — the warnings are reported and never fail the command.
1990
+
1991
+ **EXAMPLES**
1992
+
1993
+ ```
1994
+ $ content-build map --tree
1995
+ assets/content/Regions/Sea.md:16:5: warning: place "innersea" has more than one parent (northc, southc), which is legal for a sea between continents or a region split between two, and worth a look otherwise
1996
+ assets/content/Regions/Marches/Lost_Fort.md:9:14: error: place "lostfort" names parent "marchs", which does not resolve to any place in this package or a fetched index
1997
+ […] 394 place(s) → 7 drawing(s) under build/map
1998
+
1999
+ $ content-build map --from dunharargn --base /thalorna/
2000
+ […] 394 place(s) → 1 drawing(s) under build/map
2001
+
2002
+ $ content-build map --travel
2003
+ […] 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
+ ```
2005
+
2006
+ **SEE ALSO**
2007
+
2008
+ `content-build lint [root]` (which checks `borders` and `routes` from both
2009
+ ends), `content-build deps fetch`, `content-build content-index [root]`,
2010
+ [Content format](content-format.md), [Diagnostics](diagnostics.md).
2011
+
1832
2012
  ### `content-build reachability <dir> [file]`
1833
2013
 
1834
2014
  **NAME**
@@ -769,6 +769,7 @@ Any other key under `docs.itemFields` is refused:
769
769
  | `site.passOptions` | object | `{}` |
770
770
  | `site.notfound` | object | `null` |
771
771
  | `site.hugo` | object | `{}` |
772
+ | `site.search` | boolean | `true` |
772
773
 
773
774
  How much of a package reaches the web at all is **not** here — it is
774
775
  [`publish.site`](#publish). `site` is framing: which named pass bundle
@@ -818,7 +819,7 @@ published. A `site.out` is refused by name:
818
819
 
819
820
  > ``package-build config: `site` must be a mapping.``
820
821
 
821
- > ``package-build config: `site.<key>` is not a recognized option (expected one of: base, assets, description, packages, pass, passOptions, notfound, hugo).``
822
+ > ``package-build config: `site.<key>` is not a recognized option (expected one of: base, assets, description, packages, pass, passOptions, notfound, hugo, search).``
822
823
 
823
824
  `site.assets` is the host every package's imagery is served from, and it is
824
825
  the one address in this file that is not this repository's own. A note names
@@ -932,6 +933,23 @@ the block cannot grow into a second configuration file:
932
933
 
933
934
  > ``package-build config: `site.hugo.baseURL` is derived from package.json `homepage` and must not be declared — it would be overwritten, and the two would disagree with nothing to say so.``
934
935
 
936
+ `site.search` is whether the rendered site carries a search index. On by
937
+ default: `package-build site-root` runs Pagefind over the rendered pages after
938
+ it writes `_headers`, and the index lands beside them as
939
+ `build/site/<contentPackage>/pagefind/`, served at `/<contentPackage>/pagefind/`
940
+ with the rest of the site. The theme loads it relative to the site's base URL
941
+ and renders the search box; what is indexed is the body of every page, with the
942
+ theme's own chrome marked out. `false` skips the step and removes an index an
943
+ earlier build left, so a site that wants no search deploys none. See
944
+ [`package-build site-root`](commands.md#package-build-site-root).
945
+
946
+ ```yaml
947
+ site:
948
+ search: false
949
+ ```
950
+
951
+ > ``package-build config: `site.search` must be a boolean.``
952
+
935
953
  ### The generated Hugo configuration
936
954
 
937
955
  `content-build site` writes `build/hugo/hugo.toml` on every run. Every value
@@ -3081,12 +3081,111 @@ three maps, and none of those maps needs to know it is a keep.
3081
3081
  - structure: A single building or habitation — halls, keeps, temples, inns, towers.
3082
3082
  - feature: A place significant by its terrain — forests, rivers, falls, passes, fords.
3083
3083
 
3084
- | `data` property | Values | Description |
3085
- | --------------- | ------------ | ---------------------------------------------------------------------------- |
3086
- | `demonym` | `string` | What a person from this place is called — a Vylarian |
3087
- | `lore` | `WikiLink[]` | Lore concerning this place — its peoples, its law, its calendar, its history |
3088
- | `parents` | `WikiLink[]` | Enclosing places within which this place is located |
3089
- | `population` | `number` | Approximate population (precision 2 significant digits) |
3084
+ | `data` property | Values | Description |
3085
+ | --------------- | --------------------------------------------------- | ---------------------------------------------------------------------------- |
3086
+ | `demonym` | `string` | What a person from this place is called — a Vylarian |
3087
+ | `lore` | `WikiLink[]` | Lore concerning this place — its peoples, its law, its calendar, its history |
3088
+ | `parents` | `WikiLink[]` | Enclosing places within which this place is located |
3089
+ | `population` | `number` | Approximate population (precision 2 significant digits) |
3090
+ | `borders` | `{ to, bearing }[]` | Places sharing a frontier with this one, and where each lies from here |
3091
+ | `routes` | `{ to, bearing, mode, days, terrain?, leagues? }[]` | Journeys from this place's centre to another place |
3092
+
3093
+ #### Where a place is, in relation to other places
3094
+
3095
+ `parents` states what a place is **within**. Two more properties state what
3096
+ it is **next to** and what it is **reachable from**, as data rather than as
3097
+ prose, so that two notes describing one frontier cannot quietly disagree about
3098
+ which side of it each is on:
3099
+
3100
+ ```yaml
3101
+ data:
3102
+ borders: # places sharing a frontier
3103
+ - { to: dunharargn, bearing: NE } # both required
3104
+ - { to: bethuargn, bearing: W }
3105
+ routes: # journeys from this place's centre
3106
+ - { to: steinmark, bearing: SW, mode: land, days: 3, terrain: [road, mountains] }
3107
+ - { to: denizara, bearing: W, mode: ship, days: 5 }
3108
+ - { to: kethramir, bearing: E, mode: land, days: 30, terrain: [dunes], leagues: 90 }
3109
+ ```
3110
+
3111
+ - `to` — required; the `shortcode` of a `place` note in this package or in a
3112
+ declared dependency's index. A shortcode, not an address.
3113
+ - `bearing` — required; where the neighbour or the destination lies from here.
3114
+ - `mode` — required on a route; how the journey is travelled.
3115
+ - `days` — required on a route; a marker meaning "about this, under normal
3116
+ conditions", from the scale below. Any other value is an error.
3117
+ - `terrain` — optional on a route; the terrains crossed, in travel order, from
3118
+ the registry below. Each terrain names the modes that cross it, so open sea
3119
+ on a land route — or a road on a ship route — is an error.
3120
+ - `leagues` — optional on a route; a distance, only where the note states one.
3121
+
3122
+ **Regions border; settlements are days apart.** A frontier is a fact about two
3123
+ regions, and a journey is a fact about two places a traveller sets out from and
3124
+ arrives at. A pair appears in `routes` once per `mode` — a port and its
3125
+ neighbour may be three days by land and one by ship — and in `borders` once.
3126
+ **A place never borders its own parent or child**: containment is `parents`,
3127
+ and restating it as adjacency makes the two contradict each other.
3128
+
3129
+ **Both ends state the relation, and `content-build lint` checks that they
3130
+ agree.** A border at `NE` from one side is a border at `SW` from the other; a
3131
+ route stated by land in three days from one side is stated by land in three
3132
+ days from the other, at the opposite bearing. A neighbour that states nothing
3133
+ back is a warning naming both notes — the pair is half-written, not wrong. A
3134
+ neighbour that states a different bearing, a different `days` or a different
3135
+ `mode` is an error, because one of the two notes is wrong and a reader cannot
3136
+ tell which. Every `to` must resolve to a place, every value must come from its
3137
+ closed set, and each finding is located at the entry that states it.
3138
+
3139
+ | `bearing` value | where the other place lies |
3140
+ | --------------- | -------------------------- |
3141
+ | `N` | north |
3142
+ | `NE` | north-east |
3143
+ | `E` | east |
3144
+ | `SE` | south-east |
3145
+ | `S` | south |
3146
+ | `SW` | south-west |
3147
+ | `W` | west |
3148
+ | `NW` | north-west |
3149
+
3150
+ | `mode` value | travelled |
3151
+ | ------------ | ---------------------------- |
3152
+ | `land` | on foot, mounted, or by cart |
3153
+ | `boat` | on a river or a lake |
3154
+ | `ship` | on open sea |
3155
+
3156
+ | `days` value | meaning |
3157
+ | ------------ | -------------------------------------------- |
3158
+ | `1` | a day |
3159
+ | `2` | two days |
3160
+ | `3` | three days |
3161
+ | `5` | about five days |
3162
+ | `10` | a ten-day week |
3163
+ | `20` | two ten-day weeks |
3164
+ | `30` | three ten-day weeks |
3165
+ | `45` | a month and a half |
3166
+ | `60` | two months |
3167
+ | `90` | a season |
3168
+ | `180` | many months |
3169
+ | `360` | who knows — a journey nobody reckons in days |
3170
+
3171
+ | `terrain` value | crossed by |
3172
+ | --------------- | ------------------ |
3173
+ | `road` | land |
3174
+ | `track` | land |
3175
+ | `plain` | land |
3176
+ | `steppe` | land |
3177
+ | `hills` | land |
3178
+ | `mountains` | land |
3179
+ | `forest` | land |
3180
+ | `jungle` | land |
3181
+ | `marsh` | land |
3182
+ | `dunes` | land |
3183
+ | `desert` | land |
3184
+ | `ice` | land |
3185
+ | `coast` | land, boat or ship |
3186
+ | `open-sea` | ship |
3187
+ | `river` | boat |
3188
+ | `lake` | boat |
3090
3189
 
3091
3190
  **A place declares only what is true of ground.** Four properties were removed
3092
3191
  because they were true of something else, and each removal has a home to go to.
@@ -242,6 +242,7 @@ over one would teach people to stop reading the report.
242
242
  | `content-build markdown [paths..]` | it reports any markdownlint finding |
243
243
  | `content-build site` | any gate finding (no homepage, a wikilink in frontmatter, an address that cannot be derived, an unusable or unaddressable foreign manifest, a conflicting address) or any table or wikilink error while writing pages — the run stops at the first gate that fires |
244
244
  | `content-build pdf` | it could not build the book for a reason other than a deliberate no-op — never on a reported finding by itself |
245
+ | `content-build map` | `--tree` reports an `error`-severity finding (a place with no parent, a parent that does not resolve, a cycle), a named place is not one, the GraphViz engine a drawing needs is not installed, or the corpus cannot be indexed — never on a warning |
245
246
  | `content-build docs item-fields --check` | the generated page differs from what is committed |
246
247
  | `content-build package compile` | pack JSON generation reported any `error`-severity finding (checked, and the compile refused, before any pack is written), or a compiled pack fails its Scene/Level integrity check |
247
248
  | `content-build deps fetch` | the fetch itself throws — it emits no diagnostics |
@@ -263,12 +263,13 @@ package carries this group:
263
263
  `build:site-content` writes the whole Hugo source tree under `build/hugo/` —
264
264
  the generated `hugo.toml` and the content mount — with `content-build site`;
265
265
  `build:site-html` runs Hugo over it, rendering into `build/site/<contentPackage>/`;
266
- `build:site-root` writes the deployment's `_headers` beside
267
- that; and `serve:site` does the first and then `hugo server` for a live
268
- preview. The repository carries no Hugo configuration of its own: `hugo.toml`
269
- is generated on every run from `package.json`, `package-build.config.yaml`,
270
- the installed `@heroiclands/hugo-theme` and the navigation `deps fetch`
271
- cached, and the only file to add is `@heroiclands/hugo-theme` under
266
+ `build:site-root` writes the deployment's `_headers` beside that and indexes
267
+ the rendered pages for search into `build/site/<contentPackage>/pagefind/`;
268
+ and `serve:site` does the first and then `hugo server` for a live preview.
269
+ The repository carries no Hugo configuration of its own: `hugo.toml` is
270
+ generated on every run from `package.json`, `package-build.config.yaml`, the
271
+ installed `@heroiclands/hugo-theme` and the navigation `deps fetch` cached,
272
+ and the only file to add is `@heroiclands/hugo-theme` under
272
273
  `devDependencies`. Hugo itself is a separate install — the extended edition,
273
274
  on the developer's `PATH` and the runner's.
274
275
 
@@ -1403,17 +1403,27 @@ export function lintNote(
1403
1403
  // to recognise it would be worse than not checking.
1404
1404
  const entry = vocabulary?.[current];
1405
1405
  if (entry) {
1406
+ const fields = dataFields(current, vocabulary) ?? [];
1406
1407
  findings.push(
1407
1408
  ...checkDataContainer(note, {
1408
1409
  type,
1409
1410
  // Read through `dataFields`, so the keys **every** type accepts
1410
1411
  // are part of what this type declares rather than a second list
1411
1412
  // the container check would have to be told about.
1412
- fields: dataFields(current, vocabulary) ?? [],
1413
+ fields,
1413
1414
  packs,
1414
1415
  }),
1415
1416
  );
1416
1417
  findings.push(...checkSubType(note, { type, entry }));
1418
+ // A field that declares a check of its own, beyond its shape. Handed
1419
+ // the index the reference check resolves through, so a value naming
1420
+ // another note reads that note — local or in a fetched index — the
1421
+ // way a wikilink would. The linter names no such field itself; the
1422
+ // vocabulary does, beside the field.
1423
+ for (const field of fields) {
1424
+ if (typeof field.check !== "function") continue;
1425
+ findings.push(...field.check(note, { index }));
1426
+ }
1417
1427
  }
1418
1428
 
1419
1429
  const fields = authoredFields(schema);
package/engine/index.mjs CHANGED
@@ -84,6 +84,24 @@ export * as noteSchemas from "./note-schemas.mjs";
84
84
  /** The closed frontmatter regions: the `data:` container and each type's `subType`. */
85
85
  export * as noteVocabulary from "./note-vocabulary.mjs";
86
86
 
87
+ /** What a place is next to and reachable from: the closed sets, and the checks. */
88
+ export * as placeRelations from "./place-relations.mjs";
89
+
90
+ /** The places a map is drawn from, read from the content index, and what `parents` says about them. */
91
+ export * as mapPlaces from "./map-places.mjs";
92
+
93
+ /** The geometry of the map from a place: bearings to angles, days to rings, hops composed. */
94
+ export * as mapLayout from "./map-layout.mjs";
95
+
96
+ /** The three drawings of `content-build map`, as DOT. */
97
+ export * as mapDot from "./map-dot.mjs";
98
+
99
+ /** GraphViz, as the map command finds and runs it. */
100
+ export * as mapGraphviz from "./map-graphviz.mjs";
101
+
102
+ /** `content-build map`: the drawings, written under `build/map/`. */
103
+ export * as mapBuild from "./map-build.mjs";
104
+
87
105
  /** The closed registry of system ids, and the `none` that stands for no system. */
88
106
  export * as systems from "./systems.mjs";
89
107