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
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"properties": {
|
|
9
9
|
"N9": {
|
|
10
10
|
"title": "N9 — A quantity/unit/operator is typeset in `$…$`, never as plain text",
|
|
11
|
-
"description": "Never write `45 m/s`, `t (s)`, `vx` or `KE/m` as plain text, and never spell a stated quantity's unit out: \"4 seconds\", \"2 meters per second squared\", \"30 degrees\", \"$x = 3$ meters\" are `$4\\ \\text{s}$`, `$2\\ \\text{m/s}^2$`, `$30^{\\circ}$`, `$x = 3\\ \\text{m}$`. A unit inside math is `\\text{}`-wrapped, short form, in the same span as its number or symbol. A unit named on its own (\"measured in meters\") stays a word; a sentence that defines a unit is waived. JSX prop strings (`caption=\"…\"`)
|
|
11
|
+
"description": "Never write `45 m/s`, `t (s)`, `vx` or `KE/m` as plain text, and never spell a stated quantity's unit out: \"4 seconds\", \"2 meters per second squared\", \"30 degrees\", \"$x = 3$ meters\" are `$4\\ \\text{s}$`, `$2\\ \\text{m/s}^2$`, `$30^{\\circ}$`, `$x = 3\\ \\text{m}$`. A unit inside math is `\\text{}`-wrapped, short form, in the same span as its number or symbol. A unit named on its own (\"measured in meters\") stays a word; a sentence that defines a unit is waived. JSX prop strings (`caption=\"…\"`) render no math, so N9 does not apply there; nor does it apply to an assessment choice label, which may still hold math (`$30^{\\circ}$`).",
|
|
12
12
|
"x-element": "prose",
|
|
13
13
|
"x-elements": [
|
|
14
14
|
"prose",
|
|
@@ -81,26 +81,6 @@
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
},
|
|
84
|
-
"S5": {
|
|
85
|
-
"title": "S5 — A sign / perspective convention is declared once and cited elsewhere",
|
|
86
|
-
"description": "Prose that states a sign / cash-flow-perspective convention resolves it to the single declaration — the `conventions.signConventionKey` notation entry (`[[key]]`) or the `conventions.cashFlowPerspectiveCompetency` competency — rather than restating it.",
|
|
87
|
-
"x-element": "prose",
|
|
88
|
-
"x-elements": [
|
|
89
|
-
"prose"
|
|
90
|
-
],
|
|
91
|
-
"x-enforcement": "script",
|
|
92
|
-
"x-doc": "docs/authoring/structure-rules.md#s5",
|
|
93
|
-
"type": "object",
|
|
94
|
-
"additionalProperties": false,
|
|
95
|
-
"properties": {
|
|
96
|
-
"enabled": {
|
|
97
|
-
"title": "Enabled",
|
|
98
|
-
"description": "Off: the check does not run, and the rule leaves the rules-in-effect page.",
|
|
99
|
-
"type": "boolean",
|
|
100
|
-
"default": true
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
84
|
"S8": {
|
|
105
85
|
"title": "S8 — Prefer `<Memo>` over a Starlight aside when the content needs an anchor, a caption or collapsing",
|
|
106
86
|
"description": "A `:::note`/`:::tip`/`:::caution`/`:::danger` (or `<Aside>`) is a short callout read in passing: no number, no link, never folded. Anything a reader may want to cite, skip or come back to is a `<Memo id=\"…\">`.",
|
|
@@ -596,6 +576,27 @@
|
|
|
596
576
|
}
|
|
597
577
|
}
|
|
598
578
|
},
|
|
579
|
+
"N23": {
|
|
580
|
+
"title": "N23 — An index is part of the symbol: whole form, family or index entry",
|
|
581
|
+
"description": "A subscript on a symbol is explained by the indexed symbol’s own entry (`latex: v_0`), a family entry whose index runs (`latex: x_k` explains `x_1`), or an index entry for the subscript (`latex: \"{}_0\"`, which composes a derived card); a card on the base alone does not explain it, and arithmetic on an index letter with its own card does (`X_{t-1}`). A running index — a lowercase letter not marked `fixedIndex` — states its set, as `range` on its card or after a `\\quad` on the first display line that uses it. Never wrap an indexed symbol in `\\explain` with a key whose `latex` has no index. Not checked by the build: whether a `\\quad` clause states the set correctly; whether a lowercase index is really running; lab math whose glyph table is a copy of the one `labMathScope` returned.",
|
|
582
|
+
"x-element": "math",
|
|
583
|
+
"x-elements": [
|
|
584
|
+
"math",
|
|
585
|
+
"notation"
|
|
586
|
+
],
|
|
587
|
+
"x-enforcement": "partial",
|
|
588
|
+
"x-doc": "docs/authoring/notation.md#n23",
|
|
589
|
+
"type": "object",
|
|
590
|
+
"additionalProperties": false,
|
|
591
|
+
"properties": {
|
|
592
|
+
"enabled": {
|
|
593
|
+
"title": "Enabled",
|
|
594
|
+
"description": "Off: the check does not run, and the rule leaves the rules-in-effect page.",
|
|
595
|
+
"type": "boolean",
|
|
596
|
+
"default": true
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
},
|
|
599
600
|
"N5": {
|
|
600
601
|
"title": "N5 — Referenced display equations carry `\\label{eq:key}`",
|
|
601
602
|
"description": "Label a display equation with `\\label{eq:key}` when — and only when — prose refers back to it with `[[eq-key]]`. A label nothing references is noise. Not checked by the build: that a referenced-in-prose equation actually carries a label.",
|
|
@@ -638,7 +639,7 @@
|
|
|
638
639
|
},
|
|
639
640
|
"N19": {
|
|
640
641
|
"title": "N19 — A notation entry states `units` from the vocabulary, or `dimensionless`",
|
|
641
|
-
"description": "Every notation entry has `units:` from `units-vocab.ts` (`m/s`, `s`, `kg`, …) or `dimensionless: true
|
|
642
|
+
"description": "Every notation entry has `units:` from `units-vocab.ts` (`m/s`, `s`, `kg`, …) or `dimensionless: true`, except an index entry (`latex: \"{}_0\"`, N23), which takes neither. A token outside the vocabulary is a warning.",
|
|
642
643
|
"x-element": "notation",
|
|
643
644
|
"x-elements": [
|
|
644
645
|
"notation"
|
|
@@ -679,7 +680,7 @@
|
|
|
679
680
|
},
|
|
680
681
|
"N21": {
|
|
681
682
|
"title": "N21 — A gloss is named by a short noun phrase, not a sentence",
|
|
682
|
-
"description": "A gloss `
|
|
683
|
+
"description": "A gloss `name` names the symbol in a few words (“launch angle”); a clause, sentence punctuation, or a definition belongs in a full notation entry instead.",
|
|
683
684
|
"x-element": "notation",
|
|
684
685
|
"x-elements": [
|
|
685
686
|
"notation"
|
|
@@ -812,6 +813,24 @@
|
|
|
812
813
|
}
|
|
813
814
|
}
|
|
814
815
|
},
|
|
816
|
+
"S10": {
|
|
817
|
+
"title": "S10 — A page that is not a chapter explains its symbols but numbers nothing: it links a chapter’s float instead",
|
|
818
|
+
"description": "On `content/docs/index.mdx`, a `content/docs/<part>/index.mdx`, or any page outside a part: `[[key]]`, `\\explain`, math, citations and `[[chapter#tab-key]]` links work and open cards, and the math and prose gates apply. No `<Table>`, `<Figure>`, `<Diagram>`, `<CompactExamples>`, `<AssessmentSet>`, lab, `\\label{eq:…}` or `notation.local`/`notation.suspend`; no `$…$` or `[[…]]` in `hero.title`, `hero.tagline` or a `<PartOverview chain>` step. Locked — a float needs a chapter number, and such a page has none — turning the rule off would not render one.",
|
|
819
|
+
"x-element": "part-page",
|
|
820
|
+
"x-elements": [
|
|
821
|
+
"part-page",
|
|
822
|
+
"plot",
|
|
823
|
+
"table",
|
|
824
|
+
"diagram",
|
|
825
|
+
"equation",
|
|
826
|
+
"notation"
|
|
827
|
+
],
|
|
828
|
+
"x-enforcement": "locked",
|
|
829
|
+
"x-doc": "docs/authoring/structure-rules.md#s10",
|
|
830
|
+
"type": "object",
|
|
831
|
+
"additionalProperties": false,
|
|
832
|
+
"properties": {}
|
|
833
|
+
},
|
|
815
834
|
"V2": {
|
|
816
835
|
"title": "V2 — Static charts: SVG → D3 → Observable Plot, chosen per figure",
|
|
817
836
|
"description": "For a static chart pick the lightest tool that draws it: inline SVG, then D3, then Observable Plot. State the choice in the figure’s source comment.",
|
|
@@ -834,19 +853,19 @@
|
|
|
834
853
|
},
|
|
835
854
|
"V3": {
|
|
836
855
|
"title": "V3 — Interactive figures: a hydrated island + the `renderLabMath` seam",
|
|
837
|
-
"description": "An interactive figure is an island under `content/labs/` inside a `<Figure>`, renders its equations through `renderLabMath
|
|
856
|
+
"description": "An interactive figure is an island under `content/labs/` inside a `<Figure>`, renders its equations through `renderLabMath` (`{ display: false }` for a legend, an axis title or a label; a `{ math }` run for the caption clause) and never KaTeX directly, and labels its controls; the figure’s caption is its name, so the lab writes no accessible name or text alternative of its own. Its default picture is drawn at build time too and handed to the island as children, so the built page has it. Not checked by the build: that a lab labels its controls and writes no name of its own, and math a lab draws without importing `katex` — the build’s rendered check (`figure-symbols.ts`) covers the page it renders.",
|
|
838
857
|
"x-element": "plot",
|
|
839
858
|
"x-elements": [
|
|
840
859
|
"plot"
|
|
841
860
|
],
|
|
842
|
-
"x-enforcement": "
|
|
861
|
+
"x-enforcement": "partial",
|
|
843
862
|
"x-doc": "docs/authoring/visualizations.md#v3",
|
|
844
863
|
"type": "object",
|
|
845
864
|
"additionalProperties": false,
|
|
846
865
|
"properties": {
|
|
847
866
|
"enabled": {
|
|
848
867
|
"title": "Enabled",
|
|
849
|
-
"description": "Off: the rule leaves the rules-in-effect page
|
|
868
|
+
"description": "Off: the check does not run, and the rule leaves the rules-in-effect page.",
|
|
850
869
|
"type": "boolean",
|
|
851
870
|
"default": true
|
|
852
871
|
}
|
|
@@ -926,6 +945,33 @@
|
|
|
926
945
|
}
|
|
927
946
|
}
|
|
928
947
|
},
|
|
948
|
+
"V7": {
|
|
949
|
+
"title": "V7 — A figure’s picture fits on one screen",
|
|
950
|
+
"description": "The default slot of a `<Figure>` — plot, key and tables — stays within `maxPercent` of the viewport height, so the reader sees the picture and its caption line together. A square or tall plot gets a fixed width instead of the full column. Not checked by the build: any page or viewport the course’s Playwright suite does not open — the check runs in the browser, not in the build.",
|
|
951
|
+
"x-element": "plot",
|
|
952
|
+
"x-elements": [
|
|
953
|
+
"plot"
|
|
954
|
+
],
|
|
955
|
+
"x-enforcement": "partial",
|
|
956
|
+
"x-doc": "docs/authoring/visualizations.md#v7",
|
|
957
|
+
"type": "object",
|
|
958
|
+
"additionalProperties": false,
|
|
959
|
+
"properties": {
|
|
960
|
+
"enabled": {
|
|
961
|
+
"title": "Enabled",
|
|
962
|
+
"description": "Off: the check does not run, and the rule leaves the rules-in-effect page.",
|
|
963
|
+
"type": "boolean",
|
|
964
|
+
"default": true
|
|
965
|
+
},
|
|
966
|
+
"maxPercent": {
|
|
967
|
+
"title": "Largest picture height (% of screen)",
|
|
968
|
+
"description": "How much of the viewport height a figure’s picture may take.",
|
|
969
|
+
"type": "integer",
|
|
970
|
+
"minimum": 10,
|
|
971
|
+
"default": 80
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
},
|
|
929
975
|
"S9": {
|
|
930
976
|
"title": "S9 — A float’s short caption names it; the long caption goes on from that name",
|
|
931
977
|
"description": "Give each figure, table and diagram a `short` caption that names it: it opens the caption line in bold, and names the float in \"Hidden here\", a copied link and the \"Figures and tables\" page. The long `caption` goes on from that name to say what the float shows — its subject, its marks and symbols, the case shown — and at most the one thing to notice. The argument drawn from a figure is lesson text after it, and a lab’s instructions are the first line of its `tools`.",
|
|
@@ -968,6 +1014,33 @@
|
|
|
968
1014
|
}
|
|
969
1015
|
}
|
|
970
1016
|
},
|
|
1017
|
+
"V8": {
|
|
1018
|
+
"title": "V8 — A diagram fits the lesson column",
|
|
1019
|
+
"description": "A `<Diagram>` lays out no wider than `columnWidth`, the lesson column at a 1366px-wide window, so the reader sees the whole graph without scrolling it. Narrow it with `direction=\"TB\"`, a shorter label or a node `width` (its label wraps inside it); `warnAboveWidth={false}` marks a diagram meant to scroll.",
|
|
1020
|
+
"x-element": "diagram",
|
|
1021
|
+
"x-elements": [
|
|
1022
|
+
"diagram"
|
|
1023
|
+
],
|
|
1024
|
+
"x-enforcement": "script",
|
|
1025
|
+
"x-doc": "docs/authoring/visualizations.md#v8",
|
|
1026
|
+
"type": "object",
|
|
1027
|
+
"additionalProperties": false,
|
|
1028
|
+
"properties": {
|
|
1029
|
+
"enabled": {
|
|
1030
|
+
"title": "Enabled",
|
|
1031
|
+
"description": "Off: the check does not run, and the rule leaves the rules-in-effect page.",
|
|
1032
|
+
"type": "boolean",
|
|
1033
|
+
"default": true
|
|
1034
|
+
},
|
|
1035
|
+
"columnWidth": {
|
|
1036
|
+
"title": "Column width (px)",
|
|
1037
|
+
"description": "The widest a diagram may lay out: the lesson column at the window width the course is read at most (707px at 1366px).",
|
|
1038
|
+
"type": "integer",
|
|
1039
|
+
"minimum": 200,
|
|
1040
|
+
"default": 707
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
},
|
|
971
1044
|
"S4": {
|
|
972
1045
|
"title": "S4 — A `<Diagram>` carries an `id` and sits where numbering can see it",
|
|
973
1046
|
"description": "Give every `<Diagram>` an `id`, and place it at the top level or inside `<Memo>`/`<ShortNote>`/`<Table>`/`<Figure>` — a diagram nested elsewhere (e.g. in `<CompactExample>`) is never numbered.",
|
|
@@ -990,7 +1063,7 @@
|
|
|
990
1063
|
},
|
|
991
1064
|
"S3": {
|
|
992
1065
|
"title": "S3 — A table is a `<Table id=\"…\">`, never a raw Markdown/HTML table",
|
|
993
|
-
"description": "Wrap every pipe table or `<table>` in `<Table id=\"…\" caption=\"…\">` so it gets a number and `[[tab-…]]` can reach it.",
|
|
1066
|
+
"description": "Wrap every pipe table or `<table>` in `<Table id=\"…\" caption=\"…\">` so it gets a number and `[[tab-…]]` can reach it; a table in a worked example stays plain.",
|
|
994
1067
|
"x-element": "table",
|
|
995
1068
|
"x-elements": [
|
|
996
1069
|
"table"
|
package/dist/rules/settings.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import './catalog.js';
|
|
2
2
|
import './course-rules.js';
|
|
3
|
-
export {
|
|
3
|
+
export { d as ConfigDiagnostic, j as CourseRulesConfig, M as ManifestRules, R as ResolvedRules, k as RuleSettingsInput, l as catalogIds, m as disabledCodes, n as dropDisabled, p as partPageLimits, r as resolveRules, o as rulesJsonSchema, q as rulesSnapshot } from '../course-config-rRtME5UV.js';
|
package/dist/rules/settings.js
CHANGED
|
@@ -84,6 +84,13 @@ function resolveRules(config) {
|
|
|
84
84
|
message: `CourseConfig \`${legacyKey}\` is deprecated \u2014 move it to \`rules.${id}\` (same \`allow\` / \`deny\` shape). The old key is honoured for now.`
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
|
+
if (config.conventions !== void 0) {
|
|
88
|
+
diagnostics.push({
|
|
89
|
+
code: "config-deprecated-key",
|
|
90
|
+
severity: "warning",
|
|
91
|
+
message: "CourseConfig `conventions` is no longer read: rule S5, its only reader, was retired into rule N4. Delete the block. See docs/authoring/retired.md."
|
|
92
|
+
});
|
|
93
|
+
}
|
|
87
94
|
const enabled = /* @__PURE__ */ new Map();
|
|
88
95
|
const settings = /* @__PURE__ */ new Map();
|
|
89
96
|
for (const rule of catalogRules()) {
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
* cookie-backed store) and nothing else changes. `createBrowserPreferenceStore`
|
|
12
12
|
* is the "versioned local-storage adapter" the architecture doc anticipates —
|
|
13
13
|
* kept deliberately tiny, and the only place `git grep localStorage` matches.
|
|
14
|
+
* `createSessionPreferenceStore` is its per-tab twin, for state one tab keeps
|
|
15
|
+
* of its own (the cards it carries, `card-carry.ts`).
|
|
14
16
|
*/
|
|
15
17
|
interface PreferenceStore {
|
|
16
18
|
get(key: string): string | null;
|
|
@@ -27,7 +29,22 @@ interface PreferenceStore {
|
|
|
27
29
|
* controls still work, they just do not persist.
|
|
28
30
|
*/
|
|
29
31
|
declare function createBrowserPreferenceStore(): PreferenceStore;
|
|
32
|
+
/**
|
|
33
|
+
* A `sessionStorage`-backed store: one tab's own state, which a reload, Back
|
|
34
|
+
* and Forward keep and another tab never sees. Wrapped like the local one.
|
|
35
|
+
*/
|
|
36
|
+
declare function createSessionPreferenceStore(): PreferenceStore;
|
|
37
|
+
/**
|
|
38
|
+
* The store's one inline twin: the source of a script that copies a stored
|
|
39
|
+
* preference onto the root element as `attribute` before the page first
|
|
40
|
+
* paints. Every other reader of a preference is a module script, which runs
|
|
41
|
+
* after that paint: fine for a panel's state, but a page drawn at one text
|
|
42
|
+
* size and then redrawn at another visibly jumps. Only a value in `values`
|
|
43
|
+
* is copied; anything else stored is ignored. It is built here so that
|
|
44
|
+
* browser storage is still touched in this file alone.
|
|
45
|
+
*/
|
|
46
|
+
declare function inlineRootAttributeScript(key: string, attribute: string, values: readonly string[]): string;
|
|
30
47
|
/** An in-memory store — the no-op-equivalent seam for SSR or tests. */
|
|
31
48
|
declare function createMemoryPreferenceStore(): PreferenceStore;
|
|
32
49
|
|
|
33
|
-
export { type PreferenceStore, createBrowserPreferenceStore, createMemoryPreferenceStore };
|
|
50
|
+
export { type PreferenceStore, createBrowserPreferenceStore, createMemoryPreferenceStore, createSessionPreferenceStore, inlineRootAttributeScript };
|
|
@@ -21,6 +21,32 @@ function createBrowserPreferenceStore() {
|
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
+
function createSessionPreferenceStore() {
|
|
25
|
+
return {
|
|
26
|
+
get(key) {
|
|
27
|
+
try {
|
|
28
|
+
return window.sessionStorage.getItem(key);
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
set(key, value) {
|
|
34
|
+
try {
|
|
35
|
+
window.sessionStorage.setItem(key, value);
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
remove(key) {
|
|
40
|
+
try {
|
|
41
|
+
window.sessionStorage.removeItem(key);
|
|
42
|
+
} catch {
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function inlineRootAttributeScript(key, attribute, values) {
|
|
48
|
+
return `try{var v=window.localStorage.getItem(${JSON.stringify(key)});if(${JSON.stringify(values)}.indexOf(v)>=0)document.documentElement.setAttribute(${JSON.stringify(attribute)},v)}catch(e){}`;
|
|
49
|
+
}
|
|
24
50
|
function createMemoryPreferenceStore() {
|
|
25
51
|
const map = /* @__PURE__ */ new Map();
|
|
26
52
|
return {
|
|
@@ -35,5 +61,7 @@ function createMemoryPreferenceStore() {
|
|
|
35
61
|
}
|
|
36
62
|
export {
|
|
37
63
|
createBrowserPreferenceStore,
|
|
38
|
-
createMemoryPreferenceStore
|
|
64
|
+
createMemoryPreferenceStore,
|
|
65
|
+
createSessionPreferenceStore,
|
|
66
|
+
inlineRootAttributeScript
|
|
39
67
|
};
|
package/docs/authoring/README.md
CHANGED
|
@@ -15,10 +15,12 @@ leave that reason in the diff or the PR description. "I preferred it" is not a
|
|
|
15
15
|
reason; "the cited source writes it this way and the passage shows the mapping"
|
|
16
16
|
is.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Three kinds of rule live here:
|
|
19
19
|
|
|
20
20
|
- **Build-enforced** — the engine already fails the build when the rule is
|
|
21
21
|
broken. The rule text tells you _how_ to satisfy the gate, not whether to.
|
|
22
|
+
- **Partial** — the build checks part of the rule and a reviewer the rest;
|
|
23
|
+
the rule index says which part is which.
|
|
22
24
|
- **Review-only** — nothing checks it automatically; a reviewer does. Breaking
|
|
23
25
|
one is a review comment, not a broken build.
|
|
24
26
|
|
|
@@ -75,16 +77,16 @@ the line before the next blank line — and may name several rules
|
|
|
75
77
|
depends on the rule:
|
|
76
78
|
|
|
77
79
|
- **A rule with a check that reports a line** (`waivable` on the rules-in-effect
|
|
78
|
-
page
|
|
79
|
-
waiver that silences nothing is a `waiver-unused` warning, so a
|
|
80
|
-
gets removed.
|
|
80
|
+
page, such as N9, N14, N23 and S1) — the build drops the findings the waiver
|
|
81
|
+
covers. A waiver that silences nothing is a `waiver-unused` warning, so a
|
|
82
|
+
stale one gets removed.
|
|
81
83
|
- **A guide rule** (every `P` and `V` rule, N2, N11, …) — nothing to silence;
|
|
82
84
|
the waiver is the reason on record, next to the sentence it is about, and a
|
|
83
85
|
reviewer reads it as such.
|
|
84
86
|
- **One of the course's own rules** (`X1`, …) — always waivable inline: an
|
|
85
87
|
enforced one reports a line, and a guide one has nothing to silence.
|
|
86
88
|
- **A rule whose check has no line** — a notation entry (N8, N10, N19–N21), a
|
|
87
|
-
per-lesson count (S3, S4
|
|
89
|
+
per-lesson count (S3, S4), the changelog (C3) — cannot be waived inline.
|
|
88
90
|
Silence one finding per key in `lint-ignore.yml`
|
|
89
91
|
(`- <code>:<key> — <reason>`), or turn the rule off in `rules.<ID>`.
|
|
90
92
|
- **A locked rule** (N4, N13, N15) and an invariant cannot be waived: the
|
|
@@ -108,7 +110,8 @@ rule and a course can number its own without waiting for a release.
|
|
|
108
110
|
> **N1 — One-line imperative.**
|
|
109
111
|
> _Rationale._ Why the rule exists; the failure it prevents.
|
|
110
112
|
> _How to apply._ Concrete steps, with the smallest example that shows it.
|
|
111
|
-
> _Enforcement._ Build-enforced (naming the gate module) or
|
|
113
|
+
> _Enforcement._ Build-enforced or Partial (naming the gate module), or
|
|
114
|
+
> Review-only.
|
|
112
115
|
> _Exceptions._ The stateable reasons that override it, if any.
|
|
113
116
|
|
|
114
117
|
IDs are permanent, so a `N3` in an old commit message never goes ambiguous — but
|
|
@@ -199,12 +202,15 @@ waits without affecting this term's lessons.
|
|
|
199
202
|
|
|
200
203
|
**What a pattern sees.** A JavaScript regular expression, matched against the
|
|
201
204
|
lesson's prose with code fences, inline code, `$…$` and `$$…$$`, `[[key]]`
|
|
202
|
-
references,
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
references, link addresses (a link is read by its text), `import` lines, JSX
|
|
206
|
+
tags and MDX comments blanked out first — exactly the surface rule N9 scans,
|
|
207
|
+
so a pattern never trips over LaTeX or a component's syntax. The text a reader
|
|
208
|
+
sees in a prop (`caption`, `short`, `title`, `label`) is read too, each as a
|
|
209
|
+
paragraph of its own. `scope` picks the unit: `paragraph` (the default — a
|
|
210
|
+
block between blank lines, right-trimmed, so `^` and `$` are its ends, or a
|
|
211
|
+
visible prop's text), `prose` (the whole lesson, so a pattern may span
|
|
212
|
+
paragraphs, and each visible prop), or `heading` (the text of each Markdown
|
|
213
|
+
heading). `flags` takes `i`, `m`, `s`, `u`; `g` is always applied. A
|
|
208
214
|
pattern that does not compile, or that matches the empty string, fails the build
|
|
209
215
|
with the path of the setting — the rule never silently does nothing.
|
|
210
216
|
|
|
@@ -225,7 +231,7 @@ of to the settings file.
|
|
|
225
231
|
| [notation.md](notation.md) | `N` | how math symbols are written and bound |
|
|
226
232
|
| [visualizations.md](visualizations.md) | `V` | diagrams, charts, interactive figures, randomness |
|
|
227
233
|
| [versioning.md](versioning.md) | `C` | the knowledge version and `content/CHANGELOG.md` |
|
|
228
|
-
| [structure-rules.md](structure-rules.md) | `S` | heading and float title length; part page paragraphs; tables
|
|
234
|
+
| [structure-rules.md](structure-rules.md) | `S` | heading and float title length; part page paragraphs; tables and diagrams declared so they can be cited |
|
|
229
235
|
| [prose.md](prose.md) | `P` | how a lesson's sentences, terms, and equation lead-ins are worded |
|
|
230
236
|
| [components.md](components.md) | — | _catalog_: inline/block features available in a lesson body — tooltips, tables, figures, diagrams, memos, abbreviations, citations |
|
|
231
237
|
| [agents.md](agents.md) | — | _guide_: working on a course repo (with an AI agent) |
|
|
@@ -254,13 +260,16 @@ of to the settings file.
|
|
|
254
260
|
| [N19](notation.md#n19) | notation | A notation entry states `units` from the vocabulary, or `dimensionless` | Script — `notation-units` (warning), `units-vocab` (warning) in [`consistency.ts`](../../src/reference/consistency.ts) `checkNotationUnits` |
|
|
255
261
|
| [N20](notation.md#n20) | notation, source | A notation entry's source citation carries a locator | Script — `notation-source-locator` (warning) in [`consistency.ts`](../../src/reference/consistency.ts) `checkNotationSourceLocator` |
|
|
256
262
|
| [N21](notation.md#n21) | notation | A gloss is named by a short noun phrase, not a sentence | Script — `gloss-name-shape` (warning) in [`consistency.ts`](../../src/reference/consistency.ts) `checkGlossNameShape` |
|
|
257
|
-
| [N22](notation.md#n22) | math, notation | An accent or mark is an operator: universal, explained, or a whole form — settings: `allow` = `[]`, `deny` = `[]` | Script — `accent-explained` (warning), `suspended-operator-unresolved`, `operator-suspension-reason` (warning), `operator-suspended` (info), `operator-shadowed` (info) in [`consistency.ts`](../../src/reference/consistency.ts) `checkAccentExplained`, `checkOperatorSuspension`; [`gate-math.ts`](../../src/reference/gate-math.ts) `resolveInto` |
|
|
263
|
+
| [N22](notation.md#n22) | math, notation | An accent or mark is an operator: universal, explained, or a whole form — settings: `allow` = `[]`, `deny` = `[]` | Script — `accent-explained` (warning), `accent-swallowed` (warning), `suspended-operator-unresolved`, `operator-suspension-reason` (warning), `operator-suspended` (info), `operator-shadowed` (info) in [`consistency.ts`](../../src/reference/consistency.ts) `checkAccentExplained`, `checkOperatorSuspension`; [`gate-math.ts`](../../src/reference/gate-math.ts) `resolveInto` |
|
|
264
|
+
| [N23](notation.md#n23) | math, notation | An index is part of the symbol: whole form, family or index entry | Partial — `index-explained`, `index-swallowed`, `index-range`, `derived-key-taken` in [`gate-indices.ts`](../../src/reference/gate-indices.ts) `gateIndices`. review: whether a `\quad` clause states the set correctly; whether a lowercase index is really running; lab math whose glyph table is a copy of the one `labMathScope` returned |
|
|
258
265
|
| [V1](visualizations.md#v1) | diagram | Graphs and flowcharts use the `Diagram` component | Guide |
|
|
259
266
|
| [V2](visualizations.md#v2) | plot | Static charts: SVG → D3 → Observable Plot, chosen per figure | Guide |
|
|
260
|
-
| [V3](visualizations.md#v3) | plot | Interactive figures: a hydrated island + the `renderLabMath` seam |
|
|
267
|
+
| [V3](visualizations.md#v3) | plot | Interactive figures: a hydrated island + the `renderLabMath` seam | Partial — `lab-katex-direct`, `lab-picture-undrawn` (warning) in [`lab-katex-validate.ts`](../../src/reference/lab-katex-validate.ts) `validateLabKatexImports`; [`figure-pictures.ts`](../../src/reference/figure-pictures.ts) `undrawnFigurePictures`. review: that a lab labels its controls and writes no name of its own, and math a lab draws without importing `katex` — the build’s rendered check (`figure-symbols.ts`) covers the page it renders |
|
|
261
268
|
| [V4](visualizations.md#v4) | plot | Randomised figures expose an adjustable, deterministic seed | Guide |
|
|
262
269
|
| [V5](visualizations.md#v5) | plot | Axis ranges span the first 10 seeds at the current control values — settings: `seeds` = `10` | Guide |
|
|
263
270
|
| [V6](visualizations.md#v6) | plot | Every quantitative axis shows at least three labelled values — settings: `minLabels` = `3` | Guide |
|
|
271
|
+
| [V7](visualizations.md#v7) | plot | A figure’s picture fits on one screen — settings: `maxPercent` = `80` | Partial — `figure-too-tall` (warning) in [`figure-fit.ts`](../../src/reference/figure-fit.ts) `checkFigureFit`. review: any page or viewport the course’s Playwright suite does not open — the check runs in the browser, not in the build |
|
|
272
|
+
| [V8](visualizations.md#v8) | diagram | A diagram fits the lesson column — settings: `columnWidth` = `707` | Script — `dia-too-wide` (warning) in [`diagram-fit.ts`](../../src/reference/diagram-fit.ts) `oversizedDiagrams` |
|
|
264
273
|
| [C1](versioning.md#c1) | changelog | Every content change lands with a `content/CHANGELOG.md` entry | Guide |
|
|
265
274
|
| [C2](versioning.md#c2) | changelog | The knowledge version is semver over learning-facing content | Guide |
|
|
266
275
|
| [C3](versioning.md#c3) | changelog | `about.version` equals the newest changelog heading; a release moves both | Partial — `knowledge-version-mismatch` (warning), `knowledge-version-invalid` (warning), `knowledge-changelog-missing` (warning) in [`knowledge-version.ts`](../../src/compiler/knowledge-version.ts) `resolveKnowledgeVersion`. review: that the two edits landed in one commit — the build only ever sees the end state, so a release split across commits warns until the second half lands |
|
|
@@ -268,11 +277,11 @@ of to the settings file.
|
|
|
268
277
|
| [S2](structure-rules.md#s2) | part-page | A part page carries a `<PartBridge>` (earlier parts → this one) and a `<PartScope>` paragraph — settings: `bridgeMinWords` = `30`, `bridgeMaxWords` = `150`, `scopeMinWords` = `30`, `scopeMaxWords` = `150` | Partial — `part-page-paragraph` in [`gate-part-pages.ts`](../../src/reference/gate-part-pages.ts) `gatePartPages`. review: what each paragraph says — the gate cannot tell a bridge that links the parts from one that does not |
|
|
269
278
|
| [S3](structure-rules.md#s3) | table | A table is a `<Table id="…">`, never a raw Markdown/HTML table | Script — `raw-table-markdown` (warning), `raw-table-html` (warning) in [`raw-floats-validate.ts`](../../src/reference/raw-floats-validate.ts) `validateRawFloats` |
|
|
270
279
|
| [S4](structure-rules.md#s4) | diagram | A `<Diagram>` carries an `id` and sits where numbering can see it | Script — `diagram-unkeyed` (warning), `diagram-nested` (warning) in [`raw-floats-validate.ts`](../../src/reference/raw-floats-validate.ts) `validateRawFloats` |
|
|
271
|
-
| [
|
|
272
|
-
| [S6](structure-rules.md#s6) | heading | Headings descend one level at a time, from `##` | Script — `heading-skip` in [`gate-heading-structure.ts`](../../src/reference/gate-heading-structure.ts) `gateHeadingStructure` |
|
|
280
|
+
| [S6](structure-rules.md#s6) | heading | Headings descend one level at a time, from `##` | Script — `heading-skip`, `heading-nested` in [`gate-heading-structure.ts`](../../src/reference/gate-heading-structure.ts) `gateHeadingStructure` |
|
|
273
281
|
| [S7](structure-rules.md#s7) | heading | A heading is followed by body content, never by another heading | Script — `heading-adjacent` in [`gate-heading-structure.ts`](../../src/reference/gate-heading-structure.ts) `gateHeadingStructure` |
|
|
274
282
|
| [S8](structure-rules.md#s8) | prose | Prefer `<Memo>` over a Starlight aside when the content needs an anchor, a caption or collapsing | Guide |
|
|
275
283
|
| [S9](structure-rules.md#s9) | plot, table, diagram | A float’s short caption names it; the long caption goes on from that name | Guide |
|
|
284
|
+
| [S10](structure-rules.md#s10) | part-page, plot, table, diagram, equation, notation | A page that is not a chapter explains its symbols but numbers nothing: it links a chapter’s float instead | **Locked** — a float needs a chapter number, and such a page has none — turning the rule off would not render one. Script — `non-chapter-float`, `non-chapter-local-notation`, `non-chapter-plain-text` in [`gate-non-chapter-pages.ts`](../../src/reference/gate-non-chapter-pages.ts) `gateNonChapterPages` |
|
|
276
285
|
| [P1](prose.md#p1) | prose | "or" never introduces a second name for the same thing | Guide |
|
|
277
286
|
| [P2](prose.md#p2) | prose | One term for each concept, repeated — no synonyms for variety | Guide |
|
|
278
287
|
| [P3](prose.md#p3) | prose | One meaning for each term; no technical term in its everyday sense | Guide |
|
|
@@ -302,11 +311,14 @@ next to the syntax it belongs to.
|
|
|
302
311
|
|
|
303
312
|
| Invariant | Element | Holds that | Codes |
|
|
304
313
|
| --- | --- | --- | --- |
|
|
305
|
-
| [`notation-references`](components.md#reference-systems) | notation, math | Notation keys are well-formed, unique, defined, and acyclic. | `undefined-reference`, `invalid-key`, `duplicate-key`, `duplicate-page`, `duplicate-definition`, `conflicting-definition`, `reference-cycle`, `gloss-collides-with-card`, `unknown-explicit-key`, `malformed-explicit-binding`, `unused-definition` (info) in [`registry.ts`](../../src/reference/registry.ts) `buildNotationRegistry`; [`math-glyphs.mjs`](../../src/reference/math-glyphs.mjs) `resolveMathGlyphs`; [`gate-math.ts`](../../src/reference/gate-math.ts) `reportUnknownScopeKeys` |
|
|
306
|
-
| [`math-syntax`](notation.md) | math | Every math span parses and resolves unambiguously. | `invalid-latex`, `invalid-latex-input`, `invalid-notation`, `invalid-definitions`, `unsupported-katex-version`, `ambiguous-span`, `ambiguous-base-fallback`, `ambiguous-canonical-notation`, `math-compile-error` in [`math-glyphs.mjs`](../../src/reference/math-glyphs.mjs) `resolveMathGlyphs`; [`gate-math.ts`](../../src/reference/gate-math.ts) `resolveInto` |
|
|
307
|
-
| [`keyed-floats`](structure.md#the-invariant-and-why-it-is-build-enforced) | equation, table, plot, diagram, assessment, heading | A keyed float’s `id` is well-formed and unique, it is named by its caption pair, and every `[[…]]` to it or to a section resolves. | `eq-duplicate-key`, `eq-ref-resolves`, `tab-invalid-key`, `tab-duplicate-key`, `tab-ref-resolves`, `tab-key-unused` (info), `tab-removed-prop`, `fig-invalid-key`, `fig-duplicate-key`, `fig-ref-resolves`, `fig-key-unused` (info), `fig-removed-prop`, `dia-invalid-key`, `dia-duplicate-key`, `dia-ref-resolves`, `dia-key-unused` (info), `dia-removed-prop`, `ex-invalid-key`, `ex-duplicate-key`, `ex-ref-resolves`, `ex-key-unused` (info), `ex-removed-prop`, `check-invalid-key`, `check-duplicate-key`, `check-ref-resolves`, `ex-missing-prop`, `sec-ref-resolves`, `fold-unnamed` in [`equations-validate.ts`](../../src/reference/equations-validate.ts) `validateEquations`; [`keyed-float-validate.ts`](../../src/reference/keyed-float-validate.ts) `validateKeyedFloats`; [`knowledge-checks-validate.ts`](../../src/reference/knowledge-checks-validate.ts) `validateKnowledgeChecks`; [`examples-validate.ts`](../../src/reference/examples-validate.ts) `validateExamples`; [`sections-validate.ts`](../../src/reference/sections-validate.ts) `validateSectionRefs`; [`folds-validate.ts`](../../src/reference/folds-validate.ts) `validateFolds` |
|
|
314
|
+
| [`notation-references`](components.md#reference-systems) | notation, math | Notation keys are well-formed, unique, defined, and acyclic. | `undefined-reference`, `invalid-key`, `duplicate-key`, `duplicate-page`, `duplicate-definition`, `conflicting-definition`, `reference-cycle`, `gloss-collides-with-card`, `unknown-explicit-key`, `malformed-explicit-binding`, `unused-definition` (info), `local-shadows-shared` (warning), `malformed-reference` in [`registry.ts`](../../src/reference/registry.ts) `buildNotationRegistry`; [`math-glyphs.mjs`](../../src/reference/math-glyphs.mjs) `resolveMathGlyphs`; [`gate-math.ts`](../../src/reference/gate-math.ts) `reportUnknownScopeKeys` |
|
|
315
|
+
| [`math-syntax`](notation.md) | math | Every math span parses and resolves unambiguously. | `invalid-latex`, `invalid-latex-input`, `invalid-notation`, `invalid-definitions`, `unsupported-katex-version`, `ambiguous-span`, `ambiguous-base-fallback`, `ambiguous-canonical-notation`, `math-compile-error`, `currency-dollar` in [`math-glyphs.mjs`](../../src/reference/math-glyphs.mjs) `resolveMathGlyphs`; [`gate-math.ts`](../../src/reference/gate-math.ts) `resolveInto`, `gateContentMath` |
|
|
316
|
+
| [`keyed-floats`](structure.md#the-invariant-and-why-it-is-build-enforced) | equation, table, plot, diagram, assessment, heading | A keyed float’s `id` is well-formed and unique, it is named by its caption pair, and every `[[…]]` to it or to a section resolves. | `eq-duplicate-key`, `eq-ref-resolves`, `eq-label-repeated`, `eq-latex-ref`, `tab-invalid-key`, `tab-duplicate-key`, `tab-ref-resolves`, `tab-key-unused` (info), `tab-removed-prop`, `tab-unread-prop` (warning), `tab-several-tables`, `fig-invalid-key`, `fig-duplicate-key`, `fig-ref-resolves`, `fig-key-unused` (info), `fig-removed-prop`, `fig-unread-prop` (warning), `dia-invalid-key`, `dia-duplicate-key`, `dia-ref-resolves`, `dia-key-unused` (info), `dia-removed-prop`, `dia-unread-prop` (warning), `ex-invalid-key`, `ex-duplicate-key`, `ex-ref-resolves`, `ex-key-unused` (info), `ex-removed-prop`, `ex-unread-prop` (warning), `check-invalid-key`, `check-duplicate-key`, `check-ref-resolves`, `ex-missing-prop`, `sec-ref-resolves`, `heading-anchor-collision`, `fold-unnamed` in [`equations-validate.ts`](../../src/reference/equations-validate.ts) `validateEquations`; [`keyed-float-validate.ts`](../../src/reference/keyed-float-validate.ts) `validateKeyedFloats`; [`tables-validate.ts`](../../src/reference/tables-validate.ts) `validateTables`; [`knowledge-checks-validate.ts`](../../src/reference/knowledge-checks-validate.ts) `validateKnowledgeChecks`; [`examples-validate.ts`](../../src/reference/examples-validate.ts) `validateExamples`; [`sections-validate.ts`](../../src/reference/sections-validate.ts) `validateSectionRefs`, `validateHeadingAnchors`; [`folds-validate.ts`](../../src/reference/folds-validate.ts) `validateFolds` |
|
|
308
317
|
| [`course-settings`](README.md#amending) | changelog | The course settings name real rules and current keys. | `config-deprecated-key` (warning), `config-retired-rule` (warning) in [`settings.ts`](../../src/rules/settings.ts) `resolveRules` |
|
|
309
318
|
| [`waivers`](README.md#waiving-a-rule-at-one-place) | prose | A per-place waiver names a waivable rule, gives a reason, and covers something. | `waiver-malformed`, `waiver-invalid`, `waiver-unused` (warning) in [`waivers.ts`](../../src/rules/waivers.ts) `collectWaivers`, `applyWaivers` |
|
|
310
|
-
| [`curriculum`](structure.md#the-names) | changelog | The curriculum graph is well-formed. | `invalid-id`, `duplicate-id`, `unknown-reference`, `duplicate-reference`, `self-prerequisite`, `cycle`, `lesson-order`, `track-order`, `assessment-coverage`, `invalid-assessment`, `
|
|
319
|
+
| [`curriculum`](structure.md#the-names) | changelog | The curriculum graph is well-formed. | `invalid-id`, `duplicate-id`, `unknown-reference`, `duplicate-reference`, `self-prerequisite`, `cycle`, `lesson-order`, `track-order`, `assessment-coverage`, `invalid-assessment`, `missing-assumptions`, `teaches-support`, `citation-in-link`, `alignment-unknown-competency`, `alignment-unknown-lesson`, `alignment-introduction`, `alignment-unavailable`, `lesson-outside-parts`, `part-empty` (warning) in [`validation.ts`](../../src/curriculum/validation.ts) `validateCurriculum`; [`curriculum-alignment.ts`](../../src/reference/curriculum-alignment.ts) `validateNotationAlignment`; [`manifest.ts`](../../src/compiler/manifest.ts) `compileManifest` |
|
|
320
|
+
| [`content-schema`](structure.md#content-schemas) | notation, assessment, source, changelog | Every content file satisfies its collection’s schema. | `content-schema` in [`content-schema.ts`](../../src/compiler/content-schema.ts) `validateContentSchemas` |
|
|
321
|
+
| [`retired-keys`](structure.md#retired-keys) | changelog | No content file sets a key the engine has retired or cannot honour. | `retired-key`, `unsupported-key`, `ignored-key` (warning) in [`gate-retired-keys.ts`](../../src/reference/gate-retired-keys.ts) `findRetiredKeys`, `findUnsupportedKeys` |
|
|
322
|
+
| [`prop-text`](components.md#props-are-plain-text) | math, plot, diagram, table | A component’s quoted prop holds plain text, and prose holds no `{…}` expression. | `markup-in-prop`, `mdx-expression` in [`gate-prop-text.ts`](../../src/reference/gate-prop-text.ts) `findMarkupInProps`; [`gate-mdx-expression.ts`](../../src/reference/gate-mdx-expression.ts) `gateMdxExpressions` |
|
|
311
323
|
|
|
312
324
|
<!-- RULES-INDEX:END -->
|
package/docs/authoring/agents.md
CHANGED
|
@@ -34,9 +34,10 @@ and a rule disagree, the engine wins — see [`README.md`](README.md).
|
|
|
34
34
|
editing this folder.
|
|
35
35
|
- **Start from the CLI, not a file hunt.** `pnpm --filter <course> content
|
|
36
36
|
context <lesson>` prints a lesson plus exactly its notation, references, and
|
|
37
|
-
assumptions. `pnpm content status` is the
|
|
38
|
-
diagnostics info` lists everything;
|
|
39
|
-
severity. `pnpm content warnings`
|
|
37
|
+
assumptions. `pnpm content status` is the overview: counts, diagnostic
|
|
38
|
+
totals and orphans. `pnpm content diagnostics info` lists everything;
|
|
39
|
+
`warning` and `error` raise the minimum severity. `pnpm content warnings`
|
|
40
|
+
lists warnings only.
|
|
40
41
|
`pnpm content check <lesson> | --changed` is schema + refs + MDX→KaTeX, exits
|
|
41
42
|
non-zero on an error. Read those before opening files.
|
|
42
43
|
- **Validate, twice.** `pnpm --filter <course> validate:content` regenerates
|
|
@@ -77,10 +78,17 @@ they are all `guide`, and the review is yours.
|
|
|
77
78
|
- Every glyph in a `formula:` must resolve (rule N4, locked): to the entry
|
|
78
79
|
itself, one of its `glosses:`, a card named with `\explain{key}{latex}`, or
|
|
79
80
|
the base library. An unresolved bare letter fails the build with the entry
|
|
80
|
-
name.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
name. A formula resolves against its own card's table, so an index entry
|
|
82
|
+
(`{}_0`, rule N23) does not compose there: explain `v_0` with a whole form
|
|
83
|
+
(`\explain{motion.launch-speed}{v_0}`), a gloss, or by wrapping the
|
|
84
|
+
subscript in the index entry's key,
|
|
85
|
+
`\mathbf{v}_{\explain{motion.initial}{0}}`.
|
|
86
|
+
- The notation reference graph must be **acyclic** through meanings and
|
|
87
|
+
bodies: if `a`'s meaning names `b` and `b`'s names `a`, the build rejects
|
|
88
|
+
it. Link only *down* a chain (acceleration → velocity → position, not back
|
|
89
|
+
up). A `formula` may name any card, even one whose formula names it back:
|
|
90
|
+
`confidence-level` (γ = 1 − α) and `significance-level` (α = 1 − γ), or
|
|
91
|
+
three entries that each show the one model equation they appear in.
|
|
84
92
|
- `\mathbf` is the house style for a vector, and a bold letter is its own
|
|
85
93
|
symbol (rule N4): `\mathbf{v}` needs an entry (`latex: \mathbf{v}`) or an
|
|
86
94
|
`\explain{key}{\mathbf{v}}` wrap even when a scalar `v` is on the page. The
|
|
@@ -103,6 +111,29 @@ they are all `guide`, and the review is yours.
|
|
|
103
111
|
own entry, so it is stricter, not a shortcut; one whole-form entry is enough
|
|
104
112
|
when a single decorated symbol is special.
|
|
105
113
|
|
|
114
|
+
## Indices: `x_0`, `v_x`, `x_i` (rule N23)
|
|
115
|
+
|
|
116
|
+
- A subscript on a symbol is part of the symbol, and a card on the base alone
|
|
117
|
+
does not explain it. Before drafting, decide per indexed symbol which of the
|
|
118
|
+
three it is: a **whole form** with its own entry (`latex: v_0`, "Launch
|
|
119
|
+
speed") for a named quantity; a **family** (`latex: x_k`) for an index that
|
|
120
|
+
runs, which explains `x_1`, `x_{k+1}`, `x_N`; or an **index entry**
|
|
121
|
+
(`latex: "{}_0"`, quoted) for a subscript with one meaning on the page,
|
|
122
|
+
which makes every carded symbol it indexes one derived card. An index entry
|
|
123
|
+
takes no `units`; its title for the symbol comes from `reads`.
|
|
124
|
+
- A base-library `i`, `e` or `d`, a digit or a `\mathrm{…}` label in a
|
|
125
|
+
subscript needs one of the three; an index letter with its own card
|
|
126
|
+
(`X_{t-1}`) explains its slot. A running index (lowercase, not marked
|
|
127
|
+
`fixedIndex: true`) states its set once: `range` on its card, or after a
|
|
128
|
+
`\quad` on the first display line that uses it (`\quad i = 1, \dots, n`).
|
|
129
|
+
- Do not wrap an indexed symbol in a card that has no index:
|
|
130
|
+
`\explain{motion.velocity}{v_x}` fails `index-swallowed`. An indexed entry
|
|
131
|
+
lends its card to no bare symbol (rule N4): a bare `\alpha` beside a family
|
|
132
|
+
`\alpha_i` needs its own entry.
|
|
133
|
+
- Lab and `<Diagram>` math is checked as it renders, at `astro build`. A lab
|
|
134
|
+
passes the table `labMathScope` returned to `renderLabMath` unchanged; a
|
|
135
|
+
copy gets no derived cards and no check.
|
|
136
|
+
|
|
106
137
|
## Versioning
|
|
107
138
|
|
|
108
139
|
Every content change adds a bullet under `## [Unreleased]` in
|