@heroiclands/package-build 23.13.0 → 24.0.1

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 (236) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +2 -1
  3. package/assets/preview/gitea.ini +12 -7
  4. package/assets/styles/content-base.css +150 -1
  5. package/bin/content-commands.mjs +356 -210
  6. package/bin/package-build.mjs +3 -2
  7. package/ci/check-banners.mjs +7 -7
  8. package/config.mjs +21 -6
  9. package/content-config.mjs +199 -80
  10. package/docs/api.md +93 -72
  11. package/docs/authoring/links-and-markup.md +316 -78
  12. package/docs/commands.md +248 -80
  13. package/docs/configuration.md +210 -102
  14. package/docs/content-format.md +2 -2
  15. package/docs/diagnostics.md +2 -2
  16. package/docs/getting-started.md +1 -1
  17. package/docs/guides/icons.md +1 -1
  18. package/docs/guides/module-project.md +5 -8
  19. package/docs/guides/release-and-deploy.md +2 -2
  20. package/docs/guides/site.md +155 -23
  21. package/docs/guides/system-project.md +1 -1
  22. package/docs/guides/writing-in-invented-scripts.md +1247 -0
  23. package/docs/index.md +1 -0
  24. package/docs/project-setup.md +28 -30
  25. package/docs/reference/format-details.md +589 -308
  26. package/docs/reference/note-types.md +40 -10
  27. package/docs/reference/theme-pages.md +127 -108
  28. package/docs/source-preview.md +15 -1
  29. package/engine/asset-shipping.mjs +22 -10
  30. package/engine/base-compiler.mjs +62 -104
  31. package/engine/changelog-lint.mjs +1 -1
  32. package/engine/content-address.mjs +1 -1
  33. package/engine/content-alerts.mjs +8 -4
  34. package/engine/content-blocks.mjs +26 -11
  35. package/engine/content-embeds.mjs +1 -1
  36. package/engine/content-expand.mjs +376 -0
  37. package/engine/content-figures.mjs +13 -6
  38. package/engine/content-format.yaml +8 -0
  39. package/engine/content-glyphs.mjs +213 -0
  40. package/engine/content-images.mjs +6 -7
  41. package/engine/content-links.mjs +3 -3
  42. package/engine/content-lint.mjs +1 -1
  43. package/engine/content-render.mjs +453 -0
  44. package/engine/content-scripts.mjs +326 -27
  45. package/engine/content-spans.mjs +4 -1
  46. package/engine/content-styles.mjs +91 -0
  47. package/engine/content-symbols.mjs +186 -0
  48. package/engine/content-verse.mjs +6 -18
  49. package/engine/core-report.mjs +169 -0
  50. package/engine/core-vocabulary.mjs +208 -0
  51. package/engine/dictionary-html.mjs +119 -0
  52. package/engine/field-reference.mjs +1 -1
  53. package/engine/frontmatter-lint.mjs +1 -1
  54. package/engine/heading-attributes.mjs +89 -0
  55. package/engine/helpers.mjs +61 -101
  56. package/engine/homepage.mjs +17 -29
  57. package/engine/html-minify.mjs +70 -0
  58. package/engine/index.mjs +8 -5
  59. package/engine/language-rows.mjs +8 -2
  60. package/engine/language-terms.mjs +115 -14
  61. package/engine/language-words.mjs +12 -0
  62. package/engine/logographic.mjs +255 -0
  63. package/engine/map-lexicon.mjs +221 -25
  64. package/engine/map-places.mjs +5 -4
  65. package/engine/markdown-expressions.mjs +0 -2
  66. package/engine/markdownlint-run.mjs +9 -3
  67. package/engine/markup-validation.mjs +21 -0
  68. package/engine/metre-declaration.mjs +134 -0
  69. package/engine/note-matter.mjs +2 -2
  70. package/engine/note-vocabulary.mjs +187 -3
  71. package/engine/pdf-build.mjs +68 -133
  72. package/engine/pdf-render.mjs +102 -44
  73. package/engine/post-fields.mjs +157 -0
  74. package/engine/preview-index.mjs +130 -0
  75. package/engine/preview-source.mjs +450 -0
  76. package/engine/project-init.mjs +5 -12
  77. package/engine/prose-config.mjs +3 -3
  78. package/engine/run-words.mjs +3 -2
  79. package/engine/script-emphasis-terms.mjs +38 -0
  80. package/engine/script-emphasis.mjs +295 -0
  81. package/engine/script-font-delivery.mjs +4 -4
  82. package/engine/site-build.mjs +265 -313
  83. package/engine/site-config.mjs +26 -238
  84. package/engine/site-files.mjs +175 -0
  85. package/engine/site-index.mjs +9 -4
  86. package/engine/site-preview.mjs +50 -523
  87. package/engine/site-reach.mjs +213 -0
  88. package/engine/site-render.mjs +668 -0
  89. package/engine/site-root.mjs +90 -39
  90. package/engine/site-search.mjs +161 -0
  91. package/engine/site-serve.mjs +274 -0
  92. package/engine/site-theme-banner.mjs +154 -0
  93. package/engine/site-theme-urls.mjs +125 -0
  94. package/engine/site-theme.mjs +939 -0
  95. package/engine/sql-tables.mjs +9 -6
  96. package/engine/text-maps.mjs +57 -10
  97. package/engine/typographer.mjs +248 -0
  98. package/engine/verse-metre.mjs +357 -0
  99. package/engine/wikilink-syntax.mjs +29 -47
  100. package/engine/wikilinks.mjs +758 -279
  101. package/engine/word-forms.mjs +39 -24
  102. package/engine/word-rows.mjs +12 -2
  103. package/engine/word-terms.mjs +29 -4
  104. package/manifest.mjs +3 -4
  105. package/package.json +10 -7
  106. package/{hugo-theme → site-theme}/data/banners.yaml +6 -10
  107. package/site-theme/layouts/base.hbs +31 -0
  108. package/site-theme/layouts/blog-list.hbs +30 -0
  109. package/site-theme/layouts/blog-post.hbs +40 -0
  110. package/site-theme/layouts/home.hbs +35 -0
  111. package/site-theme/layouts/list.hbs +20 -0
  112. package/site-theme/layouts/not-found.hbs +31 -0
  113. package/site-theme/layouts/page.hbs +7 -0
  114. package/site-theme/partials/copy-buttons.hbs +37 -0
  115. package/site-theme/partials/draft-notice.hbs +5 -0
  116. package/site-theme/partials/exturl.hbs +2 -0
  117. package/{hugo-theme/layouts/partials/footer.html → site-theme/partials/footer.hbs} +10 -7
  118. package/site-theme/partials/header.hbs +44 -0
  119. package/site-theme/partials/hero-banner.hbs +11 -0
  120. package/site-theme/partials/infobox-entry.hbs +2 -0
  121. package/site-theme/partials/infobox-section.hbs +31 -0
  122. package/site-theme/partials/infobox-value.hbs +2 -0
  123. package/site-theme/partials/infobox.hbs +18 -0
  124. package/site-theme/partials/list-members.hbs +9 -0
  125. package/site-theme/partials/nav-links.hbs +5 -0
  126. package/site-theme/partials/page-body.hbs +48 -0
  127. package/site-theme/partials/page-list.hbs +14 -0
  128. package/site-theme/partials/related.hbs +24 -0
  129. package/site-theme/partials/search-meta.hbs +6 -0
  130. package/site-theme/partials/search-names.hbs +2 -0
  131. package/site-theme/partials/search.hbs +52 -0
  132. package/site-theme/partials/tags.hbs +4 -0
  133. package/site-theme/partials/toc.hbs +7 -0
  134. package/{hugo-theme → site-theme}/static/css/style.css +14 -0
  135. package/stage.mjs +1 -2
  136. package/types/config.d.mts +8 -4
  137. package/types/content-config.d.mts +15 -15
  138. package/types/engine/asset-shipping.d.mts +5 -2
  139. package/types/engine/base-compiler.d.mts +20 -2
  140. package/types/engine/content-address.d.mts +1 -1
  141. package/types/engine/content-alerts.d.mts +8 -2
  142. package/types/engine/content-blocks.d.mts +11 -4
  143. package/types/engine/content-expand.d.mts +288 -0
  144. package/types/engine/content-figures.d.mts +11 -3
  145. package/types/engine/content-glyphs.d.mts +85 -0
  146. package/types/engine/content-images.d.mts +6 -7
  147. package/types/engine/content-links.d.mts +1 -1
  148. package/types/engine/content-render.d.mts +199 -0
  149. package/types/engine/content-scripts.d.mts +62 -0
  150. package/types/engine/content-spans.d.mts +1 -1
  151. package/types/engine/content-styles.d.mts +33 -0
  152. package/types/engine/content-symbols.d.mts +35 -0
  153. package/types/engine/core-report.d.mts +45 -0
  154. package/types/engine/core-vocabulary.d.mts +53 -0
  155. package/types/engine/dictionary-html.d.mts +8 -0
  156. package/types/engine/field-reference.d.mts +1 -1
  157. package/types/engine/heading-attributes.d.mts +20 -0
  158. package/types/engine/helpers.d.mts +3 -10
  159. package/types/engine/homepage.d.mts +11 -24
  160. package/types/engine/html-minify.d.mts +9 -0
  161. package/types/engine/index.d.mts +2 -1
  162. package/types/engine/language-terms.d.mts +24 -2
  163. package/types/engine/logographic.d.mts +45 -0
  164. package/types/engine/map-lexicon.d.mts +48 -8
  165. package/types/engine/map-places.d.mts +8 -0
  166. package/types/engine/markdown-expressions.d.mts +0 -2
  167. package/types/engine/metre-declaration.d.mts +39 -0
  168. package/types/engine/pdf-render.d.mts +6 -2
  169. package/types/engine/post-fields.d.mts +44 -0
  170. package/types/engine/preview-index.d.mts +72 -0
  171. package/types/engine/preview-source.d.mts +51 -0
  172. package/types/engine/script-emphasis-terms.d.mts +21 -0
  173. package/types/engine/script-emphasis.d.mts +84 -0
  174. package/types/engine/script-font-delivery.d.mts +4 -4
  175. package/types/engine/site-build.d.mts +71 -113
  176. package/types/engine/site-config.d.mts +14 -134
  177. package/types/engine/site-files.d.mts +73 -0
  178. package/types/engine/site-index.d.mts +11 -3
  179. package/types/engine/site-preview.d.mts +15 -19
  180. package/types/engine/site-reach.d.mts +76 -0
  181. package/types/engine/site-render.d.mts +173 -0
  182. package/types/engine/site-root.d.mts +14 -4
  183. package/types/engine/site-search.d.mts +54 -0
  184. package/types/engine/site-serve.d.mts +44 -0
  185. package/types/engine/site-theme-banner.d.mts +51 -0
  186. package/types/engine/site-theme-urls.d.mts +60 -0
  187. package/types/engine/site-theme.d.mts +127 -0
  188. package/types/engine/text-maps.d.mts +17 -3
  189. package/types/engine/typographer.d.mts +11 -0
  190. package/types/engine/verse-metre.d.mts +131 -0
  191. package/types/engine/wikilink-syntax.d.mts +30 -48
  192. package/types/engine/wikilinks.d.mts +330 -14
  193. package/types/engine/word-forms.d.mts +3 -2
  194. package/types/manifest.d.mts +3 -4
  195. package/types/stage.d.mts +1 -2
  196. package/types/vendor/markdownlint.d.mts +8 -0
  197. package/vendor/markdownlint.mjs +20388 -0
  198. package/engine/web-wikilinks.mjs +0 -594
  199. package/hugo-theme/layouts/404.html +0 -85
  200. package/hugo-theme/layouts/_default/baseof.html +0 -67
  201. package/hugo-theme/layouts/_default/list.html +0 -139
  202. package/hugo-theme/layouts/_default/single.html +0 -4
  203. package/hugo-theme/layouts/blog/list.html +0 -54
  204. package/hugo-theme/layouts/blog-post/single.html +0 -36
  205. package/hugo-theme/layouts/index.html +0 -75
  206. package/hugo-theme/layouts/partials/banner-url.html +0 -141
  207. package/hugo-theme/layouts/partials/cdn-url.html +0 -36
  208. package/hugo-theme/layouts/partials/dictionary-lists.html +0 -58
  209. package/hugo-theme/layouts/partials/draft-notice.html +0 -41
  210. package/hugo-theme/layouts/partials/draft-state.html +0 -26
  211. package/hugo-theme/layouts/partials/header.html +0 -35
  212. package/hugo-theme/layouts/partials/hero-banner.html +0 -85
  213. package/hugo-theme/layouts/partials/infobox/entry.html +0 -18
  214. package/hugo-theme/layouts/partials/infobox/items.html +0 -26
  215. package/hugo-theme/layouts/partials/infobox/section.html +0 -56
  216. package/hugo-theme/layouts/partials/infobox/value.html +0 -43
  217. package/hugo-theme/layouts/partials/infobox.html +0 -57
  218. package/hugo-theme/layouts/partials/page-body.html +0 -152
  219. package/hugo-theme/layouts/partials/related.html +0 -138
  220. package/hugo-theme/layouts/partials/search.html +0 -84
  221. package/hugo-theme/layouts/partials/site-url.html +0 -32
  222. package/hugo-theme/layouts/partials/tags.html +0 -30
  223. package/hugo-theme/layouts/partials/toc.html +0 -28
  224. package/hugo-theme/layouts/partials/warn-missing-banner.html +0 -3
  225. package/hugo-theme/layouts/shortcodes/cartouche.html +0 -64
  226. package/hugo-theme/layouts/shortcodes/exturl.html +0 -12
  227. package/hugo-theme/layouts/shortcodes/glyph.html +0 -43
  228. package/hugo-theme/layouts/shortcodes/pagelist.html +0 -63
  229. package/hugo-theme/theme.toml +0 -11
  230. package/types/engine/web-wikilinks.d.mts +0 -107
  231. /package/{hugo-theme → site-theme}/data/banner-kinds.yaml +0 -0
  232. /package/{hugo-theme → site-theme}/static/css/sohl-icons.css +0 -0
  233. /package/{hugo-theme → site-theme}/static/fonts/game-icons-kb.woff2 +0 -0
  234. /package/{hugo-theme → site-theme}/static/img/banners/takheperu-hieroglyphs.svg +0 -0
  235. /package/{hugo-theme → site-theme}/static/img/cartouches/takheperu.svg +0 -0
  236. /package/{hugo-theme → site-theme}/static/js/inline-spoilers.js +0 -0
