@heroiclands/package-build 22.2.0 → 22.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/CONTENT.md +27 -32
- package/bin/content-build.mjs +0 -3
- package/content-config.mjs +42 -40
- package/docs/api.md +25 -25
- package/docs/configuration.md +19 -29
- package/docs/content-format.md +36 -6
- package/engine/foundry-entries.mjs +12 -1
- package/engine/frontmatter-lint.mjs +2 -3
- package/engine/helpers.mjs +4 -1
- package/engine/ids.mjs +12 -0
- package/engine/note-claims.mjs +21 -0
- package/engine/pack-router.mjs +82 -5
- package/engine/pdf-build.mjs +2 -2
- package/engine/retired-fields.mjs +2 -3
- package/engine/site-build.mjs +59 -218
- package/engine/site-index.mjs +18 -62
- package/engine/web-wikilinks.mjs +2 -16
- package/engine/wikilinks.mjs +35 -14
- package/package.json +1 -1
- package/sohl/kb-passes.mjs +14 -85
- package/types/content-config.d.mts +6 -6
- package/types/engine/ids.d.mts +11 -0
- package/types/engine/pack-router.d.mts +20 -2
- package/types/engine/site-build.d.mts +12 -62
- package/types/engine/site-index.d.mts +3 -28
- package/types/engine/web-wikilinks.d.mts +1 -1
- package/types/engine/wikilinks.d.mts +6 -3
- package/types/sohl/kb-passes.d.mts +5 -36
package/engine/wikilinks.mjs
CHANGED
|
@@ -353,12 +353,14 @@ export function anchorPageId(noteId, anchorSlug) {
|
|
|
353
353
|
* Builds the link-resolution tables for a content tree.
|
|
354
354
|
*
|
|
355
355
|
* @param {Array<{type: string, id: string, shortcode?: string|null,
|
|
356
|
-
* name?: string, pack?: string, docPack?: string,
|
|
356
|
+
* name?: string, pack?: string, docPack?: string, none?: boolean,
|
|
357
357
|
* draft?: boolean}>} docs -
|
|
358
358
|
* One entry per content note. `pack` / `docPack` name the packs the note's
|
|
359
359
|
* document and its documentation entry landed in; omitted, the conventional
|
|
360
|
-
* one-pack-per-type names stand in. `
|
|
361
|
-
*
|
|
360
|
+
* one-pack-per-type names stand in. `none` says the note declares
|
|
361
|
+
* `pack: none` and compiles into no document, so it has no UUID to link to.
|
|
362
|
+
* `draft` says the note carries the `draft` tag, which marks links *into* it
|
|
363
|
+
* and changes nothing else.
|
|
362
364
|
* @param {string} packageId - The Foundry package shipping the packs; the first
|
|
363
365
|
* segment of every emitted UUID.
|
|
364
366
|
* @param {Map<string, object>} [foreign] - Canonically keyed entries from
|
|
@@ -408,17 +410,29 @@ export function buildWikilinkIndex(
|
|
|
408
410
|
if (!d.id || !d.type) continue;
|
|
409
411
|
types.add(norm(d.type));
|
|
410
412
|
|
|
411
|
-
uuidByDoc.set(
|
|
412
|
-
|
|
413
|
-
//
|
|
414
|
-
//
|
|
415
|
-
//
|
|
416
|
-
|
|
417
|
-
//
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
413
|
+
uuidByDoc.set(
|
|
414
|
+
d,
|
|
415
|
+
// A note declaring `pack: none` compiles into no document, so it
|
|
416
|
+
// has no address in any compendium: a link to it is a page on the
|
|
417
|
+
// web and prose in a journal. Recorded as an entry with no UUIDs
|
|
418
|
+
// rather than left out, so the address still resolves and a link
|
|
419
|
+
// to it is never reported as dead.
|
|
420
|
+
d.none ?
|
|
421
|
+
{ uuid: undefined, docUuid: undefined }
|
|
422
|
+
: {
|
|
423
|
+
// `d.pack` is where this note's document actually landed,
|
|
424
|
+
// resolved by the pack router when the index was
|
|
425
|
+
// collected. A repository may ship several packs of one
|
|
426
|
+
// type and a UUID carries the pack name, so the address
|
|
427
|
+
// cannot be derived from the type alone.
|
|
428
|
+
uuid: compendiumUuid(packageId, d.type, d.id, d.pack),
|
|
429
|
+
// An item's prose compiles into a separate JournalEntry,
|
|
430
|
+
// addressed by the virtual `doc<type>` qualifier. Its id
|
|
431
|
+
// is derived from the item's, so its address is knowable
|
|
432
|
+
// here too.
|
|
433
|
+
docUuid: compendiumUuid(packageId, "doc", itemDocEntryId(d.id), d.docPack),
|
|
434
|
+
},
|
|
435
|
+
);
|
|
422
436
|
|
|
423
437
|
if (d.shortcode) byShortcode.set(`${norm(d.type)}/${norm(d.shortcode)}`, d);
|
|
424
438
|
}
|
|
@@ -783,6 +797,13 @@ export function convertWikilinks(markdown, { type, id, pack, docPack, index }) {
|
|
|
783
797
|
docUuid: compendiumUuid(index.packageId, "doc", itemDocEntryId(doc.id), doc.docPack),
|
|
784
798
|
};
|
|
785
799
|
const entryUuid = itemDoc ? addresses.docUuid : addresses.uuid;
|
|
800
|
+
// The target is a note that compiles into no document — `pack: none`.
|
|
801
|
+
// The address is real and the page exists on the web, so this is not
|
|
802
|
+
// a dead link and must not fail the build; but a compendium has
|
|
803
|
+
// nothing to open, so the reader gets the prose and no `@UUID`. The
|
|
804
|
+
// mirror of what the website does for an address that publishes a
|
|
805
|
+
// document and no page.
|
|
806
|
+
if (entryUuid === undefined) return text;
|
|
786
807
|
const entryId = itemDoc ? itemDocEntryId(doc.id) : doc.id;
|
|
787
808
|
const isJournal = itemDoc || packForType(doc.type).docType === "JournalEntry";
|
|
788
809
|
// A JournalEntry link opens a journal — at its first page, or at the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heroiclands/package-build",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.3.0",
|
|
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",
|
package/sohl/kb-passes.mjs
CHANGED
|
@@ -12,25 +12,23 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* The `sohl` knowledgebase's own body
|
|
15
|
+
* The `sohl` knowledgebase's own body pass.
|
|
16
16
|
*
|
|
17
17
|
* `content-build site` publishes a content tree as a website, and almost all of
|
|
18
|
-
* that job is the same for every package.
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* that job is the same for every package. This rewrite is not: it is driven by
|
|
19
|
+
* a TypeDoc symbol map only this package has, and it is ruled explicitly
|
|
20
|
+
* per-consumer.
|
|
21
21
|
*
|
|
22
|
-
*
|
|
22
|
+
* It lives here rather than in a script in the consuming repository for the
|
|
23
23
|
* same reason `sohl/item-builders.mjs` and `sohl/being-info.mjs` do: a
|
|
24
24
|
* configuration is data and cannot hold a function, so a package-specific table
|
|
25
25
|
* of code is **named** from configuration and resolved from a registry. What is
|
|
26
26
|
* package-specific is the code; what is repository-specific — where the symbol
|
|
27
|
-
* map sits, what the API is served at
|
|
28
|
-
* options, supplied beside the name.
|
|
27
|
+
* map sits, what the API is served at — is options, supplied beside the name.
|
|
29
28
|
*
|
|
30
|
-
*
|
|
31
|
-
* degrades to a code span,
|
|
32
|
-
*
|
|
33
|
-
* broken link or a failed build for a syntax example in prose would not be.
|
|
29
|
+
* The *rewrite* never fails a build. A `{@link}` the map does not know
|
|
30
|
+
* degrades to a code span, which is legible to a reader; a failed build for a
|
|
31
|
+
* syntax example in prose would not be.
|
|
34
32
|
*
|
|
35
33
|
* Building the bundle is a different matter: a `symbolMap` that is configured
|
|
36
34
|
* and cannot be used fails, loudly, before a page is rendered. Degrading
|
|
@@ -168,80 +166,21 @@ export function resolveApiLinks(body, symbols, apiBase) {
|
|
|
168
166
|
});
|
|
169
167
|
}
|
|
170
168
|
|
|
171
|
-
/**
|
|
172
|
-
* Rewrites the relative links in a developer-doc body so they resolve on the
|
|
173
|
-
* published site.
|
|
174
|
-
*
|
|
175
|
-
* Developer docs are authored to link one another and the source tree with
|
|
176
|
-
* repository-relative paths, and neither target exists at the same path once
|
|
177
|
-
* rendered. Each link is resolved against the doc's own location:
|
|
178
|
-
*
|
|
179
|
-
* - a `*.md` link landing inside the documentation tree becomes the published
|
|
180
|
-
* route, preserving any `#anchor`; a `README` is its directory's landing, so
|
|
181
|
-
* that segment is dropped.
|
|
182
|
-
* - anything else — source, templates, a repository-root `*.md` — becomes its
|
|
183
|
-
* GitHub blob URL.
|
|
184
|
-
*
|
|
185
|
-
* Absolute URLs, anchor-only links, `mailto:` and site-root links are untouched.
|
|
186
|
-
*
|
|
187
|
-
* @param {string} body - The markdown body.
|
|
188
|
-
* @param {string} docRel - The doc's path relative to the documentation tree.
|
|
189
|
-
* @param {object} options - `{ repoRoot, docsSrc, docsRel, route, blob }`.
|
|
190
|
-
* @returns {string} The body with every relative link rewritten.
|
|
191
|
-
*/
|
|
192
|
-
export function rewriteRepoLinks(body, docRel, options) {
|
|
193
|
-
const { repoRoot, docsSrc, docsRel, route, blob } = options;
|
|
194
|
-
const docDir = path.dirname(docRel);
|
|
195
|
-
return body.replace(/\]\(([^)]+)\)/g, (whole, raw) => {
|
|
196
|
-
// Peel an optional link title: [text](url "title").
|
|
197
|
-
const sp = raw.search(/\s/);
|
|
198
|
-
const href = sp === -1 ? raw : raw.slice(0, sp);
|
|
199
|
-
const title = sp === -1 ? "" : raw.slice(sp);
|
|
200
|
-
if (/^(https?:|mailto:|tel:|#|\/)/.test(href)) return whole;
|
|
201
|
-
|
|
202
|
-
const hash = href.indexOf("#");
|
|
203
|
-
const filePart = hash === -1 ? href : href.slice(0, hash);
|
|
204
|
-
const anchor = hash === -1 ? "" : href.slice(hash);
|
|
205
|
-
if (!filePart) return whole;
|
|
206
|
-
|
|
207
|
-
const repoRel = path
|
|
208
|
-
.relative(repoRoot, path.resolve(docsSrc, docDir, filePart))
|
|
209
|
-
.replace(/\\/g, "/");
|
|
210
|
-
|
|
211
|
-
let out;
|
|
212
|
-
if (repoRel.startsWith(`${docsRel}/`) && repoRel.endsWith(".md")) {
|
|
213
|
-
const rel2 = repoRel.slice(docsRel.length + 1, -3).toLowerCase();
|
|
214
|
-
const devPath = path.basename(rel2) === "readme" ? path.posix.dirname(rel2) : rel2;
|
|
215
|
-
out = `${route}${devPath === "." ? "" : `${devPath}/`}${anchor}`;
|
|
216
|
-
} else {
|
|
217
|
-
out = `${blob}${repoRel}${anchor}`;
|
|
218
|
-
}
|
|
219
|
-
return `](${out}${title})`;
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
|
|
223
169
|
/**
|
|
224
170
|
* The `sohl` knowledgebase pass bundle, built from its options.
|
|
225
171
|
*
|
|
226
|
-
* A pass bundle is
|
|
227
|
-
* resolution,
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
* `{@link}` tag may sit inside prose a wikilink also touches.
|
|
231
|
-
* - `afterLinks` runs only on pages from an **extra tree** — the documentation
|
|
232
|
-
* tree — because repository-relative links are a property of how those pages
|
|
233
|
-
* are authored, not of content notes.
|
|
234
|
-
*
|
|
235
|
-
* Both run inside code-fence protection, so neither can rewrite a fenced example.
|
|
172
|
+
* A pass bundle is the hook the page renderer calls before wikilink
|
|
173
|
+
* resolution: `beforeLinks` runs on every page, before wikilinks resolve,
|
|
174
|
+
* because a `{@link}` tag may sit inside prose a wikilink also touches. It
|
|
175
|
+
* runs inside code-fence protection, so it cannot rewrite a fenced example.
|
|
236
176
|
*
|
|
237
177
|
* @param {object} options - Resolved from `site.passOptions`.
|
|
238
178
|
* @param {string} [options.symbolMap] - Path to the TypeDoc symbol map,
|
|
239
179
|
* relative to `repoRoot`. Absent means no API links; present and unusable is
|
|
240
180
|
* a build failure.
|
|
241
181
|
* @param {string} [options.apiBase] - Where the API documentation is served.
|
|
242
|
-
* @param {string} [options.blob] - GitHub blob base for repository files.
|
|
243
182
|
* @param {string} options.repoRoot - The repository root, for relative paths.
|
|
244
|
-
* @returns {{beforeLinks: Function
|
|
183
|
+
* @returns {{beforeLinks: Function}} The bundle.
|
|
245
184
|
* @throws {Error} When a configured `symbolMap` cannot be resolved, read,
|
|
246
185
|
* parsed, or is not a name → page object.
|
|
247
186
|
*/
|
|
@@ -250,15 +189,5 @@ export function sohlKbPass(options) {
|
|
|
250
189
|
const apiBase = options.apiBase ?? "";
|
|
251
190
|
return {
|
|
252
191
|
beforeLinks: (text) => resolveApiLinks(text, symbols, apiBase),
|
|
253
|
-
afterLinks: (text, page) =>
|
|
254
|
-
page.tree ?
|
|
255
|
-
rewriteRepoLinks(text, page.rel, {
|
|
256
|
-
repoRoot: options.repoRoot,
|
|
257
|
-
docsSrc: page.tree.from,
|
|
258
|
-
docsRel: page.tree.rel,
|
|
259
|
-
route: page.tree.route,
|
|
260
|
-
blob: options.blob ?? "",
|
|
261
|
-
})
|
|
262
|
-
: text,
|
|
263
192
|
};
|
|
264
193
|
}
|
|
@@ -133,10 +133,10 @@ export const DEFAULT_ADDRESS_SCHEME: Readonly<{
|
|
|
133
133
|
* and the default.
|
|
134
134
|
*
|
|
135
135
|
* - `homepage` — the authored homepage, and **no other page**. The content tree
|
|
136
|
-
* is not walked for pages, `site.sections` / `site.
|
|
137
|
-
*
|
|
136
|
+
* is not walked for pages, `site.sections` / `site.landing` emit nothing,
|
|
137
|
+
* and nothing serves a page for its addresses.
|
|
138
138
|
* - `content` — the homepage *plus* every page the content tree publishes: the
|
|
139
|
-
* knowledgebase
|
|
139
|
+
* knowledgebase and the section landings.
|
|
140
140
|
*
|
|
141
141
|
* **Homepage-only is a first-class mode, not an accommodation.**
|
|
142
142
|
* `sohl-kethira-basic` (unofficial Hârn fan material under Keléstia Productions'
|
|
@@ -200,10 +200,10 @@ export const DERIVED_HUGO_KEYS: Readonly<Record<string, string>>;
|
|
|
200
200
|
* and the default.
|
|
201
201
|
*
|
|
202
202
|
* - `homepage` — the authored homepage, and **no other page**. The content tree
|
|
203
|
-
* is not walked for pages, `site.sections` / `site.
|
|
204
|
-
*
|
|
203
|
+
* is not walked for pages, `site.sections` / `site.landing` emit nothing,
|
|
204
|
+
* and nothing serves a page for its addresses.
|
|
205
205
|
* - `content` — the homepage *plus* every page the content tree publishes: the
|
|
206
|
-
* knowledgebase
|
|
206
|
+
* knowledgebase and the section landings.
|
|
207
207
|
*
|
|
208
208
|
* **Homepage-only is a first-class mode, not an accommodation.**
|
|
209
209
|
* `sohl-kethira-basic` (unofficial Hârn fan material under Keléstia Productions'
|
package/types/engine/ids.d.mts
CHANGED
|
@@ -148,6 +148,17 @@ export const MAP_SUBTYPES: readonly string[];
|
|
|
148
148
|
* @type {ReadonlySet<string>}
|
|
149
149
|
*/
|
|
150
150
|
export const JOURNAL_TYPES: ReadonlySet<string>;
|
|
151
|
+
/**
|
|
152
|
+
* The `pack:` value that routes a note's document into no compendium.
|
|
153
|
+
*
|
|
154
|
+
* One reading, on the key that already decides which compendium receives a
|
|
155
|
+
* note: the note publishes to the site and compiles into nothing. Declared
|
|
156
|
+
* here, beside the pack table, so the configuration can refuse a pack of this
|
|
157
|
+
* name and the router can read the value from one spelling.
|
|
158
|
+
*
|
|
159
|
+
* @type {string}
|
|
160
|
+
*/
|
|
161
|
+
export const NO_PACK: string;
|
|
151
162
|
/**
|
|
152
163
|
* Content type → the pack its documents compile into, and the document type
|
|
153
164
|
* that pack holds.
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a note declares `pack: none` for one system's document.
|
|
3
|
+
*
|
|
4
|
+
* The same reading {@link createPackRouter}'s `resolve` applies: the system's
|
|
5
|
+
* block wins where it declares a pack, and the shared top-level value stands
|
|
6
|
+
* otherwise. Asked with no system, it reads the shared value alone, which is
|
|
7
|
+
* what every single-system build and the content index read.
|
|
8
|
+
*
|
|
9
|
+
* Pure, so the readers that never route — the Foundry-address pass, the link
|
|
10
|
+
* index, the unclaimed-type check — can ask it without a router.
|
|
11
|
+
*
|
|
12
|
+
* @param {object} fm - The note's frontmatter.
|
|
13
|
+
* @param {string} [system] - The system whose document is asked about.
|
|
14
|
+
* @returns {boolean} True when the answer for that document is `none`.
|
|
15
|
+
*/
|
|
16
|
+
export function declaresNoPack(fm: object, system?: string): boolean;
|
|
1
17
|
/**
|
|
2
18
|
* Build the router for one configured pack list.
|
|
3
19
|
*
|
|
@@ -6,13 +22,13 @@
|
|
|
6
22
|
*
|
|
7
23
|
* @param {readonly object[]} packs - The resolved `packs` list from
|
|
8
24
|
* `defineConfig`.
|
|
9
|
-
* @returns {{resolve: (fm: object, docType: string, system?: string) => string,
|
|
25
|
+
* @returns {{resolve: (fm: object, docType: string, system?: string) => string|undefined,
|
|
10
26
|
* resolveOrNull: (fm: object, docType: string, system?: string) => string|undefined,
|
|
11
27
|
* packsOfType: (docType: string) => string[],
|
|
12
28
|
* defaultOf: (docType: string) => string|undefined}} The router.
|
|
13
29
|
*/
|
|
14
30
|
export function createPackRouter(packs: readonly object[]): {
|
|
15
|
-
resolve: (fm: object, docType: string, system?: string) => string;
|
|
31
|
+
resolve: (fm: object, docType: string, system?: string) => string | undefined;
|
|
16
32
|
resolveOrNull: (fm: object, docType: string, system?: string) => string | undefined;
|
|
17
33
|
packsOfType: (docType: string) => string[];
|
|
18
34
|
defaultOf: (docType: string) => string | undefined;
|
|
@@ -52,3 +68,5 @@ export class PackRoutingError extends Error {
|
|
|
52
68
|
* says which *compendium* receives its document.
|
|
53
69
|
*/
|
|
54
70
|
export const PACK_FIELD: "pack";
|
|
71
|
+
export { NO_PACK };
|
|
72
|
+
import { NO_PACK } from "./ids.mjs";
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Every `.md` file under `dir`, depth-first in directory order.
|
|
3
|
-
*
|
|
4
|
-
* Deliberately *not* {@link walkMarkdownTree}, whose stack-based walk yields a
|
|
5
|
-
* tree in reverse. Order was load-bearing here when the address index carried
|
|
6
|
-
* first-writer-wins fallbacks for a page's name, filename and slug — reversing
|
|
7
|
-
* the walk silently changed which page an ambiguous name resolved to. Those
|
|
8
|
-
* fallbacks are gone with the bare `[[Name]]` form, so this is now
|
|
9
|
-
* ordinary reading order rather than a dependency; it is kept because a site's
|
|
10
|
-
* emitted pages should not reorder for no reason.
|
|
11
|
-
*
|
|
12
|
-
* @param {string} dir - Directory to walk.
|
|
13
|
-
* @param {readonly string[]} skip - Directory names to ignore at any depth.
|
|
14
|
-
* @returns {string[]} Absolute paths.
|
|
15
|
-
*/
|
|
16
|
-
export function walkSiteTree(dir: string, skip?: readonly string[]): string[];
|
|
17
1
|
/**
|
|
18
2
|
* The content tree's pages, and what could not be addressed.
|
|
19
3
|
*
|
|
@@ -29,29 +13,6 @@ export function collectContentPages(contentBase: string, ctx: object): {
|
|
|
29
13
|
addressFindings: object[];
|
|
30
14
|
fmLinkFindings: object[];
|
|
31
15
|
};
|
|
32
|
-
/**
|
|
33
|
-
* An extra tree's pages — a documentation tree published alongside the content.
|
|
34
|
-
*
|
|
35
|
-
* These preserve their **source layout** below the section rather than being
|
|
36
|
-
* addressed by type and slug: they are a book with chapters, and a reader
|
|
37
|
-
* follows their paths. A `README` is its directory's landing.
|
|
38
|
-
*
|
|
39
|
-
* **The section is the tree's, never the note's.** `tree.section` is the
|
|
40
|
-
* mount point a `trees` entry configures — fixed, physical, and the same
|
|
41
|
-
* value `site-index.mjs` indexes a tree page's address under. A note's own
|
|
42
|
-
* `subType` is a genre and reaches no address, the same contract
|
|
43
|
-
* `packageAddress()` holds for a content page: reading it here would move a
|
|
44
|
-
* page's URL, its file destination (`pageDestination`) and the address a
|
|
45
|
-
* wikilink cites it by, every time an author classified it.
|
|
46
|
-
*
|
|
47
|
-
* @param {object} tree - `{ from, rel, section, route }`.
|
|
48
|
-
* @param {object} ctx - `{ mount }`.
|
|
49
|
-
* @returns {{pages: object[], fmLinkFindings: object[]}}
|
|
50
|
-
*/
|
|
51
|
-
export function collectTreePages(tree: object, ctx: object): {
|
|
52
|
-
pages: object[];
|
|
53
|
-
fmLinkFindings: object[];
|
|
54
|
-
};
|
|
55
16
|
/**
|
|
56
17
|
* The package's homepage notes — the authored page at `/<contentPackage>/`.
|
|
57
18
|
*
|
|
@@ -226,15 +187,8 @@ export function sectionFrontmatter(meta: object): object;
|
|
|
226
187
|
* self-describing and makes sweeping the field out of a content tree
|
|
227
188
|
* output-preserving for a site as it already is for the packs.
|
|
228
189
|
*
|
|
229
|
-
* A **tree** page is the one that still reads `readmeSections`: a `trees` entry
|
|
230
|
-
* keeps its source layout below a named section, so its own `README` is that
|
|
231
|
-
* section's landing and takes the title and hero the section declares.
|
|
232
|
-
*
|
|
233
190
|
* @param {object} page - The page.
|
|
234
191
|
* @param {object} options
|
|
235
|
-
* @param {Record<string, object>} [options.readmeSections] - The sections a
|
|
236
|
-
* published tree declares, which a tree page's own `README` is the landing
|
|
237
|
-
* for.
|
|
238
192
|
* @param {(data: object, page: object) => void} [options.decorate] - Called
|
|
239
193
|
* with each page's frontmatter, for whatever a consumer's own pass adds.
|
|
240
194
|
* @param {(value: unknown, type: string) => string|null} [options.artSrc] -
|
|
@@ -246,8 +200,7 @@ export function sectionFrontmatter(meta: object): object;
|
|
|
246
200
|
* same way.
|
|
247
201
|
* @returns {object} The frontmatter to write.
|
|
248
202
|
*/
|
|
249
|
-
export function pageFrontmatter(page: object, {
|
|
250
|
-
readmeSections?: Record<string, object> | undefined;
|
|
203
|
+
export function pageFrontmatter(page: object, { decorate, webSrc, artSrc }: {
|
|
251
204
|
decorate?: ((data: object, page: object) => void) | undefined;
|
|
252
205
|
artSrc?: ((value: unknown, type: string) => string | null) | undefined;
|
|
253
206
|
webSrc?: ((src: string) => string) | undefined;
|
|
@@ -267,12 +220,10 @@ export function pageFrontmatter(page: object, { readmeSections, decorate, webSrc
|
|
|
267
220
|
* the same as another note's `type`, and `doc-gear.md` and `weapongear-gear.md`
|
|
268
221
|
* are distinct whatever the sections.
|
|
269
222
|
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
* addressed by their path — so a `README` there is still its directory's
|
|
273
|
-
* `_index.md`.
|
|
223
|
+
* @param {object} page - The page.
|
|
224
|
+
* @returns {string} The file, relative to the mount.
|
|
274
225
|
*/
|
|
275
|
-
export function pageDestination(page:
|
|
226
|
+
export function pageDestination(page: object): string;
|
|
276
227
|
/**
|
|
277
228
|
* Renders and writes every page.
|
|
278
229
|
*
|
|
@@ -283,10 +234,10 @@ export function pageDestination(page: any): string;
|
|
|
283
234
|
* authored as a fenced `dataview` block, which `protectCode` would otherwise
|
|
284
235
|
* stash away before the expander saw it. Expanding first leaves an ordinary
|
|
285
236
|
* markdown table to walk, with every other fence still protected.
|
|
286
|
-
* 2. **Then, inside protection**: the consumer's `beforeLinks` pass,
|
|
287
|
-
* resolution
|
|
288
|
-
*
|
|
289
|
-
*
|
|
237
|
+
* 2. **Then, inside protection**: the consumer's `beforeLinks` pass, then
|
|
238
|
+
* wikilink resolution. A `{@link}` tag may sit in prose a wikilink also
|
|
239
|
+
* touches, so the repository's own rewrite runs before the shared one
|
|
240
|
+
* rather than replacing it.
|
|
290
241
|
*
|
|
291
242
|
* @param {object[]} pages - Every page.
|
|
292
243
|
* @param {object} options - Everything the render needs.
|
|
@@ -324,9 +275,9 @@ export function renderPages(pages: object[], options: object): {
|
|
|
324
275
|
* or its own address publishes nothing. Hugo generates a section page
|
|
325
276
|
* automatically only for a *top-level* content directory; below that, a
|
|
326
277
|
* directory without an `_index.md` is not a section, so its URL 404s while its
|
|
327
|
-
* children publish normally. With content pages flat,
|
|
328
|
-
*
|
|
329
|
-
*
|
|
278
|
+
* children publish normally. With content pages flat, no note creates a
|
|
279
|
+
* directory below the mount, so this reaches only what something else
|
|
280
|
+
* placed there.
|
|
330
281
|
*
|
|
331
282
|
* **A section listing is not a page listing any more.** A layout that reads
|
|
332
283
|
* `.Pages` off a section it declares here will find nothing, because no file is
|
|
@@ -373,11 +324,10 @@ export function pluralTitle(name: string): string;
|
|
|
373
324
|
*
|
|
374
325
|
* @param {string|undefined} name - The configured name.
|
|
375
326
|
* @param {object} options - The configured options, plus `repoRoot`.
|
|
376
|
-
* @returns {{beforeLinks?: Function
|
|
327
|
+
* @returns {{beforeLinks?: Function}} The bundle.
|
|
377
328
|
*/
|
|
378
329
|
export function resolveSitePass(name: string | undefined, options: object): {
|
|
379
330
|
beforeLinks?: Function;
|
|
380
|
-
afterLinks?: Function;
|
|
381
331
|
};
|
|
382
332
|
/**
|
|
383
333
|
* Builds a Hugo content tree from a content tree, and reports what it found.
|
|
@@ -94,9 +94,9 @@ export function resolveInfoboxRef(siteIndex: SiteIndex, ref: unknown, hint?: obj
|
|
|
94
94
|
export type SiteEntry = {
|
|
95
95
|
/**
|
|
96
96
|
* `"content"` for a note compiled from the content
|
|
97
|
-
* tree
|
|
98
|
-
*
|
|
99
|
-
*
|
|
97
|
+
* tree. Only content entries take part in
|
|
98
|
+
* type-scoped indexing; anything else is carried
|
|
99
|
+
* through unindexed.
|
|
100
100
|
*/
|
|
101
101
|
kind: string;
|
|
102
102
|
/**
|
|
@@ -111,13 +111,6 @@ export type SiteEntry = {
|
|
|
111
111
|
* URL segment.
|
|
112
112
|
*/
|
|
113
113
|
slug: string;
|
|
114
|
-
/**
|
|
115
|
-
* The Hugo section a **tree** page is filed under, and
|
|
116
|
-
* the first segment of the `<sec>/<slug>` address it
|
|
117
|
-
* is reachable by. A content page has none: it is
|
|
118
|
-
* addressed by `(type, shortcode)` and emitted flat.
|
|
119
|
-
*/
|
|
120
|
-
sec?: string | undefined;
|
|
121
114
|
/**
|
|
122
115
|
* Source file's basename, e.g. `Climbing.md`.
|
|
123
116
|
*/
|
|
@@ -126,11 +119,6 @@ export type SiteEntry = {
|
|
|
126
119
|
* The page's published address.
|
|
127
120
|
*/
|
|
128
121
|
url: string;
|
|
129
|
-
/**
|
|
130
|
-
* Whether a tree page is its directory's
|
|
131
|
-
* landing.
|
|
132
|
-
*/
|
|
133
|
-
isReadme?: boolean | undefined;
|
|
134
122
|
};
|
|
135
123
|
/**
|
|
136
124
|
* The resolved index and everything a wikilink resolver reads beside it.
|
|
@@ -157,10 +145,6 @@ export type SiteIndex = {
|
|
|
157
145
|
* an address qualifier, local and foreign.
|
|
158
146
|
*/
|
|
159
147
|
contentTypes: Set<string>;
|
|
160
|
-
/**
|
|
161
|
-
* Section names, lowercased.
|
|
162
|
-
*/
|
|
163
|
-
sections: Set<string>;
|
|
164
148
|
/**
|
|
165
149
|
* `type:shortcode` → page, for callers
|
|
166
150
|
* resolving embedded references (a
|
|
@@ -171,13 +155,4 @@ export type SiteIndex = {
|
|
|
171
155
|
url: string;
|
|
172
156
|
subType?: string;
|
|
173
157
|
}>;
|
|
174
|
-
/**
|
|
175
|
-
* Addresses claimed by
|
|
176
|
-
* more than one package. Non-empty is a
|
|
177
|
-
* build failure; the caller reports it.
|
|
178
|
-
*/
|
|
179
|
-
conflicts: {
|
|
180
|
-
key: string;
|
|
181
|
-
package: string;
|
|
182
|
-
}[];
|
|
183
158
|
};
|
|
@@ -77,7 +77,7 @@ export function frontmatterWikilinks(fm: unknown): Array<{
|
|
|
77
77
|
* for the website, and what the book reads its staging list out of.
|
|
78
78
|
*
|
|
79
79
|
* @param {string} body - The markdown body.
|
|
80
|
-
* @param {object} ctx - `{ index, assets, collide,
|
|
80
|
+
* @param {object} ctx - `{ index, assets, collide, contentTypes,
|
|
81
81
|
* packages, noIndexPackages, foreign, type, errors, src, file }`.
|
|
82
82
|
* `packages` is every package an address may name, without which the leading
|
|
83
83
|
* package segment of a canonical address reads as an unknown type;
|
|
@@ -122,12 +122,14 @@ export function anchorPageId(noteId: string, anchorSlug: string): string;
|
|
|
122
122
|
* Builds the link-resolution tables for a content tree.
|
|
123
123
|
*
|
|
124
124
|
* @param {Array<{type: string, id: string, shortcode?: string|null,
|
|
125
|
-
* name?: string, pack?: string, docPack?: string,
|
|
125
|
+
* name?: string, pack?: string, docPack?: string, none?: boolean,
|
|
126
126
|
* draft?: boolean}>} docs -
|
|
127
127
|
* One entry per content note. `pack` / `docPack` name the packs the note's
|
|
128
128
|
* document and its documentation entry landed in; omitted, the conventional
|
|
129
|
-
* one-pack-per-type names stand in. `
|
|
130
|
-
*
|
|
129
|
+
* one-pack-per-type names stand in. `none` says the note declares
|
|
130
|
+
* `pack: none` and compiles into no document, so it has no UUID to link to.
|
|
131
|
+
* `draft` says the note carries the `draft` tag, which marks links *into* it
|
|
132
|
+
* and changes nothing else.
|
|
131
133
|
* @param {string} packageId - The Foundry package shipping the packs; the first
|
|
132
134
|
* segment of every emitted UUID.
|
|
133
135
|
* @param {Map<string, object>} [foreign] - Canonically keyed entries from
|
|
@@ -153,6 +155,7 @@ export function buildWikilinkIndex(docs: Array<{
|
|
|
153
155
|
name?: string;
|
|
154
156
|
pack?: string;
|
|
155
157
|
docPack?: string;
|
|
158
|
+
none?: boolean;
|
|
156
159
|
draft?: boolean;
|
|
157
160
|
}>, packageId: string, foreign?: Map<string, object>, contentPackage?: string, { assets, noIndexPackages }?: {
|
|
158
161
|
assets?: Map<string, object> | undefined;
|
|
@@ -17,59 +17,28 @@
|
|
|
17
17
|
* @returns {string} The body with every tag resolved.
|
|
18
18
|
*/
|
|
19
19
|
export function resolveApiLinks(body: string, symbols: Record<string, string>, apiBase: string): string;
|
|
20
|
-
/**
|
|
21
|
-
* Rewrites the relative links in a developer-doc body so they resolve on the
|
|
22
|
-
* published site.
|
|
23
|
-
*
|
|
24
|
-
* Developer docs are authored to link one another and the source tree with
|
|
25
|
-
* repository-relative paths, and neither target exists at the same path once
|
|
26
|
-
* rendered. Each link is resolved against the doc's own location:
|
|
27
|
-
*
|
|
28
|
-
* - a `*.md` link landing inside the documentation tree becomes the published
|
|
29
|
-
* route, preserving any `#anchor`; a `README` is its directory's landing, so
|
|
30
|
-
* that segment is dropped.
|
|
31
|
-
* - anything else — source, templates, a repository-root `*.md` — becomes its
|
|
32
|
-
* GitHub blob URL.
|
|
33
|
-
*
|
|
34
|
-
* Absolute URLs, anchor-only links, `mailto:` and site-root links are untouched.
|
|
35
|
-
*
|
|
36
|
-
* @param {string} body - The markdown body.
|
|
37
|
-
* @param {string} docRel - The doc's path relative to the documentation tree.
|
|
38
|
-
* @param {object} options - `{ repoRoot, docsSrc, docsRel, route, blob }`.
|
|
39
|
-
* @returns {string} The body with every relative link rewritten.
|
|
40
|
-
*/
|
|
41
|
-
export function rewriteRepoLinks(body: string, docRel: string, options: object): string;
|
|
42
20
|
/**
|
|
43
21
|
* The `sohl` knowledgebase pass bundle, built from its options.
|
|
44
22
|
*
|
|
45
|
-
* A pass bundle is
|
|
46
|
-
* resolution,
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* `{@link}` tag may sit inside prose a wikilink also touches.
|
|
50
|
-
* - `afterLinks` runs only on pages from an **extra tree** — the documentation
|
|
51
|
-
* tree — because repository-relative links are a property of how those pages
|
|
52
|
-
* are authored, not of content notes.
|
|
53
|
-
*
|
|
54
|
-
* Both run inside code-fence protection, so neither can rewrite a fenced example.
|
|
23
|
+
* A pass bundle is the hook the page renderer calls before wikilink
|
|
24
|
+
* resolution: `beforeLinks` runs on every page, before wikilinks resolve,
|
|
25
|
+
* because a `{@link}` tag may sit inside prose a wikilink also touches. It
|
|
26
|
+
* runs inside code-fence protection, so it cannot rewrite a fenced example.
|
|
55
27
|
*
|
|
56
28
|
* @param {object} options - Resolved from `site.passOptions`.
|
|
57
29
|
* @param {string} [options.symbolMap] - Path to the TypeDoc symbol map,
|
|
58
30
|
* relative to `repoRoot`. Absent means no API links; present and unusable is
|
|
59
31
|
* a build failure.
|
|
60
32
|
* @param {string} [options.apiBase] - Where the API documentation is served.
|
|
61
|
-
* @param {string} [options.blob] - GitHub blob base for repository files.
|
|
62
33
|
* @param {string} options.repoRoot - The repository root, for relative paths.
|
|
63
|
-
* @returns {{beforeLinks: Function
|
|
34
|
+
* @returns {{beforeLinks: Function}} The bundle.
|
|
64
35
|
* @throws {Error} When a configured `symbolMap` cannot be resolved, read,
|
|
65
36
|
* parsed, or is not a name → page object.
|
|
66
37
|
*/
|
|
67
38
|
export function sohlKbPass(options: {
|
|
68
39
|
symbolMap?: string | undefined;
|
|
69
40
|
apiBase?: string | undefined;
|
|
70
|
-
blob?: string | undefined;
|
|
71
41
|
repoRoot: string;
|
|
72
42
|
}): {
|
|
73
43
|
beforeLinks: Function;
|
|
74
|
-
afterLinks: Function;
|
|
75
44
|
};
|