@heroiclands/package-build 21.1.0 → 22.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.
- package/CHANGELOG.md +245 -0
- package/CONTENT.md +107 -3
- package/assets/fonts/libertinus/LibertinusMono-Regular.otf +0 -0
- package/assets/fonts/libertinus/LibertinusSans-Bold.otf +0 -0
- package/assets/fonts/libertinus/LibertinusSans-Italic.otf +0 -0
- package/assets/fonts/libertinus/LibertinusSans-Regular.otf +0 -0
- package/assets/fonts/libertinus/OFL.txt +94 -0
- package/assets/fonts/libertinus/provenance.yaml +11 -0
- package/assets/images/banners/afflictionbnr.webp +0 -0
- package/assets/images/banners/armorclothingbnr.webp +0 -0
- package/assets/images/banners/attributebnr.webp +0 -0
- package/assets/images/banners/containerbnr.webp +0 -0
- package/assets/images/banners/devdocsbnr.webp +0 -0
- package/assets/images/banners/miscgearbnr.webp +0 -0
- package/assets/images/banners/mysticalabilitybnr.webp +0 -0
- package/assets/images/banners/projectilebnr.webp +0 -0
- package/assets/images/banners/rulesbnr.webp +0 -0
- package/assets/images/banners/skillbnr.webp +0 -0
- package/assets/images/banners/traumabnr.webp +0 -0
- package/assets/images/banners/userguidebnr.webp +0 -0
- package/assets/images/banners/weapongearbnr.webp +0 -0
- package/assets/images/provenance.yaml +4 -0
- package/bin/content-build.mjs +19 -5
- package/bin/package-build.mjs +6 -5
- package/ci/emit-asset-index.mjs +32 -0
- package/content-config.mjs +30 -1
- package/docs/api.md +103 -27
- package/docs/commands.md +13 -11
- package/docs/configuration.md +16 -7
- package/docs/content-format.md +523 -111
- package/engine/actor-compiler.mjs +58 -9
- package/engine/art-fields.mjs +292 -0
- package/engine/asset-index.mjs +397 -0
- package/engine/asset-types.mjs +192 -0
- package/engine/base-compiler.mjs +69 -1
- package/engine/bundles.mjs +5 -5
- package/engine/compile-corpus.mjs +4 -0
- package/engine/content-address.mjs +14 -2
- package/engine/content-charset.mjs +5 -1
- package/engine/content-embeds.mjs +314 -0
- package/engine/content-html.mjs +5 -1
- package/engine/content-icons.mjs +5 -1
- package/engine/content-images.mjs +26 -5
- package/engine/content-index.mjs +68 -33
- package/engine/content-links.mjs +164 -24
- package/engine/dependency-bump.mjs +14 -16
- package/engine/frontmatter-lint.mjs +36 -23
- package/engine/helpers.mjs +83 -31
- package/engine/index-records.mjs +63 -4
- package/engine/index.mjs +15 -0
- package/engine/infobox-registry.mjs +50 -3
- package/engine/infobox.mjs +12 -8
- package/engine/item-compiler.mjs +10 -10
- package/engine/journals.mjs +3 -0
- package/engine/macros.mjs +16 -13
- package/engine/map-notes.mjs +29 -22
- package/engine/metadata-index.mjs +44 -36
- package/engine/note-vocabulary.mjs +71 -29
- package/engine/pack-router.mjs +14 -0
- package/engine/packagebuild-index.mjs +124 -0
- package/engine/packages.mjs +83 -0
- package/engine/pathnames.mjs +74 -0
- package/engine/pdf-build.mjs +133 -8
- package/engine/pdf-render.mjs +49 -12
- package/engine/scenes.mjs +12 -9
- package/engine/site-build.mjs +43 -16
- package/engine/site-index.mjs +10 -1
- package/engine/subtype-registry.mjs +21 -0
- package/engine/web-wikilinks.mjs +46 -12
- package/engine/wikilink-syntax.mjs +20 -2
- package/engine/wikilinks.mjs +15 -2
- package/hm3/actors.mjs +11 -38
- package/manifest.mjs +67 -13
- package/package.json +5 -2
- package/packagebuild-metadata.jsonl +13 -0
- package/sohl/actors.mjs +12 -86
- package/sohl/note-schemas.mjs +4 -16
- package/types/content-config.d.mts +8 -0
- package/types/engine/actor-compiler.d.mts +29 -0
- package/types/engine/art-fields.d.mts +192 -0
- package/types/engine/asset-index.d.mts +92 -0
- package/types/engine/asset-types.d.mts +110 -0
- package/types/engine/base-compiler.d.mts +42 -1
- package/types/engine/compile-corpus.d.mts +4 -1
- package/types/engine/content-charset.d.mts +4 -0
- package/types/engine/content-embeds.d.mts +218 -0
- package/types/engine/content-html.d.mts +4 -0
- package/types/engine/content-icons.d.mts +4 -0
- package/types/engine/content-images.d.mts +15 -2
- package/types/engine/content-index.d.mts +27 -15
- package/types/engine/dependency-bump.d.mts +2 -2
- package/types/engine/frontmatter-lint.d.mts +11 -14
- package/types/engine/helpers.d.mts +7 -2
- package/types/engine/index-records.d.mts +44 -3
- package/types/engine/index.d.mts +5 -0
- package/types/engine/infobox-registry.d.mts +36 -1
- package/types/engine/infobox.d.mts +6 -4
- package/types/engine/macros.d.mts +9 -5
- package/types/engine/map-notes.d.mts +10 -6
- package/types/engine/metadata-index.d.mts +2 -17
- package/types/engine/note-vocabulary.d.mts +30 -0
- package/types/engine/packagebuild-index.d.mts +56 -0
- package/types/engine/packages.d.mts +62 -0
- package/types/engine/pathnames.d.mts +41 -81
- package/types/engine/pdf-build.d.mts +58 -1
- package/types/engine/pdf-render.d.mts +3 -1
- package/types/engine/scenes.d.mts +2 -1
- package/types/engine/site-build.d.mts +5 -1
- package/types/engine/site-index.d.mts +4 -1
- package/types/engine/subtype-registry.d.mts +20 -0
- package/types/engine/web-wikilinks.d.mts +14 -4
- package/types/engine/wikilink-syntax.d.mts +13 -1
- package/types/engine/wikilinks.d.mts +7 -1
- package/types/manifest.d.mts +42 -1
- package/types/sohl/actors.d.mts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,250 @@
|
|
|
1
1
|
# @heroiclands/package-build
|
|
2
2
|
|
|
3
|
+
## 22.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- a278438: **A manifest's `url` is the package's homepage.** It is the Project Homepage link
|
|
8
|
+
a reader follows from the Foundry package listing _before_ installing anything,
|
|
9
|
+
so it answers "what is this?" — which the authored page at
|
|
10
|
+
`https://www.heroiclands.org/<contentPackage>/` does and a source tree does not.
|
|
11
|
+
`bugs`, `manifest` and `download` address release artefacts and stay on the
|
|
12
|
+
repository holding them. The address is derived from the content package rather
|
|
13
|
+
than declared, because the shared site-deploy workflow already publishes there; a
|
|
14
|
+
declared copy would be a second spelling of a settled fact, and the one free to
|
|
15
|
+
drift, since nothing fetches `url` the way Foundry fetches `manifest`.
|
|
16
|
+
|
|
17
|
+
**Breaking — `releaseUrls` takes `homeUrl`.** A call without it produced a
|
|
18
|
+
manifest advertising `undefined`, so the parameter is required rather than
|
|
19
|
+
defaulted. `packageHomepage` and `HOMEPAGE_ORIGIN` are exported beside it, and
|
|
20
|
+
`packageHomepage` refuses an empty name for the same reason.
|
|
21
|
+
|
|
22
|
+
**A configuration always names a content package**, so the manifest no longer
|
|
23
|
+
carries the branch that handled one that did not: the content index is advertised
|
|
24
|
+
unconditionally, which is what the comment above it already claimed.
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- dec6ef4: **A full-page picture prints where it was written** — In the book, an image
|
|
29
|
+
marked as full width now opens the page that follows the prose introducing it,
|
|
30
|
+
with the rest of that prose running below it. It can no longer appear above the
|
|
31
|
+
sentence that points at it, or a page later than the text that follows it.
|
|
32
|
+
|
|
33
|
+
- _A picture that asks for a float still floats_, which is what a float is for.
|
|
34
|
+
- _A picture taller than the page takes a page of its own._
|
|
35
|
+
- 32322bd: **Dependency bumps** — `package-build bump` is described by what it is for: npm
|
|
36
|
+
performs the resolution, so a version whose dependency set differs from the one
|
|
37
|
+
it replaces is taken as correctly as one that moves three lines, while patching
|
|
38
|
+
the lockfile by hand is right only while the two dependency sets match. npm
|
|
39
|
+
writes `package-lock.json` with the indentation `package.json` uses, so a
|
|
40
|
+
formatted manifest yields a formatted lockfile; the bump holds each file to the
|
|
41
|
+
indent it already carries, which is what covers a lockfile indented unlike its
|
|
42
|
+
manifest.
|
|
43
|
+
|
|
44
|
+
## 21.2.0
|
|
45
|
+
|
|
46
|
+
### Minor Changes
|
|
47
|
+
|
|
48
|
+
- 9ccd9e1: **Art and sound have addresses** — A package's pictures and sound clips are now
|
|
49
|
+
addressed the way its notes are. `icon`, `image` and `audio` are types a
|
|
50
|
+
reference can reach, one per tree: `assets/icons`, `assets/images` and
|
|
51
|
+
`assets/audio`. The filename is the name — `anvil.svg` is `icon-anvil` — and the
|
|
52
|
+
directories above it are the package's own business, so a tree can be tidied
|
|
53
|
+
into whatever arrangement suits the people who maintain it without a single
|
|
54
|
+
reference changing.
|
|
55
|
+
|
|
56
|
+
- _The extension stays out of the name._ Changing a picture from SVG to WebP is
|
|
57
|
+
dropping a different file in place; nothing that names it has to be touched.
|
|
58
|
+
- _Two files cannot claim one name._ A root's names are one list however deeply
|
|
59
|
+
it nests, and the build says which two files collided.
|
|
60
|
+
- _Attribution travels with the file._ Who made it, where it came from and what
|
|
61
|
+
licence it carries are published beside it, taken from the `provenance.yaml`
|
|
62
|
+
nearest the file or from a record written for that one file alone.
|
|
63
|
+
- _A package can lend its art._ Every address says which package holds the
|
|
64
|
+
bytes, so a picture one package ships resolves for another that cites it — on
|
|
65
|
+
the website, in the book, and in Foundry.
|
|
66
|
+
- `packagebuild` is a reserved name, held for the files the toolchain itself
|
|
67
|
+
ships, so no package may claim it.
|
|
68
|
+
|
|
69
|
+
Fonts are deliberately not addressable: nobody names a typeface the way they
|
|
70
|
+
name a picture, and a stylesheet and a typesetter each want something an address
|
|
71
|
+
cannot give them.
|
|
72
|
+
- 888f64a: **An image a Foundry journal cannot serve is refused** — An image in a note's
|
|
73
|
+
body names the package that owns the file, and a journal can only draw one from
|
|
74
|
+
a package the install carries. An address naming a package the build declares no
|
|
75
|
+
relationship with — or `packagebuild`, whose shared banners travel with the
|
|
76
|
+
toolchain and belong to the website and the book — is reported with the file,
|
|
77
|
+
line and column it sits on, and the build stops rather than compiling a document
|
|
78
|
+
whose picture resolves against nothing.
|
|
79
|
+
|
|
80
|
+
- _Both spellings, one answer._ `` and `![[address|label]]` are one
|
|
81
|
+
image, so an address is refused in the same words whichever way it is written.
|
|
82
|
+
- _`banner:` is where a shared banner belongs._ It reaches the page and the
|
|
83
|
+
book's section plates and no compiled document, so a note plating a section
|
|
84
|
+
with one of the toolchain's banners is doing the right thing.
|
|
85
|
+
- _An address naming no package still passes through._ A URL, a
|
|
86
|
+
protocol-relative `//host/…`, a `data:` URI and a `/`-rooted path reach a
|
|
87
|
+
journal untouched, which is how a note draws core Foundry art or art from a
|
|
88
|
+
package outside this constellation.
|
|
89
|
+
- b34686f: **The shared banners can be named from anywhere** — A note borrows one of the
|
|
90
|
+
section banners the toolchain ships by naming it, and nothing has to be declared
|
|
91
|
+
or downloaded first:
|
|
92
|
+
|
|
93
|
+
```yaml
|
|
94
|
+
data:
|
|
95
|
+
banner: packagebuild-none-image-skillbnr
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The pictures travel with the toolchain itself, so a package plates a section
|
|
99
|
+
without keeping its own copy and without taking on a dependency on some parent
|
|
100
|
+
system it has no other relationship with. They appear on the website and in the
|
|
101
|
+
book; Foundry installs nothing for them, which is why nothing in a compendium
|
|
102
|
+
ever names one.
|
|
103
|
+
|
|
104
|
+
`packagebuild` is reserved, so no package can claim the name out from under
|
|
105
|
+
them.
|
|
106
|
+
- 9a937e7: **A note names its art, and the art arrives** — The picture a document carries
|
|
107
|
+
is chosen by name now, the way everything else in a note is. `icon` is what a
|
|
108
|
+
directory listing shows beside the name, `tokenIcon` what a token on the canvas
|
|
109
|
+
wears, `bgImage` a map's background, and `banner` the hero image at the top of a
|
|
110
|
+
page. Write the name of the file and the build finds it.
|
|
111
|
+
|
|
112
|
+
- _The art actually reaches the document._ Every compiled item took its type's
|
|
113
|
+
stock picture whatever its note said; it now carries the one it names, and the
|
|
114
|
+
same goes for a being's profile art, its token and its portrait.
|
|
115
|
+
- _A map is art all through._ Its background, the pictures on its tiles and the
|
|
116
|
+
sound clips placed around it are all named the same way and all resolved.
|
|
117
|
+
- _A being with no picture of its own gets one that suits it_ — a person and a
|
|
118
|
+
creature fall back to different art, chosen from what the note says it is.
|
|
119
|
+
- _A picture one package ships reaches another that names it_, on the website,
|
|
120
|
+
in the book and in Foundry, with each getting the address it serves.
|
|
121
|
+
- _`tokenIcon` unset follows `icon`._ A being naming one picture wears it on the
|
|
122
|
+
canvas too.
|
|
123
|
+
- _A name nothing answers is reported against the note_ rather than quietly
|
|
124
|
+
becoming the stock picture.
|
|
125
|
+
|
|
126
|
+
A being's portrait is the first image inside its `{#appearance}` section now,
|
|
127
|
+
written in the prose that describes it rather than declared in a field — where
|
|
128
|
+
an author can see it, move it and caption it like any other picture.
|
|
129
|
+
- 7661355: **A picture goes where it belongs in the prose** — `![[address|label]]` puts an
|
|
130
|
+
image where it is written, and every surface draws it there: a Foundry journal,
|
|
131
|
+
the website and the book alike. It is the wikilink already in use, with `!`
|
|
132
|
+
meaning _draw it here_ rather than _link to it_, so nothing new has to be
|
|
133
|
+
learned — the same short form, the same way of reaching another package's
|
|
134
|
+
artwork, the same complaint when an address names nothing.
|
|
135
|
+
|
|
136
|
+
- _The label is what the picture says._ It is the caption in print, and the
|
|
137
|
+
words a screen reader announces when the image does not load. `![[anvil|]]`
|
|
138
|
+
says the picture is decoration and needs none.
|
|
139
|
+
- _It sits where it is told._ An embed takes the same `{…}` an image does — a
|
|
140
|
+
width, a position, or both in either order — and an unrecognised value is
|
|
141
|
+
refused with the file and line it is on rather than quietly ignored.
|
|
142
|
+
- _Only a picture can be embedded._ Naming a character or a skill where a file
|
|
143
|
+
belongs is refused, and the message says to link to it instead.
|
|
144
|
+
- _A being's portrait opens its appearance._ Every creature and every character
|
|
145
|
+
now shows its picture at the top of what it looks like, in the compendium, on
|
|
146
|
+
the page and in the book.
|
|
147
|
+
- 84a6715: **Shared section banners** — package-build now ships the thirteen banner images
|
|
148
|
+
many packages draw on, and publishes them to consumers. A package can plate a
|
|
149
|
+
section without keeping its own copy, and without declaring a dependency on some
|
|
150
|
+
parent system or module to borrow one.
|
|
151
|
+
|
|
152
|
+
They are licensed CC-BY-SA-4.0, recorded beside them.
|
|
153
|
+
- 0c10ba5: **Everything a being carries now has a picture** — Gear and skills written out
|
|
154
|
+
inside a being's note, rather than copied from the catalogue, reached the sheet
|
|
155
|
+
with no artwork at all. They carry art now, by the same two rules everything
|
|
156
|
+
else does.
|
|
157
|
+
|
|
158
|
+
- _An item can name its own._ Write an icon under `data:` and the sheet shows it.
|
|
159
|
+
- _And it takes one when it names none._ A whetstone somebody wrote out by hand
|
|
160
|
+
gets the picture every other piece of miscellaneous gear gets, instead of a
|
|
161
|
+
blank.
|
|
162
|
+
- fc33f24: **The book sets in the faces the build carries, not the ones the machine has.**
|
|
163
|
+
Headings, running heads, table labels and captions are set in _Libertinus Sans_
|
|
164
|
+
— the toolchain ships it, so a book sets the same way on any machine, and the
|
|
165
|
+
sans no longer comes out in the body face because nothing could resolve it.
|
|
166
|
+
_Libertinus Mono_ is shipped beside it for a package that sets its code spans in
|
|
167
|
+
it; the default mono is unchanged.
|
|
168
|
+
|
|
169
|
+
**A face that resolves to nothing is reported.** A compile that cannot find a
|
|
170
|
+
family still writes a book, set in whatever the fallback reached — a wrong face
|
|
171
|
+
that nobody sees. The compiler's warnings are now findings like any other, with
|
|
172
|
+
the file, the line and the column.
|
|
173
|
+
|
|
174
|
+
### Patch Changes
|
|
175
|
+
|
|
176
|
+
- d2d029a: **A system panel says what the module actually ships** — A page's SoHL or HM3
|
|
177
|
+
box reads _Not available_ only where that system really has no document for the
|
|
178
|
+
note, which is what a reader acts on.
|
|
179
|
+
|
|
180
|
+
- _A note need not name a system to have one._ Where the whole of a subject
|
|
181
|
+
lives in its own fields — an affiliation, a being written without system
|
|
182
|
+
detail — the panel now carries the subject's fields instead of claiming the
|
|
183
|
+
page is outside the system's reach.
|
|
184
|
+
- _A system the module ships nothing for still says so_, on every page that
|
|
185
|
+
could have carried it.
|
|
186
|
+
- 9d4ba48: **Content format** — A map names its art the way every other note does. Its
|
|
187
|
+
background is `bgImage`, an `image` address; a tile names its art with `image`
|
|
188
|
+
and an ambient sound names its clip with `audio`. A map carries no `img` — a
|
|
189
|
+
Scene has no such field.
|
|
190
|
+
- acea050: **Content format** — The specification describes art as addresses rather than
|
|
191
|
+
file paths. A note names its artwork with a wikilink address, an asset lives at
|
|
192
|
+
an address that holds exactly one file with the extension outside the name, and
|
|
193
|
+
`icon`, `image`, `font` and `audio` are types a link can reach like any other.
|
|
194
|
+
|
|
195
|
+
- The five art slots are `icon`, `portrait`, `tokenIcon`, `bgImage` and
|
|
196
|
+
`banner`, each a wikilink field with its own default type.
|
|
197
|
+
- An image in a note's body is written `![[address|alt text]]`, an empty label
|
|
198
|
+
marking it decorative.
|
|
199
|
+
- `packagebuild` is reserved, so any package can name a shared section banner
|
|
200
|
+
without declaring a dependency to reach it.
|
|
201
|
+
|
|
202
|
+
The build reads art as file paths, so it refuses a tree written to this
|
|
203
|
+
specification. The specification is the target; the build is what runs today.
|
|
204
|
+
- 60815eb: **A lint finding opens where it says it is** — Every path a content lint prints
|
|
205
|
+
is relative to the directory the command was run from, so one `content-build
|
|
206
|
+
lint` run reports every finding in the same shape and each one opens in an
|
|
207
|
+
editor, a CI annotation or a `$EDITOR +line` jump.
|
|
208
|
+
|
|
209
|
+
- _Characters, icons, raw HTML and image directives_ report the note's path the
|
|
210
|
+
way the address and frontmatter rules beside them already do.
|
|
211
|
+
- 7d79e70: **Content format** — A being's portrait is a picture in its prose, not a field.
|
|
212
|
+
It opens the note's `{#appearance}` section — the **lead image** — and
|
|
213
|
+
`data.portrait` is gone:
|
|
214
|
+
|
|
215
|
+
```markdown
|
|
216
|
+
# Appearance {#appearance}
|
|
217
|
+
|
|
218
|
+
![[branwldrgr|Brànwâal Dôrgaar]]{float: top-left}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Nothing about that embed is special: it is an ordinary embedded image with an
|
|
222
|
+
ordinary directive, and the strictness is the convention that the portrait opens
|
|
223
|
+
the section, so every being note reads the same way. The section matters as well
|
|
224
|
+
as the order — `{#appearance}` is what becomes an actor's appearance, so a
|
|
225
|
+
picture above that heading reaches no document. An author can move it, caption it
|
|
226
|
+
or drop it like any other picture.
|
|
227
|
+
|
|
228
|
+
Four art slots remain — `icon`, `tokenIcon`, `bgImage` and `banner` — each
|
|
229
|
+
naming art that a document field needs. An embed also takes the same `{…}`
|
|
230
|
+
directive an image does, so a float or a width applies to either.
|
|
231
|
+
- d6d837c: **Content format** — An asset's address is derived from where its file sits.
|
|
232
|
+
Three roots, one per type — `assets/icons`, `assets/images` and `assets/audio` —
|
|
233
|
+
and any file with a matching extension anywhere beneath one is an asset of that
|
|
234
|
+
type, however deep. The filename is the shortcode, the
|
|
235
|
+
extension is not part of the address, and the directories in between are the
|
|
236
|
+
package's own business.
|
|
237
|
+
|
|
238
|
+
A root's shortcodes are one flat namespace, so two files under one root sharing
|
|
239
|
+
a basename are a build error naming both. Across roots they are different
|
|
240
|
+
addresses: `icon-anvil` and `image-anvil` name different pictures for different
|
|
241
|
+
purposes.
|
|
242
|
+
|
|
243
|
+
A font is not an asset and has no address. Nothing names a typeface the way a
|
|
244
|
+
note names a picture, and neither consumer of a font could use an address
|
|
245
|
+
anyway: a stylesheet wants a relative `url()` and the book wants a family name.
|
|
246
|
+
Fonts stay ordinary files a package ships and points a tool at.
|
|
247
|
+
|
|
3
248
|
## 21.1.0
|
|
4
249
|
|
|
5
250
|
### Minor Changes
|
package/CONTENT.md
CHANGED
|
@@ -100,6 +100,9 @@ icons: assets/icon-registry.yaml
|
|
|
100
100
|
# conventional layout shown here.
|
|
101
101
|
paths:
|
|
102
102
|
content: assets/content
|
|
103
|
+
# The asset roots' parent: `icons/`, `images/` and `audio/` sit directly under
|
|
104
|
+
# it, and the content tree beside them.
|
|
105
|
+
assets: assets
|
|
103
106
|
# Vendored foreign manifests, read by `links`. Inbound.
|
|
104
107
|
manifests: assets/manifests
|
|
105
108
|
# Where `manifest` writes this package's own. Outbound, and a build artifact.
|
|
@@ -1778,6 +1781,32 @@ asked for — a build that downloads silently is not reproducible and fails
|
|
|
1778
1781
|
strangely offline. The cache is keyed by version, so changing the pinned version
|
|
1779
1782
|
is a miss rather than a silent overwrite.
|
|
1780
1783
|
|
|
1784
|
+
### `packagebuild` needs no declaration
|
|
1785
|
+
|
|
1786
|
+
package-build ships a set of images of its own — section banners chiefly — and a
|
|
1787
|
+
note reaches one without declaring anything:
|
|
1788
|
+
|
|
1789
|
+
```yaml
|
|
1790
|
+
data:
|
|
1791
|
+
banner: packagebuild-none-image-skillbnr
|
|
1792
|
+
```
|
|
1793
|
+
|
|
1794
|
+
**There is nothing to declare and nothing to fetch.** package-build is an npm
|
|
1795
|
+
dependency of every consumer rather than a Foundry package, so there is no
|
|
1796
|
+
release archive behind the name and no reason to fetch one — the tree is already
|
|
1797
|
+
on disk under `node_modules/@heroiclands/package-build/assets/`. The records are
|
|
1798
|
+
walked from it on every load and join the index like any other package's, so a
|
|
1799
|
+
cold cache is not a failure mode here and every lookup stays one path.
|
|
1800
|
+
|
|
1801
|
+
`packagebuild` is a **reserved** name: no repository may configure it as its
|
|
1802
|
+
`contentPackage`, and a configuration that tries is refused.
|
|
1803
|
+
|
|
1804
|
+
**These addresses have no Foundry form.** Foundry installs no package for this
|
|
1805
|
+
one, so a resolver returns "no Foundry address" deliberately rather than
|
|
1806
|
+
deriving `modules/packagebuild/…`, which installs nowhere. That is not a
|
|
1807
|
+
limitation in practice: the only slot that names them is `banner`, which reaches
|
|
1808
|
+
no compiled document at all and is read by the website and the book.
|
|
1809
|
+
|
|
1781
1810
|
**A fetched catalogue is read one system at a time.** A dependency may ship a
|
|
1782
1811
|
pack per system, and the two hold the same `(type, shortcode)` addresses with
|
|
1783
1812
|
different data models — `skill:awar` is a real address in both vocabularies and
|
|
@@ -1956,17 +1985,59 @@ frontmatter spreads **242 distinct leaf paths** unevenly over **15 types**, from
|
|
|
1956
1985
|
authoring. A format with a fixed column set would turn that authoring into a
|
|
1957
1986
|
schema migration; a document format has no such problem.
|
|
1958
1987
|
|
|
1959
|
-
|
|
1988
|
+
Three keys are **derived** rather than authored, and a note carrying one is an
|
|
1960
1989
|
error rather than a silent overwrite:
|
|
1961
1990
|
|
|
1962
1991
|
| Key | What it holds |
|
|
1963
1992
|
| --------- | -------------------------------------------------------------------------------------------------- |
|
|
1964
1993
|
| `package` | The configured `contentPackage`. A note may not declare its own, and the expander reads the same. |
|
|
1965
1994
|
| `file` | `path`, `folder` and `name` below the content root — the same `file.*` a content-table query uses. |
|
|
1995
|
+
| `asset` | The file an asset record addresses. Present on an asset's record and on no note's. |
|
|
1966
1996
|
|
|
1967
1997
|
The location is namespaced under `file` precisely because `folder` is real
|
|
1968
1998
|
frontmatter on most notes; a record states both, and they mean different things.
|
|
1969
1999
|
|
|
2000
|
+
### A file is a record too
|
|
2001
|
+
|
|
2002
|
+
The same pass walks the package's **asset roots** — `assets/icons`,
|
|
2003
|
+
`assets/images` and `assets/audio` — and emits one record per addressable file
|
|
2004
|
+
into the same index. There is no second artifact and no asset-specific emitter:
|
|
2005
|
+
a package whose tree holds only pictures publishes an ordinary content index
|
|
2006
|
+
that happens to hold only asset records.
|
|
2007
|
+
|
|
2008
|
+
The filename is the shortcode, the root supplies the type, and the layout in
|
|
2009
|
+
between is the package's own business:
|
|
2010
|
+
|
|
2011
|
+
```json
|
|
2012
|
+
{
|
|
2013
|
+
"type": "icon",
|
|
2014
|
+
"shortcode": "anvil",
|
|
2015
|
+
"package": "sohl",
|
|
2016
|
+
"address": { "canonical": "sohl-none-icon-anvil" },
|
|
2017
|
+
"asset": {
|
|
2018
|
+
"path": "icons/game-icons/lorc/anvil.svg",
|
|
2019
|
+
"attribution": "Lorc",
|
|
2020
|
+
"source": "http://lorcblog.blogspot.com",
|
|
2021
|
+
"license": "CC-BY-3.0",
|
|
2022
|
+
"notes": "From game-icons.net"
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
```
|
|
2026
|
+
|
|
2027
|
+
An asset record carries no frontmatter, no anchors and no `foundry` block, and
|
|
2028
|
+
its `address` holds the canonical key and no page slug — a file declares nothing
|
|
2029
|
+
about itself, compiles into no document, and publishes no page. The `asset`
|
|
2030
|
+
block is what a reader tells the two shapes apart by.
|
|
2031
|
+
|
|
2032
|
+
`path` is relative to the emitting package's own asset directory, so each
|
|
2033
|
+
consumer joins its own root onto it and resolves in one step. Provenance comes
|
|
2034
|
+
from a sibling `<filename.ext>.yaml` where one exists, and otherwise from the
|
|
2035
|
+
nearest `provenance.yaml` above the file, searching no higher than the type
|
|
2036
|
+
root. `docs/content-format.md` states the whole rule.
|
|
2037
|
+
|
|
2038
|
+
Two files under one root sharing a basename are two claims on one address, and
|
|
2039
|
+
the build fails naming both.
|
|
2040
|
+
|
|
1970
2041
|
### Every note's address, and every anchor it defines
|
|
1971
2042
|
|
|
1972
2043
|
A record states the address a wikilink writes to reach the note, and every
|
|
@@ -2538,11 +2609,11 @@ pdf:
|
|
|
2538
2609
|
out: build/dist # default
|
|
2539
2610
|
front: # prose before the contents
|
|
2540
2611
|
- prose/colophon.md
|
|
2541
|
-
fonts:
|
|
2612
|
+
fonts: # every key optional — the defaults below
|
|
2542
2613
|
serif: Libertinus Serif
|
|
2543
2614
|
sans: Libertinus Sans
|
|
2544
2615
|
mono: DejaVu Sans Mono
|
|
2545
|
-
path: assets/fonts #
|
|
2616
|
+
path: assets/fonts # faces of your own, searched as well as the shipped ones
|
|
2546
2617
|
iconFonts: # icon family → the font carrying its glyphs
|
|
2547
2618
|
fontawesome: assets/fonts/fa-solid-900.ttf
|
|
2548
2619
|
binary: typst # when it is not simply `typst` on PATH
|
|
@@ -2551,6 +2622,39 @@ pdf:
|
|
|
2551
2622
|
Nothing here is an address or a brand: the title, the front matter and the faces
|
|
2552
2623
|
are the publishing repository's to choose, which is why they are configuration.
|
|
2553
2624
|
|
|
2625
|
+
### The faces come with the build, not with the machine
|
|
2626
|
+
|
|
2627
|
+
All three defaults resolve on a machine that has none of them installed. The
|
|
2628
|
+
serif and the mono the defaults name are faces the compiler embeds; the sans is
|
|
2629
|
+
one the toolchain ships, under `assets/fonts`, along with the superfamily's own
|
|
2630
|
+
mono for a package that names it. The compile searches that directory, and
|
|
2631
|
+
`pdf.fonts.path` when a package names one, and **nothing the machine has
|
|
2632
|
+
installed** — `--font-path` and `--ignore-system-fonts` together — so the same
|
|
2633
|
+
source sets the same book everywhere, and a machine carrying its own copy of a
|
|
2634
|
+
named family does not quietly change what it prints.
|
|
2635
|
+
|
|
2636
|
+
The default mono is the compiler's rather than the superfamily's because the
|
|
2637
|
+
superfamily's mono carries none of the dot-below and dot-above letters this
|
|
2638
|
+
corpus spells names with. A package whose fenced blocks stay inside what it does
|
|
2639
|
+
carry can name it instead, and the compiler reports nothing when a glyph is
|
|
2640
|
+
missing, so that is a claim to measure against the fences rather than assume.
|
|
2641
|
+
|
|
2642
|
+
A face nothing resolves is a **finding** — the compiler says so, and a compile
|
|
2643
|
+
that says it still exits 0 and writes a book set in the fallback, which is the
|
|
2644
|
+
one way a wrong face reaches a reader unnoticed.
|
|
2645
|
+
|
|
2646
|
+
Compiling an emitted `.typ` by hand takes the same two flags to set it the way
|
|
2647
|
+
the build does:
|
|
2648
|
+
|
|
2649
|
+
```bash
|
|
2650
|
+
typst compile --ignore-system-fonts \
|
|
2651
|
+
--font-path node_modules/@heroiclands/package-build/assets/fonts \
|
|
2652
|
+
build/dist/the-book.typ
|
|
2653
|
+
```
|
|
2654
|
+
|
|
2655
|
+
The shipped face is licensed under the SIL Open Font License, which travels with
|
|
2656
|
+
it.
|
|
2657
|
+
|
|
2554
2658
|
### Typst is a binary, not a dependency
|
|
2555
2659
|
|
|
2556
2660
|
The compiler is an external program, found on `PATH` or named by `pdf.binary`.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Copyright © 2012-2024 The Libertinus Project Authors,
|
|
2
|
+
with Reserved Font Name "Linux Libertine", "Biolinum", "STIX Fonts".
|
|
3
|
+
|
|
4
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
5
|
+
This license is copied below, and is also available with a FAQ at:
|
|
6
|
+
http://scripts.sil.org/OFL
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
-----------------------------------------------------------
|
|
10
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
11
|
+
-----------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
PREAMBLE
|
|
14
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
15
|
+
development of collaborative font projects, to support the font creation
|
|
16
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
17
|
+
open framework in which fonts may be shared and improved in partnership
|
|
18
|
+
with others.
|
|
19
|
+
|
|
20
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
21
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
22
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
23
|
+
redistributed and/or sold with any software provided that any reserved
|
|
24
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
25
|
+
however, cannot be released under any other type of license. The
|
|
26
|
+
requirement for fonts to remain under this license does not apply
|
|
27
|
+
to any document created using the fonts or their derivatives.
|
|
28
|
+
|
|
29
|
+
DEFINITIONS
|
|
30
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
31
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
32
|
+
include source files, build scripts and documentation.
|
|
33
|
+
|
|
34
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
35
|
+
copyright statement(s).
|
|
36
|
+
|
|
37
|
+
"Original Version" refers to the collection of Font Software components as
|
|
38
|
+
distributed by the Copyright Holder(s).
|
|
39
|
+
|
|
40
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
41
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
42
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
43
|
+
new environment.
|
|
44
|
+
|
|
45
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
46
|
+
writer or other person who contributed to the Font Software.
|
|
47
|
+
|
|
48
|
+
PERMISSION & CONDITIONS
|
|
49
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
50
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
51
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
52
|
+
Software, subject to the following conditions:
|
|
53
|
+
|
|
54
|
+
1) Neither the Font Software nor any of its individual components,
|
|
55
|
+
in Original or Modified Versions, may be sold by itself.
|
|
56
|
+
|
|
57
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
58
|
+
redistributed and/or sold with any software, provided that each copy
|
|
59
|
+
contains the above copyright notice and this license. These can be
|
|
60
|
+
included either as stand-alone text files, human-readable headers or
|
|
61
|
+
in the appropriate machine-readable metadata fields within text or
|
|
62
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
63
|
+
|
|
64
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
65
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
66
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
67
|
+
presented to the users.
|
|
68
|
+
|
|
69
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
70
|
+
Software shall not be used to promote, endorse or advertise any
|
|
71
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
72
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
73
|
+
permission.
|
|
74
|
+
|
|
75
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
76
|
+
must be distributed entirely under this license, and must not be
|
|
77
|
+
distributed under any other license. The requirement for fonts to
|
|
78
|
+
remain under this license does not apply to any document created
|
|
79
|
+
using the Font Software.
|
|
80
|
+
|
|
81
|
+
TERMINATION
|
|
82
|
+
This license becomes null and void if any of the above conditions are
|
|
83
|
+
not met.
|
|
84
|
+
|
|
85
|
+
DISCLAIMER
|
|
86
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
87
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
88
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
89
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
90
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
91
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
92
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
93
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
94
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
attribution: The Libertinus Project Authors
|
|
2
|
+
source: https://github.com/alerque/libertinus/releases/tag/v7.051
|
|
3
|
+
license: OFL-1.1
|
|
4
|
+
notes: >-
|
|
5
|
+
Libertinus Sans in the three styles a heading can ask for, and Libertinus
|
|
6
|
+
Mono, which a package may name for its code spans. Taken unmodified from the
|
|
7
|
+
release's static/OTF directory; the licence text travels with them as
|
|
8
|
+
OFL.txt, as the OFL requires. The serif half of the superfamily is not here
|
|
9
|
+
because the compiler embeds it, and the remaining faces of the release —
|
|
10
|
+
Math, Display, Initials, Keyboard and the Semibold weights — are ones no
|
|
11
|
+
book sets.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/bin/content-build.mjs
CHANGED
|
@@ -969,6 +969,10 @@ function lintCommand() {
|
|
|
969
969
|
// so these are errors and they fail the run.
|
|
970
970
|
const images = lintContentImages(root, {
|
|
971
971
|
skipDirectories: config.skipDirectories,
|
|
972
|
+
// Which packages this build can reach is configuration, and
|
|
973
|
+
// an address naming one it cannot reaches a journal as a
|
|
974
|
+
// path that resolves against nothing.
|
|
975
|
+
config,
|
|
972
976
|
});
|
|
973
977
|
|
|
974
978
|
const findings = [
|
|
@@ -1250,6 +1254,7 @@ function linksCommand() {
|
|
|
1250
1254
|
const {
|
|
1251
1255
|
deadAnchors,
|
|
1252
1256
|
deadAddresses,
|
|
1257
|
+
deadEmbeds,
|
|
1253
1258
|
unlabelledLinks,
|
|
1254
1259
|
frontmatterLinks,
|
|
1255
1260
|
homepageLinks,
|
|
@@ -1271,12 +1276,15 @@ function linksCommand() {
|
|
|
1271
1276
|
// differently because the corrections differ. The wording comes
|
|
1272
1277
|
// from the shared table, so the checker cannot describe a
|
|
1273
1278
|
// defect differently from the build that also refuses it.
|
|
1274
|
-
for (const d of [...deadAddresses, ...unlabelledLinks]) {
|
|
1279
|
+
for (const d of [...deadAddresses, ...unlabelledLinks, ...deadEmbeds]) {
|
|
1275
1280
|
emitDiagnostic({
|
|
1276
1281
|
file: d.note.file,
|
|
1277
1282
|
...positionOfLiteral(d.note.raw, d.text, d.occurrence),
|
|
1278
1283
|
severity: "error",
|
|
1279
|
-
|
|
1284
|
+
// An embed's directive speaks the image vocabulary and
|
|
1285
|
+
// carries its own sentence; everything else is worded
|
|
1286
|
+
// by the shared table.
|
|
1287
|
+
message: d.message ?? linkFindingMessage(d),
|
|
1280
1288
|
});
|
|
1281
1289
|
}
|
|
1282
1290
|
for (const f of frontmatterLinks) {
|
|
@@ -1306,6 +1314,7 @@ function linksCommand() {
|
|
|
1306
1314
|
const failures =
|
|
1307
1315
|
deadAnchors.length +
|
|
1308
1316
|
deadAddresses.length +
|
|
1317
|
+
deadEmbeds.length +
|
|
1309
1318
|
unlabelledLinks.length +
|
|
1310
1319
|
frontmatterLinks.length +
|
|
1311
1320
|
homepageLinks.length;
|
|
@@ -1315,8 +1324,9 @@ function linksCommand() {
|
|
|
1315
1324
|
} else {
|
|
1316
1325
|
log.info(
|
|
1317
1326
|
`${index.notes.length} notes: every link is a labelled ` +
|
|
1318
|
-
`address, every
|
|
1319
|
-
`address resolves
|
|
1327
|
+
`address, every embed names a file, every anchor ` +
|
|
1328
|
+
`link lands and every address resolves ` +
|
|
1329
|
+
`(${usedManifest.size} ` +
|
|
1320
1330
|
`cross-package reference(s) via manifest), no ` +
|
|
1321
1331
|
`wikilink in frontmatter, every homepage address ` +
|
|
1322
1332
|
`resolvable.`,
|
|
@@ -1576,7 +1586,11 @@ function siteCommand() {
|
|
|
1576
1586
|
file: e.file,
|
|
1577
1587
|
...positionOfLiteral(readRawNote(e.file), e.link, e.occurrence),
|
|
1578
1588
|
severity: "error",
|
|
1579
|
-
|
|
1589
|
+
// An embed's directive speaks the image vocabulary
|
|
1590
|
+
// rather than the link one, and carries its own
|
|
1591
|
+
// sentence; everything else is worded by the shared
|
|
1592
|
+
// table.
|
|
1593
|
+
message: e.message ?? linkFindingMessage(e),
|
|
1580
1594
|
});
|
|
1581
1595
|
}
|
|
1582
1596
|
// An image whose pathname the site cannot resolve, located the
|
package/bin/package-build.mjs
CHANGED
|
@@ -1137,10 +1137,11 @@ function e2eCommand() {
|
|
|
1137
1137
|
* `bump [packages..]` — take a newer version of a dependency.
|
|
1138
1138
|
*
|
|
1139
1139
|
* npm does the resolving, so a bump whose dependency set changed is as correct
|
|
1140
|
-
* as one that moves three lines
|
|
1141
|
-
*
|
|
1142
|
-
*
|
|
1143
|
-
*
|
|
1140
|
+
* as one that moves three lines; patching the lockfile by hand is right only
|
|
1141
|
+
* while the two dependency sets match, and nothing says when they stop
|
|
1142
|
+
* matching. npm writes the lockfile with `package.json`'s indentation, and
|
|
1143
|
+
* this holds each file to the indent it already carried, so a lockfile indented
|
|
1144
|
+
* unlike its manifest keeps its own.
|
|
1144
1145
|
*
|
|
1145
1146
|
* Named nothing, it takes the first-party packages — the ones a person bumps
|
|
1146
1147
|
* by hand, the moment a release publishes, usually to unblock the change that
|
|
@@ -1151,7 +1152,7 @@ function e2eCommand() {
|
|
|
1151
1152
|
function bumpCommand() {
|
|
1152
1153
|
return {
|
|
1153
1154
|
command: "bump [packages..]",
|
|
1154
|
-
describe: "Take a newer version of a dependency
|
|
1155
|
+
describe: "Take a newer published version of a declared dependency",
|
|
1155
1156
|
builder: (y) =>
|
|
1156
1157
|
y
|
|
1157
1158
|
.positional("packages", {
|