@heroiclands/package-build 0.6.1 → 3.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 (127) hide show
  1. package/CHANGELOG-content-build.md +965 -0
  2. package/CHANGELOG.md +58 -0
  3. package/CONTENT.md +824 -0
  4. package/MIGRATING.md +127 -0
  5. package/README.md +29 -17
  6. package/bin/content-build.mjs +1082 -0
  7. package/bin/package-build.mjs +2 -2
  8. package/bin/report.mjs +2 -2
  9. package/config.mjs +21 -18
  10. package/content-config.mjs +1424 -0
  11. package/coverage.mjs +1 -1
  12. package/e2e.mjs +1 -1
  13. package/engine/abbreviations.mjs +0 -0
  14. package/engine/base-compiler.mjs +608 -0
  15. package/engine/code-fences.mjs +311 -0
  16. package/engine/compendiums.mjs +353 -0
  17. package/engine/content-address.mjs +141 -0
  18. package/engine/content-links.mjs +438 -0
  19. package/engine/content-lint.mjs +204 -0
  20. package/engine/content-package.mjs +67 -0
  21. package/engine/content-slug.mjs +169 -0
  22. package/engine/content-tables.mjs +1216 -0
  23. package/engine/content-tree.mjs +56 -0
  24. package/engine/diagnostics.mjs +270 -0
  25. package/engine/field-reference.mjs +242 -0
  26. package/engine/field-spec.mjs +218 -0
  27. package/engine/foreign-catalog.mjs +450 -0
  28. package/engine/foreign-manifests.mjs +129 -0
  29. package/engine/frontmatter-lint.mjs +343 -0
  30. package/engine/frontmatter.mjs +258 -0
  31. package/engine/generate.mjs +305 -0
  32. package/engine/helpers.mjs +809 -0
  33. package/engine/ids.mjs +192 -0
  34. package/engine/index.mjs +142 -0
  35. package/engine/item-docs.mjs +153 -0
  36. package/engine/item-registry.mjs +129 -0
  37. package/engine/journals.mjs +374 -0
  38. package/engine/kb-manifest.mjs +473 -0
  39. package/engine/macros.mjs +333 -0
  40. package/engine/manifest-emit.mjs +339 -0
  41. package/engine/map-notes.mjs +1302 -0
  42. package/engine/pack-config.mjs +479 -0
  43. package/engine/pack-router.mjs +254 -0
  44. package/engine/prose-config.mjs +238 -0
  45. package/engine/prose-lint.mjs +294 -0
  46. package/engine/region-events.mjs +79 -0
  47. package/engine/scene-levels.mjs +420 -0
  48. package/engine/scenes.mjs +528 -0
  49. package/engine/site-build.mjs +778 -0
  50. package/engine/site-index.mjs +332 -0
  51. package/engine/web-wikilinks.mjs +330 -0
  52. package/engine/wikilink-syntax.mjs +105 -0
  53. package/engine/wikilinks.mjs +645 -0
  54. package/index.mjs +42 -25
  55. package/lang.mjs +1 -1
  56. package/manifest.mjs +79 -5
  57. package/markdownlint-config.mjs +45 -0
  58. package/package.json +78 -35
  59. package/prettier-config.mjs +34 -0
  60. package/sohl/actors.mjs +581 -0
  61. package/sohl/affiliation-standings.mjs +44 -0
  62. package/sohl/being-info.mjs +173 -0
  63. package/sohl/default-item-art.mjs +82 -0
  64. package/sohl/index.mjs +55 -0
  65. package/sohl/item-builders.mjs +114 -0
  66. package/sohl/item-fields.mjs +867 -0
  67. package/sohl/items.mjs +197 -0
  68. package/sohl/kb-passes.mjs +207 -0
  69. package/sohl/note-schemas.mjs +322 -0
  70. package/templates.mjs +1 -1
  71. package/types/config.d.mts +1 -1
  72. package/types/content-config.d.mts +571 -0
  73. package/types/engine/abbreviations.d.mts +44 -0
  74. package/types/engine/base-compiler.d.mts +320 -0
  75. package/types/engine/code-fences.d.mts +102 -0
  76. package/types/engine/compendiums.d.mts +77 -0
  77. package/types/engine/content-address.d.mts +61 -0
  78. package/types/engine/content-links.d.mts +87 -0
  79. package/types/engine/content-lint.d.mts +47 -0
  80. package/types/engine/content-package.d.mts +36 -0
  81. package/types/engine/content-slug.d.mts +59 -0
  82. package/types/engine/content-tables.d.mts +131 -0
  83. package/types/engine/content-tree.d.mts +12 -0
  84. package/types/engine/diagnostics.d.mts +152 -0
  85. package/types/engine/field-reference.d.mts +20 -0
  86. package/types/engine/field-spec.d.mts +181 -0
  87. package/types/engine/foreign-catalog.d.mts +103 -0
  88. package/types/engine/foreign-manifests.d.mts +43 -0
  89. package/types/engine/frontmatter-lint.d.mts +74 -0
  90. package/types/engine/frontmatter.d.mts +99 -0
  91. package/types/engine/generate.d.mts +56 -0
  92. package/types/engine/helpers.d.mts +348 -0
  93. package/types/engine/ids.d.mts +126 -0
  94. package/types/engine/index.d.mts +33 -0
  95. package/types/engine/item-docs.d.mts +73 -0
  96. package/types/engine/item-registry.d.mts +57 -0
  97. package/types/engine/journals.d.mts +121 -0
  98. package/types/engine/kb-manifest.d.mts +214 -0
  99. package/types/engine/macros.d.mts +201 -0
  100. package/types/engine/manifest-emit.d.mts +137 -0
  101. package/types/engine/map-notes.d.mts +283 -0
  102. package/types/engine/pack-config.d.mts +77 -0
  103. package/types/engine/pack-router.d.mts +53 -0
  104. package/types/engine/prose-config.d.mts +121 -0
  105. package/types/engine/prose-lint.d.mts +59 -0
  106. package/types/engine/region-events.d.mts +43 -0
  107. package/types/engine/scene-levels.d.mts +36 -0
  108. package/types/engine/scenes.d.mts +48 -0
  109. package/types/engine/site-build.d.mts +214 -0
  110. package/types/engine/site-index.d.mts +141 -0
  111. package/types/engine/web-wikilinks.d.mts +67 -0
  112. package/types/engine/wikilink-syntax.d.mts +101 -0
  113. package/types/engine/wikilinks.d.mts +172 -0
  114. package/types/index.d.mts +3 -0
  115. package/types/manifest.d.mts +52 -4
  116. package/types/markdownlint-config.d.mts +8 -0
  117. package/types/prettier-config.d.mts +1 -0
  118. package/types/sohl/actors.d.mts +65 -0
  119. package/types/sohl/affiliation-standings.d.mts +22 -0
  120. package/types/sohl/being-info.d.mts +78 -0
  121. package/types/sohl/default-item-art.d.mts +28 -0
  122. package/types/sohl/index.d.mts +7 -0
  123. package/types/sohl/item-builders.d.mts +11 -0
  124. package/types/sohl/item-fields.d.mts +20 -0
  125. package/types/sohl/items.d.mts +19 -0
  126. package/types/sohl/kb-passes.d.mts +71 -0
  127. package/types/sohl/note-schemas.d.mts +7 -0
@@ -0,0 +1,105 @@
1
+ /*
2
+ * This file is part of the Song of Heroic Lands (SoHL) system for Foundry VTT.
3
+ * Copyright (c) 2024-2026 Tom Rodriguez ("Toasty") — <toasty@heroiclands.org>
4
+ *
5
+ * This work is licensed under the GNU General Public License v3.0 (GPLv3).
6
+ * You may copy, modify, and distribute it under the terms of that license.
7
+ *
8
+ * For full terms, see the LICENSE.md file in the project root or visit:
9
+ * https://www.gnu.org/licenses/gpl-3.0.html
10
+ *
11
+ * SPDX-License-Identifier: GPL-3.0-or-later
12
+ */
13
+
14
+ /**
15
+ * What a `[[…]]` **is**, before anything decides where it points.
16
+ *
17
+ * One authored link compiles to two different addresses — a Foundry `@UUID`
18
+ * enricher for the packs, a URL for the web — and those two destinations are the
19
+ * *only* thing that legitimately differs. The syntax is the author's, and it is
20
+ * the same syntax whichever build is reading it.
21
+ *
22
+ * It was written twice, and the two copies had already drifted:
23
+ *
24
+ * | Body | `foundry` side | `web` side |
25
+ * | --- | --- | --- |
26
+ * | `[[weapongear-bsw` ⏎ `]]` in a table cell | not a link | a link whose target ends in a newline |
27
+ * | a stray `[[`, a real link two paragraphs later | finds the real link | swallows both paragraphs as one target |
28
+ *
29
+ * The web side's pattern omitted `\n` from the excluded set, so an unclosed
30
+ * bracket consumed everything up to the next `]]` anywhere in the document —
31
+ * the same shape of corruption a hand-rolled code-fence regex caused on the one
32
+ * page whose subject is link syntax (SoHL#1665). It was also internally
33
+ * inconsistent: its *frontmatter* scan excluded newlines while its body scan did
34
+ * not.
35
+ *
36
+ * So the parse lives here, once. A resolver receives the parts and decides only
37
+ * what it is actually for: which address space the target belongs to.
38
+ *
39
+ * @module
40
+ */
41
+
42
+ /**
43
+ * A wikilink, as authored.
44
+ *
45
+ * **Newlines are excluded deliberately.** A link is written on one line; an
46
+ * unclosed `[[` is a typo, and the alternative is letting it swallow arbitrary
47
+ * prose in search of a closer. Erring towards "not a link" leaves the author's
48
+ * text as written, which is the safe direction for a rewriter.
49
+ */
50
+ export const WIKILINK = /\[\[([^\]\n]+)\]\]/g;
51
+
52
+ /**
53
+ * The parts of a wikilink's interior.
54
+ *
55
+ * @typedef {object} ParsedWikilink
56
+ * @property {string} inner - The whole interior, unescaped and trimmed. What an
57
+ * unlabelled link displays, anchor and all.
58
+ * @property {string} target - What is linked to: an address, an alias, or `""`
59
+ * for a link to a section of the same page.
60
+ * @property {string} anchor - The `#section` slug, `""` when there is none.
61
+ * @property {string|null} display - The text after `|`, or `null` when the link
62
+ * is unlabelled. `null` and `""` differ: an author may write `[[x|]]`.
63
+ * @property {boolean} labelled - Whether a `|` was present at all. What an
64
+ * unlabelled link shows depends on whether its target read as an address
65
+ * (SoHL#1409), so the caller needs to know.
66
+ */
67
+
68
+ /**
69
+ * Split a wikilink's interior into its parts.
70
+ *
71
+ * Takes the **inside** of the brackets — the capture group of {@link WIKILINK} —
72
+ * not the whole link, so a caller that has already matched does not re-match.
73
+ *
74
+ * @param {string} rawInner - The text between `[[` and `]]`.
75
+ * @returns {ParsedWikilink} The parts, each trimmed.
76
+ */
77
+ export function parseWikilink(rawInner) {
78
+ // A pipe inside a markdown table cell is escaped as `\|`; undo that before
79
+ // looking for the label separator, or the cell's own escape reads as one.
80
+ const inner = String(rawInner ?? "").replace(/\\\|/g, "|");
81
+
82
+ const bar = inner.indexOf("|");
83
+ const labelled = bar !== -1;
84
+ const linkPart = (labelled ? inner.slice(0, bar) : inner).trim();
85
+ const display = labelled ? inner.slice(bar + 1).trim() : null;
86
+
87
+ const hash = linkPart.indexOf("#");
88
+ const target = (hash === -1 ? linkPart : linkPart.slice(0, hash)).trim();
89
+ const anchor = hash === -1 ? "" : linkPart.slice(hash + 1).trim();
90
+
91
+ return { inner: inner.trim(), target, anchor, display, labelled };
92
+ }
93
+
94
+ /**
95
+ * Whether a parsed link addresses a section of the page it is written on.
96
+ *
97
+ * `[[#some-heading]]` — no target, only an anchor. Both resolvers special-case
98
+ * it before consulting any index, because there is nothing to look up.
99
+ *
100
+ * @param {ParsedWikilink} parsed - A parsed wikilink.
101
+ * @returns {boolean} True when the link is same-page.
102
+ */
103
+ export function isSamePage({ target, anchor }) {
104
+ return !target && Boolean(anchor);
105
+ }