@@ -0,0 +1,127 @@
1
+ /** A string with its first letter capitalised and its separators read as spaces. */
2
+ export function humanize(value: any): string;
3
+ /** The text of HTML: tags dropped, character references decoded, whitespace collapsed. */
4
+ export function plainText(html: any): string;
5
+ /** Whether a page states it is a draft. */
6
+ export function isDraft(params?: {}): any;
7
+ /**
8
+ * The subject tags of a page: every tag but the one that marks a draft.
9
+ *
10
+ * @param {object} params - The page's frontmatter.
11
+ * @returns {string[]} The tags.
12
+ */
13
+ export function subjectTags(params?: object): string[];
14
+ /**
15
+ * The headings of rendered HTML that a contents list names.
16
+ *
17
+ * @param {string} html - A page's body.
18
+ * @returns {Array<{level: number, id: string, text: string}>} The `h2` and `h3`
19
+ * headings in document order, the footnote list's own heading left out; `id`
20
+ * is empty for a heading that has none.
21
+ */
22
+ export function pageHeadings(html: string): Array<{
23
+ level: number;
24
+ id: string;
25
+ text: string;
26
+ }>;
27
+ /**
28
+ * A contents list for a page's headings.
29
+ *
30
+ * @param {Array<{level: number, id: string, text: string}>} headings - From {@link pageHeadings}.
31
+ * @returns {string} A `nav` of nested lists, or `""` when there are no headings. A
32
+ * heading with no id is listed without a link.
33
+ */
34
+ export function tableOfContents(headings: Array<{
35
+ level: number;
36
+ id: string;
37
+ text: string;
38
+ }>): string;
39
+ /**
40
+ * The page before and the page after this one.
41
+ *
42
+ * `siblings` is in the order a reader walks. Where the section holds more than
43
+ * one catalog, the siblings are narrowed to the pages sharing this page's
44
+ * catalog key: `type`, or for a `doc` its `subType` or `category`. A section
45
+ * holding one catalog is left alone, as is a page declaring none.
46
+ *
47
+ * @param {object} page - The page.
48
+ * @param {boolean} [narrow] - Whether to narrow to the page's catalog.
49
+ * @returns {{prev?: object, next?: object}} The neighbours; `prev` is the entry
50
+ * after this one in `siblings`, and `next` the entry before it.
51
+ */
52
+ export function neighbours(page: object, narrow?: boolean): {
53
+ prev?: object;
54
+ next?: object;
55
+ };
56
+ /**
57
+ * @typedef {object} Finding
58
+ * @property {"warning"|"error"} severity
59
+ * @property {string} message
60
+ * @property {string} [page] - The address of the page the finding is about.
61
+ * @property {string} [file] - The file the page was written in.
62
+ * @property {Array<string|number>} [param] - The path of the site parameter
63
+ * the finding is about, such as `["notfound", "links", 1, "url"]`.
64
+ */
65
+ /**
66
+ * Create the layouts for one site.
67
+ *
68
+ * @param {object} options - The inputs.
69
+ * @param {object} options.site - The site; see the module description.
70
+ * @param {string} [options.dir] - The directory holding `layouts/` and
71
+ * `partials/`. The shipped theme by default.
72
+ * @param {{banners: object, kinds: object}} [options.bannerData] - The banner
73
+ * inventory and kind mapping. The shipped ones by default.
74
+ * @param {(finding: Finding) => void} [options.report] - Receives each finding
75
+ * as it is made. Every finding is also kept in `findings`.
76
+ * @returns {{
77
+ * render: (page: object) => string,
78
+ * layoutFor: (page: object) => string,
79
+ * partial: (name: string, context?: object) => string,
80
+ * findings: Finding[],
81
+ * }} The theme.
82
+ */
83
+ export function createSiteTheme({ site, dir, bannerData, report }: {
84
+ site: object;
85
+ dir?: string | undefined;
86
+ bannerData?: {
87
+ banners: object;
88
+ kinds: object;
89
+ } | undefined;
90
+ report?: ((finding: Finding) => void) | undefined;
91
+ }): {
92
+ render: (page: object) => string;
93
+ layoutFor: (page: object) => string;
94
+ partial: (name: string, context?: object) => string;
95
+ findings: Finding[];
96
+ };
97
+ /**
98
+ * The files the layouts link that the theme generates.
99
+ *
100
+ * @returns {Array<{path: string, content: string}>} Each file's path under the
101
+ * site and its contents.
102
+ */
103
+ export function siteThemeAssets(): Array<{
104
+ path: string;
105
+ content: string;
106
+ }>;
107
+ /** The directory the layouts and partials are read from. */
108
+ export const SITE_THEME_DIR: string;
109
+ /** The layouts a page can be drawn by. */
110
+ export const LAYOUTS: readonly string[];
111
+ export type Finding = {
112
+ severity: "warning" | "error";
113
+ message: string;
114
+ /**
115
+ * - The address of the page the finding is about.
116
+ */
117
+ page?: string | undefined;
118
+ /**
119
+ * - The file the page was written in.
120
+ */
121
+ file?: string | undefined;
122
+ /**
123
+ * - The path of the site parameter
124
+ * the finding is about, such as `["notfound", "links", 1, "url"]`.
125
+ */
126
+ param?: (string | number)[] | undefined;
127
+ };
@@ -39,14 +39,16 @@ export function capitalNative(map: TextMap, font: string | undefined, word: stri
39
39
  * as it is.
40
40
  * @param {string} text - The text, with no escapes in it.
41
41
  * @param {MapOptions} [options] - The face, and the native forms of words.
42
- * @returns {{text: string, pieces: Array<{at: number, from: string, to: string, row: boolean, native?: boolean}>}}
42
+ * @returns {{text: string, pieces: Array<{at: number, from: string, to: string, row: boolean, native?: boolean, unwritten?: object}>}}
43
43
  * The rewritten text, and each piece of it with the UTF-16 offset in `text`
44
44
  * it came from: a matched row's `from` and what it wrote, a word and its
45
45
  * native form (`native: true`), or one character that passed through. A
46
46
  * capitalised word whose native form the rows cannot capitalise is written
47
47
  * as stated and carries `uncapitalised`, the lowercase form it was found by.
48
+ * Under a logographic map, a word with no writing is written as typed and
49
+ * carries `unwritten`, why it has none.
48
50
  */
49
- export function applyMap(map: TextMap | undefined, text: string, { font, native }?: MapOptions): {
51
+ export function applyMap(map: TextMap | undefined, text: string, { font, native, writing }?: MapOptions): {
50
52
  text: string;
51
53
  pieces: Array<{
52
54
  at: number;
@@ -54,6 +56,7 @@ export function applyMap(map: TextMap | undefined, text: string, { font, native
54
56
  to: string;
55
57
  row: boolean;
56
58
  native?: boolean;
59
+ unwritten?: object;
57
60
  }>;
58
61
  };
59
62
  /**
@@ -78,7 +81,8 @@ export function mapRows(records: Iterable<Record<string, any>>, ownerOf: (record
78
81
  /**
79
82
  * Check a note's `data.map`: its name, that no other note declares it, each
80
83
  * row written as a list, a `before` condition on a map with no `vowels`, an
81
- * empty `fonts`, and a generic family in it. The data-key check owns every
84
+ * empty `fonts`, a generic family in it, and a row of a logographic map that
85
+ * matches a letter. The data-key check owns every
82
86
  * key, its kind and the words a condition takes; whether a listed face is
83
87
  * installed, and draws what the map writes, is
84
88
  * {@link module:engine/map-lexicon.checkMapFonts}'s.
@@ -136,6 +140,11 @@ export type TextMap = {
136
140
  * - Its name.
137
141
  */
138
142
  name: string;
143
+ /**
144
+ * - Whether it writes words from the lexicon
145
+ * alone, its rows only between them.
146
+ */
147
+ logographic: boolean;
139
148
  /**
140
149
  * - The characters `before: vowel` reads.
141
150
  */
@@ -172,4 +181,9 @@ export type MapOptions = {
172
181
  * form, for the word exactly as given, or `undefined` where it states none.
173
182
  */
174
183
  native?: ((word: string) => string | undefined) | undefined;
184
+ /**
185
+ * -
186
+ * A word's writing under a logographic map; without one, no word has one.
187
+ */
188
+ writing?: ((word: string) => import("./logographic.mjs").Writing) | undefined;
175
189
  };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Set typographic punctuation in every inline run.
3
+ *
4
+ * @param {import("markdown-it")} md - Markdown parser to extend.
5
+ */
6
+ export function typographerPlugin(md: typeof import("markdown-it")): void;
7
+ /**
8
+ * The token a typographic character is written as. It is a token of its own,
9
+ * not text, so a reader of a heading's text can tell where it stands.
10
+ */
11
+ export const TYPOGRAPHIC: "typographic";
@@ -0,0 +1,131 @@
1
+ /**
2
+ * The syllables of a word, each as the vowel group that makes it.
3
+ *
4
+ * @param {string} word - The word.
5
+ * @param {Iterable<string>} pairs - The vowel pairs that are one syllable.
6
+ * @returns {string[]} The nuclei, in order; none for a word with no vowel.
7
+ */
8
+ export function nucleiOf(word: string, pairs: Iterable<string>): string[];
9
+ /**
10
+ * The index of the stressed syllable of a word.
11
+ *
12
+ * @param {string} word - The word.
13
+ * @param {{two: string, longer: string, mark?: string}} rule - The language's
14
+ * `data.sounds.stress`.
15
+ * @param {Iterable<string>} pairs - The vowel pairs that are one syllable.
16
+ * @returns {number} The 0-based syllable; 0 for a word of one syllable or none.
17
+ */
18
+ export function stressIndex(word: string, rule: {
19
+ two: string;
20
+ longer: string;
21
+ mark?: string;
22
+ }, pairs: Iterable<string>): number;
23
+ /**
24
+ * Each configured language's metre book: one per language whose `note` names a
25
+ * language note stating a complete `data.sounds.stress`.
26
+ *
27
+ * @param {Iterable<Record<string, any>>|undefined} records - Index records.
28
+ * @param {{languages?: Readonly<Record<string, {tag: string, note?: string}>>, contentPackage?: string}} config -
29
+ * The resolved configuration.
30
+ * @returns {Map<string, MetreBook>} The books by language name.
31
+ */
32
+ export function metreBooksFromRecords(records: Iterable<Record<string, any>> | undefined, config?: {
33
+ languages?: Readonly<Record<string, {
34
+ tag: string;
35
+ note?: string;
36
+ }>>;
37
+ contentPackage?: string;
38
+ }): Map<string, MetreBook>;
39
+ /**
40
+ * Every metre the index's `doc` notes declare, by name. The first note to
41
+ * declare a name keeps it.
42
+ *
43
+ * @param {Iterable<Record<string, any>>|undefined} records - Index records.
44
+ * @returns {Map<string, import("./metre-declaration.mjs").Metre>} The metres.
45
+ */
46
+ export function metresFromRecords(records: Iterable<Record<string, any>> | undefined): Map<string, import("./metre-declaration.mjs").Metre>;
47
+ /**
48
+ * The beats a line of verse can have.
49
+ *
50
+ * @param {string} text - The line.
51
+ * @param {MetreBook} book - The line's language's book.
52
+ * @returns {{min: number, max: number}} The beats without the second beats a
53
+ * long word may take, and with all of them.
54
+ */
55
+ export function lineBeats(text: string, book: MetreBook): {
56
+ min: number;
57
+ max: number;
58
+ };
59
+ /**
60
+ * The warning for a line that cannot have its metre's beats.
61
+ *
62
+ * @param {{min: number, max: number}} beats - The line's beats.
63
+ * @param {import("./metre-declaration.mjs").Metre} metre - The fence's metre.
64
+ * @returns {string} The message.
65
+ */
66
+ export function metreMessage({ min, max }: {
67
+ min: number;
68
+ max: number;
69
+ }, metre: import("./metre-declaration.mjs").Metre): string;
70
+ /**
71
+ * Check the verse fences that state `scan=`.
72
+ *
73
+ * @param {ReadonlyArray<{start: number, end: number, indent: string, attributes: Record<string, string>, classes: string[]}>} blocks -
74
+ * The fences, from {@link module:engine/content-verse.scanVerse}.
75
+ * @param {string[]} lines - The source's lines.
76
+ * @param {{metres?: ReadonlyMap<string, import("./metre-declaration.mjs").Metre>, metreBooks?: ReadonlyMap<string, MetreBook>, lexicons?: ReadonlyMap<string, unknown>, columnsClass: string, columnKeys: readonly string[], attributeColumns: (line: string, key: string) => {key: number, value: number}}} ctx -
77
+ * The metres and books, and how the fence says its columns and where its
78
+ * keys sit.
79
+ * @returns {{errors: object[], warnings: object[]}} The findings at 1-based
80
+ * positions.
81
+ */
82
+ export function metreFindings(blocks: ReadonlyArray<{
83
+ start: number;
84
+ end: number;
85
+ indent: string;
86
+ attributes: Record<string, string>;
87
+ classes: string[];
88
+ }>, lines: string[], ctx: {
89
+ metres?: ReadonlyMap<string, import("./metre-declaration.mjs").Metre>;
90
+ metreBooks?: ReadonlyMap<string, MetreBook>;
91
+ lexicons?: ReadonlyMap<string, unknown>;
92
+ columnsClass: string;
93
+ columnKeys: readonly string[];
94
+ attributeColumns: (line: string, key: string) => {
95
+ key: number;
96
+ value: number;
97
+ };
98
+ }): {
99
+ errors: object[];
100
+ warnings: object[];
101
+ };
102
+ /** The bases whose one-syllable words carry a beat. */
103
+ export const BEAT_BASES: readonly string[];
104
+ /**
105
+ * What a language's lines are counted by.
106
+ */
107
+ export type MetreBook = {
108
+ /**
109
+ * - The language's configured name.
110
+ */
111
+ language: string;
112
+ /**
113
+ * - Its stress rule.
114
+ */
115
+ rule: {
116
+ two: string;
117
+ longer: string;
118
+ mark?: string;
119
+ };
120
+ /**
121
+ * - Its vowel pairs.
122
+ */
123
+ pairs: ReadonlySet<string>;
124
+ /**
125
+ * - Each lexicon
126
+ * form, and each form its rules derive, folded, with the class bases of its
127
+ * entries.
128
+ */
129
+ classes: ReadonlyMap<string, ReadonlySet<string>>;
130
+ };
131
+ export { METRE_KINDS, METRE_NAME, checkMetresField } from "./metre-declaration.mjs";
@@ -36,12 +36,8 @@ export function parseWikilink(rawInner: string, literal?: string): ParsedWikilin
36
36
  * `[[x|]]` is labelled and `[[x]]` is not, and only the first addresses
37
37
  * anything.
38
38
  *
39
- * Stated here because the two resolvers had already drawn the line in two
40
- * places and drawn it differently: the packs tested falsiness and were right,
41
- * the web tested `??` — which falls through on `null` only — and emitted
42
- * `[](/url/)`, a link with no clickable text, through every build. That
43
- * is the same drift this module exists to prevent, in the case its own
44
- * {@link ParsedWikilink} docstring calls out. One reading, one place.
39
+ * Read with `??`, which falls through on `null` only, an empty label would
40
+ * emit `[](/url/)`: a link with no clickable text. One reading, one place.
45
41
  *
46
42
  * @param {{display: string|null}} parsed - A parsed wikilink, or anything
47
43
  * carrying its `display`.
@@ -53,7 +49,7 @@ export function authoredLabel({ display }: {
53
49
  /**
54
50
  * What an author writing an unlabelled link is told, in one place.
55
51
  *
56
- * Shared by the link checker, the pack compilers and the web resolver, because
52
+ * Shared by the link checker and the resolver, on every target, because
57
53
  * an author meets whichever runs first and they should read the same. It names
58
54
  * the form to write rather than a value to correct: there is no value that
59
55
  * makes an unlabelled link resolve.
@@ -99,7 +95,7 @@ export function isEventAnchor(hit: {
99
95
  *
100
96
  * An address naming no note is a typo or an omission: the intent of a
101
97
  * placeholder for a note nobody has written yet is spelled as a `draft`-tagged
102
- * note that exists, resolves and renders marked. Both want fixing, and all three builds say so.
98
+ * note that exists, resolves and renders marked. Both want fixing, and every build says so.
103
99
  *
104
100
  * @param {string} target - The address as authored, named in the message.
105
101
  * @returns {string} The message, unpunctuated at the end as a finding is.
@@ -143,9 +139,9 @@ export function ambiguousAddressMessage(target: string, packages?: Iterable<stri
143
139
  /**
144
140
  * The message for one link finding, whichever resolver found it.
145
141
  *
146
- * The single table the checker, the pack compilers and the web resolver all
147
- * report through, so one authored link cannot get three different explanations
148
- * of the same mistake depending on which build the author ran first. Callers
142
+ * The single table the checker and the resolver report through, on every
143
+ * target, so one authored link cannot get different explanations of the same
144
+ * mistake depending on which build the author ran first. Callers
149
145
  * add their own context around it — the note's name, the file it sits in — and
150
146
  * never their own wording for the defect.
151
147
  *
@@ -181,8 +177,9 @@ export function linkFindingMessage({ reason, target, packages, anchor, type, stu
181
177
  /**
182
178
  * Whether a parsed link addresses a section of the page it is written on.
183
179
  *
184
- * `[[#some-heading]]` — no target, only an anchor. Both resolvers special-case
185
- * it before consulting any index, because there is nothing to look up.
180
+ * `[[#some-heading]]` — no target, only an anchor. The resolver and the checker
181
+ * special-case it before consulting any index, because there is nothing to look
182
+ * up.
186
183
  *
187
184
  * @param {ParsedWikilink} parsed - A parsed wikilink.
188
185
  * @returns {boolean} True when the link is same-page.
@@ -212,36 +209,23 @@ export function presentWikilink(reference: string, parsed: object, destination:
212
209
  /**
213
210
  * What a `[[…]]` **is**, before anything decides where it points.
214
211
  *
215
- * One authored link compiles to two different addresses — a Foundry `@UUID`
216
- * enricher for the packs, a URL for the web — and those two destinations are the
217
- * *only* thing that legitimately differs. The syntax is the author's, and it is
218
- * the same syntax whichever build is reading it.
212
+ * One authored link is written three ways — a Foundry `@UUID` content link for
213
+ * the packs, a URL for the web, a cross-reference for the book — and those
214
+ * forms are the *only* thing that legitimately differs. The syntax is the
215
+ * author's, and it is the same syntax whichever build is reading it.
219
216
  *
220
- * It was written twice, and the two copies had already drifted:
217
+ * So the parse lives here, once, and two readers take it: the link checker
218
+ * (`content-links.mjs`) and the resolver (`wikilinks.mjs`). Each receives the
219
+ * parts and decides only what it is for: which document the address names.
221
220
  *
222
- * | Body | `foundry` side | `web` side |
223
- * | --- | --- | --- |
224
- * | `[[weapongear-bsw` ⏎ `]]` in a table cell | not a link | a link whose target ends in a newline |
225
- * | a stray `[[`, a real link two paragraphs later | finds the real link | swallows both paragraphs as one target |
226
- *
227
- * The web side's pattern omitted `\n` from the excluded set, so an unclosed
228
- * bracket consumed everything up to the next `]]` anywhere in the document —
229
- * the same shape of corruption a hand-rolled code-fence regex caused on the one
230
- * page whose subject is link syntax. It was also internally
231
- * inconsistent: its *frontmatter* scan excluded newlines while its body scan did
232
- * not.
233
- *
234
- * So the parse lives here, once. A resolver receives the parts and decides only
235
- * what it is actually for: which document the address names.
236
- *
237
- * The one rule about a link's *shape* that both resolvers share also lives here
238
- * — **a link carries a label** ({@link unlabelledLinkMessage}) — because the
239
- * two state it through one message and the author reads the same words
240
- * whichever ran first.
221
+ * The one rule about a link's *shape* also lives here — **a link carries a
222
+ * label** ({@link unlabelledLinkMessage}) — because every build states it
223
+ * through one message and the author reads the same words whichever ran
224
+ * first.
241
225
  *
242
226
  * For the same reason, so does the **vocabulary of link findings**
243
227
  * ({@link LINK_FINDING_REASONS}) and the message each one reports through
244
- * ({@link linkFindingMessage}). Three builds read one authored link; an author
228
+ * ({@link linkFindingMessage}). Every build reads one authored link; an author
245
229
  * meets whichever ran first, and a consumer switching on a `reason` should not
246
230
  * be switching on which build produced it.
247
231
  *
@@ -258,20 +242,18 @@ export function presentWikilink(reference: string, parsed: object, destination:
258
242
  * **A leading `!` makes it an embed, not a link**, and the lookbehind is what
259
243
  * keeps every reader from seeing one as the other. Stated here rather than in
260
244
  * each reader for the reason the rest of this module exists: the checker, the
261
- * pack compilers and the web resolver all match on this pattern, and three
262
- * copies of the exclusion is three places for it to be forgotten. An embed's
245
+ * resolver and the embed reader all match on this pattern, and a copy of the
246
+ * exclusion in each is a place for it to be forgotten. An embed's
263
247
  * own grammar is {@link module:engine/content-embeds}.
264
248
  */
265
249
  export const WIKILINK: RegExp;
266
250
  /**
267
- * Every way a link can fail, named once for all three resolvers.
268
- *
269
- * A link is read in three places — the checker (`content-links.mjs`), the pack
270
- * compilers (`wikilinks.mjs`) and the web resolver (`web-wikilinks.mjs`) — and
271
- * each would otherwise name the failures in its own words. `unknown` in one is
272
- * `unresolved` in another and `broken type/shortcode` in the third, so a
273
- * consumer switching on a `reason` was switching on which build had produced
274
- * it. The set is closed and lives here, beside the syntax the three share.
251
+ * Every way a link can fail, named once for every reader of a link.
252
+ *
253
+ * A link is read by the checker (`content-links.mjs`) and by the resolver
254
+ * (`wikilinks.mjs`) for every target, and each names a failure by one of these
255
+ * reasons, so a consumer switching on a `reason` never switches on which build
256
+ * produced it. The set is closed and lives here, beside the syntax they share.
275
257
  *
276
258
  * - `unlabelled` — no `|`, so the link addresses nothing.
277
259
  * - `not-an-address` — labelled, but the target does not parse as an address.