explico 0.7.0 → 0.11.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 +1409 -1
- package/README.md +60 -15
- package/dist/compiler/astro.d.ts +6 -1
- package/dist/compiler/cli.d.ts +54 -3
- package/dist/compiler/cli.js +80 -6
- package/dist/compiler/collections.d.ts +35 -2
- package/dist/compiler/collections.js +84 -8
- package/dist/compiler/course-config.d.ts +3 -194
- package/dist/compiler/course-config.js +78 -5
- package/dist/compiler/exports/standalone-html.d.ts +6 -1
- package/dist/compiler/knowledge-version.js +1 -1
- package/dist/compiler/lesson-derivation.d.ts +27 -10
- package/dist/compiler/lesson-derivation.js +23 -8
- package/dist/compiler/logging.d.ts +14 -1
- package/dist/compiler/logging.js +6 -2
- package/dist/compiler/manifest.d.ts +204 -31
- package/dist/compiler/manifest.js +270 -55
- package/dist/compiler/resolution-report.d.ts +6 -1
- package/dist/course-config-Dsnri9Tk.d.ts +464 -0
- package/dist/reference/base-accents.d.mts +26 -0
- package/dist/reference/base-accents.mjs +31 -0
- package/dist/reference/base-roman-labels.d.mts +2 -2
- package/dist/reference/base-roman-labels.mjs +2 -2
- package/dist/reference/consistency.d.ts +14 -2
- package/dist/reference/consistency.js +108 -4
- package/dist/reference/delimiter-size.d.ts +21 -11
- package/dist/reference/delimiter-size.js +15 -39
- package/dist/reference/diagrams-validate.d.ts +7 -2
- package/dist/reference/diagrams-validate.js +9 -1
- package/dist/reference/equations-validate.d.ts +8 -5
- package/dist/reference/equations-validate.js +1 -0
- package/dist/reference/equations.d.mts +69 -34
- package/dist/reference/equations.mjs +90 -44
- package/dist/reference/examples-validate.d.ts +31 -0
- package/dist/reference/examples-validate.js +48 -0
- package/dist/reference/figures-validate.d.ts +1 -1
- package/dist/reference/figures-validate.js +4 -1
- package/dist/reference/folds-validate.d.ts +33 -0
- package/dist/reference/folds-validate.js +32 -0
- package/dist/reference/gate-abbreviations.d.ts +3 -1
- package/dist/reference/gate-abbreviations.js +3 -2
- package/dist/reference/gate-course-rules.d.ts +32 -0
- package/dist/reference/gate-course-rules.js +85 -0
- package/dist/reference/gate-heading-length.d.ts +5 -2
- package/dist/reference/gate-heading-length.js +47 -23
- package/dist/reference/gate-heading-structure.d.ts +41 -0
- package/dist/reference/gate-heading-structure.js +113 -0
- package/dist/reference/gate-math-punctuation.d.ts +71 -0
- package/dist/reference/gate-math-punctuation.js +251 -0
- package/dist/reference/gate-math.d.ts +44 -6
- package/dist/reference/gate-math.js +63 -10
- package/dist/reference/gate-part-pages.d.ts +50 -0
- package/dist/reference/gate-part-pages.js +118 -0
- package/dist/reference/gate-prose-notation.d.ts +32 -11
- package/dist/reference/gate-prose-notation.js +30 -8
- package/dist/reference/katex-delimiters.d.mts +15 -0
- package/dist/reference/katex-delimiters.mjs +138 -0
- package/dist/reference/katex-options.mjs +4 -0
- package/dist/reference/keyed-float-validate.d.ts +27 -10
- package/dist/reference/keyed-float-validate.js +15 -1
- package/dist/reference/keyed-jsx-floats.d.mts +11 -5
- package/dist/reference/keyed-jsx-floats.mjs +73 -20
- package/dist/reference/knowledge-checks-validate.d.ts +1 -1
- package/dist/reference/knowledge-checks.d.mts +3 -1
- package/dist/reference/knowledge-checks.mjs +9 -4
- package/dist/reference/lab-math-scope.d.ts +1 -0
- package/dist/reference/lab-math-slot.d.ts +34 -0
- package/dist/reference/lab-math-slot.js +6 -0
- package/dist/reference/math-glyphs.d.mts +80 -4
- package/dist/reference/math-glyphs.mjs +588 -39
- package/dist/reference/page-notation.d.ts +6 -1
- package/dist/reference/raw-floats-validate.js +1 -1
- package/dist/reference/raw-floats.mjs +1 -1
- package/dist/reference/rehype-heading-anchors.d.mts +14 -0
- package/dist/reference/rehype-heading-anchors.mjs +116 -17
- package/dist/reference/rehype-table-header-labels.d.mts +6 -1
- package/dist/reference/rehype-table-header-labels.mjs +21 -3
- package/dist/reference/remark-asides.d.mts +3 -0
- package/dist/reference/remark-asides.mjs +180 -0
- package/dist/reference/remark-memo.d.mts +3 -1
- package/dist/reference/remark-memo.mjs +42 -11
- package/dist/reference/remark-notation.d.mts +60 -10
- package/dist/reference/remark-notation.mjs +387 -36
- package/dist/reference/render-lab-math.d.ts +4 -26
- package/dist/reference/render-lab-math.js +5 -5
- package/dist/reference/sections-validate.d.ts +27 -0
- package/dist/reference/sections-validate.js +41 -0
- package/dist/reference/sections.d.mts +97 -0
- package/dist/reference/sections.mjs +306 -0
- package/dist/reference/tables-validate.d.ts +1 -1
- package/dist/reference/types.d.ts +24 -1
- package/dist/reference/unit-words.d.ts +37 -0
- package/dist/reference/unit-words.js +170 -0
- package/dist/rules/catalog.d.ts +176 -0
- package/dist/rules/catalog.js +983 -0
- package/dist/rules/course-rules.d.ts +115 -0
- package/dist/rules/course-rules.js +292 -0
- package/dist/rules/course-rules.schema.json +138 -0
- package/dist/rules/in-effect.d.ts +53 -0
- package/dist/rules/in-effect.js +142 -0
- package/dist/rules/rules.schema.json +1072 -0
- package/dist/rules/settings.d.ts +3 -0
- package/dist/rules/settings.js +290 -0
- package/dist/rules/waivers.d.ts +53 -0
- package/dist/rules/waivers.js +132 -0
- package/dist/session/PreferenceStore.d.ts +5 -0
- package/dist/session/PreferenceStore.js +9 -0
- package/docs/VERSIONING.md +2 -2
- package/docs/authoring/README.md +232 -40
- package/docs/authoring/agents.md +55 -9
- package/docs/authoring/components.md +178 -22
- package/docs/authoring/migrating.md +1324 -2
- package/docs/authoring/notation.md +616 -344
- package/docs/authoring/prose.md +551 -0
- package/docs/authoring/retired.md +35 -0
- package/docs/authoring/structure-rules.md +422 -40
- package/docs/authoring/structure.md +445 -62
- package/docs/authoring/versioning.md +20 -28
- package/docs/authoring/visualizations.md +142 -20
- package/docs/katex-bracket-scaling.md +191 -0
- package/package.json +3 -2
- package/src/compiler/cli.ts +139 -6
- package/src/compiler/collections.ts +144 -10
- package/src/compiler/course-config.ts +273 -34
- package/src/compiler/knowledge-version.ts +1 -1
- package/src/compiler/lesson-derivation.ts +54 -15
- package/src/compiler/logging.ts +21 -4
- package/src/compiler/manifest.ts +573 -104
- package/src/components/BlockHeading.astro +113 -0
- package/src/components/CourseContents.astro +221 -0
- package/src/components/CurriculumMap.astro +5 -6
- package/src/components/FloatIndex.astro +200 -0
- package/src/components/HoverPanel.astro +431 -79
- package/src/components/PartBridge.astro +27 -0
- package/src/components/PartOverview.astro +401 -0
- package/src/components/PartScope.astro +27 -0
- package/src/components/abbreviation/AbbreviationLayer.astro +49 -51
- package/src/components/assessments/AssessmentRunner.tsx +8 -5
- package/src/components/assessments/AssessmentSet.astro +23 -26
- package/src/components/block-heading.ts +146 -0
- package/src/components/card-arrow.ts +243 -0
- package/src/components/card-drag.ts +631 -0
- package/src/components/card-jump.ts +45 -0
- package/src/components/card-manager.ts +1589 -0
- package/src/components/card-memory.ts +177 -0
- package/src/components/card-placement.ts +504 -0
- package/src/components/card-side.ts +336 -0
- package/src/components/card-travel.ts +197 -0
- package/src/components/citation/CitationLayer.astro +77 -76
- package/src/components/diagram/Diagram.astro +161 -316
- package/src/components/disclosure/course-disclosure.ts +24 -0
- package/src/components/disclosure/hover-preview.ts +122 -42
- package/src/components/disclosure/persisted-disclosure.ts +3 -3
- package/src/components/disclosure/print-as-shown.ts +252 -0
- package/src/components/examples/CompactExample.astro +3 -1
- package/src/components/examples/CompactExamples.astro +101 -94
- package/src/components/figure/Figure.astro +174 -274
- package/src/components/figure/FloatCaption.astro +87 -0
- package/src/components/figure/figure-state.ts +58 -0
- package/src/components/figure/figure-tools.ts +87 -0
- package/src/components/float-name.ts +101 -0
- package/src/components/fold/Fold.astro +125 -0
- package/src/components/fold/fold-id.ts +40 -0
- package/src/components/memo/Memo.astro +162 -231
- package/src/components/memo/ShortNote.astro +6 -6
- package/src/components/notation/NotationFormula.astro +5 -1
- package/src/components/notation/NotationGlossary.astro +24 -14
- package/src/components/notation/NotationLayer.astro +169 -162
- package/src/components/notation/NotationMath.astro +10 -1
- package/src/components/notation/render-notation-math.ts +111 -10
- package/src/components/reference/FloatRefLayer.astro +485 -423
- package/src/components/starlight/AboutPanel.astro +22 -6
- package/src/components/starlight/CollapsibleSections.astro +207 -93
- package/src/components/starlight/DiagramEnhancer.astro +15 -138
- package/src/components/starlight/HeadingAnchorEnhancer.astro +193 -1
- package/src/components/starlight/KeyedFloatEnhancer.astro +100 -9
- package/src/components/starlight/LayoutHeader.astro +298 -19
- package/src/components/starlight/LayoutPageSidebar.astro +99 -12
- package/src/components/starlight/LayoutPageTitle.astro +120 -0
- package/src/components/starlight/LayoutSidebar.astro +229 -11
- package/src/components/starlight/LessonExportActions.astro +53 -72
- package/src/components/starlight/LessonFooter.astro +26 -4
- package/src/components/starlight/section-parts.ts +15 -2
- package/src/components/starlight/section-summary.ts +181 -0
- package/src/components/table/Table.astro +95 -76
- package/src/components/table/TableOverflowExpander.astro +65 -28
- package/src/content-config.ts +40 -4
- package/src/reference/base-accents.mjs +31 -0
- package/src/reference/base-roman-labels.mjs +2 -2
- package/src/reference/consistency.ts +176 -5
- package/src/reference/delimiter-size.ts +40 -61
- package/src/reference/diagrams-validate.ts +17 -1
- package/src/reference/equations-validate.ts +10 -5
- package/src/reference/equations.mjs +90 -44
- package/src/reference/examples-validate.ts +97 -0
- package/src/reference/figures-validate.ts +6 -1
- package/src/reference/folds-validate.ts +65 -0
- package/src/reference/gate-abbreviations.ts +3 -2
- package/src/reference/gate-course-rules.ts +134 -0
- package/src/reference/gate-heading-length.ts +68 -37
- package/src/reference/gate-heading-structure.ts +193 -0
- package/src/reference/gate-math-punctuation.ts +381 -0
- package/src/reference/gate-math.ts +119 -12
- package/src/reference/gate-part-pages.ts +217 -0
- package/src/reference/gate-prose-notation.ts +74 -13
- package/src/reference/katex-delimiters.mjs +138 -0
- package/src/reference/katex-options.mjs +4 -0
- package/src/reference/keyed-float-validate.ts +45 -11
- package/src/reference/keyed-jsx-floats.mjs +73 -20
- package/src/reference/knowledge-checks-validate.ts +1 -1
- package/src/reference/knowledge-checks.mjs +9 -4
- package/src/reference/lab-math-slot.ts +36 -0
- package/src/reference/math-glyphs.mjs +588 -39
- package/src/reference/raw-floats-validate.ts +1 -1
- package/src/reference/raw-floats.mjs +1 -1
- package/src/reference/rehype-heading-anchors.mjs +116 -17
- package/src/reference/rehype-table-header-labels.mjs +21 -3
- package/src/reference/remark-asides.mjs +180 -0
- package/src/reference/remark-memo.mjs +42 -11
- package/src/reference/remark-notation.mjs +387 -36
- package/src/reference/render-lab-math.ts +17 -32
- package/src/reference/sections-validate.ts +81 -0
- package/src/reference/sections.mjs +306 -0
- package/src/reference/tables-validate.ts +2 -1
- package/src/reference/types.ts +24 -0
- package/src/reference/unit-words.ts +233 -0
- package/src/rules/catalog.ts +1298 -0
- package/src/rules/course-rules.ts +456 -0
- package/src/rules/in-effect.ts +235 -0
- package/src/rules/settings.ts +448 -0
- package/src/rules/waivers.ts +249 -0
- package/src/session/PreferenceStore.ts +15 -0
- package/src/styles/global.css +1471 -163
- package/src/styles/surfaces.css +182 -0
- package/src/components/hover-panel.ts +0 -339
- package/src/components/popup-stack.ts +0 -345
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
* `#eq-key` — `keyedFloatAnchorId` prepends `tab-`/`fig-`/`dia-`.
|
|
12
12
|
*
|
|
13
13
|
* Only top-level occurrences count, exactly like `collectDisplayEquations`,
|
|
14
|
-
* except that `<Memo
|
|
15
|
-
*
|
|
14
|
+
* except that the `TRANSPARENT_COMPONENTS` (`<Memo>`, `<ShortNote>`,
|
|
15
|
+
* `<Fold>`) are see-through: a float in a memo or a fold stays in the
|
|
16
|
+
* lesson's reading order. A keyed float nested inside a
|
|
16
17
|
* `<CompactExample>` (or any other component) is illustrative, not part of the
|
|
17
18
|
* official sequence.
|
|
18
19
|
*
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
resolveNumbering,
|
|
27
28
|
stripFencedCode,
|
|
28
29
|
stripJsxComponents,
|
|
30
|
+
TRANSPARENT_COMPONENTS,
|
|
29
31
|
} from './equations.mjs';
|
|
30
32
|
|
|
31
33
|
/** Same shape as `EQ_KEY_PATTERN` — the notation-key grammar without dots. */
|
|
@@ -37,10 +39,11 @@ function floatNumber(section, index) {
|
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
/**
|
|
40
|
-
* The visible number for one float. With a `prefix` (
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
42
|
+
* The visible number for one float. With a `prefix` (`‹part›.‹chapter›`, or
|
|
43
|
+
* the part alone under `numbering.floats: "part"`) the scheme is
|
|
44
|
+
* `‹prefix›.‹offset + indexInLesson›` and `##` headings are ignored; without
|
|
45
|
+
* it, the legacy `##`-section scheme. Mirrors `displayEquationNumber` in
|
|
46
|
+
* `equations.mjs`. Each kind of float counts on its own — a `<Table>` never
|
|
44
47
|
* advances the `<Figure>` or `<Diagram>` sequence — so `offset` is per kind too.
|
|
45
48
|
*/
|
|
46
49
|
function keyedFloatNumber({
|
|
@@ -79,22 +82,60 @@ function readIdAttribute(attributesSource) {
|
|
|
79
82
|
return match ? match[2] : undefined;
|
|
80
83
|
}
|
|
81
84
|
|
|
85
|
+
/**
|
|
86
|
+
* A literal string attribute (`name="…"` / `name='…'`) of a JSX opening tag's
|
|
87
|
+
* attribute source, trimmed; `null` when absent, empty, or an expression.
|
|
88
|
+
*/
|
|
89
|
+
function readStringAttribute(attributesSource, name) {
|
|
90
|
+
const match = new RegExp(
|
|
91
|
+
String.raw`(?:^|\s)${name}\s*=\s*(?:"([^"]*)"|'([^']*)')`,
|
|
92
|
+
).exec(attributesSource);
|
|
93
|
+
const value = (match?.[1] ?? match?.[2])?.trim();
|
|
94
|
+
return value ? value : null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Every prop name a JSX opening tag's attribute source sets (`name=`). */
|
|
98
|
+
function attributeNames(attributesSource) {
|
|
99
|
+
const bare = attributesSource.replace(
|
|
100
|
+
/"[^"]*"|'[^']*'|\{(?:[^{}]|\{[^{}]*\})*\}/g,
|
|
101
|
+
' ',
|
|
102
|
+
);
|
|
103
|
+
return [...bare.matchAll(/(?:^|\s)([A-Za-z_][\w:.-]*)\s*=/g)].map(
|
|
104
|
+
(match) => match[1],
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** A literal string value of an mdast JSX attribute, trimmed, else `null`. */
|
|
109
|
+
function mdxStringAttribute(node, name) {
|
|
110
|
+
const attribute = (node.attributes ?? []).find(
|
|
111
|
+
(candidate) =>
|
|
112
|
+
candidate?.type === 'mdxJsxAttribute' && candidate.name === name,
|
|
113
|
+
);
|
|
114
|
+
const value =
|
|
115
|
+
typeof attribute?.value === 'string' ? attribute.value.trim() : '';
|
|
116
|
+
return value ? value : null;
|
|
117
|
+
}
|
|
118
|
+
|
|
82
119
|
/**
|
|
83
120
|
* The raw-text equivalent of `collectKeyedJsxFloats`, mirroring
|
|
84
|
-
* `scanEquationLabels`: every top-level `<TagName …>` in appearance order
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
121
|
+
* `scanEquationLabels`: every top-level `<TagName …>` in appearance order,
|
|
122
|
+
* with its literal `short` / `caption` (the caption pair every float takes;
|
|
123
|
+
* `null` when absent or an expression) and `props`, the names of every prop
|
|
124
|
+
* the tag sets, for `keyed-float-validate.ts`'s removed-prop check.
|
|
125
|
+
* With `numbering` (`{ prefix, offset }` — the lesson's float-number prefix
|
|
126
|
+
* and the count of this kind of float before it in that scope) the number is
|
|
127
|
+
* `‹prefix›.‹offset + n›`, `n` sequential over the whole lesson; without it, `##`
|
|
88
128
|
* headings advance a section counter. Other JSX components' bodies are blanked
|
|
89
129
|
* first so a `<Table>` nested inside e.g. `<CompactExample>` (and any `##`-like
|
|
90
130
|
* text inside an unrelated component) is never counted.
|
|
91
131
|
*/
|
|
92
132
|
export function scanKeyedJsxFloats(markdown, { tagName, numbering }) {
|
|
93
133
|
const { prefix, offset } = resolveNumbering(numbering);
|
|
94
|
-
const text = stripJsxComponents(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
134
|
+
const text = stripJsxComponents(
|
|
135
|
+
stripFencedCode(markdown),
|
|
136
|
+
tagName,
|
|
137
|
+
TRANSPARENT_COMPONENTS,
|
|
138
|
+
);
|
|
98
139
|
const tokens = [];
|
|
99
140
|
const heading = /^[ \t]{0,3}##[ \t]+\S/gm;
|
|
100
141
|
const opening = new RegExp(`<${tagName}\\b([^>]*)>`, 'g');
|
|
@@ -102,8 +143,16 @@ export function scanKeyedJsxFloats(markdown, { tagName, numbering }) {
|
|
|
102
143
|
tokens.push({ kind: 'section', index: match.index });
|
|
103
144
|
}
|
|
104
145
|
for (const match of text.matchAll(opening)) {
|
|
105
|
-
const
|
|
106
|
-
|
|
146
|
+
const attributes = match[1] ?? '';
|
|
147
|
+
const key = readIdAttribute(attributes);
|
|
148
|
+
tokens.push({
|
|
149
|
+
kind: 'float',
|
|
150
|
+
index: match.index,
|
|
151
|
+
key: key ?? null,
|
|
152
|
+
short: readStringAttribute(attributes, 'short'),
|
|
153
|
+
caption: readStringAttribute(attributes, 'caption'),
|
|
154
|
+
props: attributeNames(attributes),
|
|
155
|
+
});
|
|
107
156
|
}
|
|
108
157
|
tokens.sort((a, b) => a.index - b.index);
|
|
109
158
|
|
|
@@ -128,6 +177,9 @@ export function scanKeyedJsxFloats(markdown, { tagName, numbering }) {
|
|
|
128
177
|
indexInSection,
|
|
129
178
|
indexInLesson,
|
|
130
179
|
}),
|
|
180
|
+
short: token.short,
|
|
181
|
+
caption: token.caption,
|
|
182
|
+
props: token.props,
|
|
131
183
|
section,
|
|
132
184
|
indexInSection,
|
|
133
185
|
});
|
|
@@ -145,7 +197,7 @@ export function countKeyedJsxFloats(markdown, { tagName }) {
|
|
|
145
197
|
|
|
146
198
|
/**
|
|
147
199
|
* The mdast equivalent of `scanKeyedJsxFloats`: walk the tree's top-level
|
|
148
|
-
* children (and through
|
|
200
|
+
* children (and through the `TRANSPARENT_COMPONENTS`' bodies) in document order, advancing the
|
|
149
201
|
* section counter on every top-level depth-2 heading and emitting a record for
|
|
150
202
|
* every `mdxJsxFlowElement` named `tagName` — keyed or not, exactly like
|
|
151
203
|
* `collectDisplayEquations`. `numbering` is threaded the same way as in
|
|
@@ -171,6 +223,8 @@ export function collectKeyedJsxFloats(tree, { tagName, numbering }) {
|
|
|
171
223
|
typeof idAttribute?.value === 'string' ? idAttribute.value : undefined;
|
|
172
224
|
floats.push({
|
|
173
225
|
key: key ?? null,
|
|
226
|
+
short: mdxStringAttribute(node, 'short'),
|
|
227
|
+
caption: mdxStringAttribute(node, 'caption'),
|
|
174
228
|
number: keyedFloatNumber({
|
|
175
229
|
prefix,
|
|
176
230
|
offset,
|
|
@@ -186,8 +240,7 @@ export function collectKeyedJsxFloats(tree, { tagName, numbering }) {
|
|
|
186
240
|
}
|
|
187
241
|
if (
|
|
188
242
|
node.type === 'mdxJsxFlowElement' &&
|
|
189
|
-
node.name
|
|
190
|
-
node.name !== 'ShortNote'
|
|
243
|
+
!TRANSPARENT_COMPONENTS.includes(node.name)
|
|
191
244
|
) {
|
|
192
245
|
return;
|
|
193
246
|
}
|
|
@@ -207,7 +260,7 @@ export function collectKeyedJsxFloats(tree, { tagName, numbering }) {
|
|
|
207
260
|
collectFromDetail(node);
|
|
208
261
|
} else if (
|
|
209
262
|
node.type === 'mdxJsxFlowElement' &&
|
|
210
|
-
(node.name
|
|
263
|
+
TRANSPARENT_COMPONENTS.includes(node.name)
|
|
211
264
|
) {
|
|
212
265
|
collectFromDetail(node);
|
|
213
266
|
}
|
|
@@ -12,7 +12,7 @@ export interface KnowledgeCheckLessonInput {
|
|
|
12
12
|
readonly file: string;
|
|
13
13
|
readonly body: string;
|
|
14
14
|
readonly assessmentIds: readonly string[];
|
|
15
|
-
readonly numbering?: { readonly prefix: number; readonly offset: number };
|
|
15
|
+
readonly numbering?: { readonly prefix: number | string; readonly offset: number };
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export interface KnowledgeCheckLabelRecord {
|
|
@@ -28,12 +28,17 @@ export function knowledgeCheckAnchorId(key) {
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Number an ordered assessment-id list. With manifest placement, the number
|
|
31
|
-
* is
|
|
31
|
+
* is `‹prefix›.‹offset + index›` — `prefix` is `‹part›.‹chapter›`, or the part
|
|
32
|
+
* alone under `numbering.floats: "part"`; without it, the list remains
|
|
33
|
+
* usefully page-local.
|
|
32
34
|
*/
|
|
33
35
|
export function collectKnowledgeChecks(assessmentIds, numbering) {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
const rawPrefix = numbering?.prefix;
|
|
37
|
+
const prefix =
|
|
38
|
+
(Number.isInteger(rawPrefix) && rawPrefix > 0) ||
|
|
39
|
+
(typeof rawPrefix === 'string' && /^\d+(?:\.\d+)*$/.test(rawPrefix))
|
|
40
|
+
? rawPrefix
|
|
41
|
+
: undefined;
|
|
37
42
|
const offset = Number.isInteger(numbering?.offset) && numbering.offset >= 0
|
|
38
43
|
? numbering.offset
|
|
39
44
|
: 0;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The half of lab math an interactive island needs in the browser: the shape
|
|
3
|
+
* of a compiled template and its slot placeholder. It imports nothing, so an
|
|
4
|
+
* island that uses it stays clear of the KaTeX build chain behind
|
|
5
|
+
* `render-lab-math.ts`, which is server-only (`katex-delimiters.mjs` reads
|
|
6
|
+
* KaTeX's bundle from disk).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export interface RenderedLabMath {
|
|
10
|
+
/** KaTeX HTML+MathML with `data-notation-key` and `data-lab-slot` spans. */
|
|
11
|
+
readonly html: string;
|
|
12
|
+
/** Slot names, in template order, the island must supply at runtime. */
|
|
13
|
+
readonly slots: readonly string[];
|
|
14
|
+
/** Notation keys the template resolved to, for diagnostics. */
|
|
15
|
+
readonly keys: readonly string[];
|
|
16
|
+
/**
|
|
17
|
+
* Plain, copyable LaTeX — every explained glyph resolved to its bare
|
|
18
|
+
* symbol, every `\slot{name}{…}` replaced by `slotPlaceholder(name)` — so
|
|
19
|
+
* the island can substitute each slot's *current* live value in and keep
|
|
20
|
+
* `[data-notation-formula]`'s `data-latex` accurate as the reader drags a
|
|
21
|
+
* control, the same "click the equation to copy it" gesture a static
|
|
22
|
+
* lesson or glossary equation gets (`NotationLayer.astro`).
|
|
23
|
+
*/
|
|
24
|
+
readonly plainLatexTemplate: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A slot's placeholder inside `plainLatexTemplate` — distinct from the
|
|
29
|
+
* numeric sentinel `render-lab-math.ts` uses internally (that one only has to
|
|
30
|
+
* survive a single notation-binding pass at build time; this one is the
|
|
31
|
+
* stable, name-keyed token an island substitutes with a live value at
|
|
32
|
+
* runtime, so it's exported for that purpose).
|
|
33
|
+
*/
|
|
34
|
+
export function slotPlaceholder(name: string): string {
|
|
35
|
+
return `⟦${name}⟧`;
|
|
36
|
+
}
|