@heroiclands/package-build 23.12.8 → 24.0.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.
Files changed (258) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +3 -2
  3. package/assets/preview/gitea.ini +12 -7
  4. package/assets/styles/content-base.css +293 -24
  5. package/bin/content-commands.mjs +370 -213
  6. package/bin/package-build-preview.mjs +2 -2
  7. package/bin/package-build.mjs +3 -2
  8. package/ci/check-banners.mjs +7 -7
  9. package/config.mjs +21 -6
  10. package/content-config.mjs +199 -80
  11. package/docs/api.md +110 -89
  12. package/docs/authoring/links-and-markup.md +469 -97
  13. package/docs/commands.md +259 -78
  14. package/docs/configuration.md +211 -103
  15. package/docs/content-format.md +4 -4
  16. package/docs/diagnostics.md +44 -2
  17. package/docs/getting-started.md +1 -1
  18. package/docs/guides/icons.md +1 -1
  19. package/docs/guides/module-project.md +5 -8
  20. package/docs/guides/release-and-deploy.md +2 -2
  21. package/docs/guides/site.md +112 -23
  22. package/docs/guides/system-project.md +1 -1
  23. package/docs/guides/writing-in-invented-scripts.md +1247 -0
  24. package/docs/index.md +1 -0
  25. package/docs/project-setup.md +28 -30
  26. package/docs/reference/format-details.md +677 -319
  27. package/docs/reference/note-types.md +47 -10
  28. package/docs/reference/theme-pages.md +178 -108
  29. package/docs/source-preview.md +16 -2
  30. package/engine/anchors.mjs +2 -2
  31. package/engine/asset-shipping.mjs +22 -10
  32. package/engine/base-compiler.mjs +62 -104
  33. package/engine/changelog-lint.mjs +1 -1
  34. package/engine/code-fences.mjs +3 -3
  35. package/engine/content-address.mjs +1 -1
  36. package/engine/content-alerts.mjs +8 -4
  37. package/engine/content-blocks.mjs +29 -14
  38. package/engine/content-embeds.mjs +1 -1
  39. package/engine/content-expand.mjs +376 -0
  40. package/engine/content-figures.mjs +18 -11
  41. package/engine/content-format.yaml +8 -0
  42. package/engine/content-glyphs.mjs +213 -0
  43. package/engine/content-images.mjs +6 -7
  44. package/engine/content-index.mjs +1 -1
  45. package/engine/content-links.mjs +3 -3
  46. package/engine/content-lint.mjs +1 -1
  47. package/engine/content-render.mjs +453 -0
  48. package/engine/content-scripts.mjs +376 -43
  49. package/engine/content-spans.mjs +6 -3
  50. package/engine/content-styles.mjs +91 -0
  51. package/engine/content-symbols.mjs +186 -0
  52. package/engine/content-verse.mjs +738 -0
  53. package/engine/core-report.mjs +169 -0
  54. package/engine/core-vocabulary.mjs +208 -0
  55. package/engine/dictionary-html.mjs +119 -0
  56. package/engine/dictionary-rows.mjs +15 -4
  57. package/engine/field-reference.mjs +5 -5
  58. package/engine/first-use.mjs +17 -27
  59. package/engine/frontmatter-lint.mjs +1 -1
  60. package/engine/heading-attributes.mjs +89 -0
  61. package/engine/helpers.mjs +61 -101
  62. package/engine/homepage.mjs +17 -29
  63. package/engine/html-minify.mjs +70 -0
  64. package/engine/index.mjs +8 -5
  65. package/engine/key-case-collisions.mjs +136 -0
  66. package/engine/language-data.mjs +203 -6
  67. package/engine/language-rows.mjs +8 -2
  68. package/engine/language-terms.mjs +186 -16
  69. package/engine/language-words.mjs +12 -0
  70. package/engine/logographic.mjs +255 -0
  71. package/engine/map-lexicon.mjs +262 -47
  72. package/engine/map-places.mjs +5 -4
  73. package/engine/markdown-expressions.mjs +0 -2
  74. package/engine/markdownlint-run.mjs +9 -3
  75. package/engine/markup-validation.mjs +21 -0
  76. package/engine/metre-declaration.mjs +134 -0
  77. package/engine/names.mjs +36 -9
  78. package/engine/note-matter.mjs +66 -0
  79. package/engine/note-vocabulary.mjs +187 -3
  80. package/engine/pdf-build.mjs +69 -133
  81. package/engine/pdf-render.mjs +205 -58
  82. package/engine/post-fields.mjs +157 -0
  83. package/engine/preview-index.mjs +130 -0
  84. package/engine/preview-source.mjs +450 -0
  85. package/engine/project-init.mjs +5 -12
  86. package/engine/prose-config.mjs +3 -3
  87. package/engine/read-stdin.mjs +29 -0
  88. package/engine/run-rows.mjs +2 -2
  89. package/engine/run-words.mjs +6 -112
  90. package/engine/script-emphasis-terms.mjs +38 -0
  91. package/engine/script-emphasis.mjs +295 -0
  92. package/engine/script-font-delivery.mjs +4 -4
  93. package/engine/site-build.mjs +260 -315
  94. package/engine/site-config.mjs +26 -238
  95. package/engine/site-files.mjs +175 -0
  96. package/engine/site-index.mjs +9 -4
  97. package/engine/site-preview.mjs +52 -525
  98. package/engine/site-render.mjs +593 -0
  99. package/engine/site-root.mjs +22 -13
  100. package/engine/site-search.mjs +161 -0
  101. package/engine/site-serve.mjs +273 -0
  102. package/engine/site-theme-banner.mjs +154 -0
  103. package/engine/site-theme-urls.mjs +125 -0
  104. package/engine/site-theme.mjs +926 -0
  105. package/engine/sql-tables.mjs +20 -3
  106. package/engine/text-maps.mjs +57 -10
  107. package/engine/typographer.mjs +248 -0
  108. package/engine/verse-metre.mjs +357 -0
  109. package/engine/wikilink-syntax.mjs +29 -47
  110. package/engine/wikilinks.mjs +758 -279
  111. package/engine/word-forms.mjs +364 -0
  112. package/engine/word-rows.mjs +12 -2
  113. package/engine/word-terms.mjs +38 -4
  114. package/manifest.mjs +3 -4
  115. package/package.json +11 -8
  116. package/{hugo-theme → site-theme}/data/banners.yaml +6 -10
  117. package/site-theme/layouts/base.hbs +31 -0
  118. package/site-theme/layouts/blog-list.hbs +30 -0
  119. package/site-theme/layouts/blog-post.hbs +40 -0
  120. package/site-theme/layouts/home.hbs +35 -0
  121. package/site-theme/layouts/list.hbs +20 -0
  122. package/site-theme/layouts/not-found.hbs +31 -0
  123. package/site-theme/layouts/page.hbs +7 -0
  124. package/site-theme/partials/copy-buttons.hbs +37 -0
  125. package/site-theme/partials/draft-notice.hbs +5 -0
  126. package/site-theme/partials/exturl.hbs +2 -0
  127. package/{hugo-theme/layouts/partials/footer.html → site-theme/partials/footer.hbs} +10 -7
  128. package/site-theme/partials/header.hbs +44 -0
  129. package/site-theme/partials/hero-banner.hbs +11 -0
  130. package/site-theme/partials/infobox-entry.hbs +2 -0
  131. package/site-theme/partials/infobox-section.hbs +31 -0
  132. package/site-theme/partials/infobox-value.hbs +2 -0
  133. package/site-theme/partials/infobox.hbs +18 -0
  134. package/site-theme/partials/list-members.hbs +9 -0
  135. package/site-theme/partials/nav-links.hbs +5 -0
  136. package/site-theme/partials/page-body.hbs +48 -0
  137. package/site-theme/partials/page-list.hbs +14 -0
  138. package/site-theme/partials/related.hbs +24 -0
  139. package/site-theme/partials/search-meta.hbs +6 -0
  140. package/site-theme/partials/search-names.hbs +2 -0
  141. package/site-theme/partials/search.hbs +52 -0
  142. package/site-theme/partials/tags.hbs +4 -0
  143. package/site-theme/partials/toc.hbs +7 -0
  144. package/{hugo-theme → site-theme}/static/css/style.css +106 -14
  145. package/stage.mjs +1 -2
  146. package/types/config.d.mts +8 -4
  147. package/types/content-config.d.mts +15 -15
  148. package/types/engine/asset-shipping.d.mts +5 -2
  149. package/types/engine/base-compiler.d.mts +20 -2
  150. package/types/engine/code-fences.d.mts +3 -3
  151. package/types/engine/content-address.d.mts +1 -1
  152. package/types/engine/content-alerts.d.mts +8 -2
  153. package/types/engine/content-blocks.d.mts +11 -4
  154. package/types/engine/content-expand.d.mts +288 -0
  155. package/types/engine/content-figures.d.mts +11 -3
  156. package/types/engine/content-glyphs.d.mts +85 -0
  157. package/types/engine/content-images.d.mts +6 -7
  158. package/types/engine/content-links.d.mts +1 -1
  159. package/types/engine/content-render.d.mts +199 -0
  160. package/types/engine/content-scripts.d.mts +70 -4
  161. package/types/engine/content-spans.d.mts +1 -1
  162. package/types/engine/content-styles.d.mts +33 -0
  163. package/types/engine/content-symbols.d.mts +35 -0
  164. package/types/engine/content-verse.d.mts +240 -0
  165. package/types/engine/core-report.d.mts +45 -0
  166. package/types/engine/core-vocabulary.d.mts +53 -0
  167. package/types/engine/dictionary-html.d.mts +8 -0
  168. package/types/engine/dictionary-rows.d.mts +10 -0
  169. package/types/engine/field-reference.d.mts +2 -2
  170. package/types/engine/heading-attributes.d.mts +20 -0
  171. package/types/engine/helpers.d.mts +3 -10
  172. package/types/engine/homepage.d.mts +11 -24
  173. package/types/engine/html-minify.d.mts +9 -0
  174. package/types/engine/index.d.mts +2 -1
  175. package/types/engine/key-case-collisions.d.mts +28 -0
  176. package/types/engine/language-data.d.mts +0 -2
  177. package/types/engine/language-terms.d.mts +24 -2
  178. package/types/engine/logographic.d.mts +45 -0
  179. package/types/engine/map-lexicon.d.mts +66 -13
  180. package/types/engine/map-places.d.mts +8 -0
  181. package/types/engine/markdown-expressions.d.mts +0 -2
  182. package/types/engine/metre-declaration.d.mts +39 -0
  183. package/types/engine/names.d.mts +34 -3
  184. package/types/engine/note-matter.d.mts +48 -0
  185. package/types/engine/pdf-render.d.mts +6 -2
  186. package/types/engine/post-fields.d.mts +44 -0
  187. package/types/engine/preview-index.d.mts +72 -0
  188. package/types/engine/preview-source.d.mts +51 -0
  189. package/types/engine/read-stdin.d.mts +11 -0
  190. package/types/engine/run-rows.d.mts +2 -2
  191. package/types/engine/run-words.d.mts +0 -15
  192. package/types/engine/script-emphasis-terms.d.mts +21 -0
  193. package/types/engine/script-emphasis.d.mts +84 -0
  194. package/types/engine/script-font-delivery.d.mts +4 -4
  195. package/types/engine/site-build.d.mts +71 -113
  196. package/types/engine/site-config.d.mts +14 -134
  197. package/types/engine/site-files.d.mts +73 -0
  198. package/types/engine/site-index.d.mts +11 -3
  199. package/types/engine/site-preview.d.mts +15 -19
  200. package/types/engine/site-render.d.mts +171 -0
  201. package/types/engine/site-root.d.mts +12 -4
  202. package/types/engine/site-search.d.mts +54 -0
  203. package/types/engine/site-serve.d.mts +44 -0
  204. package/types/engine/site-theme-banner.d.mts +51 -0
  205. package/types/engine/site-theme-urls.d.mts +60 -0
  206. package/types/engine/site-theme.d.mts +127 -0
  207. package/types/engine/sql-tables.d.mts +4 -1
  208. package/types/engine/text-maps.d.mts +17 -3
  209. package/types/engine/typographer.d.mts +11 -0
  210. package/types/engine/verse-metre.d.mts +131 -0
  211. package/types/engine/wikilink-syntax.d.mts +30 -48
  212. package/types/engine/wikilinks.d.mts +330 -14
  213. package/types/engine/word-forms.d.mts +83 -0
  214. package/types/manifest.d.mts +3 -4
  215. package/types/stage.d.mts +1 -2
  216. package/types/vendor/markdownlint.d.mts +8 -0
  217. package/vendor/markdownlint.mjs +20388 -0
  218. package/engine/content-poetry.mjs +0 -240
  219. package/engine/web-wikilinks.mjs +0 -594
  220. package/hugo-theme/layouts/404.html +0 -85
  221. package/hugo-theme/layouts/_default/baseof.html +0 -67
  222. package/hugo-theme/layouts/_default/list.html +0 -139
  223. package/hugo-theme/layouts/_default/single.html +0 -4
  224. package/hugo-theme/layouts/blog/list.html +0 -54
  225. package/hugo-theme/layouts/blog-post/single.html +0 -36
  226. package/hugo-theme/layouts/index.html +0 -75
  227. package/hugo-theme/layouts/partials/banner-url.html +0 -141
  228. package/hugo-theme/layouts/partials/cdn-url.html +0 -36
  229. package/hugo-theme/layouts/partials/dictionary-lists.html +0 -58
  230. package/hugo-theme/layouts/partials/draft-notice.html +0 -41
  231. package/hugo-theme/layouts/partials/draft-state.html +0 -26
  232. package/hugo-theme/layouts/partials/header.html +0 -35
  233. package/hugo-theme/layouts/partials/hero-banner.html +0 -85
  234. package/hugo-theme/layouts/partials/infobox/entry.html +0 -18
  235. package/hugo-theme/layouts/partials/infobox/items.html +0 -26
  236. package/hugo-theme/layouts/partials/infobox/section.html +0 -56
  237. package/hugo-theme/layouts/partials/infobox/value.html +0 -43
  238. package/hugo-theme/layouts/partials/infobox.html +0 -57
  239. package/hugo-theme/layouts/partials/page-body.html +0 -152
  240. package/hugo-theme/layouts/partials/related.html +0 -138
  241. package/hugo-theme/layouts/partials/search.html +0 -84
  242. package/hugo-theme/layouts/partials/site-url.html +0 -32
  243. package/hugo-theme/layouts/partials/tags.html +0 -30
  244. package/hugo-theme/layouts/partials/toc.html +0 -28
  245. package/hugo-theme/layouts/partials/warn-missing-banner.html +0 -3
  246. package/hugo-theme/layouts/shortcodes/cartouche.html +0 -64
  247. package/hugo-theme/layouts/shortcodes/exturl.html +0 -12
  248. package/hugo-theme/layouts/shortcodes/glyph.html +0 -43
  249. package/hugo-theme/layouts/shortcodes/pagelist.html +0 -63
  250. package/hugo-theme/theme.toml +0 -11
  251. package/types/engine/content-poetry.d.mts +0 -58
  252. package/types/engine/web-wikilinks.d.mts +0 -107
  253. /package/{hugo-theme → site-theme}/data/banner-kinds.yaml +0 -0
  254. /package/{hugo-theme → site-theme}/static/css/sohl-icons.css +0 -0
  255. /package/{hugo-theme → site-theme}/static/fonts/game-icons-kb.woff2 +0 -0
  256. /package/{hugo-theme → site-theme}/static/img/banners/takheperu-hieroglyphs.svg +0 -0
  257. /package/{hugo-theme → site-theme}/static/img/cartouches/takheperu.svg +0 -0
  258. /package/{hugo-theme → site-theme}/static/js/inline-spoilers.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,89 @@
1
1
  # @heroiclands/package-build
2
2
 
3
+ ## 24.0.0
4
+
5
+ ### Major Changes
6
+
7
+ **Upgrading**
8
+
9
+ - Build and preview sites with `package-build site build` and `package-build site serve`; Hugo is no longer used, so update your scripts and workflows and drop its install step.
10
+ - Remove `site.hugo` from `package-build.config.yaml`, and write `[x]{.glyph}` or `[signs]{.cartouche}` where a note used a Hugo shortcode.
11
+ - Describe a verse's metre, rhyme or syllable pattern in prose, since `meter=`, `rhyme=` and `syllables=` are errors; write a language's `stress` as a map, `{ two: first, longer: penultimate, mark: acute }`.
12
+ - Use `engine.wikilinks` in place of `engine.webWikilinks`, and copy the new `assets/preview/gitea.ini` into the Gitea renderer's `app.ini`.
13
+
14
+ ### Patch Changes
15
+
16
+ **Every surface**
17
+
18
+ - Foundry journals, the editor preview and the book render alerts, verse, captions, footnotes, pictures and secret blocks alike; an editor passes its content index to `renderPreview` as `previewIndex`.
19
+ - Fenced code that names a language is highlighted, a captioned map reads **Map N**, and `[label]{.glyph}` and `[label]{.cartouche}` set a sign or framed seal from `icons/<slug>.svg` or `images/cartouches/<slug>.svg`.
20
+
21
+ **Fixes**
22
+
23
+ - Errors on a note's first body line are reported at their own column, `extends` in a `.markdownlint-cli2` options file applies, building pictures twice reports no collisions, and `npm audit` reports no KaTeX advisory.
24
+
25
+ **Languages and scripts**
26
+
27
+ - A `doc` note lists a setting's core concepts in `data.concepts`, a language with `core: true` must cover them, words name theirs in `concept`, and `package-build core` lists the gaps.
28
+ - Emphasis in a script reads as its own mark, a red rubric or an overline, stated in `data.script` or a language's `data.emphasis`; `_…_` and `__…__` work as `*…*` and `**…**` do.
29
+ - A mapping with `logographic: true` writes each word from the lexicon by its own writing or its parts', and a word with neither is an error.
30
+ - A verse fence's `scan=` names a metre declared in `data.metres`, and a line that cannot have its beats is a warning; a word's `variants` take the language's endings.
31
+
32
+ **Sites**
33
+
34
+ - `package-build site build` renders every page, `404.html`, `sitemap.xml` and the search index, minified; `site serve` rebuilds a page when its note or the theme changes and reloads the browser.
35
+ - Blog posts are `doc` notes of `subType: post` with `data.date` and `data.author`, listed newest first and fed as Atom by `site.feed`; `site.sections` and `site.tags` add section and tag pages.
36
+ - `site.base: /` serves a site at its domain's root, where `site.sitemaps` and `site.mergeIndexes` extend its sitemap index, `robots.txt` and search across package sites.
37
+ - Search filters by package, type, subtype, culture, continent, region, author and tag, ranks a note's name first, shows its icon, and leaves out `.secret` sections.
38
+
39
+ ## 23.13.0
40
+
41
+ ### Minor Changes
42
+
43
+ **Language registers**
44
+
45
+ - A register row tagged `other:<tongue>` or `exonym:<tongue>` that its tongue's own register does not list, or whose tongue no language note claims, is an error instead of a warning, so a package carrying one now fails its lint.
46
+
47
+ **Verse**
48
+
49
+ - A poem is written in a ` ```verse ` fence, with the same keys as before; a ` ```poetry ` fence is an ordinary code block, so rename each one to keep it a poem.
50
+ - On the site and in Foundry journals a poem carries the classes `verse` and `verse-line`; restyle any stylesheet that targets the old names.
51
+
52
+ ### Patch Changes
53
+
54
+ **Languages**
55
+
56
+ - An affix may name the word classes it attaches to in `attachesTo`, such as `[n, adj]`; mapped text then accepts its forms of those words alone.
57
+ - An affix that names no classes attaches to words of every class.
58
+
59
+ **Installing**
60
+
61
+ - `npm audit` in a package that installs this one reports no sprintf-js advisory.
62
+
63
+ **Names in prose**
64
+
65
+ - Bold text is emphasis only: a bold label such as `**Strength**:` draws no warning asking you to mark or link it as a name.
66
+ - A name marked with a `data-type` is compared only with notes of that type and subtype: a lineage that shares its name with a place draws no warning to link the place.
67
+
68
+ **Definition lists**
69
+
70
+ - A term with several descriptions sets each description on its own line on the site and in Foundry journals, instead of running them together.
71
+
72
+ **Language notes**
73
+
74
+ - A language may state `agreement` and `participles` in its grammar, and the word check then accepts its adjectives' and pronouns' agreeing forms and its participles on the verb root.
75
+ - `package-build lexicon --derived` lists every form a language's rules derive, each beside the word it comes from.
76
+
77
+ **Content index**
78
+
79
+ - Two notes that spell a key of the same map with different case, such as `carved` and `Carved`, are reported at both notes and their lines, instead of aborting with a message that names no file.
80
+
81
+ **Verse**
82
+
83
+ - A poem can number its lines with `numstep=`, and can be set in up to two columns with `col1=` and `col2=`, such as a verse in a script beside its English, line for line.
84
+ - Each column stacks entries that set one written line through a mapping and a font, so a line typed once in roman shows in its script and in roman.
85
+ - A line that does not pair across the columns is an error at that line.
86
+
3
87
  ## 23.12.8
4
88
 
5
89
  ### Patch Changes
package/README.md CHANGED
@@ -47,7 +47,7 @@ pre-push hook. Run `npm test` and the other checks directly, or use
47
47
 
48
48
  ## Documentation
49
49
 
50
- The documentation lives in the Markdown files in this repository. Start with [the documentation home](docs/index.md). This toolchain does not build its own site or book. A Hugo theme dependency would form a cycle because the theme uses package-build for releases.
50
+ The documentation lives in the Markdown files in this repository. Start with [the documentation home](docs/index.md). This toolchain does not build its own site or book.
51
51
 
52
52
  | Topic | Guide |
53
53
  | ------------------------------------------------- | ------------------------------------------------------------------------- |
@@ -69,6 +69,7 @@ The documentation lives in the Markdown files in this repository. Start with [th
69
69
  | Localization and templates | [Localization](docs/guides/localization.md) |
70
70
  | Foundry integration testing | [End-to-end testing](docs/guides/e2e.md), including an optional S3 server |
71
71
  | Release and deployment | [Release and deploy](docs/guides/release-and-deploy.md) |
72
+ | Invented languages and scripts | [Write in invented scripts](docs/guides/writing-in-invented-scripts.md) |
72
73
  | Buffer-only preview and Gitea rendering | [Source preview](docs/source-preview.md) |
73
74
  | Every CLI command | [Commands](docs/commands.md) |
74
75
  | Every build setting | [Configuration](docs/configuration.md) |
@@ -82,7 +83,7 @@ Every icon and image is covered by a provenance record stating `attribution`, `l
82
83
 
83
84
  `package-build cdn publish --set <file> --name <display name>` uploads every icon and image the package has, shipped or not, to `<site.assets>/<contentPackage>/` in that flat layout, and writes the named set listing the pictures the package leaves out. It reads the bucket from `CDN_ENDPOINT`, `CDN_BUCKET`, `CDN_ACCESS_KEY_ID` and `CDN_SECRET_ACCESS_KEY`, in the environment or `.env.local`. See [publish pictures to the CDN](docs/guides/release-and-deploy.md#publish-pictures-to-the-cdn).
84
85
 
85
- Leading captions, generic fenced divs, inline spans, and poetry code fences are described in [links and markup](docs/authoring/links-and-markup.md).
86
+ Leading captions, generic fenced divs, inline spans, and verse code fences are described in [links and markup](docs/authoring/links-and-markup.md).
86
87
 
87
88
  Cypress end-to-end suites use pinned Chrome for Testing 155.0.8059.84 by default
88
89
  on macOS arm64 and Linux x64, downloaded once into a reusable cache. Select an
@@ -9,12 +9,12 @@ RENDER_CONTENT_MODE = sanitized
9
9
  [markup.sanitizer.markdown.previewDiv]
10
10
  ELEMENT = div
11
11
  ALLOW_ATTR = class
12
- REGEXP = ^(hl-preview(?:-[a-z-]+)?|alert(?:-(?:note|tip|important|warning))?|content-figure(?:-[a-z-]+)?|poetry)( (hl-preview(?:-[a-z-]+)?|alert(?:-(?:note|tip|important|warning))?|content-figure(?:-[a-z-]+)?|poetry))*$
12
+ REGEXP = ^(hl-preview(?:-[a-z-]+)?|content-figure(?:-[a-z-]+)?|verse(?:-[a-z-]+)?|border)( (hl-preview(?:-[a-z-]+)?|content-figure(?:-[a-z-]+)?|verse(?:-[a-z-]+)?|border))*$
13
13
 
14
14
  [markup.sanitizer.markdown.previewSpan]
15
15
  ELEMENT = span
16
16
  ALLOW_ATTR = class
17
- REGEXP = ^(hl-preview-[a-z-]+|alert-(?:title|icon)|poetry-[a-z-]+|i[0-8])( (hl-preview-[a-z-]+|alert-(?:title|icon)|poetry-[a-z-]+|i[0-8]))*$
17
+ REGEXP = ^(hl-preview-[a-z-]+|alert-(?:title|icon)|verse-[a-z-]+|i[0-8]|hljs-[a-z_-]+|[a-z]+_{1,2})( (hl-preview-[a-z-]+|alert-(?:title|icon)|verse-[a-z-]+|i[0-8]|hljs-[a-z_-]+|[a-z]+_{1,2}))*$
18
18
 
19
19
  [markup.sanitizer.markdown.previewPre]
20
20
  ELEMENT = pre
@@ -29,7 +29,7 @@ REGEXP = ^(hl-preview-fence|language-[A-Za-z0-9_-]+)$
29
29
  [markup.sanitizer.markdown.previewAside]
30
30
  ELEMENT = aside
31
31
  ALLOW_ATTR = class
32
- REGEXP = ^hl-preview-infobox$
32
+ REGEXP = ^(hl-preview-infobox|alert alert-(?:note|tip|important|warning)(?: [a-z][a-z0-9-]*)*)$
33
33
 
34
34
  [markup.sanitizer.markdown.alertSvgFill]
35
35
  ELEMENT = svg
@@ -56,15 +56,20 @@ ELEMENT = main
56
56
  ALLOW_ATTR = class
57
57
  REGEXP = ^hl-preview-main$
58
58
 
59
- [markup.sanitizer.markdown.alertBox]
60
- ELEMENT = blockquote
59
+ [markup.sanitizer.markdown.alertTitle]
60
+ ELEMENT = header
61
61
  ALLOW_ATTR = class
62
- REGEXP = ^alert alert-(note|tip|important|warning)$
62
+ REGEXP = ^alert-title$
63
+
64
+ [markup.sanitizer.markdown.noteImage]
65
+ ELEMENT = figure
66
+ ALLOW_ATTR = class
67
+ REGEXP = ^note-image( note-image-[a-z-]+)*$
63
68
 
64
69
  [markup.sanitizer.markdown.previewParagraph]
65
70
  ELEMENT = p
66
71
  ALLOW_ATTR = class
67
- REGEXP = ^(alert-title|content-figure-label)$
72
+ REGEXP = ^content-figure-label$
68
73
 
69
74
  [markup.sanitizer.markdown.alertSvgClass]
70
75
  ELEMENT = svg
@@ -16,8 +16,9 @@
16
16
  * named first in the manifest's `styles`.
17
17
  *
18
18
  * It carries what every package's compiled content needs to read in Foundry as
19
- * it does in the preview and on the site: definition lists, poetry, alerts,
20
- * inline spoilers, marked names, unresolved links and captioned blocks. Every
19
+ * it does in the preview and on the site: definition lists, verse, alerts,
20
+ * inline spoilers, marked names, unresolved links, captioned blocks and
21
+ * highlighted code. Every
21
22
  * class the Foundry renderer emits is styled here or exempted by name in
22
23
  * `tests/base-styles.test.ts`. A package keeps its own stylesheet for its own
23
24
  * needs and overrides anything here from it.
@@ -119,49 +120,157 @@
119
120
  }
120
121
  }
121
122
 
123
+ /* preview:shared — verse, marked text and generic families. The rules between
124
+ * the two markers are also the editor preview's stylesheet, with the content
125
+ * roots replaced by the preview's own. */
126
+
122
127
  /* Each verse line breaks in the markup; each paragraph is a stanza. */
123
- :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .poetry {
128
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .verse {
124
129
  margin: 1.5rem 0;
125
130
  line-height: 1.7;
126
131
  }
127
132
 
128
- :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .poetry p {
133
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .verse p {
129
134
  margin: 0;
130
135
  }
131
136
 
132
- :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .poetry p + p {
137
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .verse p + p {
133
138
  margin-top: 1em;
134
139
  }
135
140
 
136
- .poetry .poetry-line {
141
+ .verse .verse-line {
137
142
  display: inline-block;
138
- margin-inline-start: var(--poetry-indent, 0em);
143
+ margin-inline-start: var(--verse-indent, 0em);
139
144
  white-space: pre-wrap;
140
145
  }
141
146
 
142
- .poetry .poetry-line.i1 {
143
- --poetry-indent: 1.25em;
147
+ .verse .verse-line.i1 {
148
+ --verse-indent: 1.25em;
149
+ }
150
+ .verse .verse-line.i2 {
151
+ --verse-indent: 2.5em;
152
+ }
153
+ .verse .verse-line.i3 {
154
+ --verse-indent: 3.75em;
155
+ }
156
+ .verse .verse-line.i4 {
157
+ --verse-indent: 5em;
158
+ }
159
+ .verse .verse-line.i5 {
160
+ --verse-indent: 6.25em;
161
+ }
162
+ .verse .verse-line.i6 {
163
+ --verse-indent: 7.5em;
164
+ }
165
+ .verse .verse-line.i7 {
166
+ --verse-indent: 8.75em;
167
+ }
168
+ .verse .verse-line.i8 {
169
+ --verse-indent: 10em;
170
+ }
171
+
172
+ /* Numbered verse carries its numbers in a margin. A verse in columns is one
173
+ * grid per verse line: its number, then each column's parts stacked, the
174
+ * first in the normal tone and the rest muted, every part in the serif unless
175
+ * its face sets it. A narrow journal stacks the columns of each line. */
176
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
177
+ .verse.verse-numbered {
178
+ position: relative;
179
+ padding-inline-start: 3em;
180
+ }
181
+
182
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
183
+ .verse
184
+ .verse-number {
185
+ color: color-mix(in srgb, currentColor 60%, transparent);
186
+ font-size: 0.8em;
187
+ }
188
+
189
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
190
+ .verse-numbered
191
+ .verse-line
192
+ .verse-number {
193
+ position: absolute;
194
+ inset-inline-start: 0;
195
+ width: 2.2em;
196
+ text-align: end;
197
+ }
198
+
199
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
200
+ .verse.verse-columns {
201
+ container-type: inline-size;
144
202
  }
145
- .poetry .poetry-line.i2 {
146
- --poetry-indent: 2.5em;
203
+
204
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
205
+ .verse-numbered.verse-columns {
206
+ padding-inline-start: 0;
207
+ }
208
+
209
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
210
+ .verse-columns
211
+ .verse-row {
212
+ display: grid;
213
+ grid-auto-flow: column;
214
+ grid-auto-columns: 1fr;
215
+ column-gap: 1.5rem;
216
+ margin-bottom: 0.5em;
217
+ }
218
+
219
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
220
+ .verse-numbered.verse-columns
221
+ .verse-row {
222
+ grid-template-columns: 2.5em;
147
223
  }
148
- .poetry .poetry-line.i3 {
149
- --poetry-indent: 3.75em;
224
+
225
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
226
+ .verse-columns
227
+ .verse-number {
228
+ text-align: end;
229
+ padding-top: 0.2em;
150
230
  }
151
- .poetry .poetry-line.i4 {
152
- --poetry-indent: 5em;
231
+
232
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
233
+ .verse-columns
234
+ :is(.verse-column, .verse-part) {
235
+ display: block;
236
+ white-space: pre-wrap;
153
237
  }
154
- .poetry .poetry-line.i5 {
155
- --poetry-indent: 6.25em;
238
+
239
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
240
+ .verse-columns
241
+ .verse-part {
242
+ font-family: serif;
156
243
  }
157
- .poetry .poetry-line.i6 {
158
- --poetry-indent: 7.5em;
244
+
245
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
246
+ .verse-columns
247
+ .verse-secondary {
248
+ color: color-mix(in srgb, currentColor 60%, transparent);
159
249
  }
160
- .poetry .poetry-line.i7 {
161
- --poetry-indent: 8.75em;
250
+
251
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
252
+ .verse-columns
253
+ .verse-part[dir="rtl"] {
254
+ text-align: start;
162
255
  }
163
- .poetry .poetry-line.i8 {
164
- --poetry-indent: 10em;
256
+
257
+ @container (max-width: 32rem) {
258
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
259
+ .verse-columns
260
+ .verse-row {
261
+ grid-auto-flow: row;
262
+ grid-template-columns: 1fr;
263
+ }
264
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
265
+ .verse-numbered.verse-columns
266
+ .verse-row {
267
+ grid-template-columns: 2.5em 1fr;
268
+ }
269
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
270
+ .verse-numbered.verse-columns
271
+ .verse-column {
272
+ grid-column: 2;
273
+ }
165
274
  }
166
275
 
167
276
  /* Text set in one of the faces. The font family and features come from the
@@ -172,10 +281,37 @@
172
281
  }
173
282
 
174
283
  .script-block[dir="rtl"],
175
- .poetry[dir="rtl"] {
284
+ .verse[dir="rtl"] {
176
285
  text-align: start;
177
286
  }
178
287
 
288
+ /*
289
+ * Emphasis in a script follows the script's convention, never a weight or a
290
+ * slant the face does not have: the element keeps the face's Regular, and its
291
+ * class sets the convention. The rubric is carried by colour alone, so each
292
+ * half holds 4.5:1 on Foundry's journal page in its theme and stays apart from
293
+ * the body text in lightness; a package that overrides it re-checks both.
294
+ */
295
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) {
296
+ --pb-rubric: #9c281b;
297
+ --pb-rubric: light-dark(#9c281b, #e0705f);
298
+ }
299
+
300
+ .script :is(em, strong) {
301
+ font-style: normal;
302
+ font-weight: inherit;
303
+ font-synthesis: none;
304
+ }
305
+
306
+ .emph-rubric {
307
+ color: var(--pb-rubric);
308
+ }
309
+
310
+ .emph-overline {
311
+ text-decoration-line: overline;
312
+ text-decoration-skip-ink: none;
313
+ }
314
+
179
315
  /* Text set in the reader's generic families, `font=serif`, `sans` and `mono`. */
180
316
  .font-serif {
181
317
  font-family: serif;
@@ -189,6 +325,8 @@
189
325
  font-family: monospace;
190
326
  }
191
327
 
328
+ /* /preview:shared */
329
+
192
330
  /*
193
331
  * Historical info/warn section classes remain available for styled prose.
194
332
  * New alerts use the separate alert classes below.
@@ -343,12 +481,31 @@
343
481
  > p:first-child {
344
482
  display: inline;
345
483
  }
484
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
485
+ .dictionary
486
+ > div
487
+ > dd
488
+ + dd {
489
+ display: block;
490
+ text-indent: 0;
491
+ }
492
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
493
+ .dictionary
494
+ > div
495
+ > dd
496
+ + dd
497
+ > p:first-child {
498
+ display: block;
499
+ }
346
500
  @media (max-width: 600px) {
347
501
  :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .dictionary {
348
502
  --indent: 100px;
349
503
  }
350
504
  }
351
505
 
506
+ /* preview:shared — inline spoilers, names, unresolved links, captioned blocks,
507
+ * pictures and highlighted code, to the end of the file. */
508
+
352
509
  /* Inline spoilers reveal on pointer hover or keyboard focus. Native secret
353
510
  * sections retain Foundry's separate GM reveal control. */
354
511
  :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
@@ -458,3 +615,115 @@
458
615
  border: 1px solid var(--pb-figure-border, currentcolor);
459
616
  border-radius: 4px;
460
617
  }
618
+
619
+ /*
620
+ * Code a fence names a language for is highlighted when the page is built, and
621
+ * its token classes are coloured here. Each colour defers to a custom property
622
+ * so a package or a theme can replace it, and `light-dark()` follows the colour
623
+ * scheme Foundry sets.
624
+ */
625
+
626
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-keyword,
627
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
628
+ .hljs-variable.language_,
629
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-doctag,
630
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-selector-tag,
631
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-template-tag,
632
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-type {
633
+ color: var(--pb-code-keyword, light-dark(#cf222e, #ff7b72));
634
+ }
635
+
636
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-title,
637
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-title.class_,
638
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
639
+ .hljs-title.class_.inherited__,
640
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
641
+ .hljs-title.function_,
642
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
643
+ .hljs-title.function_.invoke__,
644
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-selector-id {
645
+ color: var(--pb-code-title, light-dark(#8250df, #d2a8ff));
646
+ }
647
+
648
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-attr,
649
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-attribute,
650
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-literal,
651
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-meta,
652
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-number,
653
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-operator,
654
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-variable,
655
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-selector-attr,
656
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
657
+ .hljs-selector-class,
658
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-property,
659
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
660
+ .hljs-variable.constant_,
661
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
662
+ .hljs-template-variable {
663
+ color: var(--pb-code-constant, light-dark(#0550ae, #79c0ff));
664
+ }
665
+
666
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-regexp,
667
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-string,
668
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
669
+ .hljs-meta.hljs-string,
670
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-char.escape_ {
671
+ color: var(--pb-code-string, light-dark(#0a3069, #a5d6ff));
672
+ }
673
+
674
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-built_in,
675
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-symbol,
676
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-meta.prompt_,
677
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-bullet {
678
+ color: var(--pb-code-builtin, light-dark(#953800, #ffa657));
679
+ }
680
+
681
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-comment,
682
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-code,
683
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-formula {
684
+ color: var(--pb-code-comment, light-dark(#59636e, #9198a1));
685
+ }
686
+
687
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-name,
688
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-quote,
689
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror)
690
+ .hljs-selector-pseudo,
691
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-tag {
692
+ color: var(--pb-code-name, light-dark(#116329, #7ee787));
693
+ }
694
+
695
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-subst,
696
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-params,
697
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-punctuation {
698
+ color: var(--pb-code-plain, inherit);
699
+ }
700
+
701
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-section {
702
+ color: var(--pb-code-constant, light-dark(#0550ae, #79c0ff));
703
+ font-weight: 700;
704
+ }
705
+
706
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-emphasis {
707
+ font-style: italic;
708
+ }
709
+
710
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-strong {
711
+ font-weight: 700;
712
+ }
713
+
714
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-link {
715
+ color: var(--pb-code-constant, light-dark(#0550ae, #79c0ff));
716
+ text-decoration: underline;
717
+ }
718
+
719
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-addition {
720
+ color: var(--pb-code-addition, light-dark(#116329, #aff5b4));
721
+ background-color: var(--pb-code-addition-fill, light-dark(#dafbe1, #033a16));
722
+ }
723
+
724
+ :is(.journal-entry-page, .journal-entry-content, .editor-content, .prosemirror) .hljs-deletion {
725
+ color: var(--pb-code-deletion, light-dark(#82071e, #ffdcd7));
726
+ background-color: var(--pb-code-deletion-fill, light-dark(#ffebe9, #67060c));
727
+ }
728
+
729
+ /* /preview:shared */