@heroiclands/package-build 23.11.0 → 23.12.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 +21 -0
- package/README.md +1 -0
- package/assets/preview/check-sanitizer.go +68 -0
- package/assets/preview/gitea-theme.js +36 -0
- package/assets/preview/gitea.ini +127 -0
- package/assets/styles/content-base.css +119 -16
- package/bin/content-commands.mjs +2 -2
- package/bin/package-build-preview.mjs +75 -0
- package/content-config.mjs +11 -0
- package/docs/api.md +105 -46
- package/docs/authoring/links-and-markup.md +46 -11
- package/docs/commands.md +46 -2
- package/docs/configuration.md +21 -4
- package/docs/design.md +4 -3
- package/docs/guides/book.md +10 -6
- package/docs/reference/format-details.md +33 -34
- package/docs/reference/note-types.md +0 -1
- package/docs/reference/theme-pages.md +1 -1
- package/docs/source-preview.md +172 -0
- package/engine/base-compiler.mjs +7 -8
- package/engine/being-age.mjs +19 -105
- package/engine/calendar-notes.mjs +3 -25
- package/engine/compile-corpus.mjs +2 -1
- package/engine/content-format.yaml +0 -1
- package/engine/content-index.mjs +9 -9
- package/engine/content-spans.mjs +28 -6
- package/engine/current-date.mjs +37 -0
- package/engine/definition-list.mjs +58 -0
- package/engine/frontmatter-lint.mjs +7 -2
- package/engine/helpers.mjs +2 -0
- package/engine/index.mjs +2 -0
- package/engine/infobox.mjs +1 -5
- package/engine/note-vocabulary.mjs +2 -2
- package/engine/npc-generate.mjs +7 -6
- package/engine/pdf-render.mjs +37 -4
- package/engine/preview-current-date.mjs +60 -0
- package/engine/site-build.mjs +5 -5
- package/engine/site-index.mjs +5 -2
- package/engine/site-preview.mjs +641 -325
- package/hugo-theme/layouts/_default/list.html +1 -1
- package/hugo-theme/layouts/blog/list.html +1 -1
- package/hugo-theme/layouts/blog-post/single.html +1 -1
- package/hugo-theme/layouts/partials/dictionary-lists.html +53 -0
- package/hugo-theme/layouts/partials/page-body.html +1 -1
- package/hugo-theme/static/css/style.css +22 -8
- package/package.json +8 -2
- package/types/content-config.d.mts +8 -0
- package/types/engine/base-compiler.d.mts +1 -1
- package/types/engine/being-age.d.mts +10 -44
- package/types/engine/calendar-notes.d.mts +2 -6
- package/types/engine/compile-corpus.d.mts +2 -1
- package/types/engine/content-index.d.mts +3 -1
- package/types/engine/content-spans.d.mts +4 -2
- package/types/engine/current-date.d.mts +9 -0
- package/types/engine/definition-list.d.mts +8 -0
- package/types/engine/frontmatter-lint.d.mts +6 -2
- package/types/engine/index.d.mts +2 -0
- package/types/engine/npc-generate.d.mts +2 -2
- package/types/engine/preview-current-date.d.mts +8 -0
- package/types/engine/site-index.d.mts +5 -1
- package/types/engine/site-preview.d.mts +40 -33
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{{- /* Group the final Goldmark HTML. Quote-aware tokens preserve attributes,
|
|
2
|
+
literal examples, comments and raw blocks; a stack gives each nested list
|
|
3
|
+
its own rows. Existing grouped lists keep their authored divs. */ -}}
|
|
4
|
+
{{- $source := string . -}}
|
|
5
|
+
{{- if not (findRE `(?i)<dl(?:\s|>)` $source) -}}{{- return ($source | safeHTML) -}}{{- end -}}
|
|
6
|
+
{{- $pattern := `(?is)<!--.*?-->|<script\b(?:[^"'<>]|"[^"]*"|'[^']*')*>.*?</script\s*>|<style\b(?:[^"'<>]|"[^"]*"|'[^']*')*>.*?</style\s*>|<pre\b(?:[^"'<>]|"[^"]*"|'[^']*')*>.*?</pre\s*>|<textarea\b(?:[^"'<>]|"[^"]*"|'[^']*')*>.*?</textarea\s*>|<![^>]*>|</?[a-z][a-z0-9:-]*(?:[^"'<>]|"[^"]*"|'[^']*')*>|[^<]+|<` -}}
|
|
7
|
+
{{- $parts := slice -}}
|
|
8
|
+
{{- $lists := slice -}}
|
|
9
|
+
{{- $elements := slice -}}
|
|
10
|
+
{{- $tokens := findRE $pattern $source -}}
|
|
11
|
+
{{- range $i, $token := $tokens -}}
|
|
12
|
+
{{- if and (gt (len $lists) 0) (gt $i 0) (lt (add $i 1) (len $tokens)) (findRE `^\s+$` $token) (findRE `(?i)^</dt\s*>$` (index $tokens (sub $i 1))) (findRE `(?i)^<dd(?:\s|>)` (index $tokens (add $i 1))) -}}
|
|
13
|
+
{{- $token = "" -}}
|
|
14
|
+
{{- end -}}
|
|
15
|
+
{{- if and (gt (len $lists) 0) (gt $i 0) (lt (add $i 1) (len $tokens)) (findRE `^\s+$` $token) (findRE `(?i)^<dd(?:\s[^>]*)?>$` (index $tokens (sub $i 1))) (findRE `(?i)^<p(?:\s|>)` (index $tokens (add $i 1))) -}}
|
|
16
|
+
{{- $token = "" -}}
|
|
17
|
+
{{- end -}}
|
|
18
|
+
{{- $tag := "" -}}
|
|
19
|
+
{{- $opaque := findRE `(?i)^<(?:!--|script\b|style\b|pre\b|textarea\b)` $token -}}
|
|
20
|
+
{{- if and (not $opaque) (findRE `(?i)^</?[a-z]` $token) -}}
|
|
21
|
+
{{- $tag = lower (replaceRE `(?is)^</?([a-z][a-z0-9:-]*).*` "$1" $token) -}}
|
|
22
|
+
{{- $closing := hasPrefix $token "</" -}}
|
|
23
|
+
{{- if and (eq $tag "dl") (not $closing) -}}
|
|
24
|
+
{{- $list := newScratch -}}
|
|
25
|
+
{{- $list.Set "row" false -}}
|
|
26
|
+
{{- $lists = $lists | append $list -}}
|
|
27
|
+
{{- if or (findRE `(?i)\sclass\s*=\s*["'](?:[^"']*\s)?dictionary(?:\s|["'])` $token) (findRE `(?i)\sclass\s*=\s*dictionary(?:\s|>)` $token) -}}
|
|
28
|
+
{{- else if findRE `(?i)\sclass\s*=\s*["']` $token -}}
|
|
29
|
+
{{- $token = replaceRE `(?i)(\sclass\s*=\s*["'])` "${1}dictionary " $token -}}
|
|
30
|
+
{{- else if findRE `(?i)\sclass\s*=` $token -}}
|
|
31
|
+
{{- $token = replaceRE `(?i)(\sclass\s*=\s*)([^\s>]+)` `${1}"dictionary ${2}"` $token -}}
|
|
32
|
+
{{- else -}}
|
|
33
|
+
{{- $token = replaceRE `(?i)^<dl` `<dl class="dictionary"` $token -}}
|
|
34
|
+
{{- end -}}
|
|
35
|
+
{{- else if and (eq $tag "dt") (not $closing) (gt (len $lists) 0) (eq (index $elements (sub (len $elements) 1)) "dl") -}}
|
|
36
|
+
{{- $list := index $lists (sub (len $lists) 1) -}}
|
|
37
|
+
{{- if $list.Get "row" -}}{{- $parts = $parts | append "</div>" -}}{{- end -}}
|
|
38
|
+
{{- $parts = $parts | append "<div>" -}}
|
|
39
|
+
{{- $list.Set "row" true -}}
|
|
40
|
+
{{- else if and (eq $tag "dl") $closing (gt (len $lists) 0) -}}
|
|
41
|
+
{{- $list := index $lists (sub (len $lists) 1) -}}
|
|
42
|
+
{{- if $list.Get "row" -}}{{- $parts = $parts | append "</div>" -}}{{- end -}}
|
|
43
|
+
{{- $lists = first (sub (len $lists) 1) $lists -}}
|
|
44
|
+
{{- end -}}
|
|
45
|
+
{{- if $closing -}}
|
|
46
|
+
{{- if gt (len $elements) 0 -}}{{- $elements = first (sub (len $elements) 1) $elements -}}{{- end -}}
|
|
47
|
+
{{- else if not (or (findRE `/\s*>$` $token) (in (slice "area" "base" "br" "col" "embed" "hr" "img" "input" "link" "meta" "param" "source" "track" "wbr") $tag)) -}}
|
|
48
|
+
{{- $elements = $elements | append $tag -}}
|
|
49
|
+
{{- end -}}
|
|
50
|
+
{{- end -}}
|
|
51
|
+
{{- $parts = $parts | append $token -}}
|
|
52
|
+
{{- end -}}
|
|
53
|
+
{{- return (delimit $parts "" | safeHTML) -}}
|
|
@@ -2955,20 +2955,21 @@ summary.info-sidebar-title::after {
|
|
|
2955
2955
|
}
|
|
2956
2956
|
}
|
|
2957
2957
|
|
|
2958
|
-
/*
|
|
2958
|
+
/* Author alerts use the dark palette of this site's single-mode theme. */
|
|
2959
2959
|
.single-content .alert {
|
|
2960
2960
|
border-inline-start: 0.25rem solid var(--pb-alert-color);
|
|
2961
|
-
|
|
2961
|
+
border-radius: 0.375rem;
|
|
2962
|
+
padding: 1rem;
|
|
2962
2963
|
margin: 1rem 0;
|
|
2963
|
-
color:
|
|
2964
|
-
background:
|
|
2964
|
+
color: #e6edf3;
|
|
2965
|
+
background: var(--pb-alert-background);
|
|
2965
2966
|
}
|
|
2966
2967
|
.single-content .alert-title {
|
|
2967
2968
|
display: flex;
|
|
2968
2969
|
align-items: center;
|
|
2969
2970
|
gap: 0.5em;
|
|
2970
2971
|
margin: 0 0 0.5rem;
|
|
2971
|
-
font-weight:
|
|
2972
|
+
font-weight: 700;
|
|
2972
2973
|
color: var(--pb-alert-color);
|
|
2973
2974
|
}
|
|
2974
2975
|
.single-content .alert-icon {
|
|
@@ -2981,16 +2982,20 @@ summary.info-sidebar-title::after {
|
|
|
2981
2982
|
margin-bottom: 0;
|
|
2982
2983
|
}
|
|
2983
2984
|
.single-content .alert-note {
|
|
2984
|
-
--pb-alert-color: #
|
|
2985
|
+
--pb-alert-color: #58a6ff;
|
|
2986
|
+
--pb-alert-background: #101a28;
|
|
2985
2987
|
}
|
|
2986
2988
|
.single-content .alert-tip {
|
|
2987
|
-
--pb-alert-color: #
|
|
2989
|
+
--pb-alert-color: #7ee787;
|
|
2990
|
+
--pb-alert-background: #102018;
|
|
2988
2991
|
}
|
|
2989
2992
|
.single-content .alert-important {
|
|
2990
|
-
--pb-alert-color: #
|
|
2993
|
+
--pb-alert-color: #c4b0ff;
|
|
2994
|
+
--pb-alert-background: #1c172a;
|
|
2991
2995
|
}
|
|
2992
2996
|
.single-content .alert-warning {
|
|
2993
2997
|
--pb-alert-color: #d29922;
|
|
2998
|
+
--pb-alert-background: #241d10;
|
|
2994
2999
|
}
|
|
2995
3000
|
|
|
2996
3001
|
/* Inline spoiler controls remain inline, with links outside the button. */
|
|
@@ -3008,3 +3013,12 @@ summary.info-sidebar-title::after {
|
|
|
3008
3013
|
}
|
|
3009
3014
|
.inline-secret-toggle:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
|
|
3010
3015
|
.inline-secret-content { margin-inline-start: 0.25em; }
|
|
3016
|
+
|
|
3017
|
+
/* Authored definition lists use dictionary rows; profile grids remain separate. */
|
|
3018
|
+
.single-body .dictionary { --indent:150px; --gap:.75em; margin:0; display:block; }
|
|
3019
|
+
.single-body .dictionary > div { padding-left:var(--indent); text-indent:calc(-1 * var(--indent)); margin-bottom:.5em; }
|
|
3020
|
+
.single-body .dictionary > div > dt { display:inline-block; min-width:calc(var(--indent) - var(--gap)); margin-right:var(--gap); font-weight:bold; white-space:nowrap; text-indent:0; text-align:left; }
|
|
3021
|
+
.single-body .dictionary > div > dd { display:inline; margin:0; font-weight:normal; }
|
|
3022
|
+
.single-body .dictionary > div > dd > :is(p, ul, ol, dl, blockquote, pre, table, div) { text-indent:0; }
|
|
3023
|
+
.single-body .dictionary > div > dd > p:first-child { display:inline; }
|
|
3024
|
+
@media (max-width:600px) { .single-body .dictionary { --indent:100px; } }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heroiclands/package-build",
|
|
3
|
-
"version": "23.
|
|
3
|
+
"version": "23.12.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",
|
|
@@ -35,6 +35,11 @@
|
|
|
35
35
|
"types": "./types/hm3/*.d.mts",
|
|
36
36
|
"import": "./hm3/*.mjs"
|
|
37
37
|
},
|
|
38
|
+
"./preview": {
|
|
39
|
+
"types": "./types/engine/site-preview.d.mts",
|
|
40
|
+
"import": "./engine/site-preview.mjs",
|
|
41
|
+
"default": "./engine/site-preview.mjs"
|
|
42
|
+
},
|
|
38
43
|
"./content-config": {
|
|
39
44
|
"types": "./types/content-config.d.mts",
|
|
40
45
|
"import": "./content-config.mjs"
|
|
@@ -95,7 +100,8 @@
|
|
|
95
100
|
"./package.json": "./package.json"
|
|
96
101
|
},
|
|
97
102
|
"bin": {
|
|
98
|
-
"package-build": "./bin/package-build.mjs"
|
|
103
|
+
"package-build": "./bin/package-build.mjs",
|
|
104
|
+
"package-build-preview": "./bin/package-build-preview.mjs"
|
|
99
105
|
},
|
|
100
106
|
"files": [
|
|
101
107
|
"CHANGELOG-content-build.md",
|
|
@@ -628,6 +628,10 @@ export type ContentBuildConfigInput = {
|
|
|
628
628
|
* depends on the working directory.
|
|
629
629
|
*/
|
|
630
630
|
rootDir: string;
|
|
631
|
+
/**
|
|
632
|
+
* Setting-wide neutral current date; defaults to "720.1".
|
|
633
|
+
*/
|
|
634
|
+
currentDate?: string | undefined;
|
|
631
635
|
/**
|
|
632
636
|
* Content package name — the address
|
|
633
637
|
* namespace every note in this
|
|
@@ -748,6 +752,10 @@ export type ContentBuildConfigInput = {
|
|
|
748
752
|
* The normalized, frozen configuration the toolchain reads.
|
|
749
753
|
*/
|
|
750
754
|
export type ContentBuildConfig = {
|
|
755
|
+
/**
|
|
756
|
+
* Setting-wide neutral current date.
|
|
757
|
+
*/
|
|
758
|
+
currentDate: string;
|
|
751
759
|
rootDir: string;
|
|
752
760
|
contentPackage: string;
|
|
753
761
|
/**
|
|
@@ -358,7 +358,7 @@ export class BasePackCompiler {
|
|
|
358
358
|
reportsCorpusProblems: boolean | undefined;
|
|
359
359
|
linkIndex: any;
|
|
360
360
|
sqlTables: any;
|
|
361
|
-
|
|
361
|
+
currentDate: string | undefined;
|
|
362
362
|
/**
|
|
363
363
|
* Report every finding {@link BasePackCompiler#convertBody} collected
|
|
364
364
|
* across its passes, and decline the note if there were any.
|
|
@@ -15,11 +15,9 @@ export function parseAgeMagnitude(raw: unknown): {
|
|
|
15
15
|
*
|
|
16
16
|
* @param {unknown} bornRaw - The being's authored `born`, or `undefined`/`null`
|
|
17
17
|
* where it wrote none.
|
|
18
|
-
* @param {unknown} presentRaw - The
|
|
19
|
-
* {@link module:engine/calendar-notes.worldInvariants} read it, or
|
|
20
|
-
* `undefined`/`null` where the package states none.
|
|
18
|
+
* @param {unknown} presentRaw - The configured neutral current date.
|
|
21
19
|
* @returns {number|null} The age, or `null` where `born` is `unknown` or
|
|
22
|
-
* absent
|
|
20
|
+
* absent or future, or where either date fails to parse.
|
|
23
21
|
*/
|
|
24
22
|
export function computeAge(bornRaw: unknown, presentRaw: unknown, dateContext?: {}): number | null;
|
|
25
23
|
/**
|
|
@@ -35,58 +33,26 @@ export function computeAge(bornRaw: unknown, presentRaw: unknown, dateContext?:
|
|
|
35
33
|
* itself untouched.
|
|
36
34
|
*
|
|
37
35
|
* @param {object} fm - A note's frontmatter, as freshly parsed.
|
|
38
|
-
* @param {unknown} presentRaw - The
|
|
39
|
-
* `undefined`/`null` where it states none.
|
|
36
|
+
* @param {unknown} presentRaw - The configured neutral current date.
|
|
40
37
|
* @returns {void}
|
|
41
38
|
*/
|
|
42
39
|
export function applyComputedBeingAge(fm: object, presentRaw: unknown, dateContext?: {}): void;
|
|
43
40
|
/**
|
|
44
|
-
*
|
|
45
|
-
* frontmatter objects carries.
|
|
46
|
-
*
|
|
47
|
-
* Two shapes reach this by way of two thin adapters, because the callers that
|
|
48
|
-
* need a present hold their notes two different ways: a flat index record
|
|
49
|
-
* (`type` and `data` at the top level) and a raw walk's `{frontmatter}` pair.
|
|
50
|
-
* Neither shape is the `{fm, type}` pair {@link worldInvariants} reads, so each
|
|
51
|
-
* adapter states the one conversion its caller needs rather than asking every
|
|
52
|
-
* caller to know it.
|
|
53
|
-
*
|
|
54
|
-
* @param {readonly object[]|undefined} records - Flat index records — a
|
|
55
|
-
* content-index record, or anything else spreading a note's frontmatter to
|
|
56
|
-
* its own top level.
|
|
57
|
-
* @returns {unknown} The present, or `null` where no `place` note in the batch
|
|
58
|
-
* declares one.
|
|
59
|
-
*/
|
|
60
|
-
export function presentAmongRecords(records: readonly object[] | undefined): unknown;
|
|
61
|
-
/**
|
|
62
|
-
* The present read from a batch of raw frontmatter objects.
|
|
63
|
-
*
|
|
64
|
-
* @param {readonly (object|null|undefined)[]|undefined} frontmatters - One
|
|
65
|
-
* entry per note walked, as parsed — never a record.
|
|
66
|
-
* @returns {unknown} The present, or `null` where none is declared.
|
|
67
|
-
*/
|
|
68
|
-
export function presentAmongFrontmatters(frontmatters: readonly (object | null | undefined)[] | undefined): unknown;
|
|
69
|
-
/**
|
|
70
|
-
* Check a being's authored `age` against what `born` and the package's present
|
|
71
|
-
* compute.
|
|
41
|
+
* Check an authored age against the birth date and configured current date.
|
|
72
42
|
*
|
|
73
43
|
* Registered as `being`'s whole-note `check` in `note-vocabulary.mjs`, run the
|
|
74
44
|
* way `checkPlace` and `checkCalendarNote` are — beside every other check the
|
|
75
45
|
* closed `data:` container earns, with the same `index`.
|
|
76
46
|
*
|
|
77
|
-
*
|
|
78
|
-
* there is nothing to disagree with, and a package that declares no present
|
|
79
|
-
* computes no age to disagree with either — both cases are read by
|
|
80
|
-
* {@link computeAge} returning `null`, and neither says a word.
|
|
47
|
+
* An unknown or absent birth date supplies no computed age to compare.
|
|
81
48
|
*
|
|
82
|
-
* @param {object} note - The note, as the link index hands it over
|
|
83
|
-
* {@link module:engine/calendar-notes.worldInvariants}'s `index.notes` shape.
|
|
49
|
+
* @param {object} note - The note, as the link index hands it over.
|
|
84
50
|
* @param {object} [opts]
|
|
85
|
-
* @param {object} [opts.index] -
|
|
86
|
-
*
|
|
87
|
-
* index skips reporting every reference as dead.
|
|
51
|
+
* @param {object} [opts.index] - Calendar context for authored birth dates.
|
|
52
|
+
* @param {string} [opts.currentDate="720.1"] - The configured neutral current date.
|
|
88
53
|
* @returns {object[]} Findings — at most one `warning`, naming both values.
|
|
89
54
|
*/
|
|
90
|
-
export function checkBeingAge(note: object, { index }?: {
|
|
55
|
+
export function checkBeingAge(note: object, { index, currentDate }?: {
|
|
91
56
|
index?: object | undefined;
|
|
57
|
+
currentDate?: string | undefined;
|
|
92
58
|
}): object[];
|
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
* note has no year, and every question that depends on one goes unasked.
|
|
6
6
|
*
|
|
7
7
|
* @param {object} [index] - The link index, holding every note in the package.
|
|
8
|
-
* @returns {{year: object|null,
|
|
8
|
+
* @returns {{year: object|null, moon: object|null,
|
|
9
9
|
* body: object|null, moonName: string|null, yearNote: object|null,
|
|
10
10
|
* moonNote: object|null}} What the package's notes state.
|
|
11
11
|
*/
|
|
12
12
|
export function worldInvariants(index?: object): {
|
|
13
13
|
year: object | null;
|
|
14
|
-
present: unknown;
|
|
15
14
|
moon: object | null;
|
|
16
15
|
body: object | null;
|
|
17
16
|
moonName: string | null;
|
|
@@ -41,9 +40,6 @@ export function checkCalendarDateFormats(note: any): {
|
|
|
41
40
|
* - a moon with no year is refused, because a cycle measured in days has
|
|
42
41
|
* nothing to be measured against.
|
|
43
42
|
*
|
|
44
|
-
* `data.present` is read through the parser a note's dates go through, with the
|
|
45
|
-
* corpus in hand, so a present written in an era resolves where it is written.
|
|
46
|
-
*
|
|
47
43
|
* @param {object} note - The note, as the link index hands it over.
|
|
48
44
|
* @param {object} [opts]
|
|
49
45
|
* @param {object} [opts.index] - The link index, holding every note.
|
|
@@ -185,7 +181,7 @@ export const CALENDAR_FIELDS: readonly object[];
|
|
|
185
181
|
* The `data:` keys a world or a celestial body may write.
|
|
186
182
|
*
|
|
187
183
|
* Four groups, and which note carries which is a fact about the body rather
|
|
188
|
-
* than a convention: a planet states its own size, tilt
|
|
184
|
+
* than a convention: a planet states its own size, tilt and year; a
|
|
189
185
|
* moon states its own size, orbit and cycle.
|
|
190
186
|
*
|
|
191
187
|
* @type {readonly object[]}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* the index refuses is a note the compile must still *report*, exactly as the
|
|
17
17
|
* compile loop reported it when the loop was the first to see it.
|
|
18
18
|
* @param {import("./content-session.mjs").ContentSession} [opts.session] - Captured context shared with other operations.
|
|
19
|
-
* @returns {Promise<{records: object[], parsed: Map<string, object>, linkIndex: object, sqlTables: Map<string, object[]>|undefined, problems: object[], syntax?: import("./content-session.mjs").ContentSyntax}>} The corpus,
|
|
19
|
+
* @returns {Promise<{currentDate: string, records: object[], parsed: Map<string, object>, linkIndex: object, sqlTables: Map<string, object[]>|undefined, problems: object[], syntax?: import("./content-session.mjs").ContentSyntax}>} The corpus,
|
|
20
20
|
* its indexes, and the notes it could not record.
|
|
21
21
|
*/
|
|
22
22
|
export function buildCompileCorpus({ contentBase, assetsBase, skipDirectories, router, config, problems, session, }: {
|
|
@@ -28,6 +28,7 @@ export function buildCompileCorpus({ contentBase, assetsBase, skipDirectories, r
|
|
|
28
28
|
problems?: object[] | undefined;
|
|
29
29
|
session?: import("./content-session.mjs").ContentSession | undefined;
|
|
30
30
|
}): Promise<{
|
|
31
|
+
currentDate: string;
|
|
31
32
|
records: object[];
|
|
32
33
|
parsed: Map<string, object>;
|
|
33
34
|
linkIndex: object;
|
|
@@ -234,6 +234,7 @@ export function resolveCultures(records: Array<Record<string, any>>, { contentPa
|
|
|
234
234
|
* asserts that it does not exist. The same holds for a culture conflict: a
|
|
235
235
|
* reader receives each as a finding, and the emitter throws once, listing
|
|
236
236
|
* every one.
|
|
237
|
+
* @param {string} [options.currentDate="720.1"] - Setting-wide neutral current date.
|
|
237
238
|
* @param {(key: string) => ({culture?: unknown}|undefined)} [options.foreignRecord] -
|
|
238
239
|
* Another package's entry for a canonical address, read for a parent that
|
|
239
240
|
* package publishes; see {@link resolveCultures}.
|
|
@@ -246,13 +247,14 @@ export function resolveCultures(records: Array<Record<string, any>>, { contentPa
|
|
|
246
247
|
* @returns {Array<Record<string, any>>} The records, in a total order that does
|
|
247
248
|
* not depend on directory-read order.
|
|
248
249
|
*/
|
|
249
|
-
export function collectContentIndex(contentBase: string, { contentPackage, skipDirectories, assetsBase, manifest, problems, addressContext, foreignRecord, parsed, sources, syntax, nameTypes, }: {
|
|
250
|
+
export function collectContentIndex(contentBase: string, { contentPackage, currentDate, skipDirectories, assetsBase, manifest, problems, addressContext, foreignRecord, parsed, sources, syntax, nameTypes, }: {
|
|
250
251
|
contentPackage: string;
|
|
251
252
|
skipDirectories: readonly string[];
|
|
252
253
|
assetsBase?: string | undefined;
|
|
253
254
|
manifest?: object | undefined;
|
|
254
255
|
addressContext?: object | undefined;
|
|
255
256
|
problems?: object[] | undefined;
|
|
257
|
+
currentDate?: string | undefined;
|
|
256
258
|
foreignRecord?: ((key: string) => ({
|
|
257
259
|
culture?: unknown;
|
|
258
260
|
} | undefined)) | undefined;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/** Add bracket spans after recognized Markdown links and footnotes.
|
|
2
2
|
* @param {import("markdown-it")} md - Markdown parser to extend.
|
|
3
3
|
* @param {object} [options] - Surface presentation.
|
|
4
|
-
* @param {boolean} [options.
|
|
4
|
+
* @param {boolean} [options.source] - Emit opaque authored source tokens for buffer preview.
|
|
5
|
+
* @param {boolean} [options.spoilers] - Add focusable CSS spoiler wrappers (Foundry).
|
|
5
6
|
*/
|
|
6
|
-
export function spanMarkdownPlugin(md: typeof import("markdown-it"), { spoilers }?: {
|
|
7
|
+
export function spanMarkdownPlugin(md: typeof import("markdown-it"), { spoilers, source }?: {
|
|
8
|
+
source?: boolean | undefined;
|
|
7
9
|
spoilers?: boolean | undefined;
|
|
8
10
|
}): void;
|
|
9
11
|
/** Read span anchors and located attribute diagnostics outside literal code.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate a quoted neutral date and preserve its authored day digits.
|
|
3
|
+
* @param {unknown} [value] - Explicit configuration or adapter override.
|
|
4
|
+
* @returns {string} Validated neutral date; undefined selects the default.
|
|
5
|
+
* @throws {TypeError} An explicit value is not a valid neutral date string.
|
|
6
|
+
*/
|
|
7
|
+
export function normalizeCurrentDate(value?: unknown): string;
|
|
8
|
+
/** Default day on the neutral setting timeline. */
|
|
9
|
+
export const DEFAULT_CURRENT_DATE: "720.1";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Semantic dictionary rows for HTML definition lists. @module */
|
|
2
|
+
/**
|
|
3
|
+
* Group each term and its definitions without reparsing their Markdown tokens.
|
|
4
|
+
* Register after markdown-it-deflist; nested blocks and footnotes retain their
|
|
5
|
+
* document context.
|
|
6
|
+
* @param {import("markdown-it")} md - An HTML Markdown parser with definition lists.
|
|
7
|
+
*/
|
|
8
|
+
export function dictionaryListPlugin(md: typeof import("markdown-it")): void;
|
|
@@ -32,6 +32,7 @@ export function systemAddressFindings(note: object, { index, schemas, systems }?
|
|
|
32
32
|
* @param {object} note - A note from the link index (`{fm, file, raw, type}`).
|
|
33
33
|
* @param {object} opts
|
|
34
34
|
* @param {Record<string, readonly object[]>} opts.schemas - Type → declaration.
|
|
35
|
+
* @param {string} [opts.currentDate="720.1"] - Setting-wide neutral date for age checks.
|
|
35
36
|
* @param {object} [opts.index] - The link index, for the reference check, which
|
|
36
37
|
* runs through its `shortcodeHit`. Its absence skips that check rather than
|
|
37
38
|
* reporting every reference as dead.
|
|
@@ -59,8 +60,9 @@ export function systemAddressFindings(note: object, { index, schemas, systems }?
|
|
|
59
60
|
* about those keys.
|
|
60
61
|
* @returns {object[]} Findings, each with a locator where one is obtainable.
|
|
61
62
|
*/
|
|
62
|
-
export function lintNote(note: object, { schemas, index, vocabulary, packs, emittedArt, addressContext, systems, }: {
|
|
63
|
+
export function lintNote(note: object, { schemas, index, currentDate, vocabulary, packs, emittedArt, addressContext, systems, }: {
|
|
63
64
|
schemas: Record<string, readonly object[]>;
|
|
65
|
+
currentDate?: string | undefined;
|
|
64
66
|
index?: object | undefined;
|
|
65
67
|
vocabulary?: Record<string, object> | undefined;
|
|
66
68
|
emittedArt?: ((type: string) => {
|
|
@@ -77,6 +79,7 @@ export function lintNote(note: object, { schemas, index, vocabulary, packs, emit
|
|
|
77
79
|
* @param {object} index - From `buildLinkIndex`.
|
|
78
80
|
* @param {object} opts
|
|
79
81
|
* @param {Record<string, readonly object[]>} opts.schemas - Type → declaration.
|
|
82
|
+
* @param {string} [opts.currentDate="720.1"] - Setting-wide neutral date for age checks.
|
|
80
83
|
* @param {Record<string, object>} [opts.vocabulary] - Type → the closed regions
|
|
81
84
|
* it declares; see {@link lintNote}.
|
|
82
85
|
* @param {boolean} [opts.references=true] - Whether to check references.
|
|
@@ -90,8 +93,9 @@ export function lintNote(note: object, { schemas, index, vocabulary, packs, emit
|
|
|
90
93
|
* @returns {{findings: object[], notes: number}} The findings, and how many
|
|
91
94
|
* notes were inspected.
|
|
92
95
|
*/
|
|
93
|
-
export function lintFrontmatter(index: object, { schemas, vocabulary, packs, emittedArt, references, systems }: {
|
|
96
|
+
export function lintFrontmatter(index: object, { schemas, vocabulary, packs, emittedArt, references, systems, currentDate }: {
|
|
94
97
|
schemas: Record<string, readonly object[]>;
|
|
98
|
+
currentDate?: string | undefined;
|
|
95
99
|
vocabulary?: Record<string, object> | undefined;
|
|
96
100
|
references?: boolean | undefined;
|
|
97
101
|
systems?: Readonly<Record<string, SystemBlockSpec>> | undefined;
|
package/types/engine/index.d.mts
CHANGED
|
@@ -39,6 +39,8 @@ export * as cultureChoice from "./culture-choice.mjs";
|
|
|
39
39
|
export * as reckoningMarkers from "./reckoning-markers.mjs";
|
|
40
40
|
export * as calendarNotes from "./calendar-notes.mjs";
|
|
41
41
|
export * as calendarArtifacts from "./calendar-artifacts.mjs";
|
|
42
|
+
export * as definitionList from "./definition-list.mjs";
|
|
43
|
+
export * as currentDate from "./current-date.mjs";
|
|
42
44
|
export * as beingAge from "./being-age.mjs";
|
|
43
45
|
export * as contentSlug from "./content-slug.mjs";
|
|
44
46
|
export * as contentAddress from "./content-address.mjs";
|
|
@@ -59,7 +59,7 @@ export function appearanceParagraph({ name, age, gender, height, frame, appearan
|
|
|
59
59
|
* about a name that does not fit.
|
|
60
60
|
* @param {string} [context.seed] - Text joined to the spec's own seed, to draw a
|
|
61
61
|
* different person from the same spec.
|
|
62
|
-
* @param {unknown} [context.
|
|
62
|
+
* @param {unknown} [context.currentDate] - The setting's neutral current date, defaulting to "720.1".
|
|
63
63
|
* @param {object} [context.dateContext] - The reckoning context the present
|
|
64
64
|
* and `born` are read in, with `daysPerYear`.
|
|
65
65
|
* @param {{icon?: unknown, species?: unknown, packFolder?: unknown}} [context.defaults] -
|
|
@@ -75,7 +75,7 @@ export function generateNpc(spec: object, context: {
|
|
|
75
75
|
names: object;
|
|
76
76
|
language?: string | undefined;
|
|
77
77
|
seed?: string | undefined;
|
|
78
|
-
|
|
78
|
+
currentDate?: unknown;
|
|
79
79
|
dateContext?: object | undefined;
|
|
80
80
|
defaults?: {
|
|
81
81
|
icon?: unknown;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read only currentDate from the nearest package configuration.
|
|
3
|
+
* YAML does not load the full build configuration. An MJS configuration executes
|
|
4
|
+
* its own module, as any caller opting into a code configuration expects.
|
|
5
|
+
* @param {string} root - Directory at which configuration discovery starts.
|
|
6
|
+
* @returns {Promise<string>} Validated neutral current date.
|
|
7
|
+
*/
|
|
8
|
+
export function readPreviewCurrentDate(root: string): Promise<string>;
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* @param {readonly SiteEntry[]} entries - Every page the site will publish,
|
|
5
5
|
* each already knowing its own `url`.
|
|
6
6
|
* @param {object} [options] - Cross-package inputs.
|
|
7
|
+
* @param {string} [options.package] - The builder's own content package.
|
|
8
|
+
* @param {string} [options.currentDate="720.1"] - Setting-wide neutral date for recurring events.
|
|
7
9
|
* @param {Map<string, {package: string, type?: string}>} [options.foreignIndex]
|
|
8
10
|
* The merged index from `loadForeignIndexes`. Omit when the build publishes
|
|
9
11
|
* no cross-package links.
|
|
@@ -16,7 +18,9 @@
|
|
|
16
18
|
* @param {import("./content-session.mjs").ContentSyntax} [options.syntax] - Exact-text scanner projections.
|
|
17
19
|
* @returns {SiteIndex} The index, and what could not be addressed unambiguously.
|
|
18
20
|
*/
|
|
19
|
-
export function buildSiteIndex(entries: readonly SiteEntry[], { foreignIndex, noIndexPackages, package: builderPackage, records, foreignReferences, syntax, }?: {
|
|
21
|
+
export function buildSiteIndex(entries: readonly SiteEntry[], { foreignIndex, noIndexPackages, package: builderPackage, currentDate, records, foreignReferences, syntax, }?: {
|
|
22
|
+
package?: string | undefined;
|
|
23
|
+
currentDate?: string | undefined;
|
|
20
24
|
foreignIndex?: Map<string, {
|
|
21
25
|
package: string;
|
|
22
26
|
type?: string;
|
|
@@ -1,34 +1,41 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
})
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Render one complete buffer with no configuration, index, filesystem or database.
|
|
3
|
+
* @param {string} text - Markdown, optionally beginning with YAML frontmatter.
|
|
4
|
+
* @param {{dark?: boolean, infobox?: boolean, file?: string, currentDate?: string}} [options] - Explicit palette, profile visibility, diagnostic filename and neutral current date (default "720.1").
|
|
5
|
+
* @returns {{ok: boolean, html: string, frontmatter: object, findings: object[]}} HTML and metadata with locally calculable ages; unavailable ages remain absent or null.
|
|
6
|
+
*/
|
|
7
|
+
export function renderPreview(text: string, { dark, infobox, file, currentDate }?: {
|
|
8
|
+
dark?: boolean;
|
|
9
|
+
infobox?: boolean;
|
|
10
|
+
file?: string;
|
|
11
|
+
currentDate?: string;
|
|
12
|
+
}): {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
html: string;
|
|
15
|
+
frontmatter: object;
|
|
16
|
+
findings: object[];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Opt in to reading only the project's currentDate setting; never called by renderPreview.
|
|
20
|
+
* @param {string} root - Directory from which to find the nearest package configuration.
|
|
21
|
+
* @returns {Promise<string>} Validated neutral date, or the shared default when no setting is present.
|
|
22
|
+
*/
|
|
23
|
+
export function readPreviewCurrentDate(root: string): Promise<string>;
|
|
24
|
+
/** Both explicit palettes, scoped to the preview container. */
|
|
25
|
+
export function previewStyles(): string;
|
|
26
|
+
/** Explicit dependency policy: a new registered helper requires a preview decision. */
|
|
27
|
+
export const PREVIEW_HELPERS: Readonly<{
|
|
28
|
+
eq: "local";
|
|
29
|
+
gt: "local";
|
|
30
|
+
gte: "local";
|
|
31
|
+
lt: "local";
|
|
32
|
+
lte: "local";
|
|
33
|
+
not: "local";
|
|
34
|
+
and: "local";
|
|
35
|
+
or: "local";
|
|
36
|
+
words: "local";
|
|
37
|
+
digits: "local";
|
|
38
|
+
sql: "dependent";
|
|
39
|
+
dateformat: "dependent";
|
|
40
|
+
ref: "reference";
|
|
34
41
|
}>;
|