@heroiclands/package-build 23.7.1 → 23.9.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.
- package/CHANGELOG.md +41 -0
- package/README.md +32 -0
- package/bin/content-commands.mjs +32 -10
- package/ci/check-banners.mjs +37 -19
- package/container.mjs +48 -10
- package/docs/api.md +402 -58
- package/docs/authoring/first-note.md +1 -1
- package/docs/authoring/frontmatter.md +30 -1
- package/docs/authoring/links-and-markup.md +154 -56
- package/docs/commands.md +31 -12
- package/docs/content-format.md +25 -2
- package/docs/design.md +31 -0
- package/docs/diagnostics.md +1 -1
- package/docs/guides/e2e.md +37 -1
- package/docs/guides/packs.md +2 -1
- package/docs/guides/reference-pages.md +86 -63
- package/docs/project-setup.md +30 -15
- package/docs/reference/format-details.md +313 -132
- package/docs/reference/note-types.md +191 -174
- package/e2e.mjs +89 -2
- package/engine/anchors.mjs +7 -20
- package/engine/base-compiler.mjs +11 -18
- package/engine/compile-corpus.mjs +5 -3
- package/engine/content-alerts.mjs +4 -2
- package/engine/content-blocks.mjs +18 -36
- package/engine/content-format.yaml +1 -0
- package/engine/content-index.mjs +447 -33
- package/engine/content-links.mjs +43 -15
- package/engine/content-poetry.mjs +9 -0
- package/engine/content-tables.mjs +8 -4
- package/engine/culture-reach.mjs +61 -34
- package/engine/data-keys.mjs +3 -1
- package/engine/diagnostics.mjs +24 -11
- package/engine/dictionary-layout.mjs +151 -19
- package/engine/dictionary-rows.mjs +129 -79
- package/engine/foundry-entries.mjs +21 -3
- package/engine/frontmatter-lint.mjs +1 -1
- package/engine/generate.mjs +12 -22
- package/engine/glossary-entries.mjs +11 -11
- package/engine/heading-attributes.mjs +21 -28
- package/engine/helpers.mjs +20 -12
- package/engine/infobox.mjs +3 -0
- package/engine/journals.mjs +15 -2
- package/engine/language-data.mjs +53 -0
- package/engine/language-terms.mjs +86 -0
- package/engine/language-words.mjs +2 -2
- package/engine/lexical-sections.mjs +247 -0
- package/engine/markdownlint-run.mjs +12 -2
- package/engine/markup-validation.mjs +34 -0
- package/engine/note-addresses.mjs +1 -0
- package/engine/note-claims.mjs +21 -10
- package/engine/note-package.mjs +3 -5
- package/engine/note-state.mjs +9 -3
- package/engine/note-vocabulary.mjs +36 -7
- package/engine/pdf-build.mjs +17 -10
- package/engine/prose-lint.mjs +12 -6
- package/engine/related-pages.mjs +22 -3
- package/engine/see-also.mjs +150 -0
- package/engine/site-build.mjs +21 -3
- package/engine/site-preview.mjs +4 -2
- package/engine/sql-tables.mjs +287 -53
- package/engine/standings.mjs +14 -12
- package/engine/stub-lint.mjs +6 -2
- package/engine/web-wikilinks.mjs +8 -6
- package/engine/word-rows.mjs +20 -12
- package/engine/word-terms.mjs +15 -6
- package/hugo-theme/layouts/partials/related.html +25 -8
- package/package.json +2 -1
- package/types/container.d.mts +4 -3
- package/types/e2e.d.mts +28 -0
- package/types/engine/base-compiler.d.mts +2 -2
- package/types/engine/compile-corpus.d.mts +2 -1
- package/types/engine/content-index.d.mts +85 -8
- package/types/engine/content-tables.d.mts +2 -1
- package/types/engine/culture-reach.d.mts +22 -2
- package/types/engine/data-keys.d.mts +7 -0
- package/types/engine/diagnostics.d.mts +7 -6
- package/types/engine/dictionary-layout.d.mts +35 -4
- package/types/engine/dictionary-rows.d.mts +9 -0
- package/types/engine/foundry-entries.d.mts +3 -1
- package/types/engine/heading-attributes.d.mts +2 -2
- package/types/engine/helpers.d.mts +11 -5
- package/types/engine/language-terms.d.mts +7 -0
- package/types/engine/lexical-sections.d.mts +95 -0
- package/types/engine/markdownlint-run.d.mts +3 -1
- package/types/engine/markup-validation.d.mts +14 -0
- package/types/engine/note-addresses.d.mts +10 -0
- package/types/engine/note-claims.d.mts +7 -1
- package/types/engine/note-package.d.mts +3 -1
- package/types/engine/note-state.d.mts +2 -1
- package/types/engine/note-vocabulary.d.mts +1 -0
- package/types/engine/related-pages.d.mts +10 -1
- package/types/engine/see-also.d.mts +55 -0
- package/types/engine/site-build.d.mts +4 -1
- package/types/engine/sql-tables.d.mts +40 -6
- package/types/engine/word-rows.d.mts +9 -7
|
@@ -62,10 +62,10 @@ takes.
|
|
|
62
62
|
|
|
63
63
|
`data.pack: none` is appropriate when the page belongs on the site and in the
|
|
64
64
|
index but does not need a Foundry compendium entry. A documentation package
|
|
65
|
-
has no packs at all. A page with an
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
has no packs at all. A page with neither an authored body nor automatic
|
|
66
|
+
Dictionary or Glossary content is a stub: it remains in the index for data
|
|
67
|
+
references, but publishes no page address or anchors. Supply content before
|
|
68
|
+
publishing; use `draft` for prose still in progress. The [stub rules](../reference/format-details.md#a-stub-is-a-note-with-an-empty-body)
|
|
69
69
|
and [pack routing](packs.md) cover these cases.
|
|
70
70
|
|
|
71
71
|
## Link to the intended target
|
|
@@ -165,92 +165,115 @@ reconstructing them from filenames.
|
|
|
165
165
|
|
|
166
166
|
## Set words as a dictionary and terms as a glossary
|
|
167
167
|
|
|
168
|
-
A language's words
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
`
|
|
173
|
-
`layout=glossary` rows of the `terms` relation. The query decides what
|
|
174
|
-
appears, so any note may carry either.
|
|
168
|
+
A language note's `data.words` supplies its Dictionary section automatically
|
|
169
|
+
on the site, in the Foundry journal and in the book. The dictionary is the
|
|
170
|
+
language's full word list, including inherited words, in one alphabetical
|
|
171
|
+
sequence with letter headings, field tags and one key. A language with absent
|
|
172
|
+
or empty `data.words` receives no Dictionary section.
|
|
175
173
|
|
|
176
|
-
|
|
177
|
-
language:
|
|
174
|
+
The frontmatter states the words:
|
|
178
175
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
176
|
+
```yaml
|
|
177
|
+
shortcode: provnzlng
|
|
178
|
+
name: { full: Provenzal Language }
|
|
179
|
+
type: skill
|
|
180
|
+
subType: language
|
|
181
|
+
data:
|
|
182
|
+
classModifiers: [f, m]
|
|
183
|
+
fields:
|
|
184
|
+
- { name: Love and its conduct, holds: "Longing, courtship and the courts of love." }
|
|
185
|
+
words:
|
|
186
|
+
- {
|
|
187
|
+
form: solmère,
|
|
188
|
+
class: n m,
|
|
189
|
+
pronunciation: sol-MEH-reh,
|
|
190
|
+
field: Love and its conduct,
|
|
191
|
+
gloss: "longing; the ache for a person, a place or a time that is gone",
|
|
192
|
+
}
|
|
193
|
+
- {
|
|
194
|
+
form: amère,
|
|
195
|
+
class: n f,
|
|
196
|
+
field: Love and its conduct,
|
|
197
|
+
gloss: ["a beloved", "a sweetheart, in the songs"],
|
|
198
|
+
}
|
|
184
199
|
```
|
|
185
|
-
````
|
|
186
200
|
|
|
187
|
-
A culture
|
|
188
|
-
|
|
189
|
-
|
|
201
|
+
A culture or affiliation's `data.glossary` supplies its Glossary section. It
|
|
202
|
+
contains only that owner's declared entries, so each culture and affiliation
|
|
203
|
+
using a language chooses its own common words and context meanings. Ranks
|
|
204
|
+
and offices stand in the affiliation's own sections; an explicit glossary
|
|
205
|
+
entry can name one, but a glossary does not draw in the whole ladder or list
|
|
206
|
+
of offices. A note with absent or empty `data.glossary` receives no Glossary
|
|
207
|
+
section.
|
|
190
208
|
|
|
191
|
-
|
|
192
|
-
|
|
209
|
+
The [worked culture glossary](../reference/format-details.md#glossary-terms)
|
|
210
|
+
uses all three reasons for an entry:
|
|
193
211
|
|
|
194
|
-
```
|
|
195
|
-
|
|
212
|
+
```yaml
|
|
213
|
+
data:
|
|
214
|
+
language: skill-provnzlng
|
|
215
|
+
glossary:
|
|
216
|
+
- { name: solmère, common: true }
|
|
217
|
+
- { name: amère, definition: "a sweetheart, in the songs" }
|
|
218
|
+
- {
|
|
219
|
+
name: blood-field,
|
|
220
|
+
definition: "ground where a battle tore the boundary with the spirit world, and it did not close",
|
|
221
|
+
}
|
|
196
222
|
```
|
|
197
223
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
224
|
+
`solmère` is part of this culture's core vocabulary: the words a player needs
|
|
225
|
+
to adventure there. With no `definition`, it carries the senses and class of
|
|
226
|
+
the dictionary word and links to that word's entry. `amère` supplies a context
|
|
227
|
+
meaning, which takes the place of its dictionary senses while retaining the
|
|
228
|
+
word link and class. `blood-field` supplies a gloss for a term outside the
|
|
229
|
+
dictionary. Common marks belong to the glossary's owner; dictionaries mark
|
|
230
|
+
nothing common. There are no setting-wide dictionary or glossary pages.
|
|
204
231
|
|
|
205
|
-
The
|
|
206
|
-
|
|
207
|
-
|
|
232
|
+
The generated sections follow the note's authored text. A heading with
|
|
233
|
+
`{#dictionary}` or `{#lexicon}` receives the Dictionary list, and a heading
|
|
234
|
+
with `{#glossary}` receives the Glossary list, after the authored text in
|
|
235
|
+
that section. This preserves an introduction or loanword discussion under
|
|
236
|
+
an anchored heading:
|
|
208
237
|
|
|
209
238
|
```markdown
|
|
210
|
-
|
|
239
|
+
# Lexicon {#lexicon}
|
|
211
240
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
**Knight-Captain** **1** (_Kingdom of Provenzia_) A knight who leads a company. **2** (_Kingdom of Provenzia_) Commands the guard in the field. — [[thalorna-note-affiliation-kingdom|Kingdom of Provenzia]]
|
|
215
|
-
|
|
216
|
-
## O
|
|
217
|
-
|
|
218
|
-
**Ordained Priest** _Lit._ (_Church of the Rite_) Ordained to serve a parish. — [[thalorna-note-affiliation-church|Church of the Rite]]
|
|
241
|
+
The tongue of Provenzia, whose _solmère_ is its own word.
|
|
219
242
|
```
|
|
220
243
|
|
|
221
|
-
The
|
|
222
|
-
|
|
223
|
-
tongue common, so the first fence lists it, and gives it a respelling;
|
|
224
|
-
`{name: Subject, common: true}` marks a rank and lets in a title of one word,
|
|
225
|
-
which no glossary holds unless an entry names it; and
|
|
226
|
-
`{name: blood-field, definition: …}` is a term of the culture's own.
|
|
244
|
+
The list is generated once under that heading. Without such a heading, the
|
|
245
|
+
build supplies **Dictionary** or **Glossary** at the end of the note.
|
|
227
246
|
|
|
228
|
-
|
|
229
|
-
setting's two pages list everything, each word once and each term under every
|
|
230
|
-
owner that holds it:
|
|
247
|
+
### Custom views
|
|
231
248
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
```
|
|
236
|
-
````
|
|
249
|
+
An `sql` fence with `layout=dictionary` or `layout=glossary` can add a custom
|
|
250
|
+
view of the same `dictionary` and `terms` relations. This one selects only a
|
|
251
|
+
culture's common entries:
|
|
237
252
|
|
|
238
253
|
````markdown
|
|
239
|
-
|
|
240
|
-
|
|
254
|
+
# Words Everyone Knows {#common-words}
|
|
255
|
+
|
|
256
|
+
```sql {layout=glossary section-level=2}
|
|
257
|
+
SELECT * FROM terms WHERE owner = 'thalorna-note-lore-provenzianclt' AND common
|
|
241
258
|
```
|
|
242
259
|
````
|
|
243
260
|
|
|
244
|
-
|
|
245
|
-
|
|
261
|
+
The `terms` relation also holds ranks and offices for custom queries. The
|
|
262
|
+
default Glossary section selects only rows arising from its owner's explicit
|
|
263
|
+
`data.glossary` entries, including an entry naming a rank or office. The
|
|
264
|
+
[layout guide](../authoring/links-and-markup.md#dictionaries-and-glossaries)
|
|
265
|
+
describes query options and rendering.
|
|
266
|
+
|
|
267
|
+
`package-build content-index` writes both relations beside the index. To
|
|
268
|
+
read a culture's own entries with `jq`:
|
|
246
269
|
|
|
247
270
|
```bash
|
|
248
|
-
jq -r 'select(.
|
|
271
|
+
jq -r 'select(.owner == "thalorna-note-lore-provenzianclt") | .name' \
|
|
249
272
|
build/content-index/thalorna-terms.jsonl
|
|
250
273
|
```
|
|
251
274
|
|
|
252
275
|
The [format reference](../reference/format-details.md#dictionaries-and-glossaries)
|
|
253
|
-
gives every column and
|
|
276
|
+
gives every column and rule.
|
|
254
277
|
|
|
255
278
|
## Resolve another package
|
|
256
279
|
|
package/docs/project-setup.md
CHANGED
|
@@ -78,24 +78,39 @@ who knows the groups can guess a name.
|
|
|
78
78
|
### `prepare` — the git hooks
|
|
79
79
|
|
|
80
80
|
```json
|
|
81
|
-
"prepare": "git config core.hooksPath
|
|
81
|
+
"prepare": "git config core.hooksPath .githooks || true"
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
npm runs `prepare` after every install
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
does not fail on it.
|
|
84
|
+
npm runs `prepare` after every install. In this repository it points Git at the
|
|
85
|
+
committed `.githooks/`, including in a fresh worktree. Run `npm ci` for a fresh
|
|
86
|
+
checkout or `npm run prepare` to repeat setup. `|| true` allows an install
|
|
87
|
+
outside a Git checkout, such as a Docker build or CI cache step.
|
|
89
88
|
|
|
90
|
-
|
|
89
|
+
The installed `commit-msg` and `pre-commit` are byte-identical copies of the
|
|
90
|
+
[canonical POSIX hooks](https://github.com/HeroicLands/.github#local-git-hooks-and-actionsgithooks).
|
|
91
|
+
The message guard refuses assistant credits without requiring Node; the branch
|
|
92
|
+
guard refuses commits on `main` and `master`. These hooks honor
|
|
93
|
+
`hooks.noAttribution`, `hooks.protectedBranch`, and `hooks.allowCommitOnMain`.
|
|
94
|
+
CI compares every installed hook against the pinned canonical set. This setup
|
|
95
|
+
installs no pre-push or pre-merge-commit hook.
|
|
96
|
+
|
|
97
|
+
### Optional published hook bundle
|
|
98
|
+
|
|
99
|
+
The package also ships `githooks/` for repositories that explicitly select its
|
|
100
|
+
additional checks. To select that bundle, point `core.hooksPath` at
|
|
101
|
+
`node_modules/@heroiclands/package-build/githooks` in that repository’s setup.
|
|
102
|
+
That bundle requires the installed package and Node; it is separate from this
|
|
103
|
+
repository’s canonical `.githooks/` installation.
|
|
104
|
+
|
|
105
|
+
Four hooks are available, each with its own switch, read with Git’s normal
|
|
91
106
|
precedence: a plain `git config` sets one clone, `--global` sets a machine.
|
|
92
107
|
|
|
93
|
-
| Hook | What it does
|
|
94
|
-
| -------------------------------- |
|
|
95
|
-
| `pre-commit`, `pre-merge-commit` | Refuse a commit on a protected branch.
|
|
96
|
-
| `pre-commit` | Lint any `.changeset/*.md` the commit stages.
|
|
97
|
-
| `commit-msg` | Refuse AI attribution in a commit message.
|
|
98
|
-
| `pre-push` | Run
|
|
108
|
+
| Hook | What it does | Key | Default |
|
|
109
|
+
| -------------------------------- | -------------------------------------------------------------------- | ------------------------------------ | ------- |
|
|
110
|
+
| `pre-commit`, `pre-merge-commit` | Refuse a commit on a protected branch. | `hooks.allowCommitOnMain` (inverted) | on |
|
|
111
|
+
| `pre-commit` | Lint any `.changeset/*.md` the commit stages. | `hooks.changelogCheck` | on |
|
|
112
|
+
| `commit-msg` | Refuse AI attribution in a commit message. | `hooks.noAttribution` | on |
|
|
113
|
+
| `pre-push` | Run the consuming repository’s Build & Test workflow in a container. | `hooks.prePushCi` | off |
|
|
99
114
|
|
|
100
115
|
The defaults differ deliberately: a guard that costs nothing is on unless
|
|
101
116
|
refused, and one that runs a container for minutes is off unless asked for.
|
|
@@ -120,8 +135,8 @@ Git comment lines and the verbose diff after a scissors comment are excluded.
|
|
|
120
135
|
Findings report the original message line and column. This local hook examines
|
|
121
136
|
commit messages only; the shared No Attribution workflow also checks pull
|
|
122
137
|
request titles and bodies. Neither examines repository files, issues, comments,
|
|
123
|
-
or Git author/committer metadata. The
|
|
124
|
-
|
|
138
|
+
or Git author/committer metadata. The canonical shell hooks apply the same
|
|
139
|
+
credit grammar with their own POSIX implementation.
|
|
125
140
|
|
|
126
141
|
The branch guard is the one you meet first:
|
|
127
142
|
|