explico 0.13.1 → 0.15.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 +990 -1
- package/README.md +200 -30
- package/dist/compiler/astro.d.ts +15 -2
- package/dist/compiler/astro.js +40 -11
- package/dist/compiler/cli-main.d.ts +100 -0
- package/dist/compiler/cli-main.js +433 -0
- package/dist/compiler/cli-reference.d.ts +50 -0
- package/dist/compiler/cli-reference.js +213 -0
- package/dist/compiler/cli-verbs.d.ts +45 -0
- package/dist/compiler/cli-verbs.js +224 -0
- package/dist/compiler/cli-verify.d.ts +51 -0
- package/dist/compiler/cli-verify.js +151 -0
- package/dist/compiler/cli.d.ts +408 -24
- package/dist/compiler/cli.js +1328 -8
- package/dist/compiler/collections.d.ts +88 -1
- package/dist/compiler/collections.js +170 -25
- package/dist/compiler/content-release.d.ts +49 -0
- package/dist/compiler/content-release.js +63 -0
- package/dist/compiler/content-schemas.d.ts +2 -2
- package/dist/compiler/course-config.d.ts +1 -1
- package/dist/compiler/course-config.js +105 -1
- package/dist/compiler/decks.d.ts +161 -0
- package/dist/compiler/decks.js +235 -0
- package/dist/compiler/exports/combined-html.d.ts +5 -1
- package/dist/compiler/exports/deck-fit.d.ts +55 -0
- package/dist/compiler/exports/deck-fit.js +90 -0
- package/dist/compiler/exports/export-chapters.d.ts +37 -6
- package/dist/compiler/exports/export-chapters.js +64 -5
- package/dist/compiler/exports/export-pages.d.ts +30 -3
- package/dist/compiler/exports/export-pages.js +24 -1
- package/dist/compiler/exports/latex/beamerthemeexplico.sty +124 -0
- package/dist/compiler/exports/latex/cache.d.ts +78 -0
- package/dist/compiler/exports/latex/cache.js +129 -0
- package/dist/compiler/exports/latex/capture.d.ts +10 -1
- package/dist/compiler/exports/latex/capture.js +3 -1
- package/dist/compiler/exports/latex/compile.d.ts +13 -2
- package/dist/compiler/exports/latex/compile.js +12 -1
- package/dist/compiler/exports/latex/deck.d.ts +92 -0
- package/dist/compiler/exports/latex/deck.js +349 -0
- package/dist/compiler/exports/latex/document.d.ts +51 -6
- package/dist/compiler/exports/latex/document.js +71 -12
- package/dist/compiler/exports/latex/explico-common.sty +198 -0
- package/dist/compiler/exports/latex/explico.cls +13 -183
- package/dist/compiler/exports/latex/serialize.d.ts +60 -4
- package/dist/compiler/exports/latex/serialize.js +4 -2
- package/dist/compiler/exports/latex-export.d.ts +24 -2
- package/dist/compiler/exports/latex-export.js +107 -26
- package/dist/compiler/exports/markdown/serialize.d.ts +24 -4
- package/dist/compiler/exports/markdown/serialize.js +85 -8
- package/dist/compiler/exports/markdown-export.d.ts +6 -1
- package/dist/compiler/exports/markdown-export.js +50 -11
- package/dist/compiler/exports/standalone-html.d.ts +10 -5
- package/dist/compiler/exports/standalone-html.js +3 -3
- package/dist/compiler/exports/static-tree.d.ts +38 -1
- package/dist/compiler/exports/static-tree.js +120 -4
- package/dist/compiler/knowledge-version.d.ts +26 -2
- package/dist/compiler/knowledge-version.js +27 -17
- package/dist/compiler/lesson-derivation.d.ts +143 -6
- package/dist/compiler/lesson-derivation.js +145 -13
- package/dist/compiler/manifest.d.ts +133 -4
- package/dist/compiler/manifest.js +364 -58
- package/dist/compiler/page-versions.d.ts +184 -0
- package/dist/compiler/page-versions.js +217 -0
- package/dist/compiler/render-diagnostics.d.ts +5 -1
- package/dist/compiler/resolution-report.d.ts +24 -6
- package/dist/compiler/resolution-report.js +22 -4
- package/dist/compiler/validate-content.d.ts +7 -0
- package/dist/compiler/validate-content.js +160 -0
- package/dist/{course-config-rRtME5UV.d.ts → course-config-BLtIdkei.d.ts} +164 -1
- package/dist/curriculum/competency-graph.d.ts +54 -0
- package/dist/curriculum/competency-graph.js +41 -0
- package/dist/reference/base-library.d.mts +8 -0
- package/dist/reference/base-library.mjs +19 -0
- package/dist/reference/consistency.d.ts +8 -4
- package/dist/reference/consistency.js +82 -26
- package/dist/reference/deck-remark.d.mts +123 -0
- package/dist/reference/deck-remark.mjs +600 -0
- package/dist/reference/deck-source.d.ts +107 -0
- package/dist/reference/deck-source.js +140 -0
- package/dist/reference/decks-validate.d.ts +133 -0
- package/dist/reference/decks-validate.js +359 -0
- package/dist/reference/derived-entries.d.ts +5 -1
- package/dist/reference/diagram-fit.d.ts +6 -2
- package/dist/reference/diagram-fit.js +5 -1
- package/dist/reference/figure-symbols.d.ts +23 -6
- package/dist/reference/figure-symbols.js +51 -15
- package/dist/reference/float-name.d.ts +43 -0
- package/dist/reference/float-name.js +58 -0
- package/dist/reference/folds-validate.d.ts +1 -1
- package/dist/reference/gate-abbreviations.d.ts +1 -1
- package/dist/reference/gate-indices.js +5 -4
- package/dist/reference/gate-math.d.ts +29 -2
- package/dist/reference/gate-math.js +99 -18
- package/dist/reference/gate-part-pages.d.ts +1 -1
- package/dist/reference/lab-katex-validate.d.ts +10 -6
- package/dist/reference/lab-katex-validate.js +17 -9
- package/dist/reference/lab-math-scope.js +29 -4
- package/dist/reference/math-glyphs.d.mts +25 -0
- package/dist/reference/math-glyphs.mjs +189 -25
- package/dist/reference/page-notation.d.ts +22 -3
- package/dist/reference/page-notation.js +32 -10
- package/dist/reference/references.d.ts +14 -1
- package/dist/reference/references.js +13 -0
- package/dist/reference/registry-scope.d.mts +33 -0
- package/dist/reference/registry-scope.mjs +34 -0
- package/dist/reference/registry.js +29 -10
- package/dist/reference/rehype-deck.d.mts +6 -0
- package/dist/reference/rehype-deck.mjs +286 -0
- package/dist/reference/rehype-heading-anchors.d.mts +20 -0
- package/dist/reference/rehype-heading-anchors.mjs +48 -6
- package/dist/reference/remark-notation.mjs +249 -40
- package/dist/reference/source-lines.d.mts +12 -0
- package/dist/reference/source-lines.mjs +65 -0
- package/dist/reference/types.d.ts +28 -0
- package/dist/rules/catalog.d.ts +21 -4
- package/dist/rules/catalog.js +237 -2
- package/dist/rules/course-rules.d.ts +5 -1
- package/dist/rules/course-rules.js +17 -3
- package/dist/rules/course-rules.schema.json +12 -0
- package/dist/rules/in-effect.d.ts +13 -3
- package/dist/rules/in-effect.js +34 -10
- package/dist/rules/rules.schema.json +280 -1
- package/dist/rules/settings.d.ts +1 -1
- package/dist/session/PreferenceStore.d.ts +6 -0
- package/dist/session/PreferenceStore.js +18 -1
- package/dist/session/deck-memory.d.ts +116 -0
- package/dist/session/deck-memory.js +143 -0
- package/dist/session/reading-memory.d.ts +96 -0
- package/dist/session/reading-memory.js +133 -0
- package/docs/VERSIONING.md +21 -18
- package/docs/authoring/README.md +31 -9
- package/docs/authoring/agents.md +72 -18
- package/docs/authoring/cli-reference.json +2172 -0
- package/docs/authoring/cli.md +887 -0
- package/docs/authoring/components.md +15 -0
- package/docs/authoring/deck.md +612 -0
- package/docs/authoring/migrating.md +1195 -16
- package/docs/authoring/notation.md +49 -6
- package/docs/authoring/structure.md +80 -1
- package/docs/authoring/versioning.md +56 -3
- package/docs/authoring/visualizations.md +7 -2
- package/docs/course-agent/AGENTS.md +40 -0
- package/docs/course-agent/agents/rules-reviewer.md +33 -0
- package/docs/course-agent/skills/draft-lesson/SKILL.md +38 -0
- package/docs/course-agent/skills/migrate-course/SKILL.md +32 -0
- package/docs/course-agent/skills/release-content/SKILL.md +26 -0
- package/docs/diagram-scaling.md +148 -0
- package/docs/privacy.md +59 -0
- package/package.json +8 -2
- package/src/compiler/astro.ts +60 -21
- package/src/compiler/cli-main.ts +557 -0
- package/src/compiler/cli-reference.ts +285 -0
- package/src/compiler/cli-verbs.ts +270 -0
- package/src/compiler/cli-verify.ts +241 -0
- package/src/compiler/cli.ts +2119 -170
- package/src/compiler/collections.ts +284 -25
- package/src/compiler/content-release.ts +91 -0
- package/src/compiler/course-config.ts +267 -0
- package/src/compiler/decks.ts +455 -0
- package/src/compiler/exports/deck-fit.ts +127 -0
- package/src/compiler/exports/export-chapters.ts +105 -6
- package/src/compiler/exports/export-pages.ts +46 -2
- package/src/compiler/exports/latex/beamerthemeexplico.sty +124 -0
- package/src/compiler/exports/latex/cache.ts +183 -0
- package/src/compiler/exports/latex/capture.ts +5 -2
- package/src/compiler/exports/latex/compile.ts +18 -0
- package/src/compiler/exports/latex/deck.ts +419 -0
- package/src/compiler/exports/latex/document.ts +117 -21
- package/src/compiler/exports/latex/explico-common.sty +198 -0
- package/src/compiler/exports/latex/explico.cls +13 -183
- package/src/compiler/exports/latex/serialize.ts +25 -21
- package/src/compiler/exports/latex/texlive-packages.txt +6 -2
- package/src/compiler/exports/latex-export.ts +187 -45
- package/src/compiler/exports/markdown/serialize.ts +118 -9
- package/src/compiler/exports/markdown-export.ts +56 -11
- package/src/compiler/exports/standalone-html.ts +8 -7
- package/src/compiler/exports/static-tree.ts +175 -3
- package/src/compiler/knowledge-version.ts +56 -21
- package/src/compiler/lesson-derivation.ts +282 -16
- package/src/compiler/manifest.ts +568 -63
- package/src/compiler/page-versions.ts +401 -0
- package/src/compiler/resolution-report.ts +38 -7
- package/src/compiler/validate-content.ts +215 -0
- package/src/components/CourseContents.astro +124 -6
- package/src/components/CurriculumMap.astro +49 -1
- package/src/components/FloatIndex.astro +1 -1
- package/src/components/PartOverview.astro +51 -5
- package/src/components/assessments/AssessmentSet.astro +41 -15
- package/src/components/block-heading.ts +15 -6
- package/src/components/card-carry.ts +7 -4
- package/src/components/card-manager.ts +14 -2
- package/src/components/card-memory.ts +13 -9
- package/src/components/deck/DeckEnhancer.astro +13 -0
- package/src/components/deck/deck-context.ts +104 -0
- package/src/components/deck/deck-controller.ts +1287 -0
- package/src/components/deck/deck-map.ts +91 -0
- package/src/components/deck-lane.ts +163 -0
- package/src/components/diagram/Diagram.astro +131 -86
- package/src/components/disclosure/persisted-disclosure.ts +9 -1
- package/src/components/figure/Figure.astro +7 -2
- package/src/components/figure/FloatCaption.astro +5 -3
- package/src/components/fold/Fold.astro +2 -2
- package/src/components/notation/NotationFormula.astro +81 -11
- package/src/components/notation/NotationGlossary.astro +132 -1
- package/src/components/notation/NotationLayer.astro +15 -7
- package/src/components/starlight/AboutPanel.astro +186 -3
- package/src/components/starlight/CollapsibleSections.astro +24 -3
- package/src/components/starlight/DiagramEnhancer.astro +5 -1
- package/src/components/starlight/HeadingAnchorEnhancer.astro +1 -1
- package/src/components/starlight/LayoutHeader.astro +17 -0
- package/src/components/starlight/LayoutPageTitle.astro +110 -0
- package/src/components/starlight/LayoutSidebar.astro +807 -21
- package/src/components/starlight/LayoutSocialIcons.astro +62 -6
- package/src/components/starlight/LessonExportActions.astro +27 -9
- package/src/components/starlight/LessonFooter.astro +59 -0
- package/src/components/starlight/ReadingMemoryNotice.astro +114 -0
- package/src/components/starlight/TextSizeControl.astro +24 -13
- package/src/components/starlight/page-marks.ts +139 -0
- package/src/components/starlight/section-summary.ts +1 -1
- package/src/components/starlight/sidebar-editions.ts +245 -0
- package/src/components/table/Table.astro +15 -7
- package/src/content-config.ts +87 -1
- package/src/curriculum/competency-graph.ts +95 -0
- package/src/reference/base-library.mjs +19 -0
- package/src/reference/consistency.ts +137 -39
- package/src/reference/deck-remark.mjs +600 -0
- package/src/reference/deck-source.ts +273 -0
- package/src/reference/decks-validate.ts +604 -0
- package/src/reference/diagram-fit.ts +18 -4
- package/src/reference/diagram-layout.ts +3 -1
- package/src/reference/figure-symbols.ts +108 -31
- package/src/reference/folds-validate.ts +1 -1
- package/src/reference/gate-indices.ts +5 -3
- package/src/reference/gate-math.ts +169 -25
- package/src/reference/lab-katex-validate.ts +30 -15
- package/src/reference/lab-math-scope.ts +34 -3
- package/src/reference/math-glyphs.mjs +189 -25
- package/src/reference/page-notation.ts +69 -15
- package/src/reference/references.ts +28 -0
- package/src/reference/registry-scope.mjs +34 -0
- package/src/reference/registry.ts +41 -11
- package/src/reference/rehype-deck.mjs +286 -0
- package/src/reference/rehype-heading-anchors.mjs +48 -6
- package/src/reference/remark-notation.mjs +249 -40
- package/src/reference/source-lines.mjs +65 -0
- package/src/reference/types.ts +28 -0
- package/src/rules/catalog.ts +274 -4
- package/src/rules/course-rules.ts +21 -1
- package/src/rules/in-effect.ts +58 -11
- package/src/session/PreferenceStore.ts +23 -0
- package/src/session/deck-memory.ts +263 -0
- package/src/session/reading-memory.ts +243 -0
- package/src/styles/deck.css +1150 -0
- package/src/styles/global.css +958 -27
- package/src/styles/zones.css +277 -0
- /package/src/{components → reference}/float-name.ts +0 -0
|
@@ -132,12 +132,16 @@ type Block = {
|
|
|
132
132
|
readonly ordered: boolean;
|
|
133
133
|
readonly start?: number;
|
|
134
134
|
readonly items: readonly (readonly Block[])[];
|
|
135
|
+
/** On a deck, the step each item appears at (1 for the first), when an item is a step of its own. */
|
|
136
|
+
readonly itemSteps?: readonly number[];
|
|
135
137
|
} | {
|
|
136
138
|
readonly kind: 'equation';
|
|
137
139
|
readonly anchor: string;
|
|
138
140
|
readonly number: string;
|
|
139
141
|
readonly key?: string;
|
|
140
142
|
readonly tex: string;
|
|
143
|
+
/** On a deck, a recalled equation's place in its chapter. */
|
|
144
|
+
readonly recall?: string;
|
|
141
145
|
} | {
|
|
142
146
|
readonly kind: 'displayMath';
|
|
143
147
|
readonly tex: string;
|
|
@@ -249,5 +253,38 @@ declare function readDiagramGeometry(figure: HtmlElement): DiagramGeometry | und
|
|
|
249
253
|
declare function readInlineFragment(html: string, route: string, base?: string): Inline[];
|
|
250
254
|
/** Read the static reading tree of one built page. */
|
|
251
255
|
declare function readStaticPage(html: string, slug: string, route: string): StaticPage;
|
|
256
|
+
/** One frame of a deck page (docs/authoring/deck.md), as print exports read it. */
|
|
257
|
+
interface DeckFrame {
|
|
258
|
+
readonly number: number;
|
|
259
|
+
readonly kind: 'title' | 'section' | 'frame' | 'outcomes' | 'references';
|
|
260
|
+
/** The frame heading's anchor. */
|
|
261
|
+
readonly anchor?: string;
|
|
262
|
+
readonly title: readonly Inline[];
|
|
263
|
+
/** The frame's content, a run of blocks per step, in reading order: step 1 is what shows first. */
|
|
264
|
+
readonly segments: readonly {
|
|
265
|
+
readonly step: number;
|
|
266
|
+
readonly blocks: readonly Block[];
|
|
267
|
+
}[];
|
|
268
|
+
readonly steps: number;
|
|
269
|
+
readonly notes: readonly Block[];
|
|
270
|
+
/** The legend line: each symbol's TeX and its name. */
|
|
271
|
+
readonly legend: readonly {
|
|
272
|
+
readonly tex: string;
|
|
273
|
+
readonly label: readonly Inline[];
|
|
274
|
+
}[];
|
|
275
|
+
}
|
|
276
|
+
interface StaticDeck {
|
|
277
|
+
readonly slug: string;
|
|
278
|
+
readonly route: string;
|
|
279
|
+
readonly title: string;
|
|
280
|
+
readonly frames: readonly DeckFrame[];
|
|
281
|
+
/**
|
|
282
|
+
* The page's notation list: its lesson's symbols, its chapter's included.
|
|
283
|
+
* The PDF's appendix keeps the ones its frames use.
|
|
284
|
+
*/
|
|
285
|
+
readonly notation: readonly NotationEntry[];
|
|
286
|
+
}
|
|
287
|
+
/** Read the frames of one built deck page. */
|
|
288
|
+
declare function readStaticDeck(html: string, slug: string, route: string): StaticDeck;
|
|
252
289
|
|
|
253
|
-
export { type Block, type CourseTarget, type DiagramGeometry, type DiagramNodeShape, type FigurePicture, type Inline, type NotationEntry, type RefKind, type StaticPage, type TableCell, courseTarget, readDiagramGeometry, readInlineFragment, readStaticPage, readableText };
|
|
290
|
+
export { type Block, type CourseTarget, type DeckFrame, type DiagramGeometry, type DiagramNodeShape, type FigurePicture, type Inline, type NotationEntry, type RefKind, type StaticDeck, type StaticPage, type TableCell, courseTarget, readDiagramGeometry, readInlineFragment, readStaticDeck, readStaticPage, readableText };
|
|
@@ -386,7 +386,8 @@ function readBlock(node, context) {
|
|
|
386
386
|
anchor: attribute(node, "id") ?? "",
|
|
387
387
|
number: attribute(node, "data-eq-number") ?? "",
|
|
388
388
|
...key ? { key } : {},
|
|
389
|
-
tex: (katex && texOf(katex)) ?? ""
|
|
389
|
+
tex: (katex && texOf(katex)) ?? "",
|
|
390
|
+
...attribute(node, "data-eq-recall") ? { recall: attribute(node, "data-eq-recall") } : {}
|
|
390
391
|
}
|
|
391
392
|
];
|
|
392
393
|
}
|
|
@@ -480,6 +481,18 @@ function readBlock(node, context) {
|
|
|
480
481
|
if (node.tagName === "compact-examples" || hasClass(node, "compact-examples")) {
|
|
481
482
|
return [readExamples(node, context)];
|
|
482
483
|
}
|
|
484
|
+
if (hasClass(node, "deck-check__label") && attribute(node, "data-block-kind") === "check") {
|
|
485
|
+
const anchor = attribute(node, "id") ?? "";
|
|
486
|
+
return [
|
|
487
|
+
{
|
|
488
|
+
kind: "check",
|
|
489
|
+
anchor,
|
|
490
|
+
number: attribute(node, "data-check-number") ?? "",
|
|
491
|
+
assessmentId: anchor.replace(/^check-/u, ""),
|
|
492
|
+
title: [{ kind: "text", value: attribute(node, "data-check-title") ?? "" }]
|
|
493
|
+
}
|
|
494
|
+
];
|
|
495
|
+
}
|
|
483
496
|
if (hasClass(node, "sl-heading-wrapper")) {
|
|
484
497
|
const heading = headingOf(node);
|
|
485
498
|
if (!heading) return readBlocks(node, context);
|
|
@@ -599,6 +612,17 @@ function readStaticPage(html, slug, route) {
|
|
|
599
612
|
const title = elements(main, (node) => node.tagName === "h1")[0];
|
|
600
613
|
const content = elements(main, (node) => hasClass(node, "sl-markdown-content"))[0];
|
|
601
614
|
if (!content) throw new Error(`Built page ${slug} has no .sl-markdown-content element.`);
|
|
615
|
+
const { notation, notationRemarks } = readPageNotation(main, context);
|
|
616
|
+
return {
|
|
617
|
+
slug,
|
|
618
|
+
route,
|
|
619
|
+
title: title ? collapse(readableText(title)).trim() : slug,
|
|
620
|
+
blocks: readBlocks(content, context),
|
|
621
|
+
notation,
|
|
622
|
+
notationRemarks
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
function readPageNotation(main, context) {
|
|
602
626
|
const layer = elements(
|
|
603
627
|
main,
|
|
604
628
|
(node) => hasClass(node, "notation-layer") && attribute(node, "data-notation-layer-id") === "page-notation"
|
|
@@ -607,19 +631,111 @@ function readStaticPage(html, slug, route) {
|
|
|
607
631
|
const remarks = layer ? elements(layer, (node) => node.tagName === "ul" && hasClass(node, "notation-suspended")).flatMap(
|
|
608
632
|
(list) => childrenOf(list).filter((item) => isElement(item) && item.tagName === "li").map((item) => inlineContent(item, context))
|
|
609
633
|
) : [];
|
|
634
|
+
return { notation: entries.map((entry) => readNotationEntry(entry, context)), notationRemarks: remarks };
|
|
635
|
+
}
|
|
636
|
+
function listItemSteps(list) {
|
|
637
|
+
const items = childrenOf(list).filter((child) => isElement(child) && child.tagName === "li");
|
|
638
|
+
let step = 1;
|
|
639
|
+
let any = false;
|
|
640
|
+
const steps = items.map((item) => {
|
|
641
|
+
const at = attribute(item, "data-step");
|
|
642
|
+
if (at !== void 0) {
|
|
643
|
+
step = Number(at) || step;
|
|
644
|
+
any = true;
|
|
645
|
+
}
|
|
646
|
+
return step;
|
|
647
|
+
});
|
|
648
|
+
return any ? steps : void 0;
|
|
649
|
+
}
|
|
650
|
+
function readSegments(body, context) {
|
|
651
|
+
const segments = [];
|
|
652
|
+
const add = (step, blocks) => {
|
|
653
|
+
if (blocks.length === 0) return;
|
|
654
|
+
const last = segments.at(-1);
|
|
655
|
+
if (last && last.step === step) last.blocks.push(...blocks);
|
|
656
|
+
else segments.push({ step, blocks: [...blocks] });
|
|
657
|
+
};
|
|
658
|
+
let pending = [];
|
|
659
|
+
const flush = () => {
|
|
660
|
+
if (pending.length === 0) return;
|
|
661
|
+
const holder = { nodeName: "div", tagName: "div", attrs: [], childNodes: pending };
|
|
662
|
+
add(1, withItemSteps(holder, readBlocks(holder, context)));
|
|
663
|
+
pending = [];
|
|
664
|
+
};
|
|
665
|
+
for (const child of childrenOf(body)) {
|
|
666
|
+
if (isElement(child) && hasClass(child, "deck-step") && attribute(child, "data-step") !== void 0) {
|
|
667
|
+
flush();
|
|
668
|
+
add(Number(attribute(child, "data-step")) || 1, withItemSteps(child, readBlocks(child, context)));
|
|
669
|
+
continue;
|
|
670
|
+
}
|
|
671
|
+
pending.push(child);
|
|
672
|
+
}
|
|
673
|
+
flush();
|
|
674
|
+
return segments;
|
|
675
|
+
}
|
|
676
|
+
function withItemSteps(node, blocks) {
|
|
677
|
+
const lists = childrenOf(node).filter(
|
|
678
|
+
(child) => isElement(child) && (child.tagName === "ul" || child.tagName === "ol")
|
|
679
|
+
);
|
|
680
|
+
let index = 0;
|
|
681
|
+
return blocks.map((block) => {
|
|
682
|
+
if (block.kind !== "list") return block;
|
|
683
|
+
const list = lists[index++];
|
|
684
|
+
const itemSteps = list ? listItemSteps(list) : void 0;
|
|
685
|
+
return itemSteps ? { ...block, itemSteps } : block;
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
function readStaticDeck(html, slug, route) {
|
|
689
|
+
const document = parse(html);
|
|
690
|
+
const base = inferBasePrefix(document);
|
|
691
|
+
const context = { route, base };
|
|
692
|
+
const main = elements(document, (node) => node.tagName === "main")[0];
|
|
693
|
+
if (!main) throw new Error(`Built page ${slug} has no <main> element.`);
|
|
694
|
+
const deck = elements(main, (node) => hasClass(node, "deck") && attribute(node, "data-deck") !== void 0)[0];
|
|
695
|
+
if (!deck) throw new Error(`Built page ${slug} has no deck (.deck[data-deck]).`);
|
|
696
|
+
const title = elements(main, (node) => node.tagName === "h1")[0];
|
|
697
|
+
const frames = childrenOf(deck).filter((child) => isElement(child) && hasClass(child, "deck-frame")).map((frame) => {
|
|
698
|
+
const canvas = firstByClass(frame, "deck-canvas");
|
|
699
|
+
const heading = canvas ? firstByClass(canvas, "deck-frame__title") ?? firstByClass(canvas, "deck-title__title") : void 0;
|
|
700
|
+
const body = canvas ? firstByClass(canvas, "deck-frame__body") : void 0;
|
|
701
|
+
const notes = childrenOf(frame).find(
|
|
702
|
+
(child) => isElement(child) && hasClass(child, "deck-notes")
|
|
703
|
+
);
|
|
704
|
+
const legend = canvas ? firstByClass(canvas, "deck-legend") : void 0;
|
|
705
|
+
const kind = attribute(frame, "data-kind") ?? "frame";
|
|
706
|
+
const generatedContent = !body && canvas ? readBlocks(
|
|
707
|
+
canvas,
|
|
708
|
+
context,
|
|
709
|
+
(child) => !(isElement(child) && (hasClass(child, "deck-frame__title") || hasClass(child, "deck-frame__foot") || hasClass(child, "deck-title__title")))
|
|
710
|
+
) : [];
|
|
711
|
+
return {
|
|
712
|
+
number: Number(attribute(frame, "data-frame")) || 0,
|
|
713
|
+
kind,
|
|
714
|
+
...heading && attribute(heading, "id") ? { anchor: attribute(heading, "id") } : {},
|
|
715
|
+
title: heading ? inlineContent(heading, context) : [],
|
|
716
|
+
segments: body ? readSegments(body, context) : generatedContent.length > 0 ? [{ step: 1, blocks: generatedContent }] : [],
|
|
717
|
+
steps: Number(attribute(frame, "data-steps")) || 1,
|
|
718
|
+
notes: notes ? readBlocks(notes, context) : [],
|
|
719
|
+
legend: legend ? elements(legend, (node) => hasClass(node, "deck-legend__item")).map((item) => {
|
|
720
|
+
const katex = elements(item, (node) => hasClass(node, "katex"))[0];
|
|
721
|
+
const label = firstByClass(item, "deck-legend__label");
|
|
722
|
+
return { tex: (katex && texOf(katex)) ?? "", label: label ? inlineContent(label, context) : [] };
|
|
723
|
+
}) : []
|
|
724
|
+
};
|
|
725
|
+
});
|
|
610
726
|
return {
|
|
611
727
|
slug,
|
|
612
728
|
route,
|
|
613
729
|
title: title ? collapse(readableText(title)).trim() : slug,
|
|
614
|
-
|
|
615
|
-
notation:
|
|
616
|
-
notationRemarks: remarks
|
|
730
|
+
frames,
|
|
731
|
+
notation: readPageNotation(main, context).notation
|
|
617
732
|
};
|
|
618
733
|
}
|
|
619
734
|
export {
|
|
620
735
|
courseTarget,
|
|
621
736
|
readDiagramGeometry,
|
|
622
737
|
readInlineFragment,
|
|
738
|
+
readStaticDeck,
|
|
623
739
|
readStaticPage,
|
|
624
740
|
readableText
|
|
625
741
|
};
|
|
@@ -21,7 +21,13 @@ interface KnowledgeChangelogEntry {
|
|
|
21
21
|
/** Bullet lines under the heading, marker stripped, in file order. */
|
|
22
22
|
readonly notes: readonly string[];
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
/** The released entries and, apart from them, the bullets `## [Unreleased]` holds. */
|
|
25
|
+
interface KnowledgeChangelog {
|
|
26
|
+
readonly entries: readonly KnowledgeChangelogEntry[];
|
|
27
|
+
/** Bullet lines under `## [Unreleased]`, any `###` group included, marker stripped. */
|
|
28
|
+
readonly unreleased: readonly string[];
|
|
29
|
+
}
|
|
30
|
+
type KnowledgeVersionCode = 'knowledge-changelog-missing' | 'knowledge-version-invalid' | 'knowledge-version-mismatch' | 'page-versions-invalid';
|
|
25
31
|
interface KnowledgeVersionDiagnostic {
|
|
26
32
|
readonly code: KnowledgeVersionCode;
|
|
27
33
|
/** Tier 3 — a knowledge-version drift never fails the build. */
|
|
@@ -34,9 +40,27 @@ interface KnowledgeVersion {
|
|
|
34
40
|
readonly version: string;
|
|
35
41
|
/** The newest released `## [x.y.z]` entry, when the changelog has one. */
|
|
36
42
|
readonly latest?: KnowledgeChangelogEntry;
|
|
43
|
+
/** Every released entry, newest first; empty without a changelog. */
|
|
44
|
+
readonly entries: readonly KnowledgeChangelogEntry[];
|
|
45
|
+
/**
|
|
46
|
+
* The bullets `## [Unreleased]` holds: a content change not yet released
|
|
47
|
+
* (rule C1). A page changed while there are any is "not yet released"
|
|
48
|
+
* (rule C5); with none, a change is the release's own, or one rule C1 lets
|
|
49
|
+
* go unlisted.
|
|
50
|
+
*/
|
|
51
|
+
readonly unreleased: readonly string[];
|
|
37
52
|
readonly diagnostics: readonly KnowledgeVersionDiagnostic[];
|
|
38
53
|
}
|
|
39
54
|
declare function isKnowledgeSemver(value: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* A `content/CHANGELOG.md` body: every released entry in file order (newest
|
|
57
|
+
* first, by Keep a Changelog convention), and the bullets of
|
|
58
|
+
* `## [Unreleased]`. A released entry's notes end at a `###` group heading,
|
|
59
|
+
* as the About panel has always shown them; the unreleased bullets are
|
|
60
|
+
* counted through every group, since what they answer is whether anything
|
|
61
|
+
* is waiting for a release.
|
|
62
|
+
*/
|
|
63
|
+
declare function scanKnowledgeChangelog(text: string): KnowledgeChangelog;
|
|
40
64
|
/**
|
|
41
65
|
* Every released entry in a `content/CHANGELOG.md` body, in file order (newest
|
|
42
66
|
* first, by Keep a Changelog convention). `## [Unreleased]` is skipped.
|
|
@@ -55,4 +79,4 @@ declare function resolveKnowledgeVersion(options: {
|
|
|
55
79
|
readonly file?: string;
|
|
56
80
|
}): KnowledgeVersion;
|
|
57
81
|
|
|
58
|
-
export { type KnowledgeChangelogEntry, type KnowledgeVersion, type KnowledgeVersionCode, type KnowledgeVersionDiagnostic, isKnowledgeSemver, parseKnowledgeChangelog, resolveKnowledgeVersion };
|
|
82
|
+
export { type KnowledgeChangelog, type KnowledgeChangelogEntry, type KnowledgeVersion, type KnowledgeVersionCode, type KnowledgeVersionDiagnostic, isKnowledgeSemver, parseKnowledgeChangelog, resolveKnowledgeVersion, scanKnowledgeChangelog };
|
|
@@ -4,18 +4,19 @@ const BULLET_RE = /^[-*]\s+(.*\S)\s*$/;
|
|
|
4
4
|
function isKnowledgeSemver(value) {
|
|
5
5
|
return SEMVER_RE.test(value.trim());
|
|
6
6
|
}
|
|
7
|
-
function
|
|
7
|
+
function scanKnowledgeChangelog(text) {
|
|
8
8
|
const lines = text.split(/\r?\n/);
|
|
9
9
|
const entries = [];
|
|
10
|
+
const unreleased = [];
|
|
10
11
|
let current = null;
|
|
12
|
+
let inUnreleased = false;
|
|
11
13
|
for (const line of lines) {
|
|
12
14
|
const heading = HEADING_RE.exec(line);
|
|
13
15
|
if (heading) {
|
|
14
16
|
const token = (heading[1] ?? "").trim();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
17
|
+
current = null;
|
|
18
|
+
inUnreleased = /^unreleased$/i.test(token);
|
|
19
|
+
if (inUnreleased) continue;
|
|
19
20
|
current = { version: token, notes: [] };
|
|
20
21
|
const date = (heading[2] ?? "").trim();
|
|
21
22
|
if (date) current.date = date;
|
|
@@ -24,17 +25,25 @@ function parseKnowledgeChangelog(text) {
|
|
|
24
25
|
}
|
|
25
26
|
if (/^#{1,3}\s/.test(line) && !line.startsWith("## [")) {
|
|
26
27
|
current = null;
|
|
28
|
+
if (/^#{1,2}\s/.test(line)) inUnreleased = false;
|
|
27
29
|
continue;
|
|
28
30
|
}
|
|
29
|
-
if (!current) continue;
|
|
30
31
|
const bullet = BULLET_RE.exec(line);
|
|
31
|
-
if (bullet)
|
|
32
|
+
if (!bullet) continue;
|
|
33
|
+
if (current) current.notes.push(bullet[1] ?? "");
|
|
34
|
+
else if (inUnreleased) unreleased.push(bullet[1] ?? "");
|
|
32
35
|
}
|
|
33
|
-
return
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
return {
|
|
37
|
+
entries: entries.map((entry) => ({
|
|
38
|
+
version: entry.version,
|
|
39
|
+
...entry.date === void 0 ? {} : { date: entry.date },
|
|
40
|
+
notes: [...entry.notes]
|
|
41
|
+
})),
|
|
42
|
+
unreleased
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function parseKnowledgeChangelog(text) {
|
|
46
|
+
return [...scanKnowledgeChangelog(text).entries];
|
|
38
47
|
}
|
|
39
48
|
function resolveKnowledgeVersion(options) {
|
|
40
49
|
const { changelogText, declaredVersion } = options;
|
|
@@ -54,16 +63,16 @@ function resolveKnowledgeVersion(options) {
|
|
|
54
63
|
"knowledge-changelog-missing",
|
|
55
64
|
`No ${file}. Add a Keep a Changelog file whose newest \`## [x.y.z]\` heading is ${JSON.stringify(declaredVersion)} (rule C1).`
|
|
56
65
|
);
|
|
57
|
-
return { version: declaredVersion, diagnostics };
|
|
66
|
+
return { version: declaredVersion, entries: [], unreleased: [], diagnostics };
|
|
58
67
|
}
|
|
59
|
-
const entries =
|
|
68
|
+
const { entries, unreleased } = scanKnowledgeChangelog(changelogText);
|
|
60
69
|
const latest = entries[0];
|
|
61
70
|
if (!latest) {
|
|
62
71
|
warn(
|
|
63
72
|
"knowledge-changelog-missing",
|
|
64
73
|
`${file} has no released \`## [x.y.z]\` entry \u2014 only \`## [Unreleased]\`. Cut a release: move it to \`## [${declaredVersion}] - <date>\` (rule C3).`
|
|
65
74
|
);
|
|
66
|
-
return { version: declaredVersion, diagnostics };
|
|
75
|
+
return { version: declaredVersion, entries, unreleased, diagnostics };
|
|
67
76
|
}
|
|
68
77
|
if (isKnowledgeSemver(declaredVersion) && latest.version !== declaredVersion) {
|
|
69
78
|
warn(
|
|
@@ -71,10 +80,11 @@ function resolveKnowledgeVersion(options) {
|
|
|
71
80
|
`about.version is ${JSON.stringify(declaredVersion)} but the newest ${file} entry is ${JSON.stringify(latest.version)}. Bump one to match the other (rule C3).`
|
|
72
81
|
);
|
|
73
82
|
}
|
|
74
|
-
return { version: declaredVersion, latest, diagnostics };
|
|
83
|
+
return { version: declaredVersion, latest, entries, unreleased, diagnostics };
|
|
75
84
|
}
|
|
76
85
|
export {
|
|
77
86
|
isKnowledgeSemver,
|
|
78
87
|
parseKnowledgeChangelog,
|
|
79
|
-
resolveKnowledgeVersion
|
|
88
|
+
resolveKnowledgeVersion,
|
|
89
|
+
scanKnowledgeChangelog
|
|
80
90
|
};
|
|
@@ -23,14 +23,62 @@
|
|
|
23
23
|
* shared keys the body names with `[[key]]` / `\explain` — so an import list
|
|
24
24
|
* is redundant.
|
|
25
25
|
*/
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* `foundations/discount-factors` → `foundations.discount-factors`. A deck
|
|
28
|
+
* file's slug (`foundations/discount-factors.deck.mdx`) gives its lesson's id;
|
|
29
|
+
* a deck's route (`foundations/discount-factors/slides`) gives the deck's page
|
|
30
|
+
* id, `foundations.discount-factors.slides` ({@link deckPageId}).
|
|
31
|
+
*/
|
|
27
32
|
declare function lessonIdFromSlug(slug: string): string;
|
|
28
33
|
/**
|
|
29
|
-
* A docs entry is a
|
|
34
|
+
* A docs entry is a chapter when it lives in a section directory. The three
|
|
30
35
|
* top-level pages (`index`, `curriculum-map`, `glossary`) are not lessons; a
|
|
31
|
-
* future `<section>/index` page would not be one either
|
|
36
|
+
* future `<section>/index` page would not be one either, and neither is a
|
|
37
|
+
* lesson's deck file (`<lesson>.deck.mdx`, {@link isDeckSlug}), which is an
|
|
38
|
+
* edition of a lesson rather than a lesson.
|
|
32
39
|
*/
|
|
33
40
|
declare function isLessonSlug(slug: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* The last segment of a deck's route when the deck stands beside its chapter:
|
|
43
|
+
* `projectiles/projectile-range` is the chapter, `projectiles/projectile-range/slides`
|
|
44
|
+
* the deck.
|
|
45
|
+
*/
|
|
46
|
+
declare const DECK_ROUTE_SEGMENT = "slides";
|
|
47
|
+
/**
|
|
48
|
+
* A deck file — a lesson's slide edition, `content/docs/<part>/<lesson>.deck.mdx`
|
|
49
|
+
* beside the chapter `<lesson>.mdx` or alone for a lesson that is only slides,
|
|
50
|
+
* or a part's deck ({@link isPartDeckSlug}). True for the docs slug with or
|
|
51
|
+
* without its extension; a caller that needs the lesson asks
|
|
52
|
+
* {@link isPartDeckSlug} first.
|
|
53
|
+
*/
|
|
54
|
+
declare function isDeckSlug(slug: string): boolean;
|
|
55
|
+
/** The lesson a lesson's deck file belongs to: `motion/range.deck.mdx` → `motion/range`. */
|
|
56
|
+
declare function deckLessonSlug(slug: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* A part's deck, `content/docs/<part>/index.deck.mdx` beside the part's page
|
|
59
|
+
* `index.mdx`: the slides of the part, served at `/<part>/slides/`
|
|
60
|
+
* ({@link partDeckRouteSlug}), whose `##` sections may each name the chapter
|
|
61
|
+
* they cover (`docs/authoring/deck.md`). It is no lesson's edition.
|
|
62
|
+
*/
|
|
63
|
+
declare function isPartDeckSlug(slug: string): boolean;
|
|
64
|
+
/** The part a part's deck belongs to: `motion/index.deck.mdx` → `motion`. */
|
|
65
|
+
declare function partDeckDir(slug: string): string;
|
|
66
|
+
/** Where a part's deck is served: `<part>/slides`, as a chapter's deck is `<lesson>/slides`. */
|
|
67
|
+
declare function partDeckRouteSlug(partDir: string): string;
|
|
68
|
+
/** The page id of a part's deck, the id of its route: `<part>.slides`. */
|
|
69
|
+
declare function partDeckPageId(partDir: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* Where a lesson's deck is served: `<lesson>/slides` beside its chapter, or
|
|
72
|
+
* the lesson's own route when the lesson has no chapter (a slides-first
|
|
73
|
+
* lesson, whose deck is its only edition).
|
|
74
|
+
*/
|
|
75
|
+
declare function deckRouteSlug(lessonSlug: string, hasChapter: boolean): string;
|
|
76
|
+
/**
|
|
77
|
+
* The page id a deck's notation bundle, gates and diagnostics use — the id of
|
|
78
|
+
* its route ({@link lessonIdFromSlug}): `<lessonId>.slides` beside a chapter,
|
|
79
|
+
* the lesson's own id for a slides-first lesson.
|
|
80
|
+
*/
|
|
81
|
+
declare function deckPageId(lessonId: string, hasChapter: boolean): string;
|
|
34
82
|
/**
|
|
35
83
|
* The docs slugs a Starlight route id can stand for. The glob loader shortens
|
|
36
84
|
* `<dir>/index.mdx` to the id `<dir>`, and may give the landing page an empty
|
|
@@ -85,12 +133,21 @@ interface SidebarSection {
|
|
|
85
133
|
/**
|
|
86
134
|
* One sidebar entry: a lesson slug, or an explicit link. `attrs` is Starlight's
|
|
87
135
|
* own passthrough onto the rendered `<a>` — the engine uses it to mark a part's
|
|
88
|
-
* overview row so CSS can give it its own icon
|
|
136
|
+
* overview row so CSS can give it its own icon, and to name each edition of a
|
|
137
|
+
* lesson for the sidebar's script ({@link buildSidebar}).
|
|
89
138
|
*/
|
|
90
139
|
type SidebarItem = string | {
|
|
91
140
|
readonly label: string;
|
|
92
141
|
readonly link: string;
|
|
93
142
|
readonly attrs?: Readonly<Record<string, string>>;
|
|
143
|
+
} | {
|
|
144
|
+
/**
|
|
145
|
+
* A docs entry by its id (Starlight's `slug` item), with its own label,
|
|
146
|
+
* or the entry's title without one.
|
|
147
|
+
*/
|
|
148
|
+
readonly slug: string;
|
|
149
|
+
readonly label?: string;
|
|
150
|
+
readonly attrs?: Readonly<Record<string, string>>;
|
|
94
151
|
};
|
|
95
152
|
interface SidebarGroup {
|
|
96
153
|
readonly label: string;
|
|
@@ -98,15 +155,95 @@ interface SidebarGroup {
|
|
|
98
155
|
}
|
|
99
156
|
/** Marks the overview row so `global.css` can give it its own icon. */
|
|
100
157
|
declare const PART_OVERVIEW_CLASS = "explico-part-overview";
|
|
158
|
+
/**
|
|
159
|
+
* Marks a deck's row, listed under its chapter, so `deck.css` can set it
|
|
160
|
+
* apart. That is the sidebar without its script; with it, the deck is its
|
|
161
|
+
* chapter row's trailing icon, or leads the row (`sidebar-editions.ts`).
|
|
162
|
+
*/
|
|
163
|
+
declare const DECK_ROW_CLASS = "explico-deck-row";
|
|
164
|
+
/**
|
|
165
|
+
* Marks a slides-first lesson's row, whose deck is the lesson, so `deck.css`
|
|
166
|
+
* gives it the deck's glyph where a chapter has none (a row) or a sheet (a
|
|
167
|
+
* compact tile). It is a lesson of the reading order, unlike {@link DECK_ROW_CLASS}.
|
|
168
|
+
*/
|
|
169
|
+
declare const DECK_LESSON_CLASS = "explico-deck-lesson";
|
|
170
|
+
/**
|
|
171
|
+
* Marks a part's deck, listed right after the part's Overview (with
|
|
172
|
+
* {@link DECK_ROW_CLASS}, so Next and Previous step past it as past any
|
|
173
|
+
* deck): the part's own, as Overview is, with the part's deck glyph. The
|
|
174
|
+
* sidebar's script makes the two one row, the part's, as a lesson's chapter
|
|
175
|
+
* and deck are one (`sidebar-editions.ts`).
|
|
176
|
+
*/
|
|
177
|
+
declare const PART_DECK_CLASS = "explico-part-deck";
|
|
178
|
+
/**
|
|
179
|
+
* Numbers as a reader reads a run of them: `1–2`, `1, 3`, `2–4, 6`. A run of
|
|
180
|
+
* two or more is its ends with an en dash.
|
|
181
|
+
*/
|
|
182
|
+
declare function numberList(numbers: readonly number[]): string;
|
|
183
|
+
/**
|
|
184
|
+
* The lesson a sidebar item lists, by its slug: an item served at its
|
|
185
|
+
* lesson's own URL (its `data-lesson` is its `slug`), a chapter or a
|
|
186
|
+
* slides-first lesson's deck. A part's overview, a chapter's slides row
|
|
187
|
+
* (served under the chapter) and a link list no lesson. A bare slug is a
|
|
188
|
+
* lesson too.
|
|
189
|
+
*/
|
|
190
|
+
declare function sidebarLessonSlug(item: SidebarItem): string | undefined;
|
|
101
191
|
/**
|
|
102
192
|
* The Starlight `sidebar` config: one group per section, lessons ordered by the
|
|
103
193
|
* merged track order (ties broken by slug), then the static Reference group.
|
|
104
194
|
* Replaces seven `autogenerate` blocks that read an authored `sidebar.order`.
|
|
105
195
|
* `floatIndex`: the course has a top-level "Figures and tables" page
|
|
106
196
|
* (`figures-and-tables.mdx`, `FloatIndex.astro`), listed in Reference.
|
|
197
|
+
*
|
|
198
|
+
* Each edition of a lesson is an item of its own, its chapter first, and
|
|
199
|
+
* names its edition, lesson and title (`data-edition`, `data-lesson`,
|
|
200
|
+
* `data-title` on the link): the HTML lists both, and the sidebar's script
|
|
201
|
+
* (`LayoutSidebar.astro`, `sidebar-editions.ts`) makes the two one row.
|
|
202
|
+
*
|
|
203
|
+
* A part's deck is an item of the part right after its Overview. Both name
|
|
204
|
+
* their part and which of its two editions they are (`data-part`,
|
|
205
|
+
* `data-part-edition`), and the deck its part's label and the ordinals of
|
|
206
|
+
* the chapters it covers (`data-title`, `data-chapters`: `1–2`), so the
|
|
207
|
+
* script makes them the part's one row. A chapter it covers that has no deck
|
|
208
|
+
* of its own carries the address of its section in the part's deck
|
|
209
|
+
* (`data-deck-href`, `/<part>/slides/#slide-N`, without the site's base),
|
|
210
|
+
* which the script makes the chapter's other edition: a lesson's own deck
|
|
211
|
+
* wins over its part's. The frames the deck and each section hold are
|
|
212
|
+
* `buildDecks`'s, added once it has run ({@link withPartDeckFrames}).
|
|
107
213
|
*/
|
|
108
|
-
declare function buildSidebar(tracks: readonly TrackLike[], lessonSlugs: readonly string[], parts: readonly SidebarSection[], { floatIndex }?: {
|
|
214
|
+
declare function buildSidebar(tracks: readonly TrackLike[], lessonSlugs: readonly string[], parts: readonly SidebarSection[], { floatIndex, decks, slidesFirst, partDecks, titleOf, }?: {
|
|
109
215
|
readonly floatIndex?: boolean;
|
|
216
|
+
/** A deck beside its chapter: chapter slug → the deck's route, listed under the chapter. */
|
|
217
|
+
readonly decks?: ReadonlyMap<string, string>;
|
|
218
|
+
/** The lessons whose only edition is a deck, by slug: listed with the deck's glyph. */
|
|
219
|
+
readonly slidesFirst?: ReadonlySet<string>;
|
|
220
|
+
/**
|
|
221
|
+
* A part's deck, by the part's directory: its route, and the frame each
|
|
222
|
+
* chapter it covers opens on (its section's divider), by chapter slug.
|
|
223
|
+
*/
|
|
224
|
+
readonly partDecks?: ReadonlyMap<string, {
|
|
225
|
+
readonly route: string;
|
|
226
|
+
readonly covers: ReadonlyMap<string, number>;
|
|
227
|
+
}>;
|
|
228
|
+
/** A lesson's title, by its slug: `data-title` on each of its items, left out when unknown. */
|
|
229
|
+
readonly titleOf?: (slug: string) => string | undefined;
|
|
110
230
|
}): SidebarGroup[];
|
|
231
|
+
/** A part's deck as {@link withPartDeckFrames} reads it: its part and its frames, each with the chapter it covers. */
|
|
232
|
+
interface PartDeckFrames {
|
|
233
|
+
readonly part?: string;
|
|
234
|
+
readonly frames: readonly {
|
|
235
|
+
readonly number: number;
|
|
236
|
+
readonly chapter?: string;
|
|
237
|
+
}[];
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* The sidebar with each part's deck's frames, as `buildDecks` numbers them:
|
|
241
|
+
* the deck's count on its item (`data-frames`), and on each chapter that
|
|
242
|
+
* links into its section the frames that section holds (`data-deck-range`,
|
|
243
|
+
* `2–16`, or `5` for one), its first to its last when it runs over several
|
|
244
|
+
* sections. `buildDecks` runs after the sidebar is built, since the chapters
|
|
245
|
+
* it numbers are ordered by the sidebar.
|
|
246
|
+
*/
|
|
247
|
+
declare function withPartDeckFrames(groups: readonly SidebarGroup[], decks: readonly PartDeckFrames[]): SidebarGroup[];
|
|
111
248
|
|
|
112
|
-
export { PART_OVERVIEW_CLASS, type SidebarGroup, type SidebarItem, type SidebarSection, buildSidebar, citedSourceIds, deriveRequires, deriveSources, docsSlugsForRoute, isLessonSlug, lessonIdFromSlug, mergeTrackOrder, parseCheckList };
|
|
249
|
+
export { DECK_LESSON_CLASS, DECK_ROUTE_SEGMENT, DECK_ROW_CLASS, PART_DECK_CLASS, PART_OVERVIEW_CLASS, type PartDeckFrames, type SidebarGroup, type SidebarItem, type SidebarSection, buildSidebar, citedSourceIds, deckLessonSlug, deckPageId, deckRouteSlug, deriveRequires, deriveSources, docsSlugsForRoute, isDeckSlug, isLessonSlug, isPartDeckSlug, lessonIdFromSlug, mergeTrackOrder, numberList, parseCheckList, partDeckDir, partDeckPageId, partDeckRouteSlug, sidebarLessonSlug, withPartDeckFrames };
|