@heroiclands/package-build 21.0.0 → 21.1.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 +24 -0
- package/CONTENT.md +2 -4
- package/engine/infobox-render.mjs +4 -3
- package/engine/pdf-build.mjs +0 -2
- package/engine/pdf-render.mjs +32 -39
- package/hm3/infobox.mjs +1 -1
- package/package.json +1 -1
- package/sohl/infobox.mjs +1 -1
- package/types/engine/pdf-render.d.mts +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @heroiclands/package-build
|
|
2
2
|
|
|
3
|
+
## 21.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7577722: **Headings in the book**
|
|
8
|
+
|
|
9
|
+
- A heading is set by its depth rather than every heading alike: a note's top-level heading opens large, keeps its underline and takes a clear run of space above it, and each level beneath is smaller and separated by space alone.
|
|
10
|
+
- Headings set in the sans face and in the case they were written in, so a section reads as words rather than as tracked capitals. A book that names no sans face still sets them in its book face, exactly as before.
|
|
11
|
+
- A parent section and the sections inside it can be told apart at a glance, without reading the words.
|
|
12
|
+
- 57fee4c: **Infobox panels in the book**
|
|
13
|
+
|
|
14
|
+
- Each panel is drawn as a closed box — a light border on all four sides over a tint a step below the paper — so a page carrying Profile, system and appearance panels reads as a stack of cards rather than a run of rules.
|
|
15
|
+
- Skill and equipment groups stand apart from one another, so a group that wraps onto a second line is no longer mistaken for the start of the next one.
|
|
16
|
+
|
|
17
|
+
**Naming the systems**
|
|
18
|
+
|
|
19
|
+
- The system panels are titled _Song of Heroic Lands_ and _HârnMaster 3_ in full, in the book and on the web, in place of the abbreviations.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 705cdc8: **The book** — an entry's first paragraph sets like any other. A raised opening
|
|
24
|
+
letter is something a note asks for, not something the book decides on its
|
|
25
|
+
own, so nothing raises one.
|
|
26
|
+
|
|
3
27
|
## 21.0.0
|
|
4
28
|
|
|
5
29
|
### Major Changes
|
package/CONTENT.md
CHANGED
|
@@ -2467,10 +2467,8 @@ alone — a scrolling page has no fixed viewport, so the website keeps one
|
|
|
2467
2467
|
measure with a side rail.
|
|
2468
2468
|
|
|
2469
2469
|
A note's `description:` sets as an epigraph between short rules under the
|
|
2470
|
-
plate
|
|
2471
|
-
|
|
2472
|
-
epigraph, and a body opening on a link or a number keeps its own first
|
|
2473
|
-
character. The running foot carries the section's name, an ornament and the
|
|
2470
|
+
plate. It disappears rather than leave a shell: a note with no description has
|
|
2471
|
+
no epigraph. The running foot carries the section's name, an ornament and the
|
|
2474
2472
|
folio.
|
|
2475
2473
|
|
|
2476
2474
|
A table of **more than three columns** is given an explicit span rather than
|
|
@@ -360,9 +360,10 @@ export function infoboxTypstPreamble() {
|
|
|
360
360
|
'#let infobox-rule = rgb("#7c3b1e")',
|
|
361
361
|
'#let infobox-faint = rgb("#6b6357")',
|
|
362
362
|
'#let infobox-hairline = rgb("#c9bfa8")',
|
|
363
|
+
'#let infobox-fill = rgb("#eae2d0")',
|
|
363
364
|
"#let infobox-panel(body) = block(width: 100%, breakable: true, " +
|
|
364
|
-
"inset: (x: 9pt, y: 8pt), below: 0.8em, " +
|
|
365
|
-
"
|
|
365
|
+
"inset: (x: 9pt, y: 8pt), below: 0.8em, radius: 2pt, " +
|
|
366
|
+
"fill: infobox-fill, stroke: 0.5pt + infobox-hairline)[" +
|
|
366
367
|
"#set par(first-line-indent: 0em, justify: false, leading: 0.40em)\n#body]",
|
|
367
368
|
'#let infobox-title(t) = { text(size: 9pt, weight: "bold", tracking: 1.3pt, ' +
|
|
368
369
|
"fill: infobox-rule)[#upper(t)]; v(0.20em) }",
|
|
@@ -373,7 +374,7 @@ export function infoboxTypstPreamble() {
|
|
|
373
374
|
"#let infobox-cell(lab, val) = align(center)[" +
|
|
374
375
|
"#text(size: 7pt, tracking: 0.6pt, fill: infobox-faint)[#lab]#h(2.5pt)" +
|
|
375
376
|
'#text(size: 8.6pt, weight: "bold")[#val]]',
|
|
376
|
-
"#let infobox-runin(lab, body) = block(below: 0.
|
|
377
|
+
"#let infobox-runin(lab, body) = block(below: 0.78em, breakable: false)[" +
|
|
377
378
|
"#set par(justify: false, first-line-indent: 0em, hanging-indent: 0.5cm, leading: 0.40em)\n" +
|
|
378
379
|
'#text(size: 7.8pt)[#if lab != "" [ #text(weight: "bold")[#lab: ] ]#body]]',
|
|
379
380
|
'#let infobox-statement(t) = text(size: 8pt, style: "italic", fill: infobox-faint)[#t]',
|
package/engine/pdf-build.mjs
CHANGED
|
@@ -498,8 +498,6 @@ export async function buildPdf({ config, out, version = "", compile = true } = {
|
|
|
498
498
|
images,
|
|
499
499
|
headingOffset,
|
|
500
500
|
anchorPrefix,
|
|
501
|
-
// An entry opens a page, so its first paragraph opens the page too.
|
|
502
|
-
dropCap: true,
|
|
503
501
|
});
|
|
504
502
|
// The infobox is generated content in document order — prepended,
|
|
505
503
|
// before the prose. An image the note authored ahead of it still comes
|
package/engine/pdf-render.mjs
CHANGED
|
@@ -168,7 +168,6 @@ export function createParser(registry) {
|
|
|
168
168
|
* note's own `##` nests beneath the entry heading the book gave it.
|
|
169
169
|
* @param {string} [opts.anchorPrefix] - The entry's anchor, which namespaces
|
|
170
170
|
* every `{#slug}` the body declares.
|
|
171
|
-
* @param {boolean} [opts.dropCap] - Whether to open the body with a raised
|
|
172
171
|
* capital. Set for an entry, which begins a page; not for front matter or a
|
|
173
172
|
* prose file, which carry headings of their own.
|
|
174
173
|
* @returns {string} Typst markup.
|
|
@@ -181,7 +180,6 @@ export function markdownToTypst(markdown, opts = {}) {
|
|
|
181
180
|
images = new Map(),
|
|
182
181
|
headingOffset = 0,
|
|
183
182
|
anchorPrefix = "",
|
|
184
|
-
dropCap = false,
|
|
185
183
|
} = opts;
|
|
186
184
|
const tokens = md.parse(String(markdown ?? ""), {});
|
|
187
185
|
// One map for the whole body, not one per block: a heading inside a
|
|
@@ -194,7 +192,6 @@ export function markdownToTypst(markdown, opts = {}) {
|
|
|
194
192
|
images,
|
|
195
193
|
headingOffset,
|
|
196
194
|
anchorPrefix,
|
|
197
|
-
dropCap,
|
|
198
195
|
seen: new Map(),
|
|
199
196
|
});
|
|
200
197
|
}
|
|
@@ -258,7 +255,7 @@ function renderBlock(tokens, i, out, ctx) {
|
|
|
258
255
|
return 3;
|
|
259
256
|
}
|
|
260
257
|
case "paragraph_open": {
|
|
261
|
-
out.push(`\n${
|
|
258
|
+
out.push(`\n${renderInline(tokens[i + 1], ctx)}\n\n`);
|
|
262
259
|
return 3;
|
|
263
260
|
}
|
|
264
261
|
case "fence":
|
|
@@ -271,7 +268,7 @@ function renderBlock(tokens, i, out, ctx) {
|
|
|
271
268
|
return 1;
|
|
272
269
|
case "blockquote_open": {
|
|
273
270
|
const end = matching(tokens, i, "blockquote_open", "blockquote_close");
|
|
274
|
-
const inner = renderTokens(tokens.slice(i + 1, end), { ...ctx
|
|
271
|
+
const inner = renderTokens(tokens.slice(i + 1, end), { ...ctx });
|
|
275
272
|
out.push(`\n#quote(block: true)[${inner}]\n\n`);
|
|
276
273
|
return end - i + 1;
|
|
277
274
|
}
|
|
@@ -298,29 +295,6 @@ function renderBlock(tokens, i, out, ctx) {
|
|
|
298
295
|
}
|
|
299
296
|
}
|
|
300
297
|
|
|
301
|
-
/**
|
|
302
|
-
* The first paragraph of an entry, opened with a raised capital.
|
|
303
|
-
*
|
|
304
|
-
* Only the first, and only when it begins with a letter: a paragraph opening
|
|
305
|
-
* on a link, a bold run or a number has no character to raise, and raising
|
|
306
|
-
* whatever happened to be first would put a 26pt accent on a bracket. The
|
|
307
|
-
* chance is spent either way — a body opens once — so a paragraph that cannot
|
|
308
|
-
* take the capital simply sets as itself.
|
|
309
|
-
*
|
|
310
|
-
* @param {string} rendered - The paragraph's Typst markup.
|
|
311
|
-
* @param {object} ctx - Render context.
|
|
312
|
-
* @returns {string} The same markup, or it with a raised capital.
|
|
313
|
-
*/
|
|
314
|
-
function openingParagraph(rendered, ctx) {
|
|
315
|
-
if (!ctx.dropCap) return rendered;
|
|
316
|
-
ctx.dropCap = false;
|
|
317
|
-
// A letter is never escaped, so the first character of the markup is the
|
|
318
|
-
// first character of the prose whenever the prose starts with one.
|
|
319
|
-
const match = /^(\p{L})([\s\S]*)$/u.exec(rendered);
|
|
320
|
-
if (!match) return rendered;
|
|
321
|
-
return `#book-dropcap[${match[1]}]#h(1pt)${match[2]}`;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
298
|
/**
|
|
325
299
|
* A heading's text, and the `{#slug}` it may end with.
|
|
326
300
|
*
|
|
@@ -438,7 +412,7 @@ function listItems(tokens, start, end, ctx) {
|
|
|
438
412
|
continue;
|
|
439
413
|
}
|
|
440
414
|
const close = matching(tokens, i, "list_item_open", "list_item_close");
|
|
441
|
-
items.push(renderTokens(tokens.slice(i + 1, close), { ...ctx
|
|
415
|
+
items.push(renderTokens(tokens.slice(i + 1, close), { ...ctx }));
|
|
442
416
|
i = close + 1;
|
|
443
417
|
}
|
|
444
418
|
return items;
|
|
@@ -825,6 +799,7 @@ export function bookTypstPreamble() {
|
|
|
825
799
|
'#let book-ink = rgb("#241f1a")',
|
|
826
800
|
'#let book-paper = rgb("#f4efe4")',
|
|
827
801
|
'#let book-accent = rgb("#7c3b1e")',
|
|
802
|
+
'#let book-head = rgb("#5e2b14")',
|
|
828
803
|
'#let book-faint = rgb("#6b6357")',
|
|
829
804
|
"#let book-ornament = box(baseline: 1pt, " +
|
|
830
805
|
"rotate(45deg, rect(width: 3pt, height: 3pt, fill: book-accent)))",
|
|
@@ -835,16 +810,34 @@ export function bookTypstPreamble() {
|
|
|
835
810
|
"}",
|
|
836
811
|
// A heading justifies and hyphenates like body text unless told
|
|
837
812
|
// otherwise, and both make a display line look broken.
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
813
|
+
//
|
|
814
|
+
// Size, weight and the space above follow the level, so a parent reads
|
|
815
|
+
// as one without the words being read. The rule belongs to the note's own
|
|
816
|
+
// top level alone; every level under it is set apart by space. Headings set
|
|
817
|
+
// in the sans face and in the case they were authored in, so neither
|
|
818
|
+
// capitals nor tracking is carrying the distinction. The scale starts
|
|
819
|
+
// at 3: `book-plate` shadows this rule while it draws the title, so
|
|
820
|
+
// the section landing and the entry title never arrive here, and the
|
|
821
|
+
// headings that do are the note's own.
|
|
822
|
+
"#let book-sechead(it) = {\n" +
|
|
823
|
+
" let lv = it.level\n" +
|
|
824
|
+
" let size = if lv <= 3 { 26pt } else if lv == 4 { 19pt }\n" +
|
|
825
|
+
" else if lv == 5 { 14pt } else { 11pt }\n" +
|
|
826
|
+
" let above = if lv <= 3 { 2.5em } else if lv == 4 { 2.0em }\n" +
|
|
827
|
+
" else { 1.0em }\n" +
|
|
828
|
+
" let below = if lv <= 3 { 0.5em } else if lv == 4 { 0.36em }\n" +
|
|
829
|
+
" else { 0.28em }\n" +
|
|
830
|
+
' let weight = if lv <= 5 { "bold" } else { "regular" }\n' +
|
|
831
|
+
" block(width: 100%, above: above, below: below, breakable: false)[\n" +
|
|
832
|
+
" #set par(justify: false, first-line-indent: 0em)\n" +
|
|
833
|
+
" #set text(hyphenate: false)\n" +
|
|
834
|
+
" #text(size: size, weight: weight, fill: book-head)[#it.body]\n" +
|
|
835
|
+
" #if lv <= 3 {\n" +
|
|
836
|
+
" v(-0.30em)\n" +
|
|
837
|
+
" line(length: 100%, stroke: 0.5pt + book-accent)\n" +
|
|
838
|
+
" }\n" +
|
|
839
|
+
" ]\n" +
|
|
840
|
+
"}",
|
|
848
841
|
// The plate bleeds off the paper: the placed panel is the full width of
|
|
849
842
|
// the sheet and starts a margin above and to the left of wherever the
|
|
850
843
|
// flow has reached, which on an entry's first page is the top corner.
|
package/hm3/infobox.mjs
CHANGED
|
@@ -33,7 +33,7 @@ import { GEAR_UNITS, defineInfobox } from "../engine/infobox.mjs";
|
|
|
33
33
|
import { HM3_ITEM_FIELDS } from "./item-fields.mjs";
|
|
34
34
|
|
|
35
35
|
/** What this system's box is called. @type {string} */
|
|
36
|
-
export const HM3_INFOBOX_TITLE = "
|
|
36
|
+
export const HM3_INFOBOX_TITLE = "HârnMaster 3";
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* HM3's presentation overlay: what one of this system's fields is called where
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heroiclands/package-build",
|
|
3
|
-
"version": "21.
|
|
3
|
+
"version": "21.1.0",
|
|
4
4
|
"description": "Shared toolchain for building and shipping a HeroicLands Foundry VTT package — content compilation, manifest, localization, staging, bundle, release and deployment.",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"type": "module",
|
package/sohl/infobox.mjs
CHANGED
|
@@ -67,7 +67,7 @@ import { NOTE_SCHEMAS } from "./note-schemas.mjs";
|
|
|
67
67
|
import { GEAR_TYPE_TO_KEY } from "./being-info.mjs";
|
|
68
68
|
|
|
69
69
|
/** What this system's box is called. @type {string} */
|
|
70
|
-
export const SOHL_INFOBOX_TITLE = "
|
|
70
|
+
export const SOHL_INFOBOX_TITLE = "Song of Heroic Lands";
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
73
|
* What a value nobody stated is shown as, where showing nothing would be the
|
|
@@ -55,7 +55,6 @@ export function createParser(registry?: object): object;
|
|
|
55
55
|
* note's own `##` nests beneath the entry heading the book gave it.
|
|
56
56
|
* @param {string} [opts.anchorPrefix] - The entry's anchor, which namespaces
|
|
57
57
|
* every `{#slug}` the body declares.
|
|
58
|
-
* @param {boolean} [opts.dropCap] - Whether to open the body with a raised
|
|
59
58
|
* capital. Set for an entry, which begins a page; not for front matter or a
|
|
60
59
|
* prose file, which carry headings of their own.
|
|
61
60
|
* @returns {string} Typst markup.
|
|
@@ -68,7 +67,6 @@ export function markdownToTypst(markdown: string, opts?: {
|
|
|
68
67
|
images?: Map<string, string> | undefined;
|
|
69
68
|
headingOffset?: number | undefined;
|
|
70
69
|
anchorPrefix?: string | undefined;
|
|
71
|
-
dropCap?: boolean | undefined;
|
|
72
70
|
}): string;
|
|
73
71
|
/**
|
|
74
72
|
* The Typst definitions the book's page furniture is drawn with.
|