@heroiclands/package-build 23.12.6 → 23.12.8

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.
Files changed (94) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/assets/styles/content-base.css +25 -0
  3. package/bin/content-commands.mjs +264 -3
  4. package/bin/package-build.mjs +25 -0
  5. package/content-config.mjs +72 -0
  6. package/docs/api.md +10 -9
  7. package/docs/authoring/assets.md +1 -1
  8. package/docs/authoring/links-and-markup.md +439 -47
  9. package/docs/commands.md +137 -3
  10. package/docs/configuration.md +73 -3
  11. package/docs/content-format.md +3 -1
  12. package/docs/guides/book.md +11 -0
  13. package/docs/guides/module-project.md +16 -0
  14. package/docs/guides/site.md +19 -0
  15. package/docs/reference/format-details.md +378 -6
  16. package/docs/reference/note-types.md +36 -11
  17. package/e2e.mjs +1 -1
  18. package/engine/asset-shipping.mjs +22 -8
  19. package/engine/base-compiler.mjs +2 -0
  20. package/engine/bundles.mjs +7 -2
  21. package/engine/compile-corpus.mjs +3 -1
  22. package/engine/content-charset.mjs +21 -2
  23. package/engine/content-format.yaml +1 -0
  24. package/engine/content-index.mjs +12 -0
  25. package/engine/content-poetry.mjs +22 -4
  26. package/engine/content-scripts.mjs +1219 -0
  27. package/engine/content-session.mjs +2 -0
  28. package/engine/data-keys.mjs +5 -1
  29. package/engine/dictionary-layout.mjs +18 -12
  30. package/engine/dictionary-rows.mjs +11 -2
  31. package/engine/helpers.mjs +8 -2
  32. package/engine/index-records.mjs +1 -0
  33. package/engine/journals.mjs +14 -3
  34. package/engine/language-data.mjs +137 -1
  35. package/engine/language-tag.mjs +103 -0
  36. package/engine/language-terms.mjs +16 -4
  37. package/engine/map-lexicon.mjs +762 -0
  38. package/engine/markup-validation.mjs +17 -3
  39. package/engine/names.mjs +1 -1
  40. package/engine/note-vocabulary.mjs +113 -0
  41. package/engine/pdf-build.mjs +28 -10
  42. package/engine/pdf-render.mjs +116 -11
  43. package/engine/run-rows.mjs +119 -0
  44. package/engine/run-words.mjs +266 -0
  45. package/engine/scenes.mjs +1 -0
  46. package/engine/script-font-delivery.mjs +321 -0
  47. package/engine/script-fonts.mjs +172 -0
  48. package/engine/site-build.mjs +10 -3
  49. package/engine/site-config.mjs +5 -0
  50. package/engine/site-root.mjs +19 -5
  51. package/engine/sql-tables.mjs +111 -1
  52. package/engine/text-maps.mjs +607 -0
  53. package/engine/verb-pattern.mjs +99 -0
  54. package/engine/word-pattern.mjs +27 -0
  55. package/engine/word-rows.mjs +8 -2
  56. package/engine/word-terms.mjs +44 -0
  57. package/hugo-theme/layouts/_default/baseof.html +3 -0
  58. package/hugo-theme/static/css/style.css +10 -0
  59. package/manifest.mjs +9 -1
  60. package/package.json +2 -2
  61. package/types/content-config.d.mts +26 -0
  62. package/types/e2e.d.mts +2 -2
  63. package/types/engine/address-fields.d.mts +1 -1
  64. package/types/engine/address-values.d.mts +1 -1
  65. package/types/engine/asset-shipping.d.mts +5 -0
  66. package/types/engine/compile-corpus.d.mts +2 -1
  67. package/types/engine/content-format-check.d.mts +1 -1
  68. package/types/engine/content-index.d.mts +11 -3
  69. package/types/engine/content-poetry.d.mts +7 -0
  70. package/types/engine/content-scripts.d.mts +226 -0
  71. package/types/engine/data-keys.d.mts +2 -2
  72. package/types/engine/dictionary-rows.d.mts +15 -0
  73. package/types/engine/helpers.d.mts +5 -1
  74. package/types/engine/journals.d.mts +7 -2
  75. package/types/engine/language-data.d.mts +2 -0
  76. package/types/engine/language-tag.d.mts +8 -0
  77. package/types/engine/language-terms.d.mts +2 -1
  78. package/types/engine/map-lexicon.d.mts +274 -0
  79. package/types/engine/markup-validation.d.mts +7 -2
  80. package/types/engine/note-vocabulary.d.mts +1 -1
  81. package/types/engine/pdf-build.d.mts +26 -3
  82. package/types/engine/pdf-coverage.d.mts +1 -1
  83. package/types/engine/pdf-render.d.mts +17 -2
  84. package/types/engine/run-rows.d.mts +89 -0
  85. package/types/engine/run-words.d.mts +86 -0
  86. package/types/engine/script-font-delivery.d.mts +134 -0
  87. package/types/engine/script-fonts.d.mts +168 -0
  88. package/types/engine/site-build.d.mts +2 -1
  89. package/types/engine/site-root.d.mts +11 -3
  90. package/types/engine/text-maps.d.mts +175 -0
  91. package/types/engine/verb-pattern.d.mts +65 -0
  92. package/types/engine/word-pattern.d.mts +13 -0
  93. package/types/engine/word-terms.d.mts +6 -0
  94. package/types/release.d.mts +1 -1
@@ -184,17 +184,33 @@ export function buildPdf({ config, configPath, book, out, version, compile, read
184
184
  * @param {string} typPath - The `.typ` file.
185
185
  * @param {string} pdfPath - Where the PDF goes.
186
186
  * @param {object} [pdf] - The resolved `pdf:` block.
187
+ * @param {{rootDir?: string, paths?: {content?: string}}} [config] - The
188
+ * resolved configuration; the installed faces are searched when a note sets
189
+ * text in one.
187
190
  * @returns {string[]} The arguments, in order.
188
191
  */
189
- export function typstArgs(typPath: string, pdfPath: string, pdf?: object): string[];
192
+ export function typstArgs(typPath: string, pdfPath: string, pdf?: object, config?: {
193
+ rootDir?: string;
194
+ paths?: {
195
+ content?: string;
196
+ };
197
+ }): string[];
190
198
  /**
191
199
  * The flags that decide which faces a layout uses, shared by the compile and by
192
200
  * the page measurement so both lay the book out in the same metrics.
193
201
  *
194
202
  * @param {object} [pdf] - The resolved `pdf:` block.
203
+ * @param {{rootDir?: string, paths?: {content?: string}}} [config] - The
204
+ * resolved configuration; the installed faces are searched when a note sets
205
+ * text in one.
195
206
  * @returns {string[]} The arguments, in order.
196
207
  */
197
- export function typstFontArgs(pdf?: object): string[];
208
+ export function typstFontArgs(pdf?: object, config?: {
209
+ rootDir?: string;
210
+ paths?: {
211
+ content?: string;
212
+ };
213
+ }): string[];
198
214
  /**
199
215
  * The compiler's own warnings, as findings.
200
216
  *
@@ -224,10 +240,17 @@ export function typstWarnings(output: string): Array<{
224
240
  * @param {string} typPath - The `.typ` file.
225
241
  * @param {string} pdfPath - Where the PDF goes.
226
242
  * @param {object} pdf - The resolved `pdf:` block.
243
+ * @param {{rootDir?: string, paths?: {content?: string}}} [config] - The
244
+ * resolved configuration, for the installed faces.
227
245
  * @returns {{ok: boolean, message: string, findings: object[]}} What happened,
228
246
  * and what the compiler warned about on the way.
229
247
  */
230
- export function compileTypst(typPath: string, pdfPath: string, pdf?: object): {
248
+ export function compileTypst(typPath: string, pdfPath: string, pdf?: object, config?: {
249
+ rootDir?: string;
250
+ paths?: {
251
+ content?: string;
252
+ };
253
+ }): {
231
254
  ok: boolean;
232
255
  message: string;
233
256
  findings: object[];
@@ -37,7 +37,7 @@ export function coverage({ books, corpus, unprinted, mode, locate }: {
37
37
  }>;
38
38
  corpus: object[];
39
39
  unprinted?: object[] | undefined;
40
- mode?: "error" | "off" | "warning" | undefined;
40
+ mode?: "warning" | "error" | "off" | undefined;
41
41
  locate?: ((record: object) => {
42
42
  file?: string;
43
43
  line?: number;
@@ -85,6 +85,9 @@ export function stripHtmlComments(markdown: string): string;
85
85
  * Typst and is told nothing.
86
86
  * @param {string} [opts.file] - The file the markdown came from, named in every
87
87
  * finding.
88
+ * @param {import("./content-scripts.mjs").RunContext} [opts.runs] - The
89
+ * package's languages, faces and maps, which text marked with `lang=`,
90
+ * `font=` and `map=` is checked against and set by.
88
91
  * @param {number} [opts.bodyLine] - The 1-based file line the body starts on, so
89
92
  * a finding's line is the file's rather than the body's.
90
93
  * @param {number} [opts.bodyColumn] - The 1-based column the body starts at.
@@ -124,6 +127,7 @@ export function markdownToTypst(markdown: string, opts?: {
124
127
  anchorPrefix?: string | undefined;
125
128
  findings?: object[] | undefined;
126
129
  file?: string | undefined;
130
+ runs?: import("./content-scripts.mjs").RunContext | undefined;
127
131
  bodyLine?: number | undefined;
128
132
  bodyColumn?: number | undefined;
129
133
  lineMap?: {
@@ -228,9 +232,17 @@ export function crossBookReference(inner: string, away: {
228
232
  * carries are not the same set, and a missing glyph on 2,000 feet is a
229
233
  * tofu box on every page of the book.
230
234
  *
235
+ * @param {import("./content-scripts.mjs").RunContext} [runs] - The installed
236
+ * faces, each of whose classes sets its family.
237
+ * @param {{serif?: string, sans?: string, mono?: string}} [families] - The
238
+ * book's own serif, sans and mono, which `font=serif`, `sans` and `mono` set.
231
239
  * @returns {string} Typst markup.
232
240
  */
233
- export function bookTypstPreamble(): string;
241
+ export function bookTypstPreamble(runs?: import("./content-scripts.mjs").RunContext, families?: {
242
+ serif?: string;
243
+ sans?: string;
244
+ mono?: string;
245
+ }): string;
234
246
  /**
235
247
  * The whole book, as one Typst document.
236
248
  *
@@ -345,9 +357,11 @@ export function bookTypstPreamble(): string;
345
357
  * @param {object} [opts.index] - As {@link module:engine/pdf-index.indexTerms}:
346
358
  * `owns` limits the index to the notes this book is home to, and `foreign`
347
359
  * (present only under `pdf.indexSeeAlso`) lists notes another book prints.
360
+ * @param {import("./content-scripts.mjs").RunContext} [opts.runs] - The
361
+ * installed faces, which the preamble maps to font families.
348
362
  * @returns {string} A complete `.typ` document.
349
363
  */
350
- export function renderBook({ plan, bodies, title, subtitle, front, fonts, version, preamble, banners, maps, coverImage, authors, copyright, license, index, }?: {
364
+ export function renderBook({ plan, bodies, title, subtitle, front, fonts, version, preamble, banners, maps, coverImage, authors, copyright, license, index, runs, }?: {
351
365
  plan: object;
352
366
  bodies: Map<string, string>;
353
367
  title: string;
@@ -369,6 +383,7 @@ export function renderBook({ plan, bodies, title, subtitle, front, fonts, versio
369
383
  copyright?: string | undefined;
370
384
  license?: string | undefined;
371
385
  index?: object | undefined;
386
+ runs?: import("./content-scripts.mjs").RunContext | undefined;
372
387
  }): string;
373
388
  /**
374
389
  * Point every internal link at a label the document actually declares.
@@ -0,0 +1,89 @@
1
+ /**
2
+ * One run as an index record carries it.
3
+ *
4
+ * @typedef {object} RecordRun
5
+ * @property {"span"|"block"|"poetry"} kind - The construct.
6
+ * @property {string|null} lang - The language it is set in, as written: its
7
+ * own `lang=`, else the one the div or fence around it states.
8
+ * @property {string|null} tag - The BCP 47 tag it resolves to, or null.
9
+ * @property {string|null} font - Its font, as written and inherited the same way.
10
+ * @property {string|null} map - Its map, as written and inherited the same way.
11
+ * @property {number} line - 1-based file line of its opening.
12
+ * @property {number} column - 1-based UTF-16 file column of its opening.
13
+ */
14
+ /**
15
+ * @typedef {RecordRun & {owner: string|null}} RunRow
16
+ */
17
+ /**
18
+ * A note body's runs, at file positions, as an index record carries them.
19
+ *
20
+ * @param {string} body - The note's body.
21
+ * @param {object} options - Options.
22
+ * @param {import("./content-scripts.mjs").RunContext} [options.context] - The
23
+ * configured languages, which give a declared name its tag.
24
+ * @param {number} [options.bodyLine] - The 1-based file line the body starts on.
25
+ * @param {number} [options.bodyColumn] - The 1-based column of its first character.
26
+ * @param {import("./content-session.mjs").ContentSyntax} [options.syntax] -
27
+ * Session scanner projections.
28
+ * @returns {RecordRun[]} One entry per run, in source order.
29
+ */
30
+ export function recordRuns(body: string, { context, bodyLine, bodyColumn, syntax }?: {
31
+ context?: import("./content-scripts.mjs").RunContext | undefined;
32
+ bodyLine?: number | undefined;
33
+ bodyColumn?: number | undefined;
34
+ syntax?: import("./content-session.mjs").ContentSyntax | undefined;
35
+ }): RecordRun[];
36
+ /**
37
+ * The containing page's NOTE identity.
38
+ *
39
+ * @param {Record<string, any>} record - An own-note index record.
40
+ * @returns {string|null} The page Address, or null for an unaddressable record.
41
+ */
42
+ export function ownerOf(record: Record<string, any>): string | null;
43
+ /**
44
+ * Project recorded runs without reading sources or changing records.
45
+ *
46
+ * @param {Iterable<Record<string, any>>} records - Index records, already
47
+ * narrowed to the audience.
48
+ * @returns {RunRow[]} One row per run, in record then source order.
49
+ */
50
+ export function runsRows(records: Iterable<Record<string, any>>): RunRow[];
51
+ /** Every column of the `runs` relation, in order. */
52
+ export const RUN_COLUMNS: readonly string[];
53
+ /**
54
+ * One run as an index record carries it.
55
+ */
56
+ export type RecordRun = {
57
+ /**
58
+ * - The construct.
59
+ */
60
+ kind: "span" | "block" | "poetry";
61
+ /**
62
+ * - The language it is set in, as written: its
63
+ * own `lang=`, else the one the div or fence around it states.
64
+ */
65
+ lang: string | null;
66
+ /**
67
+ * - The BCP 47 tag it resolves to, or null.
68
+ */
69
+ tag: string | null;
70
+ /**
71
+ * - Its font, as written and inherited the same way.
72
+ */
73
+ font: string | null;
74
+ /**
75
+ * - Its map, as written and inherited the same way.
76
+ */
77
+ map: string | null;
78
+ /**
79
+ * - 1-based file line of its opening.
80
+ */
81
+ line: number;
82
+ /**
83
+ * - 1-based UTF-16 file column of its opening.
84
+ */
85
+ column: number;
86
+ };
87
+ export type RunRow = RecordRun & {
88
+ owner: string | null;
89
+ };
@@ -0,0 +1,86 @@
1
+ /**
2
+ * A word as it is compared: NFC, lowercase, `’` read as `'`.
3
+ *
4
+ * @param {string} word - The word.
5
+ * @returns {string} Its folded form.
6
+ */
7
+ export function foldWord(word: string): string;
8
+ /**
9
+ * The words a language note accepts of its own: its forms, and what its
10
+ * plural rows, verb pattern and replacing suffixes derive from them.
11
+ *
12
+ * @param {Record<string, any>} data - The language note's `data`.
13
+ * @returns {Set<string>} The words, folded.
14
+ */
15
+ export function lexiconWords(data: Record<string, any>): Set<string>;
16
+ /**
17
+ * The words of every name a language note registers under a tongue other than
18
+ * `translation`.
19
+ *
20
+ * @param {Record<string, any>|undefined} data - The language note's `data`.
21
+ * @returns {Set<string>} The words, folded.
22
+ */
23
+ export function registeredNameWords(data: Record<string, any> | undefined): Set<string>;
24
+ /**
25
+ * What a mapped run's words are checked against, for one language.
26
+ *
27
+ * @typedef {object} WordBook
28
+ * @property {string} language - The language's configured name, as `lang=`
29
+ * writes it.
30
+ * @property {(word: string) => boolean} accepts - Whether a folded word is
31
+ * one of the language's.
32
+ */
33
+ /**
34
+ * Each configured language's word book: one per language whose `note` names a
35
+ * language note.
36
+ *
37
+ * @param {Iterable<Record<string, any>>|undefined} records - Index records.
38
+ * @param {{languages?: Readonly<Record<string, {tag: string, note?: string}>>, contentPackage?: string}} config -
39
+ * The resolved configuration.
40
+ * @returns {Map<string, WordBook>} The books by language name.
41
+ */
42
+ export function wordBooksFromRecords(records: Iterable<Record<string, any>> | undefined, config?: {
43
+ languages?: Readonly<Record<string, {
44
+ tag: string;
45
+ note?: string;
46
+ }>>;
47
+ contentPackage?: string;
48
+ }): Map<string, WordBook>;
49
+ /**
50
+ * The words of a text its book does not accept, each once, at the offset of
51
+ * its first character: a compound not accepted whole gives each part that is
52
+ * not.
53
+ *
54
+ * @param {string} text - The text, with no escapes.
55
+ * @param {WordBook} book - The language's book.
56
+ * @param {Set<string>} [said] - The folded words already reported in this
57
+ * run, which are not reported again; updated.
58
+ * @returns {Array<{offset: number, word: string}>} The words, in order.
59
+ */
60
+ export function unknownWords(text: string, book: WordBook, said?: Set<string>): Array<{
61
+ offset: number;
62
+ word: string;
63
+ }>;
64
+ /**
65
+ * The finding for a word of a mapped run that is not a word of its language.
66
+ *
67
+ * @param {string} word - The word as written.
68
+ * @param {string} language - The language as `lang=` names it.
69
+ * @returns {string} The message.
70
+ */
71
+ export function unknownWordMessage(word: string, language: string): string;
72
+ /**
73
+ * What a mapped run's words are checked against, for one language.
74
+ */
75
+ export type WordBook = {
76
+ /**
77
+ * - The language's configured name, as `lang=`
78
+ * writes it.
79
+ */
80
+ language: string;
81
+ /**
82
+ * - Whether a folded word is
83
+ * one of the language's.
84
+ */
85
+ accepts: (word: string) => boolean;
86
+ };
@@ -0,0 +1,134 @@
1
+ /**
2
+ * The faces the package's notes set text in with `font=`, read from the
3
+ * notes themselves: every Markdown file under the content tree that writes
4
+ * `font=` is scanned for its runs.
5
+ *
6
+ * @param {DeliveryConfig} config - The resolved configuration.
7
+ * @param {import("./script-fonts.mjs").ScriptFonts} installed - The fonts package.
8
+ * @returns {ReadonlySet<string>} The slugs of the faces used.
9
+ */
10
+ export function facesUsed(config: DeliveryConfig, installed: import("./script-fonts.mjs").ScriptFonts): ReadonlySet<string>;
11
+ /**
12
+ * The files a target receives, as paths relative to the fonts package root.
13
+ *
14
+ * @param {DeliveryConfig} config - The resolved configuration.
15
+ * @param {string[]} formats - The font formats the target uses: `woff2`, `ttf`.
16
+ * @returns {{root: string, version: string, files: string[]}|undefined} The
17
+ * files, sorted: `fonts.css`, `LICENSE` and every file in `fonts/` of a
18
+ * listed format. `undefined` when the consumer ships none.
19
+ */
20
+ export function scriptFontFiles(config: DeliveryConfig, formats: string[]): {
21
+ root: string;
22
+ version: string;
23
+ files: string[];
24
+ } | undefined;
25
+ /**
26
+ * The fonts package's stylesheet as a target stages it: each `@font-face`
27
+ * `src` lists only the files staged beside it, so no browser asks for a
28
+ * format the target does not carry. A `local(…)` source stays, and a face
29
+ * left with no source is dropped.
30
+ *
31
+ * @param {string} css - The stylesheet as the package publishes it.
32
+ * @param {ReadonlySet<string>} staged - The staged files, relative to the
33
+ * stylesheet: `fonts/SemaronKuriale-Regular.woff2`.
34
+ * @returns {string} The stylesheet to stage.
35
+ */
36
+ export function stagedStylesheet(css: string, staged: ReadonlySet<string>): string;
37
+ /**
38
+ * Copy the delivered files into a directory, keeping their relative layout so
39
+ * the stylesheet's `url("fonts/…")` resolves from where it lands. The
40
+ * stylesheet is rewritten by {@link stagedStylesheet} to name only the files
41
+ * copied with it.
42
+ *
43
+ * @param {DeliveryConfig} config - The resolved configuration.
44
+ * @param {string} dest - The directory to fill; created when there is
45
+ * something to put in it.
46
+ * @param {string[]} formats - The font formats the target uses.
47
+ * @returns {number} How many files were written; 0 when the consumer ships none.
48
+ */
49
+ export function copyScriptFonts(config: DeliveryConfig, dest: string, formats: string[]): number;
50
+ /**
51
+ * Whether the package ships what its manifest and stylesheet promise: the
52
+ * stylesheet, the licence and every file the manifest lists.
53
+ *
54
+ * @param {DeliveryConfig} config - The resolved configuration.
55
+ * @returns {{file: string, severity: "error", message: string}[]} One finding
56
+ * per missing file, located at the manifest; empty when the consumer ships none.
57
+ */
58
+ export function checkScriptFonts(config: DeliveryConfig): {
59
+ file: string;
60
+ severity: "error";
61
+ message: string;
62
+ }[];
63
+ /**
64
+ * The site param naming the stylesheet, relative to the site root.
65
+ *
66
+ * @param {DeliveryConfig} config - The resolved configuration.
67
+ * @returns {string|undefined} The versioned address, or `undefined` when the
68
+ * site ships no fonts.
69
+ */
70
+ export function siteFontsParam(config: DeliveryConfig): string | undefined;
71
+ /**
72
+ * The directory under the Hugo static tree that holds this version's fonts.
73
+ *
74
+ * @param {string} version - The fonts package's version.
75
+ * @returns {string} The POSIX path, relative to `build/hugo/static`.
76
+ */
77
+ export function siteFontsDestination(version: string): string;
78
+ /**
79
+ * The manifest `styles`, with the fonts' stylesheet named after the base sheet.
80
+ *
81
+ * @param {object} options
82
+ * @param {unknown} options.styles - The `styles` so far, base sheet included.
83
+ * @param {"system"|"module"} options.artifact - Which artifact is shipped.
84
+ * @param {boolean} options.delivered - Whether the module carries the fonts.
85
+ * @returns {unknown} The `styles` to emit.
86
+ */
87
+ export function withScriptFontStyle({ styles, artifact, delivered: carried }: {
88
+ styles: unknown;
89
+ artifact: "system" | "module";
90
+ delivered: boolean;
91
+ }): unknown;
92
+ /**
93
+ * The directory of TTFs a book's compiler searches.
94
+ *
95
+ * @param {DeliveryConfig} config - The resolved configuration.
96
+ * @returns {string|undefined} The package's `fonts/` directory, or `undefined`
97
+ * when the consumer ships no fonts.
98
+ */
99
+ export function typstScriptFontPath(config: DeliveryConfig): string | undefined;
100
+ /**
101
+ * Where the files land in the staged Foundry module, relative to its root.
102
+ *
103
+ * @type {string}
104
+ */
105
+ export const STAGED_FONTS_DIR: string;
106
+ /**
107
+ * Where the files land in the Hugo static tree, relative to `build/hugo/static`,
108
+ * beneath a directory per version.
109
+ *
110
+ * @type {string}
111
+ */
112
+ export const SITE_FONTS_DIR: string;
113
+ /**
114
+ * The part of a resolved configuration delivery reads.
115
+ */
116
+ export type DeliveryConfig = {
117
+ /**
118
+ * - The consuming package's root.
119
+ */
120
+ rootDir?: string | undefined;
121
+ /**
122
+ * - Where its notes are; relative to
123
+ * `rootDir` unless absolute.
124
+ */
125
+ paths?: {
126
+ content?: string;
127
+ } | undefined;
128
+ /**
129
+ * - Its languages.
130
+ */
131
+ languages?: Readonly<Record<string, {
132
+ tag: string;
133
+ }>> | undefined;
134
+ };
@@ -0,0 +1,168 @@
1
+ /**
2
+ * One code point a face draws, as `fonts.json` lists it.
3
+ *
4
+ * @typedef {object} FaceCodepoint
5
+ * @property {string} codepoint - `U+` and the hexadecimal code point.
6
+ * @property {string} glyph - The glyph's name in the face.
7
+ * @property {string} kind - What it is: `letter`, `numeral`, `mark` and so on.
8
+ */
9
+ /**
10
+ * One entry of `fonts.json`.
11
+ *
12
+ * @typedef {object} FontEntry
13
+ * @property {string} [name] - Its unique key; `family` when absent.
14
+ * @property {string} family - The CSS and Typst font family.
15
+ * @property {string} class - The class that sets text in it, `hl-<slug>`.
16
+ * @property {Record<string, string>} files - Its font files, by format.
17
+ * @property {string} direction - `ltr` or `rtl`.
18
+ * @property {string[]} features - OpenType features it turns on.
19
+ * @property {FaceCodepoint[]} [codepoints] - Every code point it draws.
20
+ */
21
+ /**
22
+ * A face as a run reads it.
23
+ *
24
+ * @typedef {object} Face
25
+ * @property {string} slug - What `font=` names it by: its class without `hl-`.
26
+ * @property {string} family - The CSS and Typst font family.
27
+ * @property {string} class - The class that sets text in it.
28
+ * @property {string} direction - `ltr` or `rtl`.
29
+ * @property {string[]} features - OpenType features it turns on.
30
+ * @property {ReadonlySet<number>} draws - Every code point it draws.
31
+ */
32
+ /**
33
+ * The installed fonts package, as a consumer sees it.
34
+ *
35
+ * @typedef {object} ScriptFonts
36
+ * @property {string} root - The package's directory.
37
+ * @property {string} version - Its `package.json` version.
38
+ * @property {{families: FontEntry[]}|undefined} manifest - Its `fonts.json`,
39
+ * `undefined` when the installed version ships none.
40
+ * @property {Map<string, Face>} faces - Each face by its slug, in manifest
41
+ * order; empty without a manifest.
42
+ */
43
+ /**
44
+ * The slug `font=` names a face by: its class without the `hl-` prefix.
45
+ *
46
+ * @param {FontEntry} entry - A `fonts.json` entry.
47
+ * @returns {string|undefined} The slug, or `undefined` for an entry with no class.
48
+ */
49
+ export function faceSlug(entry: FontEntry): string | undefined;
50
+ /**
51
+ * The fonts package the consumer at `rootDir` installed.
52
+ *
53
+ * @param {string} rootDir - The consuming package's root, holding its
54
+ * `package.json`.
55
+ * @returns {ScriptFonts|undefined} The package, or `undefined` when the
56
+ * consumer has not installed it.
57
+ * @throws {Error} When the installed `fonts.json` is not readable JSON, or
58
+ * holds no `families` list.
59
+ */
60
+ export function resolveScriptFonts(rootDir: string): ScriptFonts | undefined;
61
+ /** The npm name of the fonts package. */
62
+ export const FONTS_PACKAGE: "@heroiclands/fonts";
63
+ /** The manifest the fonts package publishes at its root. */
64
+ export const FONTS_MANIFEST: "fonts.json";
65
+ /**
66
+ * One code point a face draws, as `fonts.json` lists it.
67
+ */
68
+ export type FaceCodepoint = {
69
+ /**
70
+ * - `U+` and the hexadecimal code point.
71
+ */
72
+ codepoint: string;
73
+ /**
74
+ * - The glyph's name in the face.
75
+ */
76
+ glyph: string;
77
+ /**
78
+ * - What it is: `letter`, `numeral`, `mark` and so on.
79
+ */
80
+ kind: string;
81
+ };
82
+ /**
83
+ * One entry of `fonts.json`.
84
+ */
85
+ export type FontEntry = {
86
+ /**
87
+ * - Its unique key; `family` when absent.
88
+ */
89
+ name?: string | undefined;
90
+ /**
91
+ * - The CSS and Typst font family.
92
+ */
93
+ family: string;
94
+ /**
95
+ * - The class that sets text in it, `hl-<slug>`.
96
+ */
97
+ class: string;
98
+ /**
99
+ * - Its font files, by format.
100
+ */
101
+ files: Record<string, string>;
102
+ /**
103
+ * - `ltr` or `rtl`.
104
+ */
105
+ direction: string;
106
+ /**
107
+ * - OpenType features it turns on.
108
+ */
109
+ features: string[];
110
+ /**
111
+ * - Every code point it draws.
112
+ */
113
+ codepoints?: FaceCodepoint[] | undefined;
114
+ };
115
+ /**
116
+ * A face as a run reads it.
117
+ */
118
+ export type Face = {
119
+ /**
120
+ * - What `font=` names it by: its class without `hl-`.
121
+ */
122
+ slug: string;
123
+ /**
124
+ * - The CSS and Typst font family.
125
+ */
126
+ family: string;
127
+ /**
128
+ * - The class that sets text in it.
129
+ */
130
+ class: string;
131
+ /**
132
+ * - `ltr` or `rtl`.
133
+ */
134
+ direction: string;
135
+ /**
136
+ * - OpenType features it turns on.
137
+ */
138
+ features: string[];
139
+ /**
140
+ * - Every code point it draws.
141
+ */
142
+ draws: ReadonlySet<number>;
143
+ };
144
+ /**
145
+ * The installed fonts package, as a consumer sees it.
146
+ */
147
+ export type ScriptFonts = {
148
+ /**
149
+ * - The package's directory.
150
+ */
151
+ root: string;
152
+ /**
153
+ * - Its `package.json` version.
154
+ */
155
+ version: string;
156
+ /**
157
+ * - Its `fonts.json`,
158
+ * `undefined` when the installed version ships none.
159
+ */
160
+ manifest: {
161
+ families: FontEntry[];
162
+ } | undefined;
163
+ /**
164
+ * - Each face by its slug, in manifest
165
+ * order; empty without a manifest.
166
+ */
167
+ faces: Map<string, Face>;
168
+ };
@@ -230,7 +230,7 @@ export function pageDestination(page: {
230
230
  slug: string;
231
231
  }): string;
232
232
  /** Transform one content page without writing the site mount. */
233
- export function renderSitePage(page: any, { index, foreign, universe, pass, decorate, linkable, sqlTables, config, artIndex, figuresByAddress, events, drawings, }: {
233
+ export function renderSitePage(page: any, { index, foreign, universe, pass, decorate, linkable, sqlTables, config, artIndex, figuresByAddress, events, drawings, runs, }: {
234
234
  index: any;
235
235
  foreign: any;
236
236
  universe: any;
@@ -243,6 +243,7 @@ export function renderSitePage(page: any, { index, foreign, universe, pass, deco
243
243
  figuresByAddress?: Map<any, any> | undefined;
244
244
  events: any;
245
245
  drawings?: Map<any, any> | undefined;
246
+ runs?: import("./content-scripts.mjs").RunContext | undefined;
246
247
  }): {
247
248
  page: any;
248
249
  body: string;
@@ -18,15 +18,23 @@
18
18
  */
19
19
  export function noindexHeaders(): string[];
20
20
  /**
21
- * The `_headers` file's contents: the `noindex` rules, and nothing else.
21
+ * The `_headers` file's contents: the `noindex` rules, and the script fonts'
22
+ * cache rule when the site carries them.
22
23
  *
23
24
  * No `Cache-Control` is pinned on the prefix root. It is the homepage, and a
24
25
  * lifetime on it would hold a stale copy at the most-linked address after a
25
- * deploy; Pages' own defaults for a page apply.
26
+ * deploy; Pages' own defaults for a page apply. The fonts sit under a path
27
+ * that names their version, so a year's lifetime never serves a stale file.
26
28
  *
29
+ * @param {object} [options] - Options.
30
+ * @param {string} [options.pkg] - The content package, which is the prefix.
31
+ * @param {boolean} [options.fonts] - Whether the site carries the fonts.
27
32
  * @returns {string} The file's contents.
28
33
  */
29
- export function headers(): string;
34
+ export function headers({ pkg, fonts }?: {
35
+ pkg?: string | undefined;
36
+ fonts?: boolean | undefined;
37
+ }): string;
30
38
  export function indexSite(where: {
31
39
  site: string;
32
40
  output: string;