@heroiclands/package-build 23.12.8 → 24.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 +84 -0
- package/README.md +3 -2
- package/assets/preview/gitea.ini +12 -7
- package/assets/styles/content-base.css +293 -24
- package/bin/content-commands.mjs +370 -213
- package/bin/package-build-preview.mjs +2 -2
- package/bin/package-build.mjs +3 -2
- package/ci/check-banners.mjs +7 -7
- package/config.mjs +21 -6
- package/content-config.mjs +199 -80
- package/docs/api.md +110 -89
- package/docs/authoring/links-and-markup.md +469 -97
- package/docs/commands.md +259 -78
- package/docs/configuration.md +211 -103
- package/docs/content-format.md +4 -4
- package/docs/diagnostics.md +44 -2
- package/docs/getting-started.md +1 -1
- package/docs/guides/icons.md +1 -1
- package/docs/guides/module-project.md +5 -8
- package/docs/guides/release-and-deploy.md +2 -2
- package/docs/guides/site.md +112 -23
- package/docs/guides/system-project.md +1 -1
- package/docs/guides/writing-in-invented-scripts.md +1247 -0
- package/docs/index.md +1 -0
- package/docs/project-setup.md +28 -30
- package/docs/reference/format-details.md +677 -319
- package/docs/reference/note-types.md +47 -10
- package/docs/reference/theme-pages.md +178 -108
- package/docs/source-preview.md +16 -2
- package/engine/anchors.mjs +2 -2
- package/engine/asset-shipping.mjs +22 -10
- package/engine/base-compiler.mjs +62 -104
- package/engine/changelog-lint.mjs +1 -1
- package/engine/code-fences.mjs +3 -3
- package/engine/content-address.mjs +1 -1
- package/engine/content-alerts.mjs +8 -4
- package/engine/content-blocks.mjs +29 -14
- package/engine/content-embeds.mjs +1 -1
- package/engine/content-expand.mjs +376 -0
- package/engine/content-figures.mjs +18 -11
- package/engine/content-format.yaml +8 -0
- package/engine/content-glyphs.mjs +213 -0
- package/engine/content-images.mjs +6 -7
- package/engine/content-index.mjs +1 -1
- package/engine/content-links.mjs +3 -3
- package/engine/content-lint.mjs +1 -1
- package/engine/content-render.mjs +453 -0
- package/engine/content-scripts.mjs +376 -43
- package/engine/content-spans.mjs +6 -3
- package/engine/content-styles.mjs +91 -0
- package/engine/content-symbols.mjs +186 -0
- package/engine/content-verse.mjs +738 -0
- package/engine/core-report.mjs +169 -0
- package/engine/core-vocabulary.mjs +208 -0
- package/engine/dictionary-html.mjs +119 -0
- package/engine/dictionary-rows.mjs +15 -4
- package/engine/field-reference.mjs +5 -5
- package/engine/first-use.mjs +17 -27
- package/engine/frontmatter-lint.mjs +1 -1
- package/engine/heading-attributes.mjs +89 -0
- package/engine/helpers.mjs +61 -101
- package/engine/homepage.mjs +17 -29
- package/engine/html-minify.mjs +70 -0
- package/engine/index.mjs +8 -5
- package/engine/key-case-collisions.mjs +136 -0
- package/engine/language-data.mjs +203 -6
- package/engine/language-rows.mjs +8 -2
- package/engine/language-terms.mjs +186 -16
- package/engine/language-words.mjs +12 -0
- package/engine/logographic.mjs +255 -0
- package/engine/map-lexicon.mjs +262 -47
- package/engine/map-places.mjs +5 -4
- package/engine/markdown-expressions.mjs +0 -2
- package/engine/markdownlint-run.mjs +9 -3
- package/engine/markup-validation.mjs +21 -0
- package/engine/metre-declaration.mjs +134 -0
- package/engine/names.mjs +36 -9
- package/engine/note-matter.mjs +66 -0
- package/engine/note-vocabulary.mjs +187 -3
- package/engine/pdf-build.mjs +69 -133
- package/engine/pdf-render.mjs +205 -58
- package/engine/post-fields.mjs +157 -0
- package/engine/preview-index.mjs +130 -0
- package/engine/preview-source.mjs +450 -0
- package/engine/project-init.mjs +5 -12
- package/engine/prose-config.mjs +3 -3
- package/engine/read-stdin.mjs +29 -0
- package/engine/run-rows.mjs +2 -2
- package/engine/run-words.mjs +6 -112
- package/engine/script-emphasis-terms.mjs +38 -0
- package/engine/script-emphasis.mjs +295 -0
- package/engine/script-font-delivery.mjs +4 -4
- package/engine/site-build.mjs +260 -315
- package/engine/site-config.mjs +26 -238
- package/engine/site-files.mjs +175 -0
- package/engine/site-index.mjs +9 -4
- package/engine/site-preview.mjs +52 -525
- package/engine/site-render.mjs +593 -0
- package/engine/site-root.mjs +22 -13
- package/engine/site-search.mjs +161 -0
- package/engine/site-serve.mjs +273 -0
- package/engine/site-theme-banner.mjs +154 -0
- package/engine/site-theme-urls.mjs +125 -0
- package/engine/site-theme.mjs +926 -0
- package/engine/sql-tables.mjs +20 -3
- package/engine/text-maps.mjs +57 -10
- package/engine/typographer.mjs +248 -0
- package/engine/verse-metre.mjs +357 -0
- package/engine/wikilink-syntax.mjs +29 -47
- package/engine/wikilinks.mjs +758 -279
- package/engine/word-forms.mjs +364 -0
- package/engine/word-rows.mjs +12 -2
- package/engine/word-terms.mjs +38 -4
- package/manifest.mjs +3 -4
- package/package.json +11 -8
- package/{hugo-theme → site-theme}/data/banners.yaml +6 -10
- package/site-theme/layouts/base.hbs +31 -0
- package/site-theme/layouts/blog-list.hbs +30 -0
- package/site-theme/layouts/blog-post.hbs +40 -0
- package/site-theme/layouts/home.hbs +35 -0
- package/site-theme/layouts/list.hbs +20 -0
- package/site-theme/layouts/not-found.hbs +31 -0
- package/site-theme/layouts/page.hbs +7 -0
- package/site-theme/partials/copy-buttons.hbs +37 -0
- package/site-theme/partials/draft-notice.hbs +5 -0
- package/site-theme/partials/exturl.hbs +2 -0
- package/{hugo-theme/layouts/partials/footer.html → site-theme/partials/footer.hbs} +10 -7
- package/site-theme/partials/header.hbs +44 -0
- package/site-theme/partials/hero-banner.hbs +11 -0
- package/site-theme/partials/infobox-entry.hbs +2 -0
- package/site-theme/partials/infobox-section.hbs +31 -0
- package/site-theme/partials/infobox-value.hbs +2 -0
- package/site-theme/partials/infobox.hbs +18 -0
- package/site-theme/partials/list-members.hbs +9 -0
- package/site-theme/partials/nav-links.hbs +5 -0
- package/site-theme/partials/page-body.hbs +48 -0
- package/site-theme/partials/page-list.hbs +14 -0
- package/site-theme/partials/related.hbs +24 -0
- package/site-theme/partials/search-meta.hbs +6 -0
- package/site-theme/partials/search-names.hbs +2 -0
- package/site-theme/partials/search.hbs +52 -0
- package/site-theme/partials/tags.hbs +4 -0
- package/site-theme/partials/toc.hbs +7 -0
- package/{hugo-theme → site-theme}/static/css/style.css +106 -14
- package/stage.mjs +1 -2
- package/types/config.d.mts +8 -4
- package/types/content-config.d.mts +15 -15
- package/types/engine/asset-shipping.d.mts +5 -2
- package/types/engine/base-compiler.d.mts +20 -2
- package/types/engine/code-fences.d.mts +3 -3
- package/types/engine/content-address.d.mts +1 -1
- package/types/engine/content-alerts.d.mts +8 -2
- package/types/engine/content-blocks.d.mts +11 -4
- package/types/engine/content-expand.d.mts +288 -0
- package/types/engine/content-figures.d.mts +11 -3
- package/types/engine/content-glyphs.d.mts +85 -0
- package/types/engine/content-images.d.mts +6 -7
- package/types/engine/content-links.d.mts +1 -1
- package/types/engine/content-render.d.mts +199 -0
- package/types/engine/content-scripts.d.mts +70 -4
- package/types/engine/content-spans.d.mts +1 -1
- package/types/engine/content-styles.d.mts +33 -0
- package/types/engine/content-symbols.d.mts +35 -0
- package/types/engine/content-verse.d.mts +240 -0
- package/types/engine/core-report.d.mts +45 -0
- package/types/engine/core-vocabulary.d.mts +53 -0
- package/types/engine/dictionary-html.d.mts +8 -0
- package/types/engine/dictionary-rows.d.mts +10 -0
- package/types/engine/field-reference.d.mts +2 -2
- package/types/engine/heading-attributes.d.mts +20 -0
- package/types/engine/helpers.d.mts +3 -10
- package/types/engine/homepage.d.mts +11 -24
- package/types/engine/html-minify.d.mts +9 -0
- package/types/engine/index.d.mts +2 -1
- package/types/engine/key-case-collisions.d.mts +28 -0
- package/types/engine/language-data.d.mts +0 -2
- package/types/engine/language-terms.d.mts +24 -2
- package/types/engine/logographic.d.mts +45 -0
- package/types/engine/map-lexicon.d.mts +66 -13
- package/types/engine/map-places.d.mts +8 -0
- package/types/engine/markdown-expressions.d.mts +0 -2
- package/types/engine/metre-declaration.d.mts +39 -0
- package/types/engine/names.d.mts +34 -3
- package/types/engine/note-matter.d.mts +48 -0
- package/types/engine/pdf-render.d.mts +6 -2
- package/types/engine/post-fields.d.mts +44 -0
- package/types/engine/preview-index.d.mts +72 -0
- package/types/engine/preview-source.d.mts +51 -0
- package/types/engine/read-stdin.d.mts +11 -0
- package/types/engine/run-rows.d.mts +2 -2
- package/types/engine/run-words.d.mts +0 -15
- package/types/engine/script-emphasis-terms.d.mts +21 -0
- package/types/engine/script-emphasis.d.mts +84 -0
- package/types/engine/script-font-delivery.d.mts +4 -4
- package/types/engine/site-build.d.mts +71 -113
- package/types/engine/site-config.d.mts +14 -134
- package/types/engine/site-files.d.mts +73 -0
- package/types/engine/site-index.d.mts +11 -3
- package/types/engine/site-preview.d.mts +15 -19
- package/types/engine/site-render.d.mts +171 -0
- package/types/engine/site-root.d.mts +12 -4
- package/types/engine/site-search.d.mts +54 -0
- package/types/engine/site-serve.d.mts +44 -0
- package/types/engine/site-theme-banner.d.mts +51 -0
- package/types/engine/site-theme-urls.d.mts +60 -0
- package/types/engine/site-theme.d.mts +127 -0
- package/types/engine/sql-tables.d.mts +4 -1
- package/types/engine/text-maps.d.mts +17 -3
- package/types/engine/typographer.d.mts +11 -0
- package/types/engine/verse-metre.d.mts +131 -0
- package/types/engine/wikilink-syntax.d.mts +30 -48
- package/types/engine/wikilinks.d.mts +330 -14
- package/types/engine/word-forms.d.mts +83 -0
- package/types/manifest.d.mts +3 -4
- package/types/stage.d.mts +1 -2
- package/types/vendor/markdownlint.d.mts +8 -0
- package/vendor/markdownlint.mjs +20388 -0
- package/engine/content-poetry.mjs +0 -240
- package/engine/web-wikilinks.mjs +0 -594
- package/hugo-theme/layouts/404.html +0 -85
- package/hugo-theme/layouts/_default/baseof.html +0 -67
- package/hugo-theme/layouts/_default/list.html +0 -139
- package/hugo-theme/layouts/_default/single.html +0 -4
- package/hugo-theme/layouts/blog/list.html +0 -54
- package/hugo-theme/layouts/blog-post/single.html +0 -36
- package/hugo-theme/layouts/index.html +0 -75
- package/hugo-theme/layouts/partials/banner-url.html +0 -141
- package/hugo-theme/layouts/partials/cdn-url.html +0 -36
- package/hugo-theme/layouts/partials/dictionary-lists.html +0 -58
- package/hugo-theme/layouts/partials/draft-notice.html +0 -41
- package/hugo-theme/layouts/partials/draft-state.html +0 -26
- package/hugo-theme/layouts/partials/header.html +0 -35
- package/hugo-theme/layouts/partials/hero-banner.html +0 -85
- package/hugo-theme/layouts/partials/infobox/entry.html +0 -18
- package/hugo-theme/layouts/partials/infobox/items.html +0 -26
- package/hugo-theme/layouts/partials/infobox/section.html +0 -56
- package/hugo-theme/layouts/partials/infobox/value.html +0 -43
- package/hugo-theme/layouts/partials/infobox.html +0 -57
- package/hugo-theme/layouts/partials/page-body.html +0 -152
- package/hugo-theme/layouts/partials/related.html +0 -138
- package/hugo-theme/layouts/partials/search.html +0 -84
- package/hugo-theme/layouts/partials/site-url.html +0 -32
- package/hugo-theme/layouts/partials/tags.html +0 -30
- package/hugo-theme/layouts/partials/toc.html +0 -28
- package/hugo-theme/layouts/partials/warn-missing-banner.html +0 -3
- package/hugo-theme/layouts/shortcodes/cartouche.html +0 -64
- package/hugo-theme/layouts/shortcodes/exturl.html +0 -12
- package/hugo-theme/layouts/shortcodes/glyph.html +0 -43
- package/hugo-theme/layouts/shortcodes/pagelist.html +0 -63
- package/hugo-theme/theme.toml +0 -11
- package/types/engine/content-poetry.d.mts +0 -58
- package/types/engine/web-wikilinks.d.mts +0 -107
- /package/{hugo-theme → site-theme}/data/banner-kinds.yaml +0 -0
- /package/{hugo-theme → site-theme}/static/css/sohl-icons.css +0 -0
- /package/{hugo-theme → site-theme}/static/fonts/game-icons-kb.woff2 +0 -0
- /package/{hugo-theme → site-theme}/static/img/banners/takheperu-hieroglyphs.svg +0 -0
- /package/{hugo-theme → site-theme}/static/img/cartouches/takheperu.svg +0 -0
- /package/{hugo-theme → site-theme}/static/js/inline-spoilers.js +0 -0
package/bin/content-commands.mjs
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* npx package-build map [--tree] [--from <shortcode>] [--chart <shortcode>] [--travel] [--out <dir>]
|
|
32
32
|
* npx package-build reachability <dir> [file] [--index <shortcode>]
|
|
33
33
|
* npx package-build transliterate <map> [--lang <language>] [--font <slug>] [--hex] [text..]
|
|
34
|
-
* npx package-build lexicon <language> --map <map> [--font <slug>] [--json]
|
|
34
|
+
* npx package-build lexicon <language> --map <map> [--font <slug>] [--derived] [--json]
|
|
35
35
|
* npx package-build addresses diff --from <zip|dir> [--strict]
|
|
36
36
|
* npx package-build npc new (--spec <json> | --specfile <path>) [--seed <text>] [--out <path>]
|
|
37
37
|
*
|
|
@@ -45,8 +45,9 @@ import fs from "fs";
|
|
|
45
45
|
import path from "node:path";
|
|
46
46
|
import log from "loglevel";
|
|
47
47
|
import prefix from "loglevel-plugin-prefix";
|
|
48
|
+
import { readStdin } from "../engine/read-stdin.mjs";
|
|
48
49
|
import { compilePacks, cleanPacks, unpackPacks } from "../engine/compendiums.mjs";
|
|
49
|
-
import { compilesFoundryDocuments, publishesContentPages } from "../content-config.mjs";
|
|
50
|
+
import { compilesFoundryDocuments, publishesContentPages, siteBase } from "../content-config.mjs";
|
|
50
51
|
import { loadPackConfig, packConfigPath } from "../engine/pack-config.mjs";
|
|
51
52
|
import { buildPdf, listBookAssets } from "../engine/pdf-build.mjs";
|
|
52
53
|
import { summaryLines } from "../engine/pdf-coverage.mjs";
|
|
@@ -64,19 +65,7 @@ import {
|
|
|
64
65
|
unaddressableForeignPackages,
|
|
65
66
|
formatUnaddressableFinding,
|
|
66
67
|
} from "../engine/metadata-index.mjs";
|
|
67
|
-
import {
|
|
68
|
-
fetchNavigation,
|
|
69
|
-
generateHugoConfig,
|
|
70
|
-
HUGO_SOURCE,
|
|
71
|
-
writeHugoConfig,
|
|
72
|
-
} from "../engine/site-config.mjs";
|
|
73
|
-
import {
|
|
74
|
-
checkScriptFonts,
|
|
75
|
-
copyScriptFonts,
|
|
76
|
-
scriptFontFiles,
|
|
77
|
-
SITE_FONTS_DIR,
|
|
78
|
-
siteFontsDestination,
|
|
79
|
-
} from "../engine/script-font-delivery.mjs";
|
|
68
|
+
import { DEPLOY_ROOT, fetchNavigation } from "../engine/site-config.mjs";
|
|
80
69
|
import { renderItemFieldReference, renderItemFieldsPage } from "../engine/field-reference.mjs";
|
|
81
70
|
import { checkDocLinks, checkDocIndex } from "../engine/docs-checks.mjs";
|
|
82
71
|
import { checkArtSlotSizes } from "../engine/art-fields.mjs";
|
|
@@ -117,6 +106,8 @@ import { schemaSubtypeOf } from "../engine/subtype-registry.mjs";
|
|
|
117
106
|
import { NOTE_VOCABULARY } from "../engine/note-vocabulary.mjs";
|
|
118
107
|
import { markupFindings } from "../engine/markup-validation.mjs";
|
|
119
108
|
import { runContext } from "../engine/content-scripts.mjs";
|
|
109
|
+
import { coreReport, coreReportText } from "../engine/core-report.mjs";
|
|
110
|
+
import { checkScriptNoteFonts } from "../engine/script-emphasis.mjs";
|
|
120
111
|
import {
|
|
121
112
|
checkLexiconNatives,
|
|
122
113
|
checkMapFonts,
|
|
@@ -136,8 +127,12 @@ import {
|
|
|
136
127
|
import {
|
|
137
128
|
buildSite,
|
|
138
129
|
gatesFailed,
|
|
130
|
+
siteBuildFailed,
|
|
139
131
|
formatUnaddressableFinding as formatUnaddressable,
|
|
140
132
|
} from "../engine/site-build.mjs";
|
|
133
|
+
import { buildPackageSite, siteDirectory } from "../engine/site-render.mjs";
|
|
134
|
+
import { serveSite } from "../engine/site-serve.mjs";
|
|
135
|
+
import { writeSiteRoot } from "../engine/site-root.mjs";
|
|
141
136
|
import { auditLinks, buildLinkIndex, walkReachability } from "../engine/content-links.mjs";
|
|
142
137
|
import { prepareLinkSqlTables, prepareTreeSqlTables } from "../engine/sql-tables.mjs";
|
|
143
138
|
import { createContentSession, CONTENT_TARGETS } from "../engine/content-session.mjs";
|
|
@@ -324,6 +319,7 @@ export function registerContentCommands(cli) {
|
|
|
324
319
|
.command(withIndexPreflight(reachabilityCommand()))
|
|
325
320
|
.command(transliterateCommand())
|
|
326
321
|
.command(lexiconCommand())
|
|
322
|
+
.command(coreCommand())
|
|
327
323
|
.command(addressesCommand())
|
|
328
324
|
.command(withIndexPreflight(npcCommand()));
|
|
329
325
|
}
|
|
@@ -1292,6 +1288,7 @@ function lintCommand() {
|
|
|
1292
1288
|
// Each mapping note's faces, each language's native forms
|
|
1293
1289
|
// and each language's `note`, against the faces and maps.
|
|
1294
1290
|
...index.notes.flatMap((note) => checkMapFonts(note, runs)),
|
|
1291
|
+
...index.notes.flatMap((note) => checkScriptNoteFonts(note, runs)),
|
|
1295
1292
|
...index.notes.flatMap((note) => checkLexiconNatives(note, runs)),
|
|
1296
1293
|
...languageNoteFindings({ ...config, configFile: packConfigPath() }, records),
|
|
1297
1294
|
...index.notes.flatMap(firstUseChecker),
|
|
@@ -1925,60 +1922,123 @@ function pdfCommand() {
|
|
|
1925
1922
|
}
|
|
1926
1923
|
|
|
1927
1924
|
/**
|
|
1928
|
-
*
|
|
1929
|
-
*
|
|
1925
|
+
* Report what a site build found, in the order {@link siteCommand} sets out:
|
|
1926
|
+
* the gates first, stopping at the first that fired, then each note's findings,
|
|
1927
|
+
* then what drawing the maps found.
|
|
1930
1928
|
*
|
|
1931
|
-
*
|
|
1932
|
-
*
|
|
1933
|
-
*
|
|
1934
|
-
*
|
|
1935
|
-
* @param {object} config - The resolved content configuration.
|
|
1936
|
-
* @returns {void}
|
|
1929
|
+
* @param {object} result - From `buildSite`.
|
|
1930
|
+
* @returns {boolean} Whether the build may be written: no gate fired and no
|
|
1931
|
+
* note is in error.
|
|
1937
1932
|
*/
|
|
1938
|
-
function
|
|
1939
|
-
const
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1933
|
+
function reportSiteBuild(result) {
|
|
1934
|
+
const { gates } = result;
|
|
1935
|
+
|
|
1936
|
+
// First, because it is decided before the tree is walked and
|
|
1937
|
+
// before the output is cleared: a package with no front page,
|
|
1938
|
+
// or two competing for it, has nothing to say about its pages
|
|
1939
|
+
// yet.
|
|
1940
|
+
for (const f of gates.homepages) emitDiagnostic(f);
|
|
1941
|
+
for (const f of gates.frontmatterLinks) {
|
|
1942
|
+
emitDiagnostic({
|
|
1943
|
+
file: f.file,
|
|
1944
|
+
severity: "error",
|
|
1945
|
+
message:
|
|
1946
|
+
`wikilink ${f.link} authored in frontmatter at ` +
|
|
1947
|
+
`${f.path} — frontmatter is data, is copied to the ` +
|
|
1948
|
+
`page verbatim, and reaches the reader as brackets`,
|
|
1949
|
+
});
|
|
1948
1950
|
}
|
|
1949
|
-
const
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1951
|
+
for (const f of gates.addressErrors) {
|
|
1952
|
+
emitDiagnostic({
|
|
1953
|
+
file: f.file,
|
|
1954
|
+
severity: "error",
|
|
1955
|
+
message: `cannot derive a URL: ${f.reason}`,
|
|
1956
|
+
});
|
|
1957
|
+
}
|
|
1958
|
+
reportSiteFindings(gates.sections ?? []);
|
|
1959
|
+
for (const s of gates.staleManifests) {
|
|
1960
|
+
emitDiagnostic({
|
|
1961
|
+
file: cachedIndexPath(loadPackConfig(), s.package),
|
|
1962
|
+
severity: "error",
|
|
1963
|
+
message: `unusable content index: ${s.reason}`,
|
|
1964
|
+
});
|
|
1965
|
+
}
|
|
1966
|
+
for (const f of gates.unaddressable) {
|
|
1967
|
+
console.error(formatUnaddressable(f, loadPackConfig()));
|
|
1968
|
+
}
|
|
1969
|
+
if (gatesFailed(gates)) {
|
|
1970
|
+
return false;
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
// Every note's findings are reported together: stopping at the first
|
|
1974
|
+
// would make a single bad table hide every other problem in the tree.
|
|
1975
|
+
// Each is `file:line:column: error: message`, path first — the shape
|
|
1976
|
+
// the pack build reports the same findings in.
|
|
1977
|
+
for (const e of result.tableErrors) {
|
|
1978
|
+
emitDiagnostic({
|
|
1979
|
+
file: e.source,
|
|
1980
|
+
line: typeof e.line === "number" ? e.line + 1 : undefined,
|
|
1981
|
+
column: e.column,
|
|
1982
|
+
severity: "error",
|
|
1983
|
+
message: e.reason,
|
|
1984
|
+
});
|
|
1985
|
+
}
|
|
1986
|
+
for (const e of result.expressionErrors) {
|
|
1987
|
+
emitDiagnostic(e);
|
|
1988
|
+
}
|
|
1989
|
+
for (const e of result.secretErrors) {
|
|
1990
|
+
emitDiagnostic({ ...e, severity: "error" });
|
|
1991
|
+
}
|
|
1992
|
+
for (const e of result.captionErrors) {
|
|
1993
|
+
emitDiagnostic({ ...e, severity: "error" });
|
|
1994
|
+
}
|
|
1995
|
+
for (const e of result.headingErrors) {
|
|
1996
|
+
emitDiagnostic({ ...e, severity: "error" });
|
|
1997
|
+
}
|
|
1998
|
+
for (const e of result.footnoteErrors) {
|
|
1999
|
+
emitDiagnostic({ ...e, severity: "error" });
|
|
2000
|
+
}
|
|
2001
|
+
for (const e of result.embedErrors) {
|
|
2002
|
+
emitDiagnostic({ ...e, severity: "error" });
|
|
2003
|
+
}
|
|
2004
|
+
// Worded by the shared table the pack build words the same finding
|
|
2005
|
+
// with, and located by searching the note for the link.
|
|
2006
|
+
for (const e of result.wikiErrors) {
|
|
2007
|
+
emitDiagnostic({
|
|
2008
|
+
file: e.file,
|
|
2009
|
+
...positionOfLiteral(readRawNote(e.file), e.link, e.occurrence),
|
|
2010
|
+
severity: "error",
|
|
2011
|
+
// An embed's directive speaks the image vocabulary
|
|
2012
|
+
// rather than the link one, and carries its own
|
|
2013
|
+
// sentence; everything else is worded by the shared
|
|
2014
|
+
// table.
|
|
2015
|
+
message: e.message ?? linkFindingMessage(e),
|
|
2016
|
+
});
|
|
2017
|
+
}
|
|
2018
|
+
// An image whose pathname the site cannot resolve, located the
|
|
2019
|
+
// way a wikilink finding is: by searching the note for the
|
|
2020
|
+
// literal the resolver was handed.
|
|
2021
|
+
for (const e of result.imageErrors) {
|
|
2022
|
+
emitDiagnostic({
|
|
2023
|
+
file: e.file,
|
|
2024
|
+
...positionOfLiteral(readRawNote(e.file), e.src, e.occurrence),
|
|
2025
|
+
severity: "error",
|
|
2026
|
+
message: e.message,
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
if (siteBuildFailed(result)) return false;
|
|
2030
|
+
|
|
2031
|
+
// Relation warnings do not fail a site build.
|
|
2032
|
+
for (const f of result.mapFindings) emitDiagnostic(f);
|
|
2033
|
+
return true;
|
|
1957
2034
|
}
|
|
1958
2035
|
|
|
1959
2036
|
/**
|
|
1960
|
-
* `package-build site` —
|
|
2037
|
+
* `package-build site` — the website commands.
|
|
1961
2038
|
*
|
|
1962
2039
|
* The sibling of `package compile`: the same tree, rendered as pages instead of
|
|
1963
|
-
* compiled into packs.
|
|
1964
|
-
*
|
|
1965
|
-
* wikilink resolution, code-fence protection and the foreign-manifest merge —
|
|
1966
|
-
* happens here, from configuration. So does the Hugo configuration: the whole
|
|
1967
|
-
* source tree Hugo reads lands under `build/hugo/`, and the consumer's script
|
|
1968
|
-
* runs Hugo over it. With `site.maps` on, every place
|
|
1969
|
-
* page with a border or a route carries the map from that place.
|
|
1970
|
-
*
|
|
1971
|
-
* **The Hugo configuration is generated before anything is written.** Its
|
|
1972
|
-
* sources — `package.json`'s `homepage`, the cached navigation, the installed
|
|
1973
|
-
* theme — are each a way the build can fail, and failing before the output
|
|
1974
|
-
* tree is cleared leaves the last good site in place to be looked at. Nothing
|
|
1975
|
-
* the walk reads changes it: a site renders its homepage and its pages, and
|
|
1976
|
-
* the kinds Hugo disables are the same on every site.
|
|
1977
|
-
*
|
|
1978
|
-
* **Each gate is reported and the run stops at the first that fires.** They are
|
|
1979
|
-
* ordered so the report names the cause rather than its symptoms: an unusable
|
|
1980
|
-
* manifest, reported after the links that failed because of it, reads as a pile
|
|
1981
|
-
* of broken notes.
|
|
2040
|
+
* compiled into packs. `site build` renders the tree and `site serve` serves it
|
|
2041
|
+
* with live rebuilds; a bare `site` names them.
|
|
1982
2042
|
*
|
|
1983
2043
|
* @returns {object} The yargs command module.
|
|
1984
2044
|
*/
|
|
@@ -1986,163 +2046,185 @@ function stageSiteFonts(config) {
|
|
|
1986
2046
|
function siteCommand() {
|
|
1987
2047
|
return {
|
|
1988
2048
|
command: "site",
|
|
1989
|
-
describe: "
|
|
1990
|
-
builder: () =>
|
|
1991
|
-
|
|
2049
|
+
describe: "Render the content tree as a website",
|
|
2050
|
+
builder: (yargs) =>
|
|
2051
|
+
yargs
|
|
2052
|
+
.command(
|
|
2053
|
+
withIndexPreflight(
|
|
2054
|
+
withBodyPreflight(siteBuildCommand()),
|
|
2055
|
+
publishesContentPages,
|
|
2056
|
+
),
|
|
2057
|
+
)
|
|
2058
|
+
.command(
|
|
2059
|
+
withIndexPreflight(
|
|
2060
|
+
withBodyPreflight(siteServeCommand()),
|
|
2061
|
+
publishesContentPages,
|
|
2062
|
+
),
|
|
2063
|
+
)
|
|
2064
|
+
.demandCommand(1, "Name a site command: build or serve."),
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
/**
|
|
2069
|
+
* Report what the layouts, or the build's section gate, found about a site.
|
|
2070
|
+
*
|
|
2071
|
+
* A finding about a site parameter is located at the configuration's
|
|
2072
|
+
* `site.<param>` entry; one about a page, at the note the page was written
|
|
2073
|
+
* from.
|
|
2074
|
+
*
|
|
2075
|
+
* @param {readonly object[]} findings - The findings.
|
|
2076
|
+
*/
|
|
2077
|
+
function reportSiteFindings(findings) {
|
|
2078
|
+
const configFile = packConfigPath();
|
|
2079
|
+
const configText = fs.existsSync(configFile) ? fs.readFileSync(configFile, "utf8") : "";
|
|
2080
|
+
for (const finding of findings) {
|
|
2081
|
+
if (finding.param) {
|
|
2082
|
+
emitDiagnostic({
|
|
2083
|
+
file: path.relative(process.cwd(), configFile),
|
|
2084
|
+
...positionOfYamlPath(configText, ["site", ...finding.param]),
|
|
2085
|
+
severity: finding.severity,
|
|
2086
|
+
message: finding.message,
|
|
2087
|
+
});
|
|
2088
|
+
} else {
|
|
2089
|
+
emitDiagnostic({
|
|
2090
|
+
file: finding.file ?? finding.page,
|
|
2091
|
+
severity: finding.severity,
|
|
2092
|
+
message: finding.message,
|
|
2093
|
+
});
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
/**
|
|
2099
|
+
* `package-build site build` — render the content tree as a website.
|
|
2100
|
+
*
|
|
2101
|
+
* Every page is drawn by the site theme from the shared renderer's HTML and
|
|
2102
|
+
* written under `<out>/<package>/`, with `404.html`, `sitemap.xml`, the
|
|
2103
|
+
* theme's stylesheets, scripts and fonts and the package's script fonts.
|
|
2104
|
+
* `_headers` is then written beside it and the search index built inside it,
|
|
2105
|
+
* as `package-build site-root` does. The site's settings and cached menu are
|
|
2106
|
+
* read before the tree, so a site that cannot be described fails with the
|
|
2107
|
+
* last good one still in place.
|
|
2108
|
+
*
|
|
2109
|
+
* @returns {object} The yargs command module.
|
|
2110
|
+
*/
|
|
2111
|
+
function siteBuildCommand() {
|
|
2112
|
+
return {
|
|
2113
|
+
command: "build",
|
|
2114
|
+
describe: "Render the content tree as a website and index it for search",
|
|
2115
|
+
builder: (yargs) =>
|
|
2116
|
+
yargs.option("out", {
|
|
2117
|
+
type: "string",
|
|
2118
|
+
describe: `The directory that is deployed (default: ${DEPLOY_ROOT})`,
|
|
2119
|
+
}),
|
|
2120
|
+
handler: async (argv) => {
|
|
1992
2121
|
try {
|
|
1993
|
-
const config = loadPackConfig();
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
//
|
|
1998
|
-
//
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
config,
|
|
2002
|
-
sqlTables: await prepareTreeSqlTables(config.paths.content, {
|
|
2003
|
-
skipDirectories: config.skipDirectories,
|
|
2004
|
-
config,
|
|
2005
|
-
audience: "public",
|
|
2006
|
-
}),
|
|
2007
|
-
});
|
|
2008
|
-
const { gates } = result;
|
|
2009
|
-
|
|
2010
|
-
// First, because it is decided before the tree is walked and
|
|
2011
|
-
// before the output is cleared: a package with no front page,
|
|
2012
|
-
// or two competing for it, has nothing to say about its pages
|
|
2013
|
-
// yet.
|
|
2014
|
-
for (const f of gates.homepages) emitDiagnostic(f);
|
|
2015
|
-
for (const f of gates.frontmatterLinks) {
|
|
2016
|
-
emitDiagnostic({
|
|
2017
|
-
file: f.file,
|
|
2018
|
-
severity: "error",
|
|
2019
|
-
message:
|
|
2020
|
-
`wikilink ${f.link} authored in frontmatter at ` +
|
|
2021
|
-
`${f.path} — frontmatter is data, is copied to the ` +
|
|
2022
|
-
`page verbatim, and reaches the reader as brackets`,
|
|
2023
|
-
});
|
|
2024
|
-
}
|
|
2025
|
-
for (const f of gates.addressErrors) {
|
|
2026
|
-
emitDiagnostic({
|
|
2027
|
-
file: f.file,
|
|
2028
|
-
severity: "error",
|
|
2029
|
-
message: `cannot derive a URL: ${f.reason}`,
|
|
2030
|
-
});
|
|
2031
|
-
}
|
|
2032
|
-
for (const s of gates.staleManifests) {
|
|
2033
|
-
emitDiagnostic({
|
|
2034
|
-
file: cachedIndexPath(loadPackConfig(), s.package),
|
|
2035
|
-
severity: "error",
|
|
2036
|
-
message: `unusable content index: ${s.reason}`,
|
|
2037
|
-
});
|
|
2038
|
-
}
|
|
2039
|
-
for (const f of gates.unaddressable) {
|
|
2040
|
-
console.error(formatUnaddressable(f, loadPackConfig()));
|
|
2041
|
-
}
|
|
2042
|
-
if (gatesFailed(gates)) {
|
|
2122
|
+
const config = argv[CONTENT_CONFIG] ?? loadPackConfig();
|
|
2123
|
+
const root = path.resolve(config.rootDir, argv.out ?? DEPLOY_ROOT);
|
|
2124
|
+
const out = siteDirectory(config, root);
|
|
2125
|
+
const result = await buildPackageSite({ config, out });
|
|
2126
|
+
// A note in error is written as its page shows it, and the
|
|
2127
|
+
// build fails without indexing a site that is not to be
|
|
2128
|
+
// deployed.
|
|
2129
|
+
if (!reportSiteBuild(result.built) || !result.written) {
|
|
2043
2130
|
process.exitCode = 1;
|
|
2044
2131
|
return;
|
|
2045
2132
|
}
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
// before anything is emitted would make a single bad table
|
|
2050
|
-
// hide every other problem in the tree.
|
|
2051
|
-
// `file:line:column: error: message`, path first — the same
|
|
2052
|
-
// shape the pack build and the wikilink findings below use. It
|
|
2053
|
-
// was prose with a timestamp where a parser reads the path,
|
|
2054
|
-
// which made one authored table produce a machine-readable
|
|
2055
|
-
// diagnostic from one build and something ungreppable from the
|
|
2056
|
-
// other.
|
|
2057
|
-
for (const e of result.tableErrors) {
|
|
2058
|
-
emitDiagnostic({
|
|
2059
|
-
file: e.source,
|
|
2060
|
-
line: typeof e.line === "number" ? e.line + 1 : undefined,
|
|
2061
|
-
column: e.column,
|
|
2062
|
-
severity: "error",
|
|
2063
|
-
message: e.reason,
|
|
2064
|
-
});
|
|
2065
|
-
}
|
|
2066
|
-
for (const e of result.expressionErrors) {
|
|
2067
|
-
emitDiagnostic(e);
|
|
2068
|
-
}
|
|
2069
|
-
for (const e of result.secretErrors) {
|
|
2070
|
-
emitDiagnostic({ ...e, severity: "error" });
|
|
2071
|
-
}
|
|
2072
|
-
for (const e of result.captionErrors) {
|
|
2073
|
-
emitDiagnostic({ ...e, severity: "error" });
|
|
2074
|
-
}
|
|
2075
|
-
for (const e of result.headingErrors) {
|
|
2076
|
-
emitDiagnostic({ ...e, severity: "error" });
|
|
2077
|
-
}
|
|
2078
|
-
for (const e of result.footnoteErrors) {
|
|
2079
|
-
emitDiagnostic({ ...e, severity: "error" });
|
|
2080
|
-
}
|
|
2081
|
-
for (const e of result.embedErrors) {
|
|
2082
|
-
emitDiagnostic({ ...e, severity: "error" });
|
|
2083
|
-
}
|
|
2084
|
-
// Reported the way the pack build reports the very same
|
|
2085
|
-
// finding: `file:line:column: error: message`, path first, and
|
|
2086
|
-
// the message from the shared table, not a
|
|
2087
|
-
// `log.error` whose timestamp prefix sat where a parser reads
|
|
2088
|
-
// the path from, and whose text named a `reason` code rather
|
|
2089
|
-
// than saying what to do — so one authored link produced a
|
|
2090
|
-
// machine-readable diagnostic from one build and prose from
|
|
2091
|
-
// another.
|
|
2092
|
-
for (const e of result.wikiErrors) {
|
|
2093
|
-
emitDiagnostic({
|
|
2094
|
-
file: e.file,
|
|
2095
|
-
...positionOfLiteral(readRawNote(e.file), e.link, e.occurrence),
|
|
2096
|
-
severity: "error",
|
|
2097
|
-
// An embed's directive speaks the image vocabulary
|
|
2098
|
-
// rather than the link one, and carries its own
|
|
2099
|
-
// sentence; everything else is worded by the shared
|
|
2100
|
-
// table.
|
|
2101
|
-
message: e.message ?? linkFindingMessage(e),
|
|
2102
|
-
});
|
|
2103
|
-
}
|
|
2104
|
-
// An image whose pathname the site cannot resolve, located the
|
|
2105
|
-
// way a wikilink finding is: by searching the note for the
|
|
2106
|
-
// literal the resolver was handed. The page is written either
|
|
2107
|
-
// way — a missing picture is visible, and stopping before the
|
|
2108
|
-
// write would hide every other finding in the tree behind one
|
|
2109
|
-
// address.
|
|
2110
|
-
for (const e of result.imageErrors) {
|
|
2111
|
-
emitDiagnostic({
|
|
2112
|
-
file: e.file,
|
|
2113
|
-
...positionOfLiteral(readRawNote(e.file), e.src, e.occurrence),
|
|
2114
|
-
severity: "error",
|
|
2115
|
-
message: e.message,
|
|
2116
|
-
});
|
|
2117
|
-
}
|
|
2118
|
-
if (
|
|
2119
|
-
result.tableErrors.length ||
|
|
2120
|
-
result.expressionErrors.length ||
|
|
2121
|
-
result.secretErrors.length ||
|
|
2122
|
-
result.captionErrors.length ||
|
|
2123
|
-
result.headingErrors.length ||
|
|
2124
|
-
result.footnoteErrors.length ||
|
|
2125
|
-
result.wikiErrors.length ||
|
|
2126
|
-
result.imageErrors.length ||
|
|
2127
|
-
result.embedErrors.length
|
|
2128
|
-
) {
|
|
2133
|
+
reportSiteFindings(result.written.findings);
|
|
2134
|
+
for (const finding of result.fonts.findings) emitDiagnostic(finding);
|
|
2135
|
+
if (result.fonts.findings.length) {
|
|
2129
2136
|
process.exitCode = 1;
|
|
2130
2137
|
return;
|
|
2131
2138
|
}
|
|
2132
|
-
|
|
2133
|
-
// Relation warnings do not fail a site build.
|
|
2134
|
-
for (const f of result.mapFindings) emitDiagnostic(f);
|
|
2135
|
-
|
|
2136
|
-
const s = result.stats;
|
|
2137
2139
|
log.info(
|
|
2138
|
-
`wrote ${
|
|
2139
|
-
`${
|
|
2140
|
-
`${s.maps ?? 0} with a map, to ` +
|
|
2141
|
-
`${path.relative(process.cwd(), s.out)}`,
|
|
2140
|
+
`wrote ${result.written.pages.length} page(s) to ` +
|
|
2141
|
+
`${path.relative(process.cwd(), out)}`,
|
|
2142
2142
|
);
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2143
|
+
if (result.fonts.count)
|
|
2144
|
+
log.info(
|
|
2145
|
+
`wrote ${result.fonts.count} script font file(s) to ` +
|
|
2146
|
+
`${path.relative(process.cwd(), result.fonts.dest)}`,
|
|
2147
|
+
);
|
|
2148
|
+
const { search } = await writeSiteRoot({
|
|
2149
|
+
pkg: config.contentPackage,
|
|
2150
|
+
base: siteBase(config),
|
|
2151
|
+
out: root,
|
|
2152
|
+
search: config.site.search,
|
|
2153
|
+
});
|
|
2154
|
+
if (search) {
|
|
2155
|
+
log.info(
|
|
2156
|
+
`indexed ${search.pages} page(s) for search into ` +
|
|
2157
|
+
`${path.relative(process.cwd(), search.dir)}`,
|
|
2158
|
+
);
|
|
2159
|
+
}
|
|
2160
|
+
} catch (err) {
|
|
2161
|
+
reportFailure(err);
|
|
2162
|
+
process.exitCode = 1;
|
|
2163
|
+
}
|
|
2164
|
+
},
|
|
2165
|
+
};
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
/**
|
|
2169
|
+
* `package-build site serve` — serve the website, and keep it current.
|
|
2170
|
+
*
|
|
2171
|
+
* The site is built as `site build` builds it, served from the deployed root,
|
|
2172
|
+
* and written again as the content tree or the theme changes; every open page
|
|
2173
|
+
* reloads when it is. Runs until interrupted.
|
|
2174
|
+
*
|
|
2175
|
+
* @returns {object} The yargs command module.
|
|
2176
|
+
*/
|
|
2177
|
+
function siteServeCommand() {
|
|
2178
|
+
return {
|
|
2179
|
+
command: "serve",
|
|
2180
|
+
describe: "Serve the website, and rebuild and reload it as its sources change",
|
|
2181
|
+
builder: (yargs) =>
|
|
2182
|
+
yargs
|
|
2183
|
+
.option("port", {
|
|
2184
|
+
type: "number",
|
|
2185
|
+
default: 1313,
|
|
2186
|
+
describe: "The port to listen on",
|
|
2187
|
+
})
|
|
2188
|
+
.option("host", {
|
|
2189
|
+
type: "string",
|
|
2190
|
+
default: "127.0.0.1",
|
|
2191
|
+
describe: "The address to listen on",
|
|
2192
|
+
})
|
|
2193
|
+
.option("out", {
|
|
2194
|
+
type: "string",
|
|
2195
|
+
describe: `The directory the site is written to (default: ${DEPLOY_ROOT})`,
|
|
2196
|
+
}),
|
|
2197
|
+
handler: async (argv) => {
|
|
2198
|
+
try {
|
|
2199
|
+
const config = argv[CONTENT_CONFIG] ?? loadPackConfig();
|
|
2200
|
+
const root = path.resolve(config.rootDir, argv.out ?? DEPLOY_ROOT);
|
|
2201
|
+
const served = await serveSite({
|
|
2202
|
+
config,
|
|
2203
|
+
root,
|
|
2204
|
+
out: siteDirectory(config, root),
|
|
2205
|
+
host: argv.host,
|
|
2206
|
+
port: argv.port,
|
|
2207
|
+
report: (event) => {
|
|
2208
|
+
if (event.kind === "error") reportFailure(event.error);
|
|
2209
|
+
else if (event.kind === "failed") {
|
|
2210
|
+
if (event.built) reportSiteBuild(event.built);
|
|
2211
|
+
for (const finding of event.findings ?? []) emitDiagnostic(finding);
|
|
2212
|
+
} else {
|
|
2213
|
+
reportSiteFindings(event.findings ?? []);
|
|
2214
|
+
log.info(
|
|
2215
|
+
event.kind === "built" ? "built the site"
|
|
2216
|
+
: event.kind === "theme" ? "drew every page again"
|
|
2217
|
+
: `wrote ${event.files.map((f) => path.relative(process.cwd(), f)).join(", ")}`,
|
|
2218
|
+
);
|
|
2219
|
+
}
|
|
2220
|
+
},
|
|
2221
|
+
});
|
|
2222
|
+
log.info(`serving ${served.url} — interrupt to stop`);
|
|
2223
|
+
await new Promise((resolve) => {
|
|
2224
|
+
process.once("SIGINT", resolve);
|
|
2225
|
+
process.once("SIGTERM", resolve);
|
|
2226
|
+
});
|
|
2227
|
+
await served.close();
|
|
2146
2228
|
} catch (err) {
|
|
2147
2229
|
reportFailure(err);
|
|
2148
2230
|
process.exitCode = 1;
|
|
@@ -2397,7 +2479,7 @@ function transliterateCommand() {
|
|
|
2397
2479
|
default: false,
|
|
2398
2480
|
describe: "Print the code points, as `U+XXXX` separated by spaces",
|
|
2399
2481
|
}),
|
|
2400
|
-
handler: (argv) => {
|
|
2482
|
+
handler: async (argv) => {
|
|
2401
2483
|
try {
|
|
2402
2484
|
const read = mappingContext();
|
|
2403
2485
|
if (!read) {
|
|
@@ -2407,7 +2489,7 @@ function transliterateCommand() {
|
|
|
2407
2489
|
const words = (argv.text ?? []).map(String);
|
|
2408
2490
|
const text =
|
|
2409
2491
|
!words.length || (words.length === 1 && words[0] === "-") ?
|
|
2410
|
-
|
|
2492
|
+
(await readStdin()).replace(/\r?\n$/, "")
|
|
2411
2493
|
: words.join(" ");
|
|
2412
2494
|
const mapped = transliterate(
|
|
2413
2495
|
read.ctx,
|
|
@@ -2437,7 +2519,11 @@ function transliterateCommand() {
|
|
|
2437
2519
|
|
|
2438
2520
|
/**
|
|
2439
2521
|
* `package-build lexicon <language> --map <map>` — every word of a language's
|
|
2440
|
-
* lexicon with its native form under a map, as the build writes it
|
|
2522
|
+
* lexicon with its native form under a map, as the build writes it; with
|
|
2523
|
+
* `--derived`, the forms its rules derive follow, each naming its word in a
|
|
2524
|
+
* sixth column. Under a logographic map the third column says where a
|
|
2525
|
+
* word's writing comes from, `own` or `parts`, or marks it `none` or
|
|
2526
|
+
* `ambiguous`.
|
|
2441
2527
|
*
|
|
2442
2528
|
* @returns {object} The yargs command module.
|
|
2443
2529
|
*/
|
|
@@ -2461,6 +2547,12 @@ function lexiconCommand() {
|
|
|
2461
2547
|
type: "string",
|
|
2462
2548
|
describe: "The face; required when the map lists more than one",
|
|
2463
2549
|
})
|
|
2550
|
+
.option("derived", {
|
|
2551
|
+
type: "boolean",
|
|
2552
|
+
default: false,
|
|
2553
|
+
describe:
|
|
2554
|
+
"Also list the forms the language's rules derive, each beside its lexicon word",
|
|
2555
|
+
})
|
|
2464
2556
|
.option("json", {
|
|
2465
2557
|
type: "boolean",
|
|
2466
2558
|
default: false,
|
|
@@ -2477,6 +2569,7 @@ function lexiconCommand() {
|
|
|
2477
2569
|
lang: String(argv.language),
|
|
2478
2570
|
map: String(argv.map),
|
|
2479
2571
|
font: argv.font,
|
|
2572
|
+
derived: Boolean(argv.derived),
|
|
2480
2573
|
});
|
|
2481
2574
|
if ("problem" in listed) {
|
|
2482
2575
|
reportMapping(read.config, listed);
|
|
@@ -2489,9 +2582,15 @@ function lexiconCommand() {
|
|
|
2489
2582
|
[
|
|
2490
2583
|
entry.form,
|
|
2491
2584
|
entry.native,
|
|
2492
|
-
entry.
|
|
2585
|
+
entry.source === undefined ?
|
|
2586
|
+
entry.exception ?
|
|
2587
|
+
"exception"
|
|
2588
|
+
: "rows"
|
|
2589
|
+
: entry.ambiguous ? "ambiguous"
|
|
2590
|
+
: entry.source,
|
|
2493
2591
|
entry.class ?? "",
|
|
2494
2592
|
entry.gloss ?? "",
|
|
2593
|
+
...(argv.derived ? [entry.from ?? ""] : []),
|
|
2495
2594
|
].join("\t"),
|
|
2496
2595
|
);
|
|
2497
2596
|
} catch (err) {
|
|
@@ -2502,6 +2601,64 @@ function lexiconCommand() {
|
|
|
2502
2601
|
};
|
|
2503
2602
|
}
|
|
2504
2603
|
|
|
2604
|
+
/**
|
|
2605
|
+
* `package-build core [--language <name>] [--json]` — the concepts of the core
|
|
2606
|
+
* vocabulary each covering language has no word for, by group.
|
|
2607
|
+
*
|
|
2608
|
+
* @returns {object} The yargs command module.
|
|
2609
|
+
*/
|
|
2610
|
+
// eslint-disable-next-line
|
|
2611
|
+
function coreCommand() {
|
|
2612
|
+
return {
|
|
2613
|
+
command: "core",
|
|
2614
|
+
describe: "List the core concepts each covering language has no word for",
|
|
2615
|
+
builder: (yargs) =>
|
|
2616
|
+
yargs
|
|
2617
|
+
.option("language", {
|
|
2618
|
+
type: "string",
|
|
2619
|
+
describe:
|
|
2620
|
+
"Report this language alone, by its name, shortcode or reference, whether or not it states `data.core`",
|
|
2621
|
+
})
|
|
2622
|
+
.option("json", {
|
|
2623
|
+
type: "boolean",
|
|
2624
|
+
default: false,
|
|
2625
|
+
describe: "Print the report as JSON",
|
|
2626
|
+
}),
|
|
2627
|
+
handler: (argv) => {
|
|
2628
|
+
try {
|
|
2629
|
+
const config = loadPackConfig();
|
|
2630
|
+
const problems = [];
|
|
2631
|
+
const records = indexRecordsFor({
|
|
2632
|
+
contentBase: config.paths.content,
|
|
2633
|
+
config,
|
|
2634
|
+
skipDirectories: config.skipDirectories,
|
|
2635
|
+
problems,
|
|
2636
|
+
});
|
|
2637
|
+
for (const problem of problems) emitDiagnostic(problem);
|
|
2638
|
+
if (problems.length) {
|
|
2639
|
+
process.exitCode = 1;
|
|
2640
|
+
return;
|
|
2641
|
+
}
|
|
2642
|
+
const report = coreReport(records, { language: argv.language });
|
|
2643
|
+
if ("problem" in report) {
|
|
2644
|
+
emitDiagnostic({
|
|
2645
|
+
file: config.paths.content,
|
|
2646
|
+
severity: "error",
|
|
2647
|
+
message: report.problem,
|
|
2648
|
+
});
|
|
2649
|
+
process.exitCode = 1;
|
|
2650
|
+
return;
|
|
2651
|
+
}
|
|
2652
|
+
if (argv.json) console.log(JSON.stringify(report, null, 2));
|
|
2653
|
+
else process.stdout.write(coreReportText(report));
|
|
2654
|
+
} catch (err) {
|
|
2655
|
+
reportFailure(err);
|
|
2656
|
+
process.exitCode = 1;
|
|
2657
|
+
}
|
|
2658
|
+
},
|
|
2659
|
+
};
|
|
2660
|
+
}
|
|
2661
|
+
|
|
2505
2662
|
/**
|
|
2506
2663
|
* `package-build reachability <dir> [file]` — check that a corpus reads through.
|
|
2507
2664
|
*
|