explico 0.11.1 → 0.13.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 +1292 -1
- package/README.md +91 -13
- package/dist/compiler/astro.d.ts +11 -4
- package/dist/compiler/astro.js +48 -15
- package/dist/compiler/cli.d.ts +27 -12
- package/dist/compiler/cli.js +96 -25
- package/dist/compiler/collections.d.ts +33 -2
- package/dist/compiler/collections.js +91 -19
- package/dist/compiler/content-schema.d.ts +31 -0
- package/dist/compiler/content-schema.js +82 -0
- package/dist/compiler/content-schemas.d.ts +422 -0
- package/dist/compiler/content-schemas.js +229 -0
- package/dist/compiler/course-config.d.ts +1 -1
- package/dist/compiler/course-config.js +30 -2
- package/dist/compiler/exports/combined-html.d.ts +97 -0
- package/dist/compiler/exports/combined-html.js +492 -0
- package/dist/compiler/exports/download-index.d.ts +9 -0
- package/dist/compiler/exports/download-index.js +33 -0
- package/dist/compiler/exports/export-chapters.d.ts +98 -0
- package/dist/compiler/exports/export-chapters.js +164 -0
- package/dist/compiler/exports/export-pages.d.ts +48 -0
- package/dist/compiler/exports/export-pages.js +22 -0
- package/dist/compiler/exports/html-tree.d.ts +22 -0
- package/dist/compiler/exports/html-tree.js +47 -0
- package/dist/compiler/exports/latex/capture.d.ts +106 -0
- package/dist/compiler/exports/latex/capture.js +435 -0
- package/dist/compiler/exports/latex/compile.d.ts +73 -0
- package/dist/compiler/exports/latex/compile.js +115 -0
- package/dist/compiler/exports/latex/document.d.ts +102 -0
- package/dist/compiler/exports/latex/document.js +349 -0
- package/dist/compiler/exports/latex/explico.cls +415 -0
- package/dist/compiler/exports/latex/numbering.d.ts +18 -0
- package/dist/compiler/exports/latex/numbering.js +57 -0
- package/dist/compiler/exports/latex/serialize.d.ts +112 -0
- package/dist/compiler/exports/latex/serialize.js +606 -0
- package/dist/compiler/exports/latex-export.d.ts +44 -0
- package/dist/compiler/exports/latex-export.js +169 -0
- package/dist/compiler/exports/markdown/serialize.d.ts +51 -0
- package/dist/compiler/exports/markdown/serialize.js +527 -0
- package/dist/compiler/exports/markdown-export.d.ts +39 -0
- package/dist/compiler/exports/markdown-export.js +240 -0
- package/dist/compiler/exports/standalone-html.d.ts +15 -5
- package/dist/compiler/exports/standalone-html.js +23 -51
- package/dist/compiler/exports/static-tree.d.ts +253 -0
- package/dist/compiler/exports/static-tree.js +625 -0
- package/dist/compiler/exports/zip.d.ts +16 -0
- package/dist/compiler/exports/zip.js +72 -0
- package/dist/compiler/lesson-derivation.d.ts +8 -2
- package/dist/compiler/lesson-derivation.js +6 -7
- package/dist/compiler/manifest.d.ts +115 -8
- package/dist/compiler/manifest.js +221 -39
- package/dist/compiler/render-diagnostics.d.ts +65 -0
- package/dist/compiler/render-diagnostics.js +56 -0
- package/dist/compiler/resolution-report.d.ts +3 -1
- package/dist/{course-config-Dsnri9Tk.d.ts → course-config-rRtME5UV.d.ts} +56 -13
- package/dist/curriculum/validation.d.ts +9 -3
- package/dist/curriculum/validation.js +35 -17
- package/dist/reference/base-abbreviations.d.mts +2 -2
- package/dist/reference/base-abbreviations.mjs +2 -2
- package/dist/reference/base-operators.d.mts +8 -2
- package/dist/reference/base-operators.mjs +8 -10
- package/dist/reference/base-roman-labels.d.mts +4 -3
- package/dist/reference/base-roman-labels.mjs +4 -3
- package/dist/reference/citation-format.d.mts +35 -0
- package/dist/reference/citation-format.mjs +74 -0
- package/dist/reference/consistency.d.ts +5 -9
- package/dist/reference/consistency.js +34 -38
- package/dist/reference/curriculum-alignment.js +3 -24
- package/dist/reference/derived-entries.d.ts +45 -0
- package/dist/reference/derived-entries.js +50 -0
- package/dist/reference/derived-notation.d.mts +125 -0
- package/dist/reference/derived-notation.mjs +121 -0
- package/dist/reference/diagram-fit.d.ts +45 -0
- package/dist/reference/diagram-fit.js +54 -0
- package/dist/reference/diagram-layout.d.ts +59 -10
- package/dist/reference/diagram-layout.js +85 -24
- package/dist/reference/diagrams-validate.d.ts +1 -1
- package/dist/reference/equations-validate.d.ts +1 -1
- package/dist/reference/equations-validate.js +26 -1
- package/dist/reference/equations.d.mts +27 -0
- package/dist/reference/equations.mjs +120 -22
- package/dist/reference/examples-validate.d.ts +1 -1
- package/dist/reference/figure-fit.d.ts +70 -0
- package/dist/reference/figure-fit.js +60 -0
- package/dist/reference/figure-pictures.d.ts +27 -0
- package/dist/reference/figure-pictures.js +49 -0
- package/dist/reference/figure-symbols.d.ts +32 -0
- package/dist/reference/figure-symbols.js +55 -0
- package/dist/reference/figures-validate.d.ts +1 -1
- package/dist/reference/gate-abbreviations.d.ts +1 -1
- package/dist/reference/gate-abbreviations.js +1 -1
- package/dist/reference/gate-course-rules.d.ts +4 -3
- package/dist/reference/gate-course-rules.js +9 -4
- package/dist/reference/gate-heading-length.d.ts +2 -0
- package/dist/reference/gate-heading-length.js +7 -5
- package/dist/reference/gate-heading-structure.js +26 -0
- package/dist/reference/gate-indices.d.ts +35 -0
- package/dist/reference/gate-indices.js +299 -0
- package/dist/reference/gate-math.d.ts +32 -2
- package/dist/reference/gate-math.js +68 -12
- package/dist/reference/gate-mdx-expression.d.ts +17 -0
- package/dist/reference/gate-mdx-expression.js +29 -0
- package/dist/reference/gate-non-chapter-pages.d.ts +39 -0
- package/dist/reference/gate-non-chapter-pages.js +156 -0
- package/dist/reference/gate-part-pages.d.ts +4 -2
- package/dist/reference/gate-part-pages.js +2 -1
- package/dist/reference/gate-prop-text.d.ts +28 -0
- package/dist/reference/gate-prop-text.js +106 -0
- package/dist/reference/gate-prose-notation.d.ts +3 -1
- package/dist/reference/gate-prose-notation.js +4 -2
- package/dist/reference/gate-retired-keys.d.ts +35 -0
- package/dist/reference/gate-retired-keys.js +58 -0
- package/dist/reference/gloss.d.ts +2 -0
- package/dist/reference/katex-measure.d.ts +17 -0
- package/dist/reference/katex-measure.js +223 -0
- package/dist/reference/keyed-float-validate.js +12 -0
- package/dist/reference/keyed-jsx-floats.d.mts +2 -2
- package/dist/reference/keyed-jsx-floats.mjs +11 -14
- package/dist/reference/lab-katex-validate.d.ts +43 -0
- package/dist/reference/lab-katex-validate.js +96 -0
- package/dist/reference/lab-math-scope.d.ts +1 -0
- package/dist/reference/lab-math-scope.js +13 -2
- package/dist/reference/lint-ignore.js +1 -1
- package/dist/reference/math-glyphs.d.mts +94 -2
- package/dist/reference/math-glyphs.mjs +851 -46
- package/dist/reference/mixed-content.d.ts +8 -3
- package/dist/reference/mixed-content.js +4 -2
- package/dist/reference/page-notation.d.ts +39 -7
- package/dist/reference/page-notation.js +62 -10
- package/dist/reference/raw-floats.mjs +37 -13
- package/dist/reference/references.d.ts +11 -1
- package/dist/reference/references.js +6 -0
- package/dist/reference/registry.js +115 -11
- package/dist/reference/rehype-fail-katex-errors.d.mts +9 -0
- package/dist/reference/rehype-fail-katex-errors.mjs +19 -0
- package/dist/reference/rehype-heading-anchors.mjs +11 -1
- package/dist/reference/remark-citation.mjs +0 -0
- package/dist/reference/remark-notation.mjs +275 -23
- package/dist/reference/render-lab-math.d.ts +13 -2
- package/dist/reference/render-lab-math.js +18 -6
- package/dist/reference/sections-validate.d.ts +28 -3
- package/dist/reference/sections-validate.js +31 -4
- package/dist/reference/sections.d.mts +24 -6
- package/dist/reference/sections.mjs +92 -17
- package/dist/reference/tables-validate.d.ts +1 -1
- package/dist/reference/tables-validate.js +24 -1
- package/dist/reference/text-measure.d.ts +10 -0
- package/dist/reference/text-measure.js +41 -0
- package/dist/reference/text-widths.d.ts +10 -0
- package/dist/reference/text-widths.js +1238 -0
- package/dist/reference/types.d.ts +64 -8
- package/dist/rules/catalog.js +223 -32
- package/dist/rules/in-effect.d.ts +1 -1
- package/dist/rules/rules.schema.json +100 -27
- package/dist/rules/settings.d.ts +1 -1
- package/dist/rules/settings.js +7 -0
- package/dist/session/PreferenceStore.d.ts +18 -1
- package/dist/session/PreferenceStore.js +29 -1
- package/docs/authoring/README.md +33 -21
- package/docs/authoring/agents.md +38 -7
- package/docs/authoring/components.md +115 -10
- package/docs/authoring/migrating.md +878 -0
- package/docs/authoring/notation.md +285 -30
- package/docs/authoring/retired.md +1 -0
- package/docs/authoring/structure-rules.md +84 -45
- package/docs/authoring/structure.md +67 -2
- package/docs/authoring/visualizations.md +167 -25
- package/package.json +12 -7
- package/src/compiler/astro.ts +72 -21
- package/src/compiler/cli.ts +143 -35
- package/src/compiler/collections.ts +158 -27
- package/src/compiler/content-schema.ts +108 -0
- package/src/compiler/content-schemas.ts +391 -0
- package/src/compiler/course-config.ts +86 -15
- package/src/compiler/exports/combined-html.ts +669 -0
- package/src/compiler/exports/download-index.ts +36 -0
- package/src/compiler/exports/export-chapters.ts +233 -0
- package/src/compiler/exports/export-pages.ts +44 -0
- package/src/compiler/exports/html-tree.ts +62 -0
- package/src/compiler/exports/latex/capture.ts +651 -0
- package/src/compiler/exports/latex/compile.ts +168 -0
- package/src/compiler/exports/latex/document.ts +479 -0
- package/src/compiler/exports/latex/explico.cls +415 -0
- package/src/compiler/exports/latex/numbering.ts +74 -0
- package/src/compiler/exports/latex/serialize.ts +787 -0
- package/src/compiler/exports/latex/texlive-packages.txt +76 -0
- package/src/compiler/exports/latex-export.ts +255 -0
- package/src/compiler/exports/markdown/serialize.ts +632 -0
- package/src/compiler/exports/markdown-export.ts +329 -0
- package/src/compiler/exports/standalone-html.ts +39 -70
- package/src/compiler/exports/static-tree.ts +944 -0
- package/src/compiler/exports/zip.ts +88 -0
- package/src/compiler/lesson-derivation.ts +13 -8
- package/src/compiler/manifest.ts +387 -40
- package/src/compiler/render-diagnostics.ts +111 -0
- package/src/components/CourseContents.astro +6 -0
- package/src/components/HoverPanel.astro +204 -6
- package/src/components/PartOverview.astro +18 -9
- package/src/components/abbreviation/AbbreviationGlossary.astro +6 -2
- package/src/components/abbreviation/AbbreviationLayer.astro +21 -12
- package/src/components/assessments/AssessmentRunner.tsx +7 -1
- package/src/components/assessments/AssessmentSet.astro +14 -1
- package/src/components/block-heading.ts +38 -0
- package/src/components/card-arrow.ts +18 -4
- package/src/components/card-carry.ts +406 -0
- package/src/components/card-drag.ts +1 -30
- package/src/components/card-fetch.ts +87 -0
- package/src/components/card-manager.ts +1222 -38
- package/src/components/card-memory.ts +5 -1
- package/src/components/card-placement.ts +211 -13
- package/src/components/card-side.ts +281 -31
- package/src/components/citation/CitationLayer.astro +45 -40
- package/src/components/diagram/Diagram.astro +123 -44
- package/src/components/disclosure/print-as-shown.ts +42 -6
- package/src/components/figure/Figure.astro +17 -1
- package/src/components/figure/FloatCaption.astro +4 -17
- package/src/components/figure/figure-state.ts +26 -17
- package/src/components/float-toolbar.ts +274 -0
- package/src/components/memo/Memo.astro +21 -10
- package/src/components/memo/ShortNote.astro +4 -0
- package/src/components/notation/NotationGlossary.astro +22 -17
- package/src/components/notation/NotationLayer.astro +300 -79
- package/src/components/notation/NotationMath.astro +8 -1
- package/src/components/notation/render-notation-math.ts +51 -5
- package/src/components/readable-text.ts +25 -0
- package/src/components/reference/FloatRefLayer.astro +162 -89
- package/src/components/starlight/HeadingAnchorEnhancer.astro +13 -8
- package/src/components/starlight/KeyedFloatEnhancer.astro +28 -9
- package/src/components/starlight/LayoutPageSidebar.astro +17 -3
- package/src/components/starlight/LayoutSocialIcons.astro +79 -29
- package/src/components/starlight/LessonExportActions.astro +384 -310
- package/src/components/starlight/LessonFooter.astro +66 -8
- package/src/components/starlight/PrintController.astro +28 -0
- package/src/components/starlight/TextSizeControl.astro +137 -0
- package/src/components/starlight/print-controller.ts +380 -0
- package/src/components/starlight/section-summary.ts +13 -5
- package/src/components/table/Table.astro +14 -22
- package/src/components/table/table-truncation.ts +15 -0
- package/src/content-config.ts +20 -312
- package/src/curriculum/validation.ts +72 -24
- package/src/reference/base-abbreviations.mjs +2 -2
- package/src/reference/base-operators.mjs +8 -10
- package/src/reference/base-roman-labels.mjs +4 -3
- package/src/reference/citation-format.mjs +74 -0
- package/src/reference/consistency.ts +47 -61
- package/src/reference/curriculum-alignment.ts +4 -41
- package/src/reference/derived-entries.ts +68 -0
- package/src/reference/derived-notation.mjs +121 -0
- package/src/reference/diagram-fit.ts +104 -0
- package/src/reference/diagram-layout.ts +182 -51
- package/src/reference/diagrams-validate.ts +2 -1
- package/src/reference/equations-validate.ts +41 -2
- package/src/reference/equations.mjs +120 -22
- package/src/reference/examples-validate.ts +1 -0
- package/src/reference/figure-fit.ts +139 -0
- package/src/reference/figure-pictures.ts +96 -0
- package/src/reference/figure-symbols.ts +117 -0
- package/src/reference/figures-validate.ts +2 -1
- package/src/reference/gate-abbreviations.ts +1 -1
- package/src/reference/gate-course-rules.ts +22 -7
- package/src/reference/gate-heading-length.ts +25 -7
- package/src/reference/gate-heading-structure.ts +40 -1
- package/src/reference/gate-indices.ts +470 -0
- package/src/reference/gate-math.ts +102 -13
- package/src/reference/gate-mdx-expression.ts +45 -0
- package/src/reference/gate-non-chapter-pages.ts +241 -0
- package/src/reference/gate-part-pages.ts +1 -1
- package/src/reference/gate-prop-text.ts +145 -0
- package/src/reference/gate-prose-notation.ts +19 -5
- package/src/reference/gate-retired-keys.ts +101 -0
- package/src/reference/gloss.ts +2 -0
- package/src/reference/katex-measure.ts +384 -0
- package/src/reference/keyed-float-validate.ts +22 -0
- package/src/reference/keyed-jsx-floats.mjs +11 -14
- package/src/reference/lab-katex-validate.ts +156 -0
- package/src/reference/lab-math-scope.ts +15 -1
- package/src/reference/lint-ignore.ts +4 -1
- package/src/reference/math-glyphs.mjs +851 -46
- package/src/reference/mixed-content.ts +11 -2
- package/src/reference/page-notation.ts +114 -14
- package/src/reference/raw-floats.mjs +37 -13
- package/src/reference/references.ts +14 -0
- package/src/reference/registry.ts +170 -9
- package/src/reference/rehype-fail-katex-errors.mjs +19 -0
- package/src/reference/rehype-heading-anchors.mjs +11 -1
- package/src/reference/remark-citation.mjs +0 -0
- package/src/reference/remark-notation.mjs +275 -23
- package/src/reference/render-lab-math.ts +40 -5
- package/src/reference/sections-validate.ts +67 -3
- package/src/reference/sections.mjs +92 -17
- package/src/reference/tables-validate.ts +40 -2
- package/src/reference/text-measure.ts +63 -0
- package/src/reference/text-widths.ts +133 -0
- package/src/reference/types.ts +75 -8
- package/src/rules/catalog.ts +241 -31
- package/src/rules/settings.ts +10 -0
- package/src/session/PreferenceStore.ts +53 -0
- package/src/styles/global.css +322 -83
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { availableParallelism } from "node:os";
|
|
3
|
+
import { dirname, extname, join } from "node:path";
|
|
4
|
+
import { performance } from "node:perf_hooks";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { zip } from "./zip.js";
|
|
7
|
+
import {
|
|
8
|
+
consoleLogger,
|
|
9
|
+
epochOf,
|
|
10
|
+
figuresOf,
|
|
11
|
+
imageFile,
|
|
12
|
+
needsCapture,
|
|
13
|
+
prepareChapters,
|
|
14
|
+
readBuiltPage,
|
|
15
|
+
strictMode
|
|
16
|
+
} from "./export-chapters.js";
|
|
17
|
+
import { compileLatex, missingCharacters, findLatexEngine } from "./latex/compile.js";
|
|
18
|
+
import { bookSource, chapterFolderName, chapterSource } from "./latex/document.js";
|
|
19
|
+
import { courseFileStem } from "./export-pages.js";
|
|
20
|
+
import { auxLabels, numberingMismatches, websiteNumbers } from "./latex/numbering.js";
|
|
21
|
+
async function pagePictures(outputRoot, base, page, captured) {
|
|
22
|
+
const pictures = /* @__PURE__ */ new Map();
|
|
23
|
+
for (const figure of figuresOf(page.blocks)) {
|
|
24
|
+
const capturedFigure = captured?.get(figure.anchor);
|
|
25
|
+
if (capturedFigure) {
|
|
26
|
+
pictures.set(figure.anchor, {
|
|
27
|
+
path: `figures/${page.route}/${figure.anchor}.pdf`,
|
|
28
|
+
content: capturedFigure.pdf
|
|
29
|
+
});
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (figure.picture.kind !== "image" || needsCapture(figure)) continue;
|
|
33
|
+
const file = imageFile(outputRoot, base, page.route, figure.picture.src);
|
|
34
|
+
pictures.set(figure.anchor, {
|
|
35
|
+
path: `figures/${page.route}/${figure.anchor}${extname(file).toLowerCase()}`,
|
|
36
|
+
content: await readFile(file)
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return pictures;
|
|
40
|
+
}
|
|
41
|
+
async function mapWithLimit(items, limit, work) {
|
|
42
|
+
const results = new Array(items.length);
|
|
43
|
+
let next = 0;
|
|
44
|
+
const worker = async () => {
|
|
45
|
+
while (next < items.length) {
|
|
46
|
+
const index = next++;
|
|
47
|
+
results[index] = await work(items[index]);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
await Promise.all(Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, worker));
|
|
51
|
+
return results;
|
|
52
|
+
}
|
|
53
|
+
async function writeLatexExports(directory, manifest, options = {}) {
|
|
54
|
+
if (!manifest.lessonExports.latex) return;
|
|
55
|
+
const logger = options.logger ?? consoleLogger;
|
|
56
|
+
const strict = strictMode();
|
|
57
|
+
const outputRoot = fileURLToPath(directory);
|
|
58
|
+
const { base, chapters, captures } = options.prepared ?? await prepareChapters(outputRoot, manifest, { logger, projectRoot: options.projectRoot });
|
|
59
|
+
const engine = await findLatexEngine();
|
|
60
|
+
if ("missing" in engine) {
|
|
61
|
+
if (strict) throw new Error(`LaTeX export cannot build PDFs: ${engine.missing}`);
|
|
62
|
+
logger.warn(`LaTeX export: writing the source zips only. ${engine.missing}`);
|
|
63
|
+
}
|
|
64
|
+
const jobs = [];
|
|
65
|
+
const pictures = /* @__PURE__ */ new Map();
|
|
66
|
+
for (const { lesson, page } of chapters) {
|
|
67
|
+
const chapterPictures = await pagePictures(outputRoot, base, page, captures.get(page.route));
|
|
68
|
+
pictures.set(lesson.id, chapterPictures);
|
|
69
|
+
jobs.push({
|
|
70
|
+
kind: "chapter",
|
|
71
|
+
name: lesson.slug,
|
|
72
|
+
files: chapterSource({ manifest, lesson, page, documentRoutes: /* @__PURE__ */ new Set([page.route]), pictures: chapterPictures }),
|
|
73
|
+
target: lesson.slug,
|
|
74
|
+
folder: chapterFolderName(lesson),
|
|
75
|
+
website: websiteNumbers(page, `${lesson.part}.${lesson.chapter}`)
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const byId = new Map(chapters.map((chapter) => [chapter.lesson.id, chapter]));
|
|
79
|
+
const pageSlugs = new Set(manifest.pages.map((page) => page.slug));
|
|
80
|
+
const parts = [];
|
|
81
|
+
for (const part of manifest.parts) {
|
|
82
|
+
const partChapters = part.lessons.flatMap((id) => {
|
|
83
|
+
const chapter = byId.get(id);
|
|
84
|
+
return chapter ? [{ ...chapter, pictures: pictures.get(id) }] : [];
|
|
85
|
+
});
|
|
86
|
+
if (partChapters.length === 0) continue;
|
|
87
|
+
const overview = pageSlugs.has(`${part.dir}/index`) ? (await readBuiltPage(outputRoot, `${part.dir}/index`)).page : void 0;
|
|
88
|
+
parts.push({ part, ...overview ? { overview } : {}, chapters: partChapters });
|
|
89
|
+
}
|
|
90
|
+
const bookNumbers = (bookParts) => new Map(
|
|
91
|
+
bookParts.flatMap(
|
|
92
|
+
({ chapters: partChapters }) => partChapters.flatMap(({ lesson, page }) => [...websiteNumbers(page, `${lesson.part}.${lesson.chapter}`)])
|
|
93
|
+
)
|
|
94
|
+
);
|
|
95
|
+
const course = manifest.about.material.name;
|
|
96
|
+
for (const entry of parts) {
|
|
97
|
+
jobs.push({
|
|
98
|
+
kind: "part",
|
|
99
|
+
name: `part/${entry.part.dir}`,
|
|
100
|
+
files: bookSource({
|
|
101
|
+
manifest,
|
|
102
|
+
parts: [entry],
|
|
103
|
+
document: `part/${entry.part.dir}`,
|
|
104
|
+
title: entry.part.label,
|
|
105
|
+
subtitle: `Part ${entry.part.ordinal} of ${course}`
|
|
106
|
+
}),
|
|
107
|
+
target: `part/${entry.part.dir}`,
|
|
108
|
+
folder: `${entry.part.dir}-latex`,
|
|
109
|
+
website: bookNumbers([entry])
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (parts.length > 0) {
|
|
113
|
+
jobs.push({
|
|
114
|
+
kind: "course",
|
|
115
|
+
name: "course",
|
|
116
|
+
files: bookSource({ manifest, parts, document: "course", title: course }),
|
|
117
|
+
target: "course",
|
|
118
|
+
folder: `${courseFileStem(manifest)}-latex`,
|
|
119
|
+
website: bookNumbers(parts)
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
const pending = jobs.map((job) => ({
|
|
123
|
+
target: join(outputRoot, "downloads", `${job.target}-latex.zip`),
|
|
124
|
+
content: zip(job.files.map((file) => ({ path: `${job.folder}/${file.path}`, content: file.content })))
|
|
125
|
+
}));
|
|
126
|
+
const durations = [];
|
|
127
|
+
const started = performance.now();
|
|
128
|
+
if (!("missing" in engine)) {
|
|
129
|
+
const compiled = await mapWithLimit(jobs, availableParallelism(), async (job) => {
|
|
130
|
+
const jobStarted = performance.now();
|
|
131
|
+
const result = await compileLatex(job.files, engine, { epoch: epochOf(manifest), name: job.name });
|
|
132
|
+
durations.push({ kind: job.kind, seconds: (performance.now() - jobStarted) / 1e3 });
|
|
133
|
+
const problems = numberingMismatches(job.website, auxLabels(result.aux));
|
|
134
|
+
if (problems.length > 0) {
|
|
135
|
+
throw new Error(`LaTeX numbers ${job.name} differently from the website:
|
|
136
|
+
${problems.join("\n ")}`);
|
|
137
|
+
}
|
|
138
|
+
const missing = job.kind === "chapter" ? missingCharacters(result.log) : [];
|
|
139
|
+
if (missing.length > 0) {
|
|
140
|
+
logger.warn(
|
|
141
|
+
`LaTeX export: the PDF of ${job.name} leaves ${missing.length} character(s) blank, which its fonts cannot draw: ${missing.slice(0, 12).join(", ")}${missing.length > 12 ? ", \u2026" : ""}. The web page shows them, the PDF does not. Under LuaLaTeX, install a font that covers them on the build machine (explico.cls looks for CMU Serif, Noto Serif or DejaVu Serif for Greek, Noto CJK or Fandol for Chinese, Japanese and Korean, and Noto Color Emoji for emoji); pdfLaTeX sets none of them. Or write the word in Latin script, or a symbol as math ($\\alpha$).`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
return result.pdf;
|
|
145
|
+
});
|
|
146
|
+
jobs.forEach((job, index) => {
|
|
147
|
+
pending.push({ target: join(outputRoot, "downloads", `${job.target}.pdf`), content: compiled[index] });
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
const wall = (performance.now() - started) / 1e3;
|
|
151
|
+
const temporary = pending.map((file) => ({ ...file, temporary: `${file.target}.tmp-${process.pid}` }));
|
|
152
|
+
try {
|
|
153
|
+
for (const file of temporary) {
|
|
154
|
+
await mkdir(dirname(file.target), { recursive: true });
|
|
155
|
+
await writeFile(file.temporary, file.content);
|
|
156
|
+
}
|
|
157
|
+
for (const file of temporary) await rename(file.temporary, file.target);
|
|
158
|
+
} finally {
|
|
159
|
+
await Promise.all(temporary.map((file) => rm(file.temporary, { force: true })));
|
|
160
|
+
}
|
|
161
|
+
const pdfs = pending.filter((file) => file.target.endsWith(".pdf")).length;
|
|
162
|
+
const seconds = (kind) => durations.filter((entry) => entry.kind === kind).reduce((sum, entry) => sum + entry.seconds, 0);
|
|
163
|
+
logger.info(
|
|
164
|
+
`LaTeX export: ${chapters.length} chapter(s), ${parts.length} part(s)${parts.length > 0 ? " and the course" : ""}: ${jobs.length} source zip(s)` + (pdfs > 0 ? `, ${pdfs} PDF(s) with ${"name" in engine ? engine.name : ""} in ${wall.toFixed(1)} s on up to ${availableParallelism()} core(s) (compile time: chapters ${seconds("chapter").toFixed(1)} s, parts ${seconds("part").toFixed(1)} s, course ${seconds("course").toFixed(1)} s)` : "") + (captures.size > 0 ? `, figures from ${captures.size} page(s) drawn as vector PDF` : "") + "."
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
export {
|
|
168
|
+
writeLatexExports
|
|
169
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { RootContent } from 'mdast';
|
|
2
|
+
import { CheckItem } from '../latex/serialize.js';
|
|
3
|
+
import { StaticPage, DiagramGeometry } from '../static-tree.js';
|
|
4
|
+
import '../../../reference/mixed-content.js';
|
|
5
|
+
import '../../../reference/gate-math.js';
|
|
6
|
+
import '../../../reference/types.js';
|
|
7
|
+
import '../html-tree.js';
|
|
8
|
+
import 'parse5';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Serialize explico's static reading tree to Markdown: GitHub's flavour, with
|
|
12
|
+
* `$…$` and `$$…$$` math for remark-math, KaTeX or MathJax (decisions D2, D3).
|
|
13
|
+
* It builds an mdast tree and lets `mdast-util-to-markdown` write it, so every
|
|
14
|
+
* character that means something to Markdown is escaped where it must be.
|
|
15
|
+
*
|
|
16
|
+
* What a reader of the file needs from the website comes along as text: each
|
|
17
|
+
* heading and float keeps its number, a display equation its `\tag{…}`, and
|
|
18
|
+
* every anchor an `<a id>` the links in the file land on. A reference into a
|
|
19
|
+
* page of the same download is a link into its file; any other goes to the
|
|
20
|
+
* website. The author's `\explain{key}{…}` markers are stripped from the
|
|
21
|
+
* math. Memos, notes, examples and checks are titled quotes, always open;
|
|
22
|
+
* Starlight's asides are GitHub alerts; each chapter ends with its
|
|
23
|
+
* references, its notation and the answers to its checks.
|
|
24
|
+
*/
|
|
25
|
+
interface MarkdownChapterContext {
|
|
26
|
+
readonly page: StaticPage;
|
|
27
|
+
/** Every page of this download by route, with its file relative to this one (`''` for this file). */
|
|
28
|
+
readonly documentFiles: ReadonlyMap<string, string>;
|
|
29
|
+
/** Published course root, for links that leave the download. */
|
|
30
|
+
readonly canonicalBaseUrl?: string;
|
|
31
|
+
/** Picture files written for this page, by float anchor or image `src`, relative to this file. */
|
|
32
|
+
readonly pictures: ReadonlyMap<string, string>;
|
|
33
|
+
/** Answers of this page's checks, by assessment id, in authored order. */
|
|
34
|
+
readonly checkItems: ReadonlyMap<string, readonly CheckItem[]>;
|
|
35
|
+
/** Course title, version and the page's live URL, for the line under its title. */
|
|
36
|
+
readonly source?: {
|
|
37
|
+
readonly course: string;
|
|
38
|
+
readonly version?: string;
|
|
39
|
+
readonly url?: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Each edge of a diagram as the boxes it joins: the nearest box to each end. */
|
|
43
|
+
declare function diagramEdges(geometry: DiagramGeometry): [number, number][];
|
|
44
|
+
/** The Markdown of one page: its title, its body, references, notation and answers. */
|
|
45
|
+
declare function serializeMarkdownPage(context: MarkdownChapterContext, options?: {
|
|
46
|
+
readonly number?: string;
|
|
47
|
+
}): string;
|
|
48
|
+
/** Markdown of a few blocks of mdast, written the same way (for a download's `index.md`). */
|
|
49
|
+
declare function serializeMarkdownNodes(children: RootContent[]): string;
|
|
50
|
+
|
|
51
|
+
export { type MarkdownChapterContext, diagramEdges, serializeMarkdownNodes, serializeMarkdownPage };
|