explico 0.13.1 → 0.14.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 +879 -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 +43 -0
- package/dist/compiler/cli-main.js +392 -0
- package/dist/compiler/cli.d.ts +424 -9
- package/dist/compiler/cli.js +1289 -8
- package/dist/compiler/collections.d.ts +88 -1
- package/dist/compiler/collections.js +170 -25
- 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 +359 -58
- package/dist/compiler/page-versions.d.ts +160 -0
- package/dist/compiler/page-versions.js +198 -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 +76 -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 +1 -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 +221 -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 +30 -7
- package/dist/rules/rules.schema.json +259 -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 +29 -9
- package/docs/authoring/agents.md +63 -16
- package/docs/authoring/components.md +15 -0
- package/docs/authoring/deck.md +588 -0
- package/docs/authoring/migrating.md +1045 -16
- package/docs/authoring/notation.md +49 -6
- package/docs/authoring/structure.md +80 -1
- package/docs/authoring/versioning.md +54 -2
- package/docs/authoring/visualizations.md +7 -2
- package/docs/course-agent/AGENTS.md +37 -0
- package/docs/course-agent/agents/rules-reviewer.md +33 -0
- package/docs/course-agent/skills/draft-lesson/SKILL.md +37 -0
- package/docs/course-agent/skills/migrate-course/SKILL.md +31 -0
- package/docs/course-agent/skills/release-content/SKILL.md +24 -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 +469 -0
- package/src/compiler/cli.ts +1905 -16
- package/src/compiler/collections.ts +284 -25
- 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 +558 -63
- package/src/compiler/page-versions.ts +359 -0
- package/src/compiler/resolution-report.ts +38 -7
- package/src/compiler/validate-content.ts +212 -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 +126 -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-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 +257 -4
- package/src/rules/course-rules.ts +21 -1
- package/src/rules/in-effect.ts +54 -8
- 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
package/docs/privacy.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# What an explico site keeps in a reader's browser
|
|
2
|
+
|
|
3
|
+
An explico course sets **no cookies**, loads **nothing from another site**
|
|
4
|
+
(fonts, KaTeX and search are served by the site itself), and sends nothing
|
|
5
|
+
anywhere: there is no analytics. What it keeps lives in the reader's own
|
|
6
|
+
browser storage (`localStorage` for what outlives the tab, `sessionStorage`
|
|
7
|
+
for what does not), and is read only by the pages of the course.
|
|
8
|
+
|
|
9
|
+
EU rules treat browser storage like cookies: storing something needs the
|
|
10
|
+
reader's consent unless it is strictly necessary for what the reader asked
|
|
11
|
+
for, such as a preference they set themselves (ePrivacy Directive Art. 5(3);
|
|
12
|
+
EDPB Guidelines 2/2023 on its technical scope; Article 29 Working Party
|
|
13
|
+
Opinion 04/2012 on the exemptions). explico is built so that one question
|
|
14
|
+
covers everything that needs consent.
|
|
15
|
+
|
|
16
|
+
## Settings: kept because the reader set them
|
|
17
|
+
|
|
18
|
+
| What | Key | Written when |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| Theme | `starlight-theme` (Starlight's own) | The reader picks one. Starlight also writes an empty value on each page load. |
|
|
21
|
+
| Text size (phones) | `explico:display:text-size` | The reader picks one |
|
|
22
|
+
| Panels folded away or resized | `explico:layout:*` | The reader folds or drags a panel |
|
|
23
|
+
| A part shown compact or labelled | `explico-sidebar-groups` | The reader clicks the part |
|
|
24
|
+
| Which edition a lesson opens as, and whether the other is listed | `explico-sidebar-editions` | The reader switches either in the sidebar's foot |
|
|
25
|
+
| A section folded or opened | `disclosure:<page>:<section>` | The reader folds or opens it (never on a mere visit) |
|
|
26
|
+
| "Carry cards" on or off; card width; article kept left | `explico:cards:carry`, `explico:layout:side-card-width*`, `explico:layout:keep-article-left` | The reader sets it |
|
|
27
|
+
|
|
28
|
+
These need no answer: each one is a choice the reader made, kept so it stays
|
|
29
|
+
made.
|
|
30
|
+
|
|
31
|
+
## Reading memory: kept only with the reader's yes
|
|
32
|
+
|
|
33
|
+
| What | Key | With a yes | Without one |
|
|
34
|
+
| --- | --- | --- | --- |
|
|
35
|
+
| The chapters a reader opened, as they were (the sidebar marks; the line under a changed page's title) | `explico-page-marks:<base>` | Recorded on each visit | Not recorded; no marks |
|
|
36
|
+
| The cards kept open on a page | `explico:cards:<page>` | Kept in the browser | Kept for the tab only |
|
|
37
|
+
| The cards carried from page to page | `explico:cards:carried:<base>` | Kept in the browser | Kept for the tab only |
|
|
38
|
+
| The frame and step each deck stopped at, and the frames Present mode showed, as they were (each slide's "Shown" or "Not shown yet" on a deck's page, its slide map; "Continue at slide N") | `explico:decks:<base>` | Recorded as the reader presents; the frames the tab recorded before the yes are kept with it | Before an answer, kept and marked for the tab only; after a no, the stopping place alone, for the tab: the frames shown are cleared, and none is recorded |
|
|
39
|
+
|
|
40
|
+
The course asks once ("Remember your reading?", `readingMemory: "ask"`, the
|
|
41
|
+
default), at the bottom of the window, with two answers of equal weight. Until
|
|
42
|
+
the reader answers, nothing of their reading outlives the tab. A no deletes
|
|
43
|
+
any reading memory at once. The answer (`explico-reading-memory:<base>`) is
|
|
44
|
+
the one thing kept without asking, as storing a consent choice is, and stands
|
|
45
|
+
for 13 months. The `[?]` panel's "In this browser" section changes it, and
|
|
46
|
+
"Forget what this course stored" deletes every key above for the course and
|
|
47
|
+
asks again. `readingMemory: "off"` never asks and never keeps reading memory.
|
|
48
|
+
|
|
49
|
+
## For the course's own privacy notice
|
|
50
|
+
|
|
51
|
+
- The site's host sees each request, as any web server does: GitHub Pages,
|
|
52
|
+
Cloudflare Pages or the course's own server keeps its access logs under its
|
|
53
|
+
own privacy terms. Name the host.
|
|
54
|
+
- Anything the course adds outside explico changes this page: an analytics
|
|
55
|
+
script, fonts or scripts from a CDN, an embedded video. Each sends the
|
|
56
|
+
reader's address to another site, and most need consent of their own.
|
|
57
|
+
- `src/session/reading-memory.ts` is the source of truth for what counts as
|
|
58
|
+
reading memory; `tests/e2e/reading-memory.spec.ts` in the playground checks
|
|
59
|
+
that an unanswered browser keeps nothing of the reading.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "explico",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Build-time engine for prerequisite-aware, notation-rigorous course content: one validated content model, a semantic notation/citation/equation system with a completeness gate, and a deterministic JSON manifest.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -31,11 +31,15 @@
|
|
|
31
31
|
"CHANGELOG.md",
|
|
32
32
|
"docs/VERSIONING.md",
|
|
33
33
|
"docs/katex-bracket-scaling.md",
|
|
34
|
-
"docs/
|
|
34
|
+
"docs/diagram-scaling.md",
|
|
35
|
+
"docs/privacy.md",
|
|
36
|
+
"docs/authoring",
|
|
37
|
+
"docs/course-agent"
|
|
35
38
|
],
|
|
36
39
|
"dependencies": {
|
|
37
40
|
"@dagrejs/dagre": "3.1.1",
|
|
38
41
|
"esbuild": "0.27.7",
|
|
42
|
+
"github-slugger": "2.0.0",
|
|
39
43
|
"mdast-util-gfm-table": "2.0.0",
|
|
40
44
|
"mdast-util-math": "3.0.0",
|
|
41
45
|
"mdast-util-to-markdown": "2.1.2",
|
|
@@ -70,7 +74,9 @@
|
|
|
70
74
|
},
|
|
71
75
|
"scripts": {
|
|
72
76
|
"build": "tsup && node scripts/copy-assets.mjs && node scripts/fix-esm-extensions.mjs && tsc -p tsconfig.dts-mjs.json && node scripts/gen-rules-schema.mjs",
|
|
77
|
+
"check:dist-imports": "node scripts/check-dist-imports.mjs",
|
|
73
78
|
"check:release-migration": "node scripts/check-release-migration.mjs",
|
|
79
|
+
"release": "node scripts/release.mjs",
|
|
74
80
|
"test": "vitest run",
|
|
75
81
|
"test:watch": "vitest"
|
|
76
82
|
}
|
package/src/compiler/astro.ts
CHANGED
|
@@ -12,7 +12,11 @@ import {
|
|
|
12
12
|
writeManifest,
|
|
13
13
|
} from './manifest';
|
|
14
14
|
import { missingNotationPayloadKeys } from '../reference/page-notation';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
assertNoUnboundFigureSymbols,
|
|
17
|
+
unboundFigureSymbols,
|
|
18
|
+
type PageUnboundFigureSymbols,
|
|
19
|
+
} from '../reference/figure-symbols';
|
|
16
20
|
import { undrawnFigurePictures, undrawnFigureWarning } from '../reference/figure-pictures';
|
|
17
21
|
import {
|
|
18
22
|
pageRenderDiagnostics,
|
|
@@ -25,7 +29,8 @@ import { writeLatexExports } from './exports/latex-export';
|
|
|
25
29
|
import { writeMarkdownExports } from './exports/markdown-export';
|
|
26
30
|
import { prepareChapters } from './exports/export-chapters';
|
|
27
31
|
import { writeDownloadIndex } from './exports/download-index';
|
|
28
|
-
import {
|
|
32
|
+
import { checkFrameFit } from './exports/deck-fit';
|
|
33
|
+
import { standaloneDownloads, standaloneFilename } from './exports/export-pages';
|
|
29
34
|
import remarkAbbreviations from '../reference/remark-abbreviations.mjs';
|
|
30
35
|
import remarkCitation from '../reference/remark-citation.mjs';
|
|
31
36
|
import remarkNotation from '../reference/remark-notation.mjs';
|
|
@@ -160,10 +165,11 @@ type MarkdownConfig = AstroConfig['markdown'];
|
|
|
160
165
|
|
|
161
166
|
/**
|
|
162
167
|
* Every configured remark plugin, regardless of which of Astro's two
|
|
163
|
-
* mutually-exclusive wiring surfaces a course uses:
|
|
164
|
-
*
|
|
165
|
-
* `
|
|
166
|
-
*
|
|
168
|
+
* mutually-exclusive wiring surfaces a course uses: a `markdown.processor`
|
|
169
|
+
* (e.g. `unified({ remarkPlugins })`, the form Astro 7.3 asks for) whose own
|
|
170
|
+
* `options.remarkPlugins` a non-`unified` processor (e.g. `satteri()`) may not
|
|
171
|
+
* have at all, or the flat `markdown.remarkPlugins` array Astro 7.3 deprecates
|
|
172
|
+
* and a course not yet moved still has.
|
|
167
173
|
*/
|
|
168
174
|
function configuredRemarkPlugins(markdown: MarkdownConfig): readonly unknown[] {
|
|
169
175
|
const direct = markdown?.remarkPlugins ?? [];
|
|
@@ -200,22 +206,24 @@ export function assertRemarkPluginsWired(
|
|
|
200
206
|
!remarkPluginIsWired(remarkPlugins, remarkAbbreviations)
|
|
201
207
|
) {
|
|
202
208
|
missing.push(
|
|
203
|
-
`remarkAbbreviations is missing from
|
|
209
|
+
`remarkAbbreviations is missing from the remark plugins of astro.config.mjs, but ` +
|
|
204
210
|
`manifest.abbreviations has ${manifest.abbreviations.length} ` +
|
|
205
211
|
`entr${manifest.abbreviations.length === 1 ? 'y' : 'ies'}. Import it from ` +
|
|
206
212
|
`'explico/reference/remark-abbreviations.mjs' and add ` +
|
|
207
|
-
`[remarkAbbreviations, { abbreviations: manifest.abbreviations }] to ` +
|
|
208
|
-
|
|
213
|
+
`[remarkAbbreviations, { abbreviations: manifest.abbreviations }] to the ` +
|
|
214
|
+
`\`remarkPlugins\` of \`markdown.processor: unified({ … })\` — see ` +
|
|
215
|
+
`docs/authoring/migrating.md#4-rule-n14.`,
|
|
209
216
|
);
|
|
210
217
|
}
|
|
211
218
|
|
|
212
219
|
if (manifest.sources.length > 0 && !remarkPluginIsWired(remarkPlugins, remarkCitation)) {
|
|
213
220
|
missing.push(
|
|
214
|
-
`remarkCitation is missing from
|
|
221
|
+
`remarkCitation is missing from the remark plugins of astro.config.mjs, but ` +
|
|
215
222
|
`manifest.sources has ${manifest.sources.length} ` +
|
|
216
223
|
`entr${manifest.sources.length === 1 ? 'y' : 'ies'}. Import it from ` +
|
|
217
224
|
`'explico/reference/remark-citation.mjs' and add ` +
|
|
218
|
-
`[remarkCitation, { sources: manifest.sources }] to
|
|
225
|
+
`[remarkCitation, { sources: manifest.sources }] to the \`remarkPlugins\` of ` +
|
|
226
|
+
`\`markdown.processor: unified({ … })\`.`,
|
|
219
227
|
);
|
|
220
228
|
}
|
|
221
229
|
|
|
@@ -224,11 +232,12 @@ export function assertRemarkPluginsWired(
|
|
|
224
232
|
!remarkPluginIsWired(remarkPlugins, remarkNotation)
|
|
225
233
|
) {
|
|
226
234
|
missing.push(
|
|
227
|
-
`remarkNotation is missing from
|
|
235
|
+
`remarkNotation is missing from the remark plugins of astro.config.mjs, but ` +
|
|
228
236
|
`manifest.notation.raw has ${manifest.notation.raw.length} ` +
|
|
229
237
|
`entr${manifest.notation.raw.length === 1 ? 'y' : 'ies'}. Import it from ` +
|
|
230
238
|
`'explico/reference/remark-notation.mjs' and add ` +
|
|
231
|
-
`[remarkNotation, createRemarkNotationOptions(manifest)] to
|
|
239
|
+
`[remarkNotation, createRemarkNotationOptions(manifest)] to the \`remarkPlugins\` of ` +
|
|
240
|
+
`\`markdown.processor: unified({ … })\`.`,
|
|
232
241
|
);
|
|
233
242
|
}
|
|
234
243
|
|
|
@@ -243,25 +252,41 @@ export function assertRemarkPluginsWired(
|
|
|
243
252
|
|
|
244
253
|
/**
|
|
245
254
|
* Check every built page, and return the findings only a rendered page gives
|
|
246
|
-
* (`render-diagnostics.ts`) for `content warnings`.
|
|
255
|
+
* (`render-diagnostics.ts`) for `content warnings`. A page that fails a check
|
|
256
|
+
* does not stop the walk: every page is read first, then the build throws once
|
|
257
|
+
* with the whole list, so it reports each page at once and not one per run.
|
|
258
|
+
* Exported for the test.
|
|
247
259
|
*/
|
|
248
|
-
async function validateGeneratedPages(
|
|
260
|
+
export async function validateGeneratedPages(
|
|
249
261
|
directory: URL,
|
|
250
|
-
manifest: Manifest,
|
|
262
|
+
manifest: Pick<Manifest, 'lessons'>,
|
|
251
263
|
warn: (message: string) => void,
|
|
252
264
|
): Promise<RenderDiagnostic[]> {
|
|
253
265
|
const root = fileURLToPath(directory);
|
|
254
266
|
const rendered: RenderDiagnostic[] = [];
|
|
267
|
+
const failures: string[] = [];
|
|
268
|
+
const unbound: PageUnboundFigureSymbols[] = [];
|
|
269
|
+
const messageOf = (error: unknown): string =>
|
|
270
|
+
error instanceof Error ? error.message : String(error);
|
|
255
271
|
const walk = async (path: string): Promise<void> => {
|
|
256
|
-
|
|
272
|
+
// A fixed order, so the list a build prints is the same on every machine.
|
|
273
|
+
const entries = (await readdir(path, { withFileTypes: true })).sort((a, b) =>
|
|
274
|
+
a.name.localeCompare(b.name),
|
|
275
|
+
);
|
|
276
|
+
for (const entry of entries) {
|
|
257
277
|
const child = join(path, entry.name);
|
|
258
278
|
if (entry.isDirectory()) {
|
|
259
279
|
await walk(child);
|
|
260
280
|
} else if (entry.isFile() && entry.name.endsWith('.html')) {
|
|
261
281
|
const html = await readFile(child, 'utf8');
|
|
262
282
|
const page = relative(root, child);
|
|
263
|
-
|
|
264
|
-
|
|
283
|
+
try {
|
|
284
|
+
assertNotationPayloadHtml(page, html);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
failures.push(messageOf(error));
|
|
287
|
+
}
|
|
288
|
+
const figures = unboundFigureSymbols(html);
|
|
289
|
+
if (figures.length > 0) unbound.push({ page, figures });
|
|
265
290
|
const undrawn = undrawnFigurePictures(html);
|
|
266
291
|
if (undrawn.length > 0) warn(undrawnFigureWarning(page, undrawn));
|
|
267
292
|
rendered.push(...pageRenderDiagnostics(manifest, page, html));
|
|
@@ -269,6 +294,12 @@ async function validateGeneratedPages(
|
|
|
269
294
|
}
|
|
270
295
|
};
|
|
271
296
|
await walk(root);
|
|
297
|
+
try {
|
|
298
|
+
assertNoUnboundFigureSymbols(unbound);
|
|
299
|
+
} catch (error) {
|
|
300
|
+
failures.push(messageOf(error));
|
|
301
|
+
}
|
|
302
|
+
if (failures.length > 0) throw new Error(failures.join('\n\n'));
|
|
272
303
|
return rendered;
|
|
273
304
|
}
|
|
274
305
|
|
|
@@ -407,7 +438,7 @@ export function explicoContentRefresh(
|
|
|
407
438
|
const slug = matchStandaloneDownload(
|
|
408
439
|
pathname,
|
|
409
440
|
configuredDevelopment.base,
|
|
410
|
-
|
|
441
|
+
standaloneDownloads(manifest).map(({ download }) => download),
|
|
411
442
|
);
|
|
412
443
|
if (!slug) return next();
|
|
413
444
|
|
|
@@ -419,7 +450,7 @@ export function explicoContentRefresh(
|
|
|
419
450
|
);
|
|
420
451
|
developmentDownloads ??= buildDevelopmentDownloads(
|
|
421
452
|
configuredDevelopment,
|
|
422
|
-
|
|
453
|
+
standaloneDownloads(manifest).map(({ download }) => download),
|
|
423
454
|
);
|
|
424
455
|
const currentDownloads = developmentDownloads;
|
|
425
456
|
currentDownloads.catch(() => {
|
|
@@ -456,6 +487,14 @@ export function explicoContentRefresh(
|
|
|
456
487
|
for (const diagnostic of writeRenderDiagnostics(rendered)) {
|
|
457
488
|
logger.warn(`[${diagnostic.code}] ${diagnostic.file}: ${diagnostic.message}`);
|
|
458
489
|
}
|
|
490
|
+
// Rule D2: every frame of every deck fits its canvas, measured in a browser.
|
|
491
|
+
const overflowing = await checkFrameFit(fileURLToPath(dir), manifest, { logger });
|
|
492
|
+
if (overflowing.length > 0) {
|
|
493
|
+
throw new Error(
|
|
494
|
+
`${overflowing.length} deck frame(s) do not fit their canvas (rule D2, frame-overflow):\n` +
|
|
495
|
+
overflowing.map((finding) => ` - ${finding.message}`).join('\n'),
|
|
496
|
+
);
|
|
497
|
+
}
|
|
459
498
|
await writeStandaloneLessonExports(dir, manifest);
|
|
460
499
|
await writeCombinedExports(dir, manifest);
|
|
461
500
|
// The print exports share one reading of the chapters and one
|