@heroiclands/package-build 23.7.1 → 23.9.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 +41 -0
- package/README.md +32 -0
- package/bin/content-commands.mjs +32 -10
- package/ci/check-banners.mjs +37 -19
- package/container.mjs +48 -10
- package/docs/api.md +402 -58
- package/docs/authoring/first-note.md +1 -1
- package/docs/authoring/frontmatter.md +30 -1
- package/docs/authoring/links-and-markup.md +154 -56
- package/docs/commands.md +31 -12
- package/docs/content-format.md +25 -2
- package/docs/design.md +31 -0
- package/docs/diagnostics.md +1 -1
- package/docs/guides/e2e.md +37 -1
- package/docs/guides/packs.md +2 -1
- package/docs/guides/reference-pages.md +86 -63
- package/docs/project-setup.md +30 -15
- package/docs/reference/format-details.md +313 -132
- package/docs/reference/note-types.md +191 -174
- package/e2e.mjs +89 -2
- package/engine/anchors.mjs +7 -20
- package/engine/base-compiler.mjs +11 -18
- package/engine/compile-corpus.mjs +5 -3
- package/engine/content-alerts.mjs +4 -2
- package/engine/content-blocks.mjs +18 -36
- package/engine/content-format.yaml +1 -0
- package/engine/content-index.mjs +447 -33
- package/engine/content-links.mjs +43 -15
- package/engine/content-poetry.mjs +9 -0
- package/engine/content-tables.mjs +8 -4
- package/engine/culture-reach.mjs +61 -34
- package/engine/data-keys.mjs +3 -1
- package/engine/diagnostics.mjs +24 -11
- package/engine/dictionary-layout.mjs +151 -19
- package/engine/dictionary-rows.mjs +129 -79
- package/engine/foundry-entries.mjs +21 -3
- package/engine/frontmatter-lint.mjs +1 -1
- package/engine/generate.mjs +12 -22
- package/engine/glossary-entries.mjs +11 -11
- package/engine/heading-attributes.mjs +21 -28
- package/engine/helpers.mjs +20 -12
- package/engine/infobox.mjs +3 -0
- package/engine/journals.mjs +15 -2
- package/engine/language-data.mjs +53 -0
- package/engine/language-terms.mjs +86 -0
- package/engine/language-words.mjs +2 -2
- package/engine/lexical-sections.mjs +247 -0
- package/engine/markdownlint-run.mjs +12 -2
- package/engine/markup-validation.mjs +34 -0
- package/engine/note-addresses.mjs +1 -0
- package/engine/note-claims.mjs +21 -10
- package/engine/note-package.mjs +3 -5
- package/engine/note-state.mjs +9 -3
- package/engine/note-vocabulary.mjs +36 -7
- package/engine/pdf-build.mjs +17 -10
- package/engine/prose-lint.mjs +12 -6
- package/engine/related-pages.mjs +22 -3
- package/engine/see-also.mjs +150 -0
- package/engine/site-build.mjs +21 -3
- package/engine/site-preview.mjs +4 -2
- package/engine/sql-tables.mjs +287 -53
- package/engine/standings.mjs +14 -12
- package/engine/stub-lint.mjs +6 -2
- package/engine/web-wikilinks.mjs +8 -6
- package/engine/word-rows.mjs +20 -12
- package/engine/word-terms.mjs +15 -6
- package/hugo-theme/layouts/partials/related.html +25 -8
- package/package.json +2 -1
- package/types/container.d.mts +4 -3
- package/types/e2e.d.mts +28 -0
- package/types/engine/base-compiler.d.mts +2 -2
- package/types/engine/compile-corpus.d.mts +2 -1
- package/types/engine/content-index.d.mts +85 -8
- package/types/engine/content-tables.d.mts +2 -1
- package/types/engine/culture-reach.d.mts +22 -2
- package/types/engine/data-keys.d.mts +7 -0
- package/types/engine/diagnostics.d.mts +7 -6
- package/types/engine/dictionary-layout.d.mts +35 -4
- package/types/engine/dictionary-rows.d.mts +9 -0
- package/types/engine/foundry-entries.d.mts +3 -1
- package/types/engine/heading-attributes.d.mts +2 -2
- package/types/engine/helpers.d.mts +11 -5
- package/types/engine/language-terms.d.mts +7 -0
- package/types/engine/lexical-sections.d.mts +95 -0
- package/types/engine/markdownlint-run.d.mts +3 -1
- package/types/engine/markup-validation.d.mts +14 -0
- package/types/engine/note-addresses.d.mts +10 -0
- package/types/engine/note-claims.d.mts +7 -1
- package/types/engine/note-package.d.mts +3 -1
- package/types/engine/note-state.d.mts +2 -1
- package/types/engine/note-vocabulary.d.mts +1 -0
- package/types/engine/related-pages.d.mts +10 -1
- package/types/engine/see-also.d.mts +55 -0
- package/types/engine/site-build.d.mts +4 -1
- package/types/engine/sql-tables.d.mts +40 -6
- package/types/engine/word-rows.d.mts +9 -7
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render a dictionary entry's marked headword as an inline native heading in
|
|
3
|
+
* Foundry. Its paragraph becomes a div, so the heading has a valid container.
|
|
4
|
+
* The shared Markdown keeps its span and its containing journal page.
|
|
5
|
+
*
|
|
6
|
+
* @param {import("markdown-it")} md - The Foundry Markdown parser.
|
|
7
|
+
*/
|
|
8
|
+
export function dictionaryEntryPlugin(md: typeof import("markdown-it")): void;
|
|
1
9
|
/**
|
|
2
10
|
* @typedef {object} LayoutOptions
|
|
3
11
|
* @property {(ref: object) => boolean} [linkable] - Whether an Address can be
|
|
@@ -6,10 +14,16 @@
|
|
|
6
14
|
* @property {object} [addressContext] - Address resolution context.
|
|
7
15
|
* @property {(address: string) => string|undefined} [labelOf] - A note's
|
|
8
16
|
* `name.full`, by its Address.
|
|
9
|
-
* @property {boolean|"only"} [showKey=true] - Whether the key
|
|
10
|
-
* `"only"` prints the key and nothing else.
|
|
17
|
+
* @property {boolean|"only"} [showKey=true] - Whether the key and dictionary
|
|
18
|
+
* head tables are printed; `"only"` prints the key and nothing else.
|
|
11
19
|
* @property {string} [pageLanguage] - The language of the page the fence is
|
|
12
20
|
* on, which no entry is tagged with.
|
|
21
|
+
* @property {string} [pageOwner] - The containing page's canonical note Address;
|
|
22
|
+
* a sense attributed only to its own row's owner omits that label on this page.
|
|
23
|
+
* @property {boolean} [entryAnchors=true] - Whether dictionary headwords carry
|
|
24
|
+
* their canonical targets; custom SQL views leave those to the automatic list.
|
|
25
|
+
* @property {object} [verbs] - The owning language's stated pattern, including
|
|
26
|
+
* when its automatic dictionary has no eligible word entries.
|
|
13
27
|
*/
|
|
14
28
|
/**
|
|
15
29
|
* Render a result of words as a dictionary.
|
|
@@ -44,6 +58,8 @@ export const LAYOUT_REQUIRED_COLUMNS: Readonly<{
|
|
|
44
58
|
}>;
|
|
45
59
|
/** The mark a common entry opens with. */
|
|
46
60
|
export const COMMON_MARK: "\u2022";
|
|
61
|
+
/** The word-entry span class whose Foundry rendering is a native TOC heading. */
|
|
62
|
+
export const DICTIONARY_ENTRY_CLASS: "dictionary-entry";
|
|
47
63
|
export type LayoutOptions = {
|
|
48
64
|
/**
|
|
49
65
|
* - Whether an Address can be
|
|
@@ -64,8 +80,8 @@ export type LayoutOptions = {
|
|
|
64
80
|
*/
|
|
65
81
|
labelOf?: ((address: string) => string | undefined) | undefined;
|
|
66
82
|
/**
|
|
67
|
-
* - Whether the key
|
|
68
|
-
* `"only"` prints the key and nothing else.
|
|
83
|
+
* - Whether the key and dictionary
|
|
84
|
+
* head tables are printed; `"only"` prints the key and nothing else.
|
|
69
85
|
*/
|
|
70
86
|
showKey?: boolean | "only" | undefined;
|
|
71
87
|
/**
|
|
@@ -73,4 +89,19 @@ export type LayoutOptions = {
|
|
|
73
89
|
* on, which no entry is tagged with.
|
|
74
90
|
*/
|
|
75
91
|
pageLanguage?: string | undefined;
|
|
92
|
+
/**
|
|
93
|
+
* - The containing page's canonical note Address;
|
|
94
|
+
* a sense attributed only to its own row's owner omits that label on this page.
|
|
95
|
+
*/
|
|
96
|
+
pageOwner?: string | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* - Whether dictionary headwords carry
|
|
99
|
+
* their canonical targets; custom SQL views leave those to the automatic list.
|
|
100
|
+
*/
|
|
101
|
+
entryAnchors?: boolean | undefined;
|
|
102
|
+
/**
|
|
103
|
+
* - The owning language's stated pattern, including
|
|
104
|
+
* when its automatic dictionary has no eligible word entries.
|
|
105
|
+
*/
|
|
106
|
+
verbs?: object | undefined;
|
|
76
107
|
};
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The stable prose anchor of a word in one language's dictionary. The exact
|
|
3
|
+
* language and NFC form identify it, including case and accents.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} language - The language's canonical note Address.
|
|
6
|
+
* @param {string} name - The dictionary headword.
|
|
7
|
+
* @returns {string} The anchor slug.
|
|
8
|
+
*/
|
|
9
|
+
export function dictionaryEntryAnchor(language: string, name: string): string;
|
|
1
10
|
/**
|
|
2
11
|
* The heading letter of a sort key: its first letter or digit, accents taken
|
|
3
12
|
* off and apostrophes skipped, in capitals; `#` where it has none.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Every
|
|
2
|
+
* Every anchor of a note's journal, as `anchorName → Foundry target`.
|
|
3
|
+
* A dictionary word's native heading carries its fragment after the
|
|
4
|
+
* containing page's UUID.
|
|
3
5
|
*
|
|
4
6
|
* Whole, not a fragment appended to the entry's UUID: nothing owns a page
|
|
5
7
|
* address, so a complete link restates no fact, and it keeps the page-id hash
|
|
@@ -46,8 +46,8 @@ export function opensPage({ level, id }: {
|
|
|
46
46
|
/**
|
|
47
47
|
* Every heading in a body, with what its attribute block declares.
|
|
48
48
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* Code and raw HTML blocks are skipped: an example heading in a document is
|
|
50
|
+
* not a heading of it, including an example in an HTML comment.
|
|
51
51
|
*
|
|
52
52
|
* @param {string} source - A note's markdown body.
|
|
53
53
|
* @param {number} [bodyLine=1] - The 1-based file line the body starts on, so a
|
|
@@ -19,17 +19,18 @@ export function renderFoundryMarkdown(body: string, figures?: Array<{
|
|
|
19
19
|
/**
|
|
20
20
|
* Parses a markdown file with YAML frontmatter.
|
|
21
21
|
*
|
|
22
|
-
* Returns `{ frontmatter, body, description, bodyLine, bodyColumn }` where
|
|
22
|
+
* Returns `{ frontmatter, body, description, bodyLine, bodyColumn, raw }` where
|
|
23
23
|
* `body` is the trimmed raw markdown after the frontmatter block, and
|
|
24
|
-
* `description` is `body` rendered to HTML.
|
|
24
|
+
* `description` is `body` rendered to HTML. The full source is retained as
|
|
25
|
+
* `raw` for diagnostic locations. `bodyLine` / `bodyColumn` are the
|
|
25
26
|
* 1-based **file** position of the body's first character, which is what turns
|
|
26
27
|
* an offset within `body` into a position a diagnostic can name — see
|
|
27
28
|
* {@link positionInBody}. If the file has no frontmatter block, returns
|
|
28
|
-
* `{ frontmatter: null, body: "", description: "" }`
|
|
29
|
+
* `{ frontmatter: null, body: "", description: "", raw }` and no
|
|
29
30
|
* position: there is no body to have one.
|
|
30
31
|
* @param {string} filePath - Markdown file to read.
|
|
31
32
|
* @param {{addressContext?: object}} [opts] - Address defaults for decoded fields.
|
|
32
|
-
* @returns {{frontmatter: object|null, body: string, description: string,
|
|
33
|
+
* @returns {{frontmatter: object|null, body: string, description: string, raw: string,
|
|
33
34
|
* bodyLine?: number, bodyColumn?: number, parseError?: {message: string,
|
|
34
35
|
* line?: number, column?: number}}} Parsed note and body position.
|
|
35
36
|
*/
|
|
@@ -39,6 +40,7 @@ export function parseMarkdownFile(filePath: string, { addressContext }?: {
|
|
|
39
40
|
frontmatter: object | null;
|
|
40
41
|
body: string;
|
|
41
42
|
description: string;
|
|
43
|
+
raw: string;
|
|
42
44
|
bodyLine?: number;
|
|
43
45
|
bodyColumn?: number;
|
|
44
46
|
parseError?: {
|
|
@@ -118,6 +120,7 @@ export function walkMarkdownTree(rootDir: string, { skipDirectories, addressCont
|
|
|
118
120
|
frontmatter: object | null;
|
|
119
121
|
body: string;
|
|
120
122
|
description: string;
|
|
123
|
+
raw: string;
|
|
121
124
|
bodyLine?: number;
|
|
122
125
|
bodyColumn?: number;
|
|
123
126
|
parseError?: {
|
|
@@ -361,11 +364,14 @@ export function defaultStats(): object;
|
|
|
361
364
|
* omitted.
|
|
362
365
|
* @param {readonly object[]} [opts.records] - The corpus, derived once per
|
|
363
366
|
* compile and handed in. Required: see {@link assertSuppliedCorpus}.
|
|
367
|
+
* @param {Map<string, object[]>} [opts.sqlTables] - Prepared directives,
|
|
368
|
+
* including the anchors and Foundry page maps of their expanded bodies.
|
|
364
369
|
* @returns {{byShortcode: Map, types: Set}} From `buildWikilinkIndex`.
|
|
365
370
|
*/
|
|
366
|
-
export function buildContentLinkIndex(contentBase: string, router?: object, { config, records }?: {
|
|
371
|
+
export function buildContentLinkIndex(contentBase: string, router?: object, { config, records, sqlTables }?: {
|
|
367
372
|
config?: object | undefined;
|
|
368
373
|
records?: readonly object[] | undefined;
|
|
374
|
+
sqlTables?: Map<string, object[]> | undefined;
|
|
369
375
|
}): {
|
|
370
376
|
byShortcode: Map<any, any>;
|
|
371
377
|
types: Set<any>;
|
|
@@ -319,6 +319,13 @@ export const NEAR_NAME_FIELDS: readonly import("./data-keys.mjs").InnerKeySpec[]
|
|
|
319
319
|
* @type {readonly import("./data-keys.mjs").InnerKeySpec[]}
|
|
320
320
|
*/
|
|
321
321
|
export const NAMING_FIELDS: readonly import("./data-keys.mjs").InnerKeySpec[];
|
|
322
|
+
/**
|
|
323
|
+
* The six present persons of the one optional regular verb pattern, in
|
|
324
|
+
* presentation order. Empty endings leave the citation form unchanged.
|
|
325
|
+
*
|
|
326
|
+
* @type {readonly import("./data-keys.mjs").InnerKeySpec[]}
|
|
327
|
+
*/
|
|
328
|
+
export const VERB_PERSON_FIELDS: readonly import("./data-keys.mjs").InnerKeySpec[];
|
|
322
329
|
/**
|
|
323
330
|
* The `data` fields this module declares, in the order the vocabulary lists
|
|
324
331
|
* them. {@link module:engine/language-data.checkLanguageData} checks what the
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether frontmatter supplies an automatic lexical section, including on a
|
|
3
|
+
* note with no authored prose. Such a note has content and is not a stub.
|
|
4
|
+
*
|
|
5
|
+
* @param {object|null|undefined} frontmatter - A note or its index record.
|
|
6
|
+
* @returns {boolean} Whether its own nonempty words or glossary qualify.
|
|
7
|
+
*/
|
|
8
|
+
export function hasLexicalEntries(frontmatter: object | null | undefined): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* One automatic section, whose rows are rendered at its containing heading's
|
|
11
|
+
* level when inserted.
|
|
12
|
+
*
|
|
13
|
+
* @typedef {object} LexicalSection
|
|
14
|
+
* @property {string} slug - The canonical section anchor and layout name.
|
|
15
|
+
* @property {string} heading - The heading used when none is authored.
|
|
16
|
+
* @property {readonly string[]} aliases - Authored heading anchors to reuse.
|
|
17
|
+
* @property {{columns: string[], rows: object[]}} result - The selected rows.
|
|
18
|
+
* @property {import("./dictionary-layout.mjs").LayoutOptions} options - Labels,
|
|
19
|
+
* linkability and the page's language, shared by every surface.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Automatic lexical sections by owning note's canonical Address. Only
|
|
23
|
+
* nonempty own `words` or `glossary` arrays qualify. A glossary selects only
|
|
24
|
+
* explicitly declared owner entries, including a rank only when named there.
|
|
25
|
+
*
|
|
26
|
+
* @param {object[]} records - The audience's visible index records.
|
|
27
|
+
* @param {object[]} [all=records] - Complete records for lineage traversal.
|
|
28
|
+
* @returns {Map<string, LexicalSection[]>} Sections by owning Address.
|
|
29
|
+
*/
|
|
30
|
+
export function lexicalSectionsFor(records: object[], all?: object[]): Map<string, LexicalSection[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Insert lists at the end of their authored anchored sections, or append a
|
|
33
|
+
* new H1 section when no heading names one. Source lines after an insertion
|
|
34
|
+
* retain their original positions; inserted lines point to their heading.
|
|
35
|
+
*
|
|
36
|
+
* @param {string} markdown - The body with authored directives expanded.
|
|
37
|
+
* @param {LexicalSection[]} [sections=[]] - From {@link lexicalSectionsFor}.
|
|
38
|
+
* @param {{authored?: string, lineMap?: object[], generatedFrom?: number}} [context] -
|
|
39
|
+
* The original authored body, source mappings and the start of appended
|
|
40
|
+
* nonlexical generated sections. Without `authored`, `markdown` is the source.
|
|
41
|
+
* @returns {{markdown: string, lineMap: object[], generatedFrom?: number}}
|
|
42
|
+
*/
|
|
43
|
+
export function insertLexicalSections(markdown: string, sections?: LexicalSection[], { authored, lineMap, generatedFrom }?: {
|
|
44
|
+
authored?: string;
|
|
45
|
+
lineMap?: object[];
|
|
46
|
+
generatedFrom?: number;
|
|
47
|
+
}): {
|
|
48
|
+
markdown: string;
|
|
49
|
+
lineMap: object[];
|
|
50
|
+
generatedFrom?: number;
|
|
51
|
+
};
|
|
52
|
+
/** The automatic lexical sections and the authored anchors each may reuse. */
|
|
53
|
+
export const LEXICAL_SECTIONS: readonly Readonly<{
|
|
54
|
+
aliases: readonly string[];
|
|
55
|
+
types: readonly Readonly<{
|
|
56
|
+
type: string;
|
|
57
|
+
subType: string;
|
|
58
|
+
} | {
|
|
59
|
+
type: string;
|
|
60
|
+
subType?: undefined;
|
|
61
|
+
}>[];
|
|
62
|
+
slug: string;
|
|
63
|
+
heading: string;
|
|
64
|
+
dataKey: string;
|
|
65
|
+
}>[];
|
|
66
|
+
/**
|
|
67
|
+
* One automatic section, whose rows are rendered at its containing heading's
|
|
68
|
+
* level when inserted.
|
|
69
|
+
*/
|
|
70
|
+
export type LexicalSection = {
|
|
71
|
+
/**
|
|
72
|
+
* - The canonical section anchor and layout name.
|
|
73
|
+
*/
|
|
74
|
+
slug: string;
|
|
75
|
+
/**
|
|
76
|
+
* - The heading used when none is authored.
|
|
77
|
+
*/
|
|
78
|
+
heading: string;
|
|
79
|
+
/**
|
|
80
|
+
* - Authored heading anchors to reuse.
|
|
81
|
+
*/
|
|
82
|
+
aliases: readonly string[];
|
|
83
|
+
/**
|
|
84
|
+
* - The selected rows.
|
|
85
|
+
*/
|
|
86
|
+
result: {
|
|
87
|
+
columns: string[];
|
|
88
|
+
rows: object[];
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* - Labels,
|
|
92
|
+
* linkability and the page's language, shared by every surface.
|
|
93
|
+
*/
|
|
94
|
+
options: import("./dictionary-layout.mjs").LayoutOptions;
|
|
95
|
+
};
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
* `config`, `ignores`, `gitignore` and `globs`.
|
|
10
10
|
* @param {boolean} [params.fix=false] - Repair what markdownlint can, then
|
|
11
11
|
* report what remains.
|
|
12
|
-
* @returns {Promise<{results: object[]}>} markdownlint results, each with its
|
|
12
|
+
* @returns {Promise<{results: object[], markup: object[]}>} markdownlint results, each with its
|
|
13
13
|
* `fileName` relative to `directory`, ordered by file, line and rule.
|
|
14
|
+
* `markup` carries block syntax diagnostics with absolute filenames.
|
|
14
15
|
* @throws {MarkdownConfigError} A configuration file the contract refuses.
|
|
15
16
|
*/
|
|
16
17
|
export function runMarkdownlint(params: {
|
|
@@ -20,6 +21,7 @@ export function runMarkdownlint(params: {
|
|
|
20
21
|
fix?: boolean | undefined;
|
|
21
22
|
}): Promise<{
|
|
22
23
|
results: object[];
|
|
24
|
+
markup: object[];
|
|
23
25
|
}>;
|
|
24
26
|
/** Keys an options file may declare at the repository root. */
|
|
25
27
|
export const ROOT_OPTION_KEYS: readonly string[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate authored block syntax with positions in the original file.
|
|
3
|
+
* Frontmatter is masked so literal YAML values cannot become body markup.
|
|
4
|
+
* @param {string} source - Complete Markdown source, optionally with frontmatter.
|
|
5
|
+
* @param {string} file - Diagnostic filename.
|
|
6
|
+
* @returns {Array<{file: string, line: number, column: number, severity: string, message: string}>} Syntax errors.
|
|
7
|
+
*/
|
|
8
|
+
export function markupFindings(source: string, file: string): Array<{
|
|
9
|
+
file: string;
|
|
10
|
+
line: number;
|
|
11
|
+
column: number;
|
|
12
|
+
severity: string;
|
|
13
|
+
message: string;
|
|
14
|
+
}>;
|
|
@@ -71,12 +71,21 @@ export const STRUCTURED_ADDRESSES: readonly ({
|
|
|
71
71
|
noteType: string;
|
|
72
72
|
path: (string | string[] | undefined)[];
|
|
73
73
|
shape: string;
|
|
74
|
+
} | {
|
|
75
|
+
path: string[];
|
|
76
|
+
shape: string;
|
|
77
|
+
lenient: boolean;
|
|
78
|
+
type?: undefined;
|
|
79
|
+
accepts?: undefined;
|
|
80
|
+
system?: undefined;
|
|
81
|
+
noteType?: undefined;
|
|
74
82
|
} | {
|
|
75
83
|
path: string[];
|
|
76
84
|
shape: string;
|
|
77
85
|
type: string;
|
|
78
86
|
accepts: string[];
|
|
79
87
|
system: string;
|
|
88
|
+
lenient?: undefined;
|
|
80
89
|
noteType?: undefined;
|
|
81
90
|
} | {
|
|
82
91
|
noteType: string;
|
|
@@ -84,6 +93,7 @@ export const STRUCTURED_ADDRESSES: readonly ({
|
|
|
84
93
|
shape: string;
|
|
85
94
|
type: string;
|
|
86
95
|
accepts: string[];
|
|
96
|
+
lenient?: undefined;
|
|
87
97
|
system?: undefined;
|
|
88
98
|
})[];
|
|
89
99
|
export { AddressEntries, encodeAddresses, cloneAddressState, publishAddresses, readPublishedAddresses, flattenPublishedAddresses } from "./address-values.mjs";
|
|
@@ -120,11 +120,17 @@ export function noteTypeVocabulary(sources?: ClaimSources): ReadonlySet<string>;
|
|
|
120
120
|
* @param {object} [opts] - Options.
|
|
121
121
|
* @param {readonly object[]} [opts.records] - The corpus, derived once by the
|
|
122
122
|
* compile and handed in — required, for the reason above.
|
|
123
|
+
* @param {Map<string, {body: string, raw: string}>} [opts.parsed] - Already parsed
|
|
124
|
+
* notes, keyed by file, for body checks and finding positions.
|
|
123
125
|
* @returns {Array<{file: string, line?: number, column?: number,
|
|
124
126
|
* severity: "error", message: string, type: string}>} One finding per note.
|
|
125
127
|
*/
|
|
126
|
-
export function unclaimedNoteFindings(config?: object, sources?: ClaimSources, { records }?: {
|
|
128
|
+
export function unclaimedNoteFindings(config?: object, sources?: ClaimSources, { records, parsed }?: {
|
|
127
129
|
records?: readonly object[] | undefined;
|
|
130
|
+
parsed?: Map<string, {
|
|
131
|
+
body: string;
|
|
132
|
+
raw: string;
|
|
133
|
+
}> | undefined;
|
|
128
134
|
}): Array<{
|
|
129
135
|
file: string;
|
|
130
136
|
line?: number;
|
|
@@ -21,13 +21,15 @@ export function searchableFrontmatter(fm: object | null | undefined, configured?
|
|
|
21
21
|
* @param {string} [options.absPath] - The note's file on disk, read only on the
|
|
22
22
|
* failing path to locate the offending line and column. The position rides on
|
|
23
23
|
* the thrown error as `position`, for a caller that emits a diagnostic.
|
|
24
|
+
* @param {string} [options.raw] - Source text already read by the caller.
|
|
24
25
|
* @param {string} [options.configured] - The package this build compiles.
|
|
25
26
|
* Defaults to the configured `contentPackage`.
|
|
26
27
|
* @returns {void}
|
|
27
28
|
* @throws {Error} When the note declares the field.
|
|
28
29
|
*/
|
|
29
|
-
export function assertNoDeclaredPackage(fm: object | null | undefined, { file, absPath, configured }?: {
|
|
30
|
+
export function assertNoDeclaredPackage(fm: object | null | undefined, { file, absPath, configured, raw }?: {
|
|
30
31
|
file?: string | undefined;
|
|
31
32
|
absPath?: string | undefined;
|
|
33
|
+
raw?: string | undefined;
|
|
32
34
|
configured?: string | undefined;
|
|
33
35
|
}): void;
|
|
@@ -43,7 +43,8 @@ export function isStubbableType(type: string | null | undefined, vocabulary?: Re
|
|
|
43
43
|
stubbable?: boolean;
|
|
44
44
|
}>>): boolean;
|
|
45
45
|
/**
|
|
46
|
-
* Whether a note is a stub: an empty body on a type an empty body suppresses
|
|
46
|
+
* Whether a note is a stub: an empty body on a type an empty body suppresses,
|
|
47
|
+
* without an automatic dictionary or glossary supplied by its frontmatter.
|
|
47
48
|
*
|
|
48
49
|
* The one place the two halves are put together, so the index, the lint and the
|
|
49
50
|
* guard cannot answer it differently.
|
|
@@ -14,10 +14,11 @@
|
|
|
14
14
|
* the source page's URL and the target page's.
|
|
15
15
|
* @param {ReadonlyMap<string, RelatedEntry>} entries - Every page of this
|
|
16
16
|
* site, keyed by URL.
|
|
17
|
+
* @param {ReadonlyMap<string, RelatedEntry[]>} [deliberate] Authored references, including foreign destinations.
|
|
17
18
|
* @returns {Map<string, Related>} URL → the page's `related` block, both lists
|
|
18
19
|
* sorted, for every page with at least one entry in either.
|
|
19
20
|
*/
|
|
20
|
-
export function relatedPages(edges: Iterable<readonly [string, string]>, entries: ReadonlyMap<string, RelatedEntry>): Map<string, Related>;
|
|
21
|
+
export function relatedPages(edges: Iterable<readonly [string, string]>, entries: ReadonlyMap<string, RelatedEntry>, deliberate?: ReadonlyMap<string, RelatedEntry[]>): Map<string, Related>;
|
|
21
22
|
/**
|
|
22
23
|
* The pages a homepage's body links to, as URLs.
|
|
23
24
|
*
|
|
@@ -50,6 +51,10 @@ export type RelatedEntry = {
|
|
|
50
51
|
* site-root-relative form the page states for itself.
|
|
51
52
|
*/
|
|
52
53
|
url: string;
|
|
54
|
+
/**
|
|
55
|
+
* Why the author recommends this page.
|
|
56
|
+
*/
|
|
57
|
+
gloss?: string | undefined;
|
|
53
58
|
/**
|
|
54
59
|
* The note's `type`, which the theme groups by.
|
|
55
60
|
*/
|
|
@@ -59,6 +64,10 @@ export type RelatedEntry = {
|
|
|
59
64
|
* The `related` block one page publishes.
|
|
60
65
|
*/
|
|
61
66
|
export type Related = {
|
|
67
|
+
/**
|
|
68
|
+
* Deliberate references in authored order.
|
|
69
|
+
*/
|
|
70
|
+
seeAlso?: RelatedEntry[] | undefined;
|
|
62
71
|
/**
|
|
63
72
|
* Pages that link to this one.
|
|
64
73
|
*/
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate note references, refusing unresolved, repeated and self destinations.
|
|
3
|
+
* @param {object} note - The authored note, including its raw source.
|
|
4
|
+
* @param {object} [options] - The local and declared dependency context.
|
|
5
|
+
* @param {object} [options.index] - The local and declared dependency index.
|
|
6
|
+
* @param {string} [options.index.contentPackage] - The package owning the note.
|
|
7
|
+
* @param {Set<string>} [options.index.types] - The indexed note types.
|
|
8
|
+
* @param {Set<string>} [options.index.packages] - The indexed packages.
|
|
9
|
+
* @param {(key: string) => {url?: string, uuid?: string, file?: string}|undefined}
|
|
10
|
+
* [options.index.addressHit] - Resolve a canonical Address to its destination.
|
|
11
|
+
* @param {import("./address.mjs").AddressDefaults} [options.addressContext]
|
|
12
|
+
* - The Address defaults and vocabularies at the authored reference.
|
|
13
|
+
* @returns {object[]} Findings located at the offending address.
|
|
14
|
+
*/
|
|
15
|
+
export function checkSeeAlso(note: object, { index, addressContext }?: {
|
|
16
|
+
index?: {
|
|
17
|
+
contentPackage?: string | undefined;
|
|
18
|
+
types?: Set<string> | undefined;
|
|
19
|
+
packages?: Set<string> | undefined;
|
|
20
|
+
addressHit?: ((key: string) => {
|
|
21
|
+
url?: string;
|
|
22
|
+
uuid?: string;
|
|
23
|
+
file?: string;
|
|
24
|
+
} | undefined) | undefined;
|
|
25
|
+
} | undefined;
|
|
26
|
+
addressContext?: import("./address.mjs").AddressDefaults | undefined;
|
|
27
|
+
}): object[];
|
|
28
|
+
/**
|
|
29
|
+
* Resolve deliberate references in authored order using the surface's index.
|
|
30
|
+
* @param {object} fm - The note frontmatter.
|
|
31
|
+
* @param {(address: unknown) => object|undefined} resolve - The surface's reference resolver.
|
|
32
|
+
* @returns {object[]} Display names, destinations and optional glosses.
|
|
33
|
+
*/
|
|
34
|
+
export function seeAlsoEntries(fm: object, resolve: (address: unknown) => object | undefined): object[];
|
|
35
|
+
/**
|
|
36
|
+
* A generated section; an empty list emits nothing.
|
|
37
|
+
* @param {object[]} entries - Resolved references in authored order.
|
|
38
|
+
* @param {(entry: object) => string} link - The medium's link markup.
|
|
39
|
+
* @param {number} [level=2] - Heading level; a journal uses one for a separate page.
|
|
40
|
+
* @returns {string} Markdown for the section.
|
|
41
|
+
*/
|
|
42
|
+
export function seeAlsoMarkdown(entries: object[], link: (entry: object) => string, level?: number): string;
|
|
43
|
+
/**
|
|
44
|
+
* A reference rendered as an ordinary Markdown link for the book pipeline.
|
|
45
|
+
* @param {object} entry - A resolved name and URL.
|
|
46
|
+
* @returns {string} Markdown.
|
|
47
|
+
*/
|
|
48
|
+
export function seeAlsoWebLink(entry: object): string;
|
|
49
|
+
/**
|
|
50
|
+
* Deliberate site connections for a set of pages, including dependency pages.
|
|
51
|
+
* @param {object[]} pages - Pages carrying frontmatter and their published URL.
|
|
52
|
+
* @param {(address: unknown) => object|undefined} resolve - The site's reference resolver.
|
|
53
|
+
* @returns {Map<string, import("./related-pages.mjs").RelatedEntry[]>} Entries keyed by source URL.
|
|
54
|
+
*/
|
|
55
|
+
export function seeAlsoPages(pages: object[], resolve: (address: unknown) => object | undefined): Map<string, import("./related-pages.mjs").RelatedEntry[]>;
|
|
@@ -109,11 +109,14 @@ export function writeHomepages(outRoot: string, pages: readonly object[], config
|
|
|
109
109
|
* @param {object} options
|
|
110
110
|
* @param {object} options.config - The resolved build configuration.
|
|
111
111
|
* @param {object[]} options.records - Content-index records.
|
|
112
|
+
* @param {Map<string, object[]>} [options.sqlTables] - Prepared directives,
|
|
113
|
+
* whose emitted anchors belong to the pages they expand in.
|
|
112
114
|
* @returns {object} The gate results and, when they pass, the built index.
|
|
113
115
|
*/
|
|
114
|
-
export function siteGates(pages: object[], findings: object, { config, records }: {
|
|
116
|
+
export function siteGates(pages: object[], findings: object, { config, records, sqlTables }: {
|
|
115
117
|
config: object;
|
|
116
118
|
records: object[];
|
|
119
|
+
sqlTables?: Map<string, object[]> | undefined;
|
|
117
120
|
}): object;
|
|
118
121
|
/**
|
|
119
122
|
* The gate result of a build that ran none of them.
|
|
@@ -139,8 +139,9 @@ export function renderSqlTable(result: {
|
|
|
139
139
|
* its own table and not the whole build's report.
|
|
140
140
|
*
|
|
141
141
|
* @param {object} db - From {@link openNotesDatabase}.
|
|
142
|
-
* @param {Array<{source: string, markdown: string}>} sources -
|
|
143
|
-
* scan.
|
|
142
|
+
* @param {Array<{source: string, markdown: string, frontmatter?: object, authoredSqlBlocks?: number}>} sources -
|
|
143
|
+
* The bodies to scan. `joinGeneratedSections` records the number of authored
|
|
144
|
+
* fences; following generated event fences need no stub comparison.
|
|
144
145
|
* @param {object} [opts]
|
|
145
146
|
* @param {(ref: string) => boolean} [opts.linkable] - Passed to
|
|
146
147
|
* {@link renderSqlTable}.
|
|
@@ -163,6 +164,8 @@ export function renderSqlTable(result: {
|
|
|
163
164
|
export function prepareSqlTables(db: object, sources: Array<{
|
|
164
165
|
source: string;
|
|
165
166
|
markdown: string;
|
|
167
|
+
frontmatter?: object;
|
|
168
|
+
authoredSqlBlocks?: number;
|
|
166
169
|
}>, { linkable, records, pageLanguage }?: {
|
|
167
170
|
linkable?: ((ref: string) => boolean) | undefined;
|
|
168
171
|
pageLanguage?: ((source: string, frontmatter?: object) => string | undefined) | undefined;
|
|
@@ -188,20 +191,25 @@ export function prepareInlineSqlExpressions(db: any, sources: any): Promise<Map<
|
|
|
188
191
|
* @param {Map<string, Map<string, string>>} [opts.derived] - The derived
|
|
189
192
|
* lists, from an earlier call over the same records, which are not derived
|
|
190
193
|
* again.
|
|
194
|
+
* @param {object[]} [opts.all=records] - Complete records for lexical lineage
|
|
195
|
+
* traversal through providers outside the surface's audience.
|
|
191
196
|
* @returns {Promise<{sections: Map<string, string>, views: Set<string>,
|
|
192
|
-
* derived: Map<string, Map<string, string
|
|
197
|
+
* derived: Map<string, Map<string, string>>,
|
|
198
|
+
* lexical: Map<string, import("./lexical-sections.mjs").LexicalSection[]>}>} Note file to its sections,
|
|
193
199
|
* joined in order; the files whose sections hold an event view's fence; and
|
|
194
200
|
* the derived lists alone.
|
|
195
201
|
*/
|
|
196
|
-
export function generatedSectionsFor(db: object | undefined, records: object[], contentBase: string, { only, foreignIndex, config, derived: given }?: {
|
|
202
|
+
export function generatedSectionsFor(db: object | undefined, records: object[], contentBase: string, { only, foreignIndex, config, derived: given, all }?: {
|
|
197
203
|
only?: string | undefined;
|
|
198
204
|
foreignIndex?: Map<string, object> | undefined;
|
|
199
205
|
config?: object | undefined;
|
|
200
206
|
derived?: Map<string, Map<string, string>> | undefined;
|
|
207
|
+
all?: object[] | undefined;
|
|
201
208
|
}): Promise<{
|
|
202
209
|
sections: Map<string, string>;
|
|
203
210
|
views: Set<string>;
|
|
204
211
|
derived: Map<string, Map<string, string>>;
|
|
212
|
+
lexical: Map<string, import("./lexical-sections.mjs").LexicalSection[]>;
|
|
205
213
|
}>;
|
|
206
214
|
/**
|
|
207
215
|
* Join each note's generated sections to its body among the sources a
|
|
@@ -216,7 +224,7 @@ export function generatedSectionsFor(db: object | undefined, records: object[],
|
|
|
216
224
|
*
|
|
217
225
|
* @param {{sections: Map<string, string>, views: Set<string>}} generated -
|
|
218
226
|
* From {@link generatedSectionsFor}.
|
|
219
|
-
* @param {Array<{source: string, markdown: string, frontmatter?: object}>} sources -
|
|
227
|
+
* @param {Array<{source: string, markdown: string, frontmatter?: object, authoredSqlBlocks?: number}>} sources -
|
|
220
228
|
* The bodies to answer, extended in place.
|
|
221
229
|
* @param {Map<string, {body: string, frontmatter: object|null}>} [parsed] -
|
|
222
230
|
* Notes already parsed, keyed by file; a note absent from it is read.
|
|
@@ -229,6 +237,7 @@ export function joinGeneratedSections(generated: {
|
|
|
229
237
|
source: string;
|
|
230
238
|
markdown: string;
|
|
231
239
|
frontmatter?: object;
|
|
240
|
+
authoredSqlBlocks?: number;
|
|
232
241
|
}>, parsed?: Map<string, {
|
|
233
242
|
body: string;
|
|
234
243
|
frontmatter: object | null;
|
|
@@ -239,12 +248,13 @@ export function joinGeneratedSections(generated: {
|
|
|
239
248
|
* empty set carrying them.
|
|
240
249
|
*
|
|
241
250
|
* @param {Map<string, object[]>} prepared - From {@link prepareSqlTables}.
|
|
242
|
-
* @param {{sections: Map<string, string>}} generated - From
|
|
251
|
+
* @param {{sections: Map<string, string>, lexical?: Map<string, import("./lexical-sections.mjs").LexicalSection[]>}} generated - From
|
|
243
252
|
* {@link generatedSectionsFor}.
|
|
244
253
|
* @returns {void}
|
|
245
254
|
*/
|
|
246
255
|
export function attachGeneratedSections(prepared: Map<string, object[]>, generated: {
|
|
247
256
|
sections: Map<string, string>;
|
|
257
|
+
lexical?: Map<string, import("./lexical-sections.mjs").LexicalSection[]>;
|
|
248
258
|
}): void;
|
|
249
259
|
/**
|
|
250
260
|
* Each declared dependency's cached index, as {@link openNotesDatabase} attaches
|
|
@@ -309,6 +319,30 @@ export function prepareTreeSqlTables(contentBase: string, { config, skipDirector
|
|
|
309
319
|
audience?: "all" | "public" | undefined;
|
|
310
320
|
foreignIndex?: Map<string, object> | undefined;
|
|
311
321
|
}): Promise<Map<string, object[]> | undefined>;
|
|
322
|
+
/**
|
|
323
|
+
* Prepare authored link-check tables in each source note's audience. Public
|
|
324
|
+
* sources share one public database; GM sources share one complete database.
|
|
325
|
+
* Complete records remain available for authored-link checks.
|
|
326
|
+
*
|
|
327
|
+
* @param {string} contentBase - Root of the content tree.
|
|
328
|
+
* @param {object} [opts]
|
|
329
|
+
* @param {object} [opts.config] - Resolved configuration.
|
|
330
|
+
* @param {readonly string[]} [opts.skipDirectories] - The walk's scope.
|
|
331
|
+
* @param {object[]} [opts.records] - Complete index records already derived.
|
|
332
|
+
* @param {Map<string, {body: string, frontmatter: object|null}>} [opts.parsed] - Parsed notes.
|
|
333
|
+
* @param {Map<string, object>} [opts.foreignIndex] - Published dependency indexes.
|
|
334
|
+
* @returns {Promise<Map<string, object[]>|undefined>} Prepared tables by source.
|
|
335
|
+
*/
|
|
336
|
+
export function prepareLinkSqlTables(contentBase: string, { config, skipDirectories, records, parsed, foreignIndex }?: {
|
|
337
|
+
config?: object | undefined;
|
|
338
|
+
skipDirectories?: readonly string[] | undefined;
|
|
339
|
+
records?: object[] | undefined;
|
|
340
|
+
parsed?: Map<string, {
|
|
341
|
+
body: string;
|
|
342
|
+
frontmatter: object | null;
|
|
343
|
+
}> | undefined;
|
|
344
|
+
foreignIndex?: Map<string, object> | undefined;
|
|
345
|
+
}): Promise<Map<string, object[]> | undefined>;
|
|
312
346
|
/**
|
|
313
347
|
* Aliases the renderer reads rather than printing.
|
|
314
348
|
*
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* A lookup from a built piece to its gloss, over the words (stems included)
|
|
3
|
-
* and
|
|
2
|
+
* A lookup from a built piece to its gloss, over the words (stems included),
|
|
3
|
+
* affixes and elements of one or more languages.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* affixes, then the next language's
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* For each spelling, languages are given nearest first: a language's own
|
|
6
|
+
* words, then its affixes and elements, then the next language's. A piece
|
|
7
|
+
* matches an exact spelling across the lineage first, and failing that one
|
|
8
|
+
* written with the same letters and different joining hyphens, so
|
|
9
9
|
* `wulf-` finds the word `wulf`. Within a language a word's own gloss wins over
|
|
10
|
-
* an affix's.
|
|
10
|
+
* an affix's, and both precede an element's sense. Elements also match their
|
|
11
|
+
* declared variants; affixes also match their front-vowel forms. Spelling,
|
|
12
|
+
* including case and accents, is preserved.
|
|
11
13
|
*
|
|
12
14
|
* @param {...object} datas - Each language note's `data`, nearest first.
|
|
13
15
|
* @returns {(piece: string) => string|null} The gloss, or `null` where none resolves.
|