@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
@@ -1,84 +0,0 @@
1
- {{- /*
2
- The header search box, rendered only when a consumer sets `params.search`
3
- (silent-disappear otherwise — see the README's "Search" section).
4
-
5
- `@heroiclands/package-build`'s `package-build site-root` step writes a
6
- Pagefind index beside the rendered pages, at `pagefind/` under the site's
7
- own base URL, when a consumer leaves `site.search` at its default of `true`
8
- (see that package's `docs/configuration.md`, `site.search`). Pagefind's own
9
- UI — `pagefind-ui.js` and `pagefind-ui.css` — ships inside that generated
10
- directory, so nothing here is bundled or pinned to a Pagefind version; the
11
- index and the UI that reads it travel together.
12
-
13
- Both files are referenced the same way every other theme-bundled asset is
14
- — `relURL`, exactly as `"css/style.css" | relURL` resolves in
15
- `baseof.html` — so a package served under a prefix (`/thalorna/`) finds
16
- its own index rather than another package's.
17
-
18
- A `/search/` results page would need a consumer content file at that
19
- address, and a site is its homepage and its pages with nothing generated
20
- between them (package-build's `docs/configuration.md`, "A site is its
21
- homepage and its pages") — so a dedicated results page is not this
22
- theme's to invent. Pagefind's own panel UI needs no page of its own, so
23
- the header box opens that instead.
24
-
25
- Context: the page (only .Site is read, so this partial can also be called
26
- with just `.Site` in a dict).
27
- */ -}}
28
- {{- if .Site.Params.search }}
29
- <div class="site-search" data-pagefind-ignore>
30
- <button
31
- type="button"
32
- class="search-toggle"
33
- aria-label="Search"
34
- aria-expanded="false"
35
- aria-controls="site-search-panel"
36
- ><i class="fa-solid fa-magnifying-glass" aria-hidden="true"></i></button>
37
- <div id="site-search-panel" class="search-panel" hidden>
38
- <div class="search-panel-inner" id="search"></div>
39
- </div>
40
- </div>
41
- <link rel="stylesheet" href="{{ "pagefind/pagefind-ui.css" | relURL }}">
42
- <script src="{{ "pagefind/pagefind-ui.js" | relURL }}" defer></script>
43
- <script>
44
- (function () {
45
- var toggle = document.querySelector(".search-toggle");
46
- var panel = document.getElementById("site-search-panel");
47
- if (!toggle || !panel) return;
48
- var ui = null;
49
-
50
- function open() {
51
- panel.hidden = false;
52
- toggle.setAttribute("aria-expanded", "true");
53
- if (!ui && typeof PagefindUI !== "undefined") {
54
- ui = new PagefindUI({
55
- element: "#search",
56
- showSubResults: true,
57
- showImages: false
58
- });
59
- }
60
- var input = panel.querySelector("input");
61
- if (input) input.focus();
62
- }
63
-
64
- function close() {
65
- panel.hidden = true;
66
- toggle.setAttribute("aria-expanded", "false");
67
- }
68
-
69
- toggle.addEventListener("click", function () {
70
- if (panel.hidden) { open(); } else { close(); }
71
- });
72
-
73
- document.addEventListener("keydown", function (e) {
74
- if (e.key === "Escape" && !panel.hidden) close();
75
- });
76
-
77
- document.addEventListener("click", function (e) {
78
- if (panel.hidden) return;
79
- if (panel.contains(e.target) || toggle.contains(e.target)) return;
80
- close();
81
- });
82
- })();
83
- </script>
84
- {{- end }}
@@ -1,32 +0,0 @@
1
- {{- /*
2
- Resolve a consumer-supplied link against the site it is rendered on.
3
-
4
- The theme carries layout, not addresses, so every URL it renders comes from
5
- a consuming site's configuration or front matter — and a package published
6
- under a path prefix (`/sohl/`, `/thalorna/`) needs its own links to carry
7
- that prefix without writing it down anywhere.
8
-
9
- Resolution:
10
- 1. An already-absolute URL (http://, https://, //) is returned as-is, so a
11
- consumer can point at another host.
12
- 2. A page fragment or query alone (#anchor, ?q=) is returned as-is.
13
- 3. Anything else is treated as a path within this site and resolved with
14
- `relURL`. A leading slash is trimmed first: `relURL` reads a leading
15
- slash as "from the origin" and leaves the base path off, so trimming it
16
- means a consumer writing the obvious "/section/" still gets a link
17
- inside its own site when that site is served under a prefix.
18
-
19
- Usage:
20
- {{ partial "site-url.html" (dict "site" .Site "url" "kb/rules/") }}
21
-
22
- Params:
23
- site — the site context (.Site). Accepted for symmetry with cdn-url.html
24
- and so this partial can never be tempted to read a page.
25
- url — the address to resolve. An empty value resolves to the site root.
26
- */ -}}
27
- {{- $url := .url | default "" -}}
28
- {{- $resolved := $url -}}
29
- {{- if not (or (hasPrefix $url "http://") (hasPrefix $url "https://") (hasPrefix $url "//") (hasPrefix $url "#") (hasPrefix $url "?")) -}}
30
- {{- $resolved = strings.TrimPrefix "/" $url | relURL -}}
31
- {{- end -}}
32
- {{- return $resolved -}}
@@ -1,30 +0,0 @@
1
- {{- /*
2
- A page's own subject-tag chips, rendered from .Params.tags.
3
-
4
- `draft` is suppressed here: it is a presentation fact about the writing,
5
- not a fact about the subject (package-build/engine/note-vocabulary.mjs,
6
- `DRAFT_TAG`) — a draft compiles, validates, publishes and resolves like any
7
- other note. It does not belong beside subject tags in a reader-facing tag
8
- list; `draft-notice.html` is where the state is stated,
9
- and `draft-state.html` is the one place either partial spells the tag.
10
-
11
- The taxonomy itself is untouched: a draft page still carries the tag, still
12
- lists on its term page, and the term still appears in a site-wide taxonomy
13
- listing. This partial decides only what a page's own chip row shows.
14
-
15
- Silent-disappear: a page whose only tag is `draft` emits nothing here, the
16
- same as a page with no tags at all.
17
-
18
- Context: the page.
19
- */ -}}
20
- {{- $tags := slice -}}
21
- {{- range .Params.tags -}}
22
- {{- if ne (lower .) "draft" -}}
23
- {{- $tags = $tags | append . -}}
24
- {{- end -}}
25
- {{- end -}}
26
- {{- with $tags }}
27
- <div class="single-tags">
28
- {{ range . }}<a href="{{ printf "tags/%s/" (. | urlize) | relURL }}" class="tag">{{ . }}</a>{{ end }}
29
- </div>
30
- {{ end -}}
@@ -1,28 +0,0 @@
1
- {{- /*
2
- Table of Contents partial.
3
-
4
- Renders a sticky right-rail TOC on pages that have more than 3 H2
5
- headings. We detect the threshold by grepping the raw content source
6
- (`.RawContent`) for lines starting with "## " — this is faster and
7
- more reliable than parsing the rendered HTML, and catches authored
8
- headings regardless of markdown extensions that Hugo might apply.
9
-
10
- The caller is responsible for:
11
- - wrapping the page in a CSS grid when this partial renders
12
- (see `.single.single-with-toc` in style.css)
13
- - gating invocation with `partialCached` if desired
14
-
15
- This partial prints nothing when the H2 count is 3 or less, so it's
16
- safe to include unconditionally.
17
- */ -}}
18
-
19
- {{- $raw := .RawContent | default "" -}}
20
- {{- $h2Count := len (findRE `(?m)^##\s+\S` $raw) -}}
21
- {{- if gt $h2Count 3 -}}
22
- <aside class="toc" aria-label="Table of contents" data-pagefind-ignore>
23
- <div class="toc-inner">
24
- <p class="toc-label">On this page</p>
25
- {{ .TableOfContents }}
26
- </div>
27
- </aside>
28
- {{- end -}}
@@ -1,3 +0,0 @@
1
- {{- warnidf (printf "hero-banner-missing-%s" .name)
2
- "hero-banner: no banner named %q in the shared artwork set; falling back to %s/%s. Draw it and add %q to data/banners.yaml, or name a hero image with `data.banner`. Write `data.banner: none` to decline a hero image. First seen on %s."
3
- .name .dir .fallback .name .context -}}
@@ -1,64 +0,0 @@
1
- {{- /*
2
- Cartouche shortcode — renders a named cartouche SVG as an ornamental
3
- accent on culture-flavored pages. The canonical use is Kheperi
4
- cartouches on Ta'Kheperu and Kemetian-pantheon pages, but the same
5
- pipeline works for any "named seal" SVG.
6
-
7
- Usage (shown with plain angle brackets so the Go template parser
8
- doesn't try to close this comment). Hugo forbids MIXING positional
9
- and named parameters in one call, so pick a form per call:
10
-
11
- { {< cartouche "takheperu" >} } positional
12
- { {< cartouche slug="takheperu" >} } named, centered
13
- { {< cartouche slug="takheperu" align="right" >} } floated right
14
- { {< cartouche slug="ra" size="inline" >} } inline
15
- { {< cartouche slug="anubis" caption="Anpu" >} } figure + caption
16
-
17
- Parameters (all optional except slug):
18
- slug - The cartouche SVG basename. May also be passed positionally
19
- (as the first positional argument) when no other params
20
- are needed — Hugo disallows mixing the two styles.
21
- size - "inline" to flow with text. Otherwise block-level.
22
- align - "left" or "right" to float so prose wraps. Default centered.
23
- height - CSS length override for the cartouche's height, e.g.
24
- "10rem" or "160px". Default comes from .cartouche CSS
25
- (13rem block, 9rem floated). Width scales from aspect ratio.
26
- alt - Override screen-reader text. Defaults to humanized slug.
27
- caption - Optional figcaption (block mode only).
28
-
29
- SVG is expected at /static/img/cartouches/<slug>.svg. Design note:
30
- cartouche SVGs should draw with stroke="currentColor" and fill="none"
31
- (or a hard-coded brand color) so they tint cleanly against any
32
- background.
33
- */ -}}
34
- {{- /* Accept slug as either the first positional arg or the named
35
- "slug" parameter, so a caller can pick the style that fits the
36
- rest of their arguments. */ -}}
37
- {{- $slug := .Get "slug" -}}
38
- {{- if not $slug }}{{ $slug = .Get 0 }}{{ end -}}
39
- {{- if not $slug -}}
40
- {{- errorf "cartouche shortcode at %s needs a slug (positional arg 0 or slug=\"…\")" .Position -}}
41
- {{- end -}}
42
- {{- $altDefault := humanize (replace $slug "-" " ") | title -}}
43
- {{- $alt := .Get "alt" | default $altDefault -}}
44
- {{- $size := .Get "size" | default "" -}}
45
- {{- $align := .Get "align" | default "" -}}
46
- {{- $cap := .Get "caption" | default "" -}}
47
- {{- $height := .Get "height" | default "" -}}
48
- {{- $src := printf "img/cartouches/%s.svg" $slug | relURL -}}
49
- {{- $classes := slice "cartouche" -}}
50
- {{- with $size }}{{ $classes = $classes | append (printf "cartouche-%s" .) }}{{ end -}}
51
- {{- with $align }}{{ $classes = $classes | append (printf "cartouche-%s" .) }}{{ end -}}
52
- {{- $class := delimit $classes " " -}}
53
- {{- /* When `height` is given, apply it as an inline style directly on
54
- the <img>. Inline styles on the target element are unambiguous —
55
- they trump any .cartouche img CSS rule on specificity and don't
56
- depend on custom-property inheritance. */ -}}
57
- {{- if eq $size "inline" -}}
58
- <span class="{{ $class }}"><img src="{{ $src }}" alt="{{ $alt }}" loading="lazy"{{ with $height }} style="height: {{ . }}; width: auto; max-width: none;"{{ end }} /></span>
59
- {{- else -}}
60
- <figure class="{{ $class }}">
61
- <img src="{{ $src }}" alt="{{ $alt }}" loading="lazy"{{ with $height }} style="height: {{ . }}; width: auto; max-width: none;"{{ end }} />
62
- {{- with $cap }}<figcaption>{{ . }}</figcaption>{{ end }}
63
- </figure>
64
- {{- end -}}
@@ -1,12 +0,0 @@
1
- <span class="exturl">
2
- <code class="exturl-text">{{ .Get 0 }}</code>
3
- <button class="exturl-copy" onclick="navigator.clipboard.writeText('{{ .Get 0 }}').then(()=>{const b=this;b.classList.add('copied');setTimeout(()=>b.classList.remove('copied'),1500)})" title="Copy URL to clipboard" aria-label="Copy URL to clipboard">
4
- <svg class="exturl-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
5
- <rect x="9" y="9" width="13" height="13" rx="2" ry="2"/>
6
- <path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/>
7
- </svg>
8
- <svg class="exturl-check" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
9
- <polyline points="20 6 9 17 4 12"/>
10
- </svg>
11
- </button>
12
- </span>
@@ -1,43 +0,0 @@
1
- {{- /*
2
- Glyph shortcode — renders a hieroglyphic deity-name cluster (or any
3
- "icon-scale" SVG) from the project CDN. Parallel to cartouche.html
4
- but for smaller, non-royal glyph groups: Kemetían deity names,
5
- category icons, ornamental marks, etc.
6
-
7
- Usage (Hugo disallows mixing positional and named params in one
8
- call; pick a form per call):
9
-
10
- { {< glyph "anubis" >} } inline, plain
11
- { {< glyph slug="anubis" >} } same, named form
12
- { {< glyph slug="anubis" frame="tablet" >} } inside stone tablet
13
- { {< glyph slug="ra" size="inline" >} } scales with text
14
- { {< glyph slug="ra" size="block" >} } centered block
15
- { {< glyph slug="ra" alt="Sun god Ra" >} } override alt text
16
-
17
- Parameters (all optional except slug):
18
- slug - Filename (without .svg). Passed positionally or as slug=.
19
- frame - "tablet" wraps in a limestone rectangular frame (good for
20
- catalog layouts like the pantheon table where visual
21
- parallelism across rows matters more than intrinsic width).
22
- size - "inline" (small, flows with text), "block" (centered
23
- standalone). Default sits at 1.8em height.
24
- alt - Screen-reader text. Defaults to humanized slug.
25
-
26
- SVG source: icons/<slug>.svg, resolved against the consuming site's
27
- `params.cdnBaseURL` — the theme names no host of its own.
28
- */ -}}
29
- {{- $slug := .Get "slug" -}}
30
- {{- if not $slug }}{{ $slug = .Get 0 }}{{ end -}}
31
- {{- if not $slug -}}
32
- {{- errorf "glyph shortcode at %s needs a slug (positional arg 0 or slug=\"…\")" .Position -}}
33
- {{- end -}}
34
- {{- $altDefault := humanize (replace $slug "-" " ") | title -}}
35
- {{- $alt := .Get "alt" | default $altDefault -}}
36
- {{- $frame := .Get "frame" | default "" -}}
37
- {{- $size := .Get "size" | default "" -}}
38
- {{- $src := partial "cdn-url.html" (dict "site" .Site "path" (printf "icons/%s.svg" $slug)) -}}
39
- {{- $classes := slice "glyph" -}}
40
- {{- with $frame }}{{ $classes = $classes | append (printf "glyph-%s" .) }}{{ end -}}
41
- {{- with $size }}{{ $classes = $classes | append (printf "glyph-%s" .) }}{{ end -}}
42
- {{- $class := delimit $classes " " -}}
43
- <span class="{{ $class }}"><img src="{{ $src }}" alt="{{ $alt }}" loading="lazy" /></span>
@@ -1,63 +0,0 @@
1
- {{- /*
2
- pagelist — the pages carrying a tag, as a plain list.
3
-
4
- Curated landings are the right front door, but hand-enumerated link lists
5
- drift: a page gets added and nobody updates the index. This expresses a group
6
- by INTENT instead. Tag a page and it files itself; untag it and it leaves.
7
-
8
- Usage:
9
-
10
- { {< pagelist tag="key-concept" >} } every tagged page
11
- { {< pagelist tag="key-concept" section="rules" >} } restricted to a section
12
- { {< pagelist tag="key-concept" sort="weight" >} } title (default) | weight | date
13
- { {< pagelist tag="key-concept" desc="true" >} } include page descriptions
14
-
15
- Parameters:
16
- tag - (required) taxonomy term. Matched case-insensitively.
17
- section - (optional) restrict to one top-level section, e.g. "rules".
18
- sort - (optional) "title" (default), "weight", or "date" (newest first).
19
- desc - (optional) "true" to show each page's description beneath it.
20
-
21
- An unknown or empty tag warns at build time rather than rendering nothing
22
- silently — a typo in a tag is exactly the drift this is meant to prevent.
23
- */ -}}
24
- {{- $tag := .Get "tag" -}}
25
- {{- if not $tag }}{{ $tag = .Get 0 }}{{ end -}}
26
- {{- if not $tag -}}
27
- {{- errorf "pagelist shortcode at %s needs a tag (tag=\"…\" or positional arg 0)" .Position -}}
28
- {{- end -}}
29
-
30
- {{- $term := $tag | urlize -}}
31
- {{- $pages := slice -}}
32
- {{- with index .Site.Taxonomies.tags $term -}}
33
- {{- $pages = .Pages -}}
34
- {{- end -}}
35
-
36
- {{- with $.Get "section" -}}
37
- {{- $sec := . -}}
38
- {{- $pages = where $pages "Section" $sec -}}
39
- {{- end -}}
40
-
41
- {{- $sort := $.Get "sort" | default "title" -}}
42
- {{- if eq $sort "weight" -}}
43
- {{- $pages = sort $pages "Weight" -}}
44
- {{- else if eq $sort "date" -}}
45
- {{- $pages = sort $pages "Date" "desc" -}}
46
- {{- else -}}
47
- {{- $pages = sort $pages "Title" -}}
48
- {{- end -}}
49
-
50
- {{- if not $pages -}}
51
- {{- warnf "pagelist at %s: no pages carry the tag %q — check the spelling, or tag some pages." $.Position $tag -}}
52
- {{- else -}}
53
- <ul class="page-list pagelist">
54
- {{- range $pages }}
55
- <li class="page-list-item">
56
- <a class="page-list-title" href="{{ .RelPermalink }}">{{ .Title }}</a>
57
- {{- if and (eq ($.Get "desc") "true") .Description }}
58
- <span class="page-list-desc">{{ .Description }}</span>
59
- {{- end }}
60
- </li>
61
- {{- end }}
62
- </ul>
63
- {{- end -}}
@@ -1,11 +0,0 @@
1
- name = "Heroic Lands"
2
- license = "GPL-3.0-or-later"
3
- licenselink = "https://github.com/HeroicLands/package-build/blob/main/LICENSE.md"
4
- description = "Shared Hugo theme for the Heroic Lands projects — brand chrome (header/footer, Cinzel/Lora, dark palette) and the SoHL info-block partials, so every site built on it reads as one coherent whole. Carries layout, not addresses: each consuming repository supplies its own URLs."
5
- homepage = "https://github.com/HeroicLands/package-build"
6
- min_version = "0.156.0"
7
- tags = ["heroic-lands", "sohl", "brand"]
8
-
9
- [author]
10
- name = "Tom Rodriguez"
11
- homepage = "https://github.com/HeroicLands"
@@ -1,107 +0,0 @@
1
- /**
2
- * Every wikilink authored inside a frontmatter value.
3
- *
4
- * Wikilinks are resolved in a note's **body** — by {@link resolveWebWikilinks}
5
- * here, and by the pack compilers' `convertWikilinks` for Foundry. Frontmatter
6
- * is not markdown and is never walked by either, so a link written in one is
7
- * copied through verbatim and reaches the reader as literal `[[…]]` text, in
8
- * whatever the theme renders that field as (an infobox row, a description, a
9
- * card subtitle). Nothing downstream notices: the value is a valid string, the
10
- * page builds, and the defect is visible only to someone who looks at it.
11
- *
12
- * So the form is refused rather than resolved. Resolving it would mean choosing
13
- * an output syntax for a field whose renderer is unknown to this build — a
14
- * markdown link is inert in a Hugo template that prints the value as text, and
15
- * an `<a>` is unusable in one that escapes it — and would quietly bless an
16
- * authoring habit that the pack build has no way to honour at all. Frontmatter
17
- * carries data; a link belongs in prose.
18
- *
19
- * Values are read from the *parsed* frontmatter, so a `[[` inside a YAML comment
20
- * is not a hit, and every hit can be named by the path a reader would look at.
21
- *
22
- * @param {unknown} fm - Parsed frontmatter, as `readMatter` returns it.
23
- * @returns {Array<{path: string, link: string}>} In reading order; `path` is the
24
- * dotted key path of the offending value (`government.summary`, `aliases.1`).
25
- */
26
- export function frontmatterWikilinks(fm: unknown): Array<{
27
- path: string;
28
- link: string;
29
- }>;
30
- /**
31
- * Rewrites the wikilinks in a markdown body as KB-local markdown links.
32
- *
33
- * **Every target is an address**, parsed by {@link readQualifier} and looked up
34
- * case-insensitively in the KB-wide `ctx.index` (the canonical
35
- * `package-system-type-shortcode`, `type/shortcode`, and the site's own
36
- * `section/slug`), then in the vendored `ctx.foreign` manifests. A target is a
37
- * *partial* address: an omitted package means this package, an omitted system
38
- * is a wildcard, and exactly one match resolves — two are `ambiguous`. A link written
39
- * without a label addresses nothing at all and is reported as such —
40
- * there is no second namespace left for it to name.
41
- *
42
- * Only a slash-qualified target reaches the raw key, which is what keeps
43
- * `section/slug` addressable without a page's own slug answering for it.
44
- *
45
- * **Every target that resolves nowhere fails the build**, and is
46
- * classified into the vocabulary all three resolvers share — `unlabelled`,
47
- * `not-an-address`, `unknown-type`, `ambiguous`, `unresolved`,
48
- * `no-content-index`. Failures are collected in `ctx.errors`, each carrying
49
- * the authored `link` and its `occurrence` so a caller can report the line and
50
- * column it sits on.
51
- *
52
- * There is deliberately no exception letting a hyphen-form address through while
53
- * any linkable package had no vendored manifest, since a real cross-package
54
- * reference and a typo look identical from here. The pack compilers and the
55
- * link checker never made that allowance, so its only surviving effect was to
56
- * give one authored link two verdicts. The advice moved into the message
57
- * instead.
58
- *
59
- * A target that resolves nowhere still renders through {@link unresolvedLink}
60
- * rather than as bare prose: the author's text is kept, marked so a
61
- * reader can see a link was intended. The marking and the failure are separate
62
- * jobs and always were — the mark is for whoever reads the page a *previous*
63
- * build emitted, the failure is for the author of this one.
64
- *
65
- * A target that **resolved** to an entry with no page is not this case and is
66
- * not marked: a pack-only package publishes Foundry addresses and no
67
- * web pages, so the author wrote a real address and there is simply nothing to
68
- * link to.
69
- *
70
- * ## Embeds first, and they are not links
71
- *
72
- * `![[address|label]]` names a file rather than a note, so it is resolved into
73
- * an ordinary markdown image before anything looks for a link — which is what
74
- * stops the link pass reading an embed's interior as a link to a note nobody
75
- * wrote. The image the rewrite leaves behind is what
76
- * {@link module:engine/content-images.renderImageFigures} turns into a figure
77
- * for the website, and what the book reads its staging list out of.
78
- *
79
- * ## Every hit is recorded, so the page's edges come out of one pass
80
- *
81
- * A caller that hands in `ctx.resolved` is given every index entry a link on
82
- * the page resolved to, in body order, repeats included. That is the link
83
- * graph, read at the one point where it exists: the build never has to walk a
84
- * page a second time to learn what it links to. Nothing is recorded for a
85
- * same-page anchor or for a target that resolved nowhere.
86
- *
87
- * @param {string} body - The markdown body.
88
- * @param {object} ctx - `{ index, assets, collide, contentTypes,
89
- * packages, noIndexPackages, foreign, type, errors, src, file, resolved,
90
- * output }`. `output` is `"book"` for PDF Markdown and defaults to HTML.
91
- * `packages` is every package an address may name, without which the leading
92
- * package segment of a canonical address reads as an unknown type;
93
- * `noIndexPackages` is every package declared `contentIndex: false`, so a
94
- * qualified address naming one fails with `no-content-index` rather than
95
- * `not-an-address`; `foreign`
96
- * is the cross-package manifest index; `assets` is the address space an embed
97
- * resolves against. `src` is the page's display
98
- * path and `file` the source file a diagnostic should name — absent, `src`
99
- * stands in. `resolved`, when supplied, is the array every resolved
100
- * target's index entry is appended to. `anchors` is the `{#slug}` set
101
- * *this* page declares, which a `[[#slug]]` self-link is checked against;
102
- * absent, a self-link is not checked, exactly as before this existed.
103
- * @returns {string} The body with embeds and wikilinks rewritten.
104
- */
105
- export function resolveWebWikilinks(body: string, ctx: object): string;
106
- export { slugify };
107
- import { slugify } from "./content-slug.mjs";