@heroiclands/package-build 25.2.1 → 25.4.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 +26 -0
- package/README.md +1 -1
- package/assets/styles/content-base.css +97 -116
- package/docs/api.md +30 -6
- package/docs/authoring/links-and-markup.md +214 -126
- package/docs/commands.md +2 -2
- package/docs/content-format.md +31 -6
- package/docs/diagnostics.md +27 -27
- package/docs/guides/writing-in-invented-scripts.md +89 -83
- package/docs/reference/format-details.md +6 -7
- package/docs/reference/note-types.md +15 -15
- package/docs/reference/theme-pages.md +38 -57
- package/engine/anchors.mjs +14 -0
- package/engine/code-fences.mjs +15 -6
- package/engine/content-blocks.mjs +7 -4
- package/engine/content-figures.mjs +19 -5
- package/engine/content-footnotes.mjs +60 -1
- package/engine/content-index.mjs +1 -1
- package/engine/content-render.mjs +66 -48
- package/engine/content-scripts.mjs +357 -101
- package/engine/content-spans.mjs +76 -10
- package/engine/content-verse.mjs +687 -358
- package/engine/first-use.mjs +43 -12
- package/engine/heading-attributes.mjs +2 -1
- package/engine/journals.mjs +8 -1
- package/engine/markdown-blocks.mjs +3 -2
- package/engine/markup-validation.mjs +17 -0
- package/engine/name-markup.mjs +1 -0
- package/engine/note-vocabulary.mjs +2 -2
- package/engine/pdf-render.mjs +89 -130
- package/engine/prose-lint.mjs +14 -2
- package/engine/roman-verse.mjs +68 -57
- package/engine/run-rows.mjs +1 -1
- package/engine/sql-tables.mjs +1 -1
- package/engine/verse-format.mjs +77 -0
- package/engine/verse-metre.mjs +49 -47
- package/engine/verse-regions.mjs +181 -0
- package/engine/wikilink-pattern.mjs +31 -0
- package/engine/wikilink-syntax.mjs +2 -16
- package/package.json +1 -1
- package/site-theme/static/css/style.css +68 -96
- package/types/engine/code-fences.d.mts +1 -3
- package/types/engine/content-blocks.d.mts +3 -1
- package/types/engine/content-footnotes.d.mts +23 -0
- package/types/engine/content-scripts.d.mts +12 -7
- package/types/engine/content-spans.d.mts +3 -1
- package/types/engine/content-verse.d.mts +263 -82
- package/types/engine/name-markup.d.mts +5 -0
- package/types/engine/roman-verse.d.mts +7 -6
- package/types/engine/verse-format.d.mts +9 -0
- package/types/engine/verse-metre.d.mts +4 -4
- package/types/engine/verse-regions.d.mts +78 -0
- package/types/engine/wikilink-pattern.d.mts +17 -0
- package/types/engine/wikilink-syntax.d.mts +1 -41
|
@@ -1380,118 +1380,90 @@ a.tag:hover {
|
|
|
1380
1380
|
background: var(--bg-card);
|
|
1381
1381
|
}
|
|
1382
1382
|
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
margin: 1.5rem 0;
|
|
1386
|
-
line-height: 1.7;
|
|
1387
|
-
}
|
|
1388
|
-
|
|
1389
|
-
.single-content .verse p {
|
|
1390
|
-
margin: 0;
|
|
1383
|
+
.single-content .verse .verse-stanza p {
|
|
1384
|
+
margin: 0;
|
|
1391
1385
|
}
|
|
1392
1386
|
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
white-space: pre-wrap;
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
.single-content .verse :is(.verse-line, .verse-part).i1 { --verse-indent: 1.25em; }
|
|
1404
|
-
.single-content .verse :is(.verse-line, .verse-part).i2 { --verse-indent: 2.5em; }
|
|
1405
|
-
.single-content .verse :is(.verse-line, .verse-part).i3 { --verse-indent: 3.75em; }
|
|
1406
|
-
.single-content .verse :is(.verse-line, .verse-part).i4 { --verse-indent: 5em; }
|
|
1407
|
-
.single-content .verse :is(.verse-line, .verse-part).i5 { --verse-indent: 6.25em; }
|
|
1408
|
-
.single-content .verse :is(.verse-line, .verse-part).i6 { --verse-indent: 7.5em; }
|
|
1409
|
-
.single-content .verse :is(.verse-line, .verse-part).i7 { --verse-indent: 8.75em; }
|
|
1410
|
-
.single-content .verse :is(.verse-line, .verse-part).i8 { --verse-indent: 10em; }
|
|
1411
|
-
|
|
1412
|
-
.single-content .verse .verse-stanza-break { display: block; height: 0.5em; }
|
|
1413
|
-
|
|
1414
|
-
/* Numbered verse carries its numbers in a margin. A verse in columns is one
|
|
1415
|
-
grid per verse line: its number, then each column's parts stacked, the
|
|
1416
|
-
first in the normal tone and the rest muted, every part in the body serif
|
|
1417
|
-
unless its face sets it. A narrow verse stacks the columns of each line. */
|
|
1418
|
-
.single-content .verse.verse-numbered {
|
|
1419
|
-
position: relative;
|
|
1420
|
-
padding-inline-start: 3em;
|
|
1387
|
+
/* A quotation stays within its prose paragraph; canto titles retain heading type. */
|
|
1388
|
+
.single-content .verse.verse-inline {
|
|
1389
|
+
display: inline-block;
|
|
1390
|
+
vertical-align: baseline;
|
|
1391
|
+
max-inline-size: 100%;
|
|
1392
|
+
margin: 0;
|
|
1393
|
+
container-type: normal;
|
|
1421
1394
|
}
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
font-size: 0.8em;
|
|
1426
|
-
}
|
|
1427
|
-
|
|
1428
|
-
.single-content .verse-numbered .verse-line .verse-number {
|
|
1429
|
-
position: absolute;
|
|
1430
|
-
inset-inline-start: 0;
|
|
1431
|
-
width: 2.2em;
|
|
1432
|
-
text-align: end;
|
|
1395
|
+
.single-content .verse.verse-inline .verse-stanza {
|
|
1396
|
+
display: block;
|
|
1397
|
+
margin: 0;
|
|
1433
1398
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
container-type: inline-size;
|
|
1399
|
+
.single-content .verse.verse-inline .verse-stanza + .verse-stanza {
|
|
1400
|
+
margin-top: 0.5em;
|
|
1437
1401
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1402
|
+
.single-content .verse .verse-canto-heading {
|
|
1403
|
+
display: block;
|
|
1404
|
+
margin: 0.5em 0;
|
|
1405
|
+
font-family: var(--font-display);
|
|
1406
|
+
font-size: 1.1em;
|
|
1407
|
+
font-weight: bold;
|
|
1408
|
+
line-height: 1.3;
|
|
1441
1409
|
}
|
|
1442
1410
|
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
grid-template-columns: repeat(var(--verse-columns, 2), minmax(0, 1fr));
|
|
1449
|
-
column-gap: 1.5rem;
|
|
1450
|
-
margin-bottom: 0.5em;
|
|
1411
|
+
/* Logical stanzas share labels across native and Roman presentations. */
|
|
1412
|
+
.single-content .verse {
|
|
1413
|
+
margin: 1.5rem 0;
|
|
1414
|
+
line-height: 1.7;
|
|
1415
|
+
container-type: inline-size;
|
|
1451
1416
|
}
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1417
|
+
.single-content .verse .verse-stanza {
|
|
1418
|
+
position: relative;
|
|
1419
|
+
margin: 0 0 1em;
|
|
1455
1420
|
}
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
text-align: end;
|
|
1459
|
-
padding-top: 0.2em;
|
|
1421
|
+
.single-content .verse-labelled .verse-stanza {
|
|
1422
|
+
padding-inline-start: 3em;
|
|
1460
1423
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1424
|
+
.single-content .verse .verse-label {
|
|
1425
|
+
position: absolute;
|
|
1426
|
+
inset-inline-start: 0;
|
|
1427
|
+
width: 2.5em;
|
|
1428
|
+
text-align: end;
|
|
1429
|
+
font-size: 0.75em;
|
|
1430
|
+
color: color-mix(in srgb, currentColor 60%, transparent);
|
|
1465
1431
|
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1432
|
+
.single-content .verse .verse-line {
|
|
1433
|
+
display: inline-block;
|
|
1434
|
+
margin-inline-start: var(--verse-indent, 0em);
|
|
1435
|
+
white-space: pre-wrap;
|
|
1436
|
+
}
|
|
1437
|
+
.single-content .verse .verse-line.i1 { --verse-indent: 1.25em; }
|
|
1438
|
+
.single-content .verse .verse-line.i2 { --verse-indent: 2.5em; }
|
|
1439
|
+
.single-content .verse .verse-line.i3 { --verse-indent: 3.75em; }
|
|
1440
|
+
.single-content .verse .verse-line.i4 { --verse-indent: 5em; }
|
|
1441
|
+
.single-content .verse .verse-line.i5 { --verse-indent: 6.25em; }
|
|
1442
|
+
.single-content .verse .verse-line.i6 { --verse-indent: 7.5em; }
|
|
1443
|
+
.single-content .verse .verse-line.i7 { --verse-indent: 8.75em; }
|
|
1444
|
+
.single-content .verse .verse-line.i8 { --verse-indent: 10em; }
|
|
1445
|
+
.single-content .verse .verse-canto-break {
|
|
1446
|
+
display: block;
|
|
1447
|
+
height: 0.5em;
|
|
1470
1448
|
}
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1449
|
+
.single-content .verse-paired .verse-row {
|
|
1450
|
+
display: grid;
|
|
1451
|
+
direction: ltr;
|
|
1452
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1453
|
+
column-gap: 1.5rem;
|
|
1454
|
+
align-items: start;
|
|
1474
1455
|
}
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1456
|
+
.single-content .verse-paired :is(.verse-native, .verse-roman) {
|
|
1457
|
+
min-width: 0;
|
|
1458
|
+
white-space: pre-wrap;
|
|
1478
1459
|
}
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
text-align: start;
|
|
1460
|
+
.single-content .verse-paired .verse-roman {
|
|
1461
|
+
font-family: serif;
|
|
1482
1462
|
}
|
|
1483
|
-
|
|
1484
1463
|
@container (max-width: 32rem) {
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
}
|
|
1489
|
-
.single-content .verse-numbered.verse-columns .verse-row {
|
|
1490
|
-
grid-template-columns: 2.5em 1fr;
|
|
1491
|
-
}
|
|
1492
|
-
.single-content .verse-numbered.verse-columns .verse-column {
|
|
1493
|
-
grid-column: 2;
|
|
1494
|
-
}
|
|
1464
|
+
.single-content .verse-paired .verse-row {
|
|
1465
|
+
grid-template-columns: 1fr;
|
|
1466
|
+
}
|
|
1495
1467
|
}
|
|
1496
1468
|
|
|
1497
1469
|
/* Ornamental horizontal rule: thin line flanking a centered gold
|
|
@@ -17,13 +17,11 @@ export function parseHeaderArgs(info: string): {
|
|
|
17
17
|
* @param {object} [options]
|
|
18
18
|
* @param {boolean} [options.spans=true] - Include inline code spans. Set false
|
|
19
19
|
* to consider only block-level code.
|
|
20
|
-
* @param {boolean} [options.verseAsProse=true] - Treat verse bodies as inline prose.
|
|
21
20
|
* @returns {Array<{start: number, end: number}>} Non-overlapping regions, in
|
|
22
21
|
* source order. `end` is exclusive.
|
|
23
22
|
*/
|
|
24
|
-
export function codeRegions(markdown: string | null | undefined, { spans
|
|
23
|
+
export function codeRegions(markdown: string | null | undefined, { spans }?: {
|
|
25
24
|
spans?: boolean | undefined;
|
|
26
|
-
verseAsProse?: boolean | undefined;
|
|
27
25
|
}): Array<{
|
|
28
26
|
start: number;
|
|
29
27
|
end: number;
|
|
@@ -43,10 +43,12 @@ export function scanBlocks(source: string): {
|
|
|
43
43
|
* @param {object} [options]
|
|
44
44
|
* @param {(markdown: string) => string} [options.renderInline] - How a title
|
|
45
45
|
* is rendered; omitted, a title is plain inline Markdown.
|
|
46
|
+
* @param {Map<string, object>} [options.verses] - Shared encoded verse presentations.
|
|
46
47
|
* @returns {{markdown: string, errors: Array<{line: number, column: number, message: string}>}}
|
|
47
48
|
*/
|
|
48
|
-
export function renderBlocks(source: string, target: "foundry" | "web" | "preview", { renderInline }?: {
|
|
49
|
+
export function renderBlocks(source: string, target: "foundry" | "web" | "preview", { renderInline, verses }?: {
|
|
49
50
|
renderInline?: ((markdown: string) => string) | undefined;
|
|
51
|
+
verses?: Map<string, object> | undefined;
|
|
50
52
|
}): {
|
|
51
53
|
markdown: string;
|
|
52
54
|
errors: Array<{
|
|
@@ -81,6 +81,29 @@ export function footnoteFindings(source: string): Array<{
|
|
|
81
81
|
column: number;
|
|
82
82
|
message: string;
|
|
83
83
|
}>;
|
|
84
|
+
/**
|
|
85
|
+
* Labels defined at the top level of this note.
|
|
86
|
+
* @param {string} source - Complete authored note Markdown.
|
|
87
|
+
* @returns {Set<string>} Same-note footnote labels.
|
|
88
|
+
*/
|
|
89
|
+
export function footnoteLabels(source: string): Set<string>;
|
|
90
|
+
/**
|
|
91
|
+
* Actual defined references, excluding literal code, escapes and metadata.
|
|
92
|
+
* @param {string} source - Full note or raw inline fragment.
|
|
93
|
+
* @param {object} [options] - Definition context and source grammar.
|
|
94
|
+
* @param {ReadonlySet<string>} [options.definitions] - Same-note labels; derived from source when omitted.
|
|
95
|
+
* @param {boolean} [options.inline] - Treat all source as inline verse/prose.
|
|
96
|
+
* @returns {Array<{from:number,to:number,key:string,text:string}>} Original UTF-16 source ranges.
|
|
97
|
+
*/
|
|
98
|
+
export function footnoteReferences(source: string, { definitions, inline }?: {
|
|
99
|
+
definitions?: ReadonlySet<string> | undefined;
|
|
100
|
+
inline?: boolean | undefined;
|
|
101
|
+
}): Array<{
|
|
102
|
+
from: number;
|
|
103
|
+
to: number;
|
|
104
|
+
key: string;
|
|
105
|
+
text: string;
|
|
106
|
+
}>;
|
|
84
107
|
/**
|
|
85
108
|
* A footnote reference's shape, wherever it is written — excluding a
|
|
86
109
|
* definition's own `[^id]:` opener, which this never matches.
|
|
@@ -18,7 +18,7 @@ export function runContext(config: {
|
|
|
18
18
|
};
|
|
19
19
|
} | undefined, records?: Iterable<Record<string, any>>): RunContext;
|
|
20
20
|
/**
|
|
21
|
-
* Find the spans, divs and verse
|
|
21
|
+
* Find the spans, divs and verse divs marked with `lang=`, `font=` or
|
|
22
22
|
* `enc=`, and every fault in their markup and their text.
|
|
23
23
|
*
|
|
24
24
|
* @param {string} source - Authored Markdown: a note body, or a whole file
|
|
@@ -50,11 +50,10 @@ export function scanRuns(source: string, ctx?: RunContext, syntax?: import("./co
|
|
|
50
50
|
};
|
|
51
51
|
/**
|
|
52
52
|
* Rewrite text marked with `lang=`, `font=` and `enc=` into the plain span,
|
|
53
|
-
* div and verse grammar the rest of each chain renders
|
|
53
|
+
* div and verse grammar the rest of each chain renders.
|
|
54
54
|
*
|
|
55
|
-
* - **
|
|
56
|
-
*
|
|
57
|
-
* lines and source positions remain unchanged.
|
|
55
|
+
* - **Verse layout markers** stay outside encoded text. A shared logical
|
|
56
|
+
* structure retains authored source positions and both presentations.
|
|
58
57
|
* - **The enc, if any, is applied first.** Characters Markdown would read are
|
|
59
58
|
* then backslash-escaped, so they reach every later pass as characters.
|
|
60
59
|
* - **Emphasis in a face** becomes an `<em>` or a `<strong>` carrying its
|
|
@@ -81,7 +80,7 @@ export function scanRuns(source: string, ctx?: RunContext, syntax?: import("./co
|
|
|
81
80
|
* scanner projections.
|
|
82
81
|
* @param {{target?: "site"|"foundry"|"book"}} [options] - The target the
|
|
83
82
|
* Markdown is rendered for; only `site` writes the search marker.
|
|
84
|
-
* @returns {{markdown: string, errors: Array<{file?: string, line: number, column: number, message: string}>, scrolls: Map<string, import("./content-scroll.mjs").ScrollLayout>}}
|
|
83
|
+
* @returns {{markdown: string, errors: Array<{file?: string, line: number, column: number, message: string}>, scrolls: Map<string, import("./content-scroll.mjs").ScrollLayout>, verses: Map<string, {model: ReturnType<typeof import("./content-verse.mjs").parseVerse>, classes: string[], attributes: Record<string, string>, inline: boolean}>}}
|
|
85
84
|
* The rewritten Markdown, the findings of {@link scanRuns}, and each
|
|
86
85
|
* rewritten scroll fence's layout, by its rewritten body.
|
|
87
86
|
*/
|
|
@@ -96,6 +95,12 @@ export function renderRuns(source: string, ctx?: RunContext, syntax?: import("./
|
|
|
96
95
|
message: string;
|
|
97
96
|
}>;
|
|
98
97
|
scrolls: Map<string, import("./content-scroll.mjs").ScrollLayout>;
|
|
98
|
+
verses: Map<string, {
|
|
99
|
+
model: ReturnType<typeof import("./content-verse.mjs").parseVerse>;
|
|
100
|
+
classes: string[];
|
|
101
|
+
attributes: Record<string, string>;
|
|
102
|
+
inline: boolean;
|
|
103
|
+
}>;
|
|
99
104
|
};
|
|
100
105
|
/** The keys this module reads, which no construct passes through as written. */
|
|
101
106
|
export const RUN_KEYS: readonly string[];
|
|
@@ -346,7 +351,7 @@ export type RunContext = {
|
|
|
346
351
|
directions?: ReadonlyMap<string, "vertical-rl"> | undefined;
|
|
347
352
|
};
|
|
348
353
|
/**
|
|
349
|
-
* One span, div, verse
|
|
354
|
+
* One span, div, verse div or scroll fence carrying run attributes.
|
|
350
355
|
* Values combine explicit choices, class-only inheritance, encoding-document
|
|
351
356
|
* language/font defaults and the Roman default encoding.
|
|
352
357
|
*/
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
* @param {object} [options] - Surface presentation.
|
|
4
4
|
* @param {boolean} [options.source] - Emit opaque authored source tokens for buffer preview.
|
|
5
5
|
* @param {boolean} [options.spoilers] - Add focusable CSS spoiler wrappers (Foundry).
|
|
6
|
+
* @param {(token: any, state: any) => void} [options.verseInline] - Populate an opaque quoted-verse token during inline parsing.
|
|
6
7
|
*/
|
|
7
|
-
export function spanMarkdownPlugin(md: typeof import("markdown-it"), { spoilers, source }?: {
|
|
8
|
+
export function spanMarkdownPlugin(md: typeof import("markdown-it"), { spoilers, source, verseInline }?: {
|
|
8
9
|
source?: boolean | undefined;
|
|
9
10
|
spoilers?: boolean | undefined;
|
|
11
|
+
verseInline?: ((token: any, state: any) => void) | undefined;
|
|
10
12
|
}): void;
|
|
11
13
|
/** Read span anchors and located attribute diagnostics outside literal code.
|
|
12
14
|
* @param {string} source - Authored Markdown.
|