@heroiclands/package-build 23.12.6 → 23.12.7
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 +12 -0
- package/assets/styles/content-base.css +25 -0
- package/bin/content-commands.mjs +264 -3
- package/bin/package-build.mjs +25 -0
- package/content-config.mjs +72 -0
- package/docs/api.md +10 -9
- package/docs/authoring/links-and-markup.md +439 -47
- package/docs/commands.md +127 -0
- package/docs/configuration.md +66 -3
- package/docs/content-format.md +3 -1
- package/docs/guides/book.md +11 -0
- package/docs/guides/module-project.md +16 -0
- package/docs/guides/site.md +19 -0
- package/docs/reference/format-details.md +372 -6
- package/docs/reference/note-types.md +36 -11
- package/engine/base-compiler.mjs +2 -0
- package/engine/bundles.mjs +7 -2
- package/engine/compile-corpus.mjs +3 -1
- package/engine/content-charset.mjs +21 -2
- package/engine/content-format.yaml +1 -0
- package/engine/content-index.mjs +12 -0
- package/engine/content-poetry.mjs +22 -4
- package/engine/content-scripts.mjs +1219 -0
- package/engine/content-session.mjs +2 -0
- package/engine/data-keys.mjs +5 -1
- package/engine/dictionary-layout.mjs +18 -12
- package/engine/dictionary-rows.mjs +11 -2
- package/engine/helpers.mjs +8 -2
- package/engine/index-records.mjs +1 -0
- package/engine/journals.mjs +14 -3
- package/engine/language-data.mjs +137 -1
- package/engine/language-tag.mjs +103 -0
- package/engine/language-terms.mjs +16 -4
- package/engine/map-lexicon.mjs +762 -0
- package/engine/markup-validation.mjs +17 -3
- package/engine/names.mjs +1 -1
- package/engine/note-vocabulary.mjs +113 -0
- package/engine/pdf-build.mjs +28 -10
- package/engine/pdf-render.mjs +116 -11
- package/engine/run-rows.mjs +119 -0
- package/engine/run-words.mjs +266 -0
- package/engine/scenes.mjs +1 -0
- package/engine/script-font-delivery.mjs +321 -0
- package/engine/script-fonts.mjs +172 -0
- package/engine/site-build.mjs +10 -3
- package/engine/site-config.mjs +5 -0
- package/engine/site-root.mjs +19 -5
- package/engine/sql-tables.mjs +111 -1
- package/engine/text-maps.mjs +607 -0
- package/engine/verb-pattern.mjs +99 -0
- package/engine/word-pattern.mjs +27 -0
- package/engine/word-rows.mjs +8 -2
- package/engine/word-terms.mjs +44 -0
- package/hugo-theme/layouts/_default/baseof.html +3 -0
- package/hugo-theme/static/css/style.css +10 -0
- package/manifest.mjs +9 -1
- package/package.json +1 -1
- package/types/content-config.d.mts +26 -0
- package/types/engine/compile-corpus.d.mts +2 -1
- package/types/engine/content-index.d.mts +11 -3
- package/types/engine/content-poetry.d.mts +7 -0
- package/types/engine/content-scripts.d.mts +226 -0
- package/types/engine/data-keys.d.mts +2 -2
- package/types/engine/dictionary-rows.d.mts +15 -0
- package/types/engine/helpers.d.mts +5 -1
- package/types/engine/journals.d.mts +7 -2
- package/types/engine/language-data.d.mts +2 -0
- package/types/engine/language-tag.d.mts +8 -0
- package/types/engine/language-terms.d.mts +2 -1
- package/types/engine/map-lexicon.d.mts +274 -0
- package/types/engine/markup-validation.d.mts +7 -2
- package/types/engine/pdf-build.d.mts +26 -3
- package/types/engine/pdf-render.d.mts +17 -2
- package/types/engine/run-rows.d.mts +89 -0
- package/types/engine/run-words.d.mts +86 -0
- package/types/engine/script-font-delivery.d.mts +134 -0
- package/types/engine/script-fonts.d.mts +168 -0
- package/types/engine/site-build.d.mts +2 -1
- package/types/engine/site-root.d.mts +11 -3
- package/types/engine/text-maps.d.mts +175 -0
- package/types/engine/verb-pattern.d.mts +65 -0
- package/types/engine/word-pattern.d.mts +13 -0
- package/types/engine/word-terms.d.mts +6 -0
|
@@ -162,6 +162,19 @@ export const NOTATION = Object.freeze(
|
|
|
162
162
|
]),
|
|
163
163
|
);
|
|
164
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Tier 4 — the blocks the HeroicLands script fonts are registered in, so a
|
|
167
|
+
* mapping note or a `font=` run never draws a warning for a script character.
|
|
168
|
+
*
|
|
169
|
+
* @type {ReadonlyArray<readonly [number, number]>}
|
|
170
|
+
*/
|
|
171
|
+
const SCRIPT_BLOCKS = Object.freeze([
|
|
172
|
+
[0xf0000, 0xf2fff], // plane 15: Pirzath, Thuravark, Semaron, the reserved alphabets, Teng Chou
|
|
173
|
+
[0x1e960, 0x1ec6f], // Zethu overflow, Qalezu, Zethu
|
|
174
|
+
[0x1ecc0, 0x1ecff], // Qalezu catch-before forms
|
|
175
|
+
[0x13430, 0x1345f], // the Egyptian format controls Zethu uses
|
|
176
|
+
]);
|
|
177
|
+
|
|
165
178
|
/**
|
|
166
179
|
* Whether the charset admits a code point anywhere in a note.
|
|
167
180
|
*
|
|
@@ -169,7 +182,12 @@ export const NOTATION = Object.freeze(
|
|
|
169
182
|
* @returns {boolean} Whether it is allowed outside a code fence.
|
|
170
183
|
*/
|
|
171
184
|
export function isAllowedCodePoint(cp) {
|
|
172
|
-
return
|
|
185
|
+
return (
|
|
186
|
+
isLetterTier(cp) ||
|
|
187
|
+
TYPOGRAPHY.has(cp) ||
|
|
188
|
+
NOTATION.has(cp) ||
|
|
189
|
+
SCRIPT_BLOCKS.some(([from, to]) => cp >= from && cp <= to)
|
|
190
|
+
);
|
|
173
191
|
}
|
|
174
192
|
|
|
175
193
|
/**
|
|
@@ -362,7 +380,8 @@ export function checkText(text, file) {
|
|
|
362
380
|
line: i + 1,
|
|
363
381
|
column,
|
|
364
382
|
severity: /** @type {const} */ ("warning"),
|
|
365
|
-
|
|
383
|
+
// A Private Use character draws as nothing, so quoting it leaves an empty span.
|
|
384
|
+
message: `${/\p{Co}/u.test(ch) ? "" : `\`${ch}\` `}${hex(cp)} is ${refusalFor(cp)}`,
|
|
366
385
|
});
|
|
367
386
|
}
|
|
368
387
|
}
|
package/engine/content-index.mjs
CHANGED
|
@@ -106,6 +106,7 @@ import { AddressLink } from "./address-values.mjs";
|
|
|
106
106
|
import { scanSpans } from "./content-spans.mjs";
|
|
107
107
|
import { rebaseNameSpans } from "./name-markup.mjs";
|
|
108
108
|
import { analyzeNameSpans } from "./names.mjs";
|
|
109
|
+
import { recordRuns } from "./run-rows.mjs";
|
|
109
110
|
import fs from "node:fs";
|
|
110
111
|
import path from "node:path";
|
|
111
112
|
|
|
@@ -448,6 +449,8 @@ function assertNoDerivedKeys(frontmatter, relPath, absPath, contentPackage, raw)
|
|
|
448
449
|
* `name` reads `Map 1` rather than `Figure 1` where it is due — see
|
|
449
450
|
* {@link module:engine/content-figures.scanFigures}.
|
|
450
451
|
* @param {import("./content-session.mjs").ContentSyntax} [options.syntax] - Session scanner projections.
|
|
452
|
+
* @param {import("./content-scripts.mjs").RunContext} [options.runContext] -
|
|
453
|
+
* The configured languages, which give each run's `lang=` its tag.
|
|
451
454
|
* @returns {Record<string, any>} The record, keys sorted at every depth. A
|
|
452
455
|
* **stub** — a note with an empty body, on a type an empty body suppresses —
|
|
453
456
|
* carries `address` and `anchors` as `null`: it publishes no page, so it
|
|
@@ -474,6 +477,7 @@ export function buildIndexRecord({
|
|
|
474
477
|
dateContext,
|
|
475
478
|
resolveRole,
|
|
476
479
|
syntax,
|
|
480
|
+
runContext,
|
|
477
481
|
}) {
|
|
478
482
|
assertNoDerivedKeys(frontmatter, relPath, absPath, contentPackage, raw);
|
|
479
483
|
|
|
@@ -541,6 +545,7 @@ export function buildIndexRecord({
|
|
|
541
545
|
...(Object.keys(resolvedDates).length ? { resolvedDates } : {}),
|
|
542
546
|
package: contentPackage,
|
|
543
547
|
names: marked.names,
|
|
548
|
+
runs: recordRuns(source, { context: runContext, bodyLine, bodyColumn, syntax }),
|
|
544
549
|
address: stub ? null : address,
|
|
545
550
|
nameAscii: asciiName(frontmatter?.name?.full),
|
|
546
551
|
aliasesAscii: asciiAliases(frontmatter?.name?.aliases),
|
|
@@ -695,6 +700,7 @@ export function indexRecordsForNote({
|
|
|
695
700
|
dateContext,
|
|
696
701
|
resolveRole,
|
|
697
702
|
syntax,
|
|
703
|
+
runContext,
|
|
698
704
|
}) {
|
|
699
705
|
resolveNoteId(frontmatter, { pkg: contentPackage });
|
|
700
706
|
const record = buildIndexRecord({
|
|
@@ -712,6 +718,7 @@ export function indexRecordsForNote({
|
|
|
712
718
|
dateContext,
|
|
713
719
|
resolveRole,
|
|
714
720
|
syntax,
|
|
721
|
+
runContext,
|
|
715
722
|
});
|
|
716
723
|
const records = [decodeIndexAddresses(record, addressContext ?? { package: contentPackage })];
|
|
717
724
|
const address = noteAddress(frontmatter, contentPackage);
|
|
@@ -1067,6 +1074,8 @@ export function resolveCultures(
|
|
|
1067
1074
|
* calendar note's shortcode; see {@link module:engine/note-calendars}.
|
|
1068
1075
|
* @param {string} [options.configFile] - The configuration file, where an
|
|
1069
1076
|
* unknown `defaultCalendar` is reported.
|
|
1077
|
+
* @param {Readonly<Record<string, {tag: string}>>} [options.languages] - The
|
|
1078
|
+
* configured languages, which give each run's `lang=` its tag.
|
|
1070
1079
|
* @param {(key: string) => ({culture?: unknown}|undefined)} [options.foreignRecord] -
|
|
1071
1080
|
* Another package's entry for a canonical address, read for a parent that
|
|
1072
1081
|
* package publishes; see {@link resolveCultures}.
|
|
@@ -1086,6 +1095,7 @@ export function collectContentIndex(
|
|
|
1086
1095
|
currentDate,
|
|
1087
1096
|
defaultCalendar,
|
|
1088
1097
|
configFile,
|
|
1098
|
+
languages,
|
|
1089
1099
|
skipDirectories,
|
|
1090
1100
|
assetsBase,
|
|
1091
1101
|
manifest,
|
|
@@ -1192,6 +1202,7 @@ export function collectContentIndex(
|
|
|
1192
1202
|
dateContext: dates,
|
|
1193
1203
|
resolveRole,
|
|
1194
1204
|
syntax,
|
|
1205
|
+
runContext: { languages },
|
|
1195
1206
|
});
|
|
1196
1207
|
records.push(...made);
|
|
1197
1208
|
bodies.push({ record: made[0], body });
|
|
@@ -1478,6 +1489,7 @@ export function indexRecordsFor({
|
|
|
1478
1489
|
currentDate: resolved.currentDate,
|
|
1479
1490
|
defaultCalendar: resolved.defaultCalendar ?? undefined,
|
|
1480
1491
|
configFile: configFileIn(resolved.rootDir, CONFIG_FILENAMES),
|
|
1492
|
+
languages: resolved.languages,
|
|
1481
1493
|
addressContext: {
|
|
1482
1494
|
...noteAddressContext(resolved),
|
|
1483
1495
|
declaresAddress: dependencyAddresses(resolved),
|
|
@@ -77,6 +77,24 @@ import { parseExtensionAttributes, refusedAttributes } from "./extension-attribu
|
|
|
77
77
|
|
|
78
78
|
const structureParser = new MarkdownIt({ html: true });
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* The keys a poetry fence's attribute block takes. `lang`, `font` and `map`
|
|
82
|
+
* are read by `scanRuns` in content-scripts.mjs; `dir`, and on the site
|
|
83
|
+
* `data-pagefind-ignore`, are written by its rewrite of a fence set in one of
|
|
84
|
+
* the faces, and reach the element as they are written.
|
|
85
|
+
*/
|
|
86
|
+
export const POETRY_KEYS = Object.freeze([
|
|
87
|
+
"form",
|
|
88
|
+
"meter",
|
|
89
|
+
"rhyme",
|
|
90
|
+
"syllables",
|
|
91
|
+
"lang",
|
|
92
|
+
"font",
|
|
93
|
+
"map",
|
|
94
|
+
"dir",
|
|
95
|
+
"data-pagefind-ignore",
|
|
96
|
+
]);
|
|
97
|
+
|
|
80
98
|
/** Read poetry code fences; start/end are inclusive zero-based source lines.
|
|
81
99
|
* @param {string} source - Authored Markdown.
|
|
82
100
|
*/
|
|
@@ -157,15 +175,13 @@ export function scanPoetry(source) {
|
|
|
157
175
|
for (const message of [...parsed.problems, ...refusedAttributes(parsed.values)])
|
|
158
176
|
errors.push({ ...at, message });
|
|
159
177
|
for (const [key, value] of Object.entries(parsed.values)) {
|
|
160
|
-
if (!
|
|
178
|
+
if (!POETRY_KEYS.includes(key))
|
|
161
179
|
errors.push({ ...at, message: `${key}= is not a poetry attribute` });
|
|
162
180
|
else if (key === "syllables" && !/^[1-9]\d*(?:,[1-9]\d*)*$/.test(value))
|
|
163
181
|
errors.push({
|
|
164
182
|
...at,
|
|
165
183
|
message: "poetry syllables= needs positive comma-separated counts",
|
|
166
184
|
});
|
|
167
|
-
else if (key === "lang" && !/^[A-Za-z]{2,8}(?:-[A-Za-z0-9]{1,8})*$/.test(value))
|
|
168
|
-
errors.push({ ...at, message: "poetry lang= needs a language tag" });
|
|
169
185
|
}
|
|
170
186
|
}
|
|
171
187
|
if (opening?.name === "poetry")
|
|
@@ -197,7 +213,9 @@ export function renderPoetry(source) {
|
|
|
197
213
|
if (block.id) attrs.push(`id="${escape(slugify(block.id))}"`);
|
|
198
214
|
for (const [key, value] of Object.entries(block.attributes))
|
|
199
215
|
if (!refusedAttributes({ [key]: value }).length)
|
|
200
|
-
attrs.push(
|
|
216
|
+
attrs.push(
|
|
217
|
+
`${["lang", "dir", "data-pagefind-ignore"].includes(key) ? key : `data-${key}`}="${escape(value)}"`,
|
|
218
|
+
);
|
|
201
219
|
let indent = block.indent;
|
|
202
220
|
if (
|
|
203
221
|
indent.length >= 4 &&
|