explico 0.13.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/CHANGELOG.md +990 -1
  2. package/README.md +200 -30
  3. package/dist/compiler/astro.d.ts +15 -2
  4. package/dist/compiler/astro.js +40 -11
  5. package/dist/compiler/cli-main.d.ts +100 -0
  6. package/dist/compiler/cli-main.js +433 -0
  7. package/dist/compiler/cli-reference.d.ts +50 -0
  8. package/dist/compiler/cli-reference.js +213 -0
  9. package/dist/compiler/cli-verbs.d.ts +45 -0
  10. package/dist/compiler/cli-verbs.js +224 -0
  11. package/dist/compiler/cli-verify.d.ts +51 -0
  12. package/dist/compiler/cli-verify.js +151 -0
  13. package/dist/compiler/cli.d.ts +408 -24
  14. package/dist/compiler/cli.js +1328 -8
  15. package/dist/compiler/collections.d.ts +88 -1
  16. package/dist/compiler/collections.js +170 -25
  17. package/dist/compiler/content-release.d.ts +49 -0
  18. package/dist/compiler/content-release.js +63 -0
  19. package/dist/compiler/content-schemas.d.ts +2 -2
  20. package/dist/compiler/course-config.d.ts +1 -1
  21. package/dist/compiler/course-config.js +105 -1
  22. package/dist/compiler/decks.d.ts +161 -0
  23. package/dist/compiler/decks.js +235 -0
  24. package/dist/compiler/exports/combined-html.d.ts +5 -1
  25. package/dist/compiler/exports/deck-fit.d.ts +55 -0
  26. package/dist/compiler/exports/deck-fit.js +90 -0
  27. package/dist/compiler/exports/export-chapters.d.ts +37 -6
  28. package/dist/compiler/exports/export-chapters.js +64 -5
  29. package/dist/compiler/exports/export-pages.d.ts +30 -3
  30. package/dist/compiler/exports/export-pages.js +24 -1
  31. package/dist/compiler/exports/latex/beamerthemeexplico.sty +124 -0
  32. package/dist/compiler/exports/latex/cache.d.ts +78 -0
  33. package/dist/compiler/exports/latex/cache.js +129 -0
  34. package/dist/compiler/exports/latex/capture.d.ts +10 -1
  35. package/dist/compiler/exports/latex/capture.js +3 -1
  36. package/dist/compiler/exports/latex/compile.d.ts +13 -2
  37. package/dist/compiler/exports/latex/compile.js +12 -1
  38. package/dist/compiler/exports/latex/deck.d.ts +92 -0
  39. package/dist/compiler/exports/latex/deck.js +349 -0
  40. package/dist/compiler/exports/latex/document.d.ts +51 -6
  41. package/dist/compiler/exports/latex/document.js +71 -12
  42. package/dist/compiler/exports/latex/explico-common.sty +198 -0
  43. package/dist/compiler/exports/latex/explico.cls +13 -183
  44. package/dist/compiler/exports/latex/serialize.d.ts +60 -4
  45. package/dist/compiler/exports/latex/serialize.js +4 -2
  46. package/dist/compiler/exports/latex-export.d.ts +24 -2
  47. package/dist/compiler/exports/latex-export.js +107 -26
  48. package/dist/compiler/exports/markdown/serialize.d.ts +24 -4
  49. package/dist/compiler/exports/markdown/serialize.js +85 -8
  50. package/dist/compiler/exports/markdown-export.d.ts +6 -1
  51. package/dist/compiler/exports/markdown-export.js +50 -11
  52. package/dist/compiler/exports/standalone-html.d.ts +10 -5
  53. package/dist/compiler/exports/standalone-html.js +3 -3
  54. package/dist/compiler/exports/static-tree.d.ts +38 -1
  55. package/dist/compiler/exports/static-tree.js +120 -4
  56. package/dist/compiler/knowledge-version.d.ts +26 -2
  57. package/dist/compiler/knowledge-version.js +27 -17
  58. package/dist/compiler/lesson-derivation.d.ts +143 -6
  59. package/dist/compiler/lesson-derivation.js +145 -13
  60. package/dist/compiler/manifest.d.ts +133 -4
  61. package/dist/compiler/manifest.js +364 -58
  62. package/dist/compiler/page-versions.d.ts +184 -0
  63. package/dist/compiler/page-versions.js +217 -0
  64. package/dist/compiler/render-diagnostics.d.ts +5 -1
  65. package/dist/compiler/resolution-report.d.ts +24 -6
  66. package/dist/compiler/resolution-report.js +22 -4
  67. package/dist/compiler/validate-content.d.ts +7 -0
  68. package/dist/compiler/validate-content.js +160 -0
  69. package/dist/{course-config-rRtME5UV.d.ts → course-config-BLtIdkei.d.ts} +164 -1
  70. package/dist/curriculum/competency-graph.d.ts +54 -0
  71. package/dist/curriculum/competency-graph.js +41 -0
  72. package/dist/reference/base-library.d.mts +8 -0
  73. package/dist/reference/base-library.mjs +19 -0
  74. package/dist/reference/consistency.d.ts +8 -4
  75. package/dist/reference/consistency.js +82 -26
  76. package/dist/reference/deck-remark.d.mts +123 -0
  77. package/dist/reference/deck-remark.mjs +600 -0
  78. package/dist/reference/deck-source.d.ts +107 -0
  79. package/dist/reference/deck-source.js +140 -0
  80. package/dist/reference/decks-validate.d.ts +133 -0
  81. package/dist/reference/decks-validate.js +359 -0
  82. package/dist/reference/derived-entries.d.ts +5 -1
  83. package/dist/reference/diagram-fit.d.ts +6 -2
  84. package/dist/reference/diagram-fit.js +5 -1
  85. package/dist/reference/figure-symbols.d.ts +23 -6
  86. package/dist/reference/figure-symbols.js +51 -15
  87. package/dist/reference/float-name.d.ts +43 -0
  88. package/dist/reference/float-name.js +58 -0
  89. package/dist/reference/folds-validate.d.ts +1 -1
  90. package/dist/reference/gate-abbreviations.d.ts +1 -1
  91. package/dist/reference/gate-indices.js +5 -4
  92. package/dist/reference/gate-math.d.ts +29 -2
  93. package/dist/reference/gate-math.js +99 -18
  94. package/dist/reference/gate-part-pages.d.ts +1 -1
  95. package/dist/reference/lab-katex-validate.d.ts +10 -6
  96. package/dist/reference/lab-katex-validate.js +17 -9
  97. package/dist/reference/lab-math-scope.js +29 -4
  98. package/dist/reference/math-glyphs.d.mts +25 -0
  99. package/dist/reference/math-glyphs.mjs +189 -25
  100. package/dist/reference/page-notation.d.ts +22 -3
  101. package/dist/reference/page-notation.js +32 -10
  102. package/dist/reference/references.d.ts +14 -1
  103. package/dist/reference/references.js +13 -0
  104. package/dist/reference/registry-scope.d.mts +33 -0
  105. package/dist/reference/registry-scope.mjs +34 -0
  106. package/dist/reference/registry.js +29 -10
  107. package/dist/reference/rehype-deck.d.mts +6 -0
  108. package/dist/reference/rehype-deck.mjs +286 -0
  109. package/dist/reference/rehype-heading-anchors.d.mts +20 -0
  110. package/dist/reference/rehype-heading-anchors.mjs +48 -6
  111. package/dist/reference/remark-notation.mjs +249 -40
  112. package/dist/reference/source-lines.d.mts +12 -0
  113. package/dist/reference/source-lines.mjs +65 -0
  114. package/dist/reference/types.d.ts +28 -0
  115. package/dist/rules/catalog.d.ts +21 -4
  116. package/dist/rules/catalog.js +237 -2
  117. package/dist/rules/course-rules.d.ts +5 -1
  118. package/dist/rules/course-rules.js +17 -3
  119. package/dist/rules/course-rules.schema.json +12 -0
  120. package/dist/rules/in-effect.d.ts +13 -3
  121. package/dist/rules/in-effect.js +34 -10
  122. package/dist/rules/rules.schema.json +280 -1
  123. package/dist/rules/settings.d.ts +1 -1
  124. package/dist/session/PreferenceStore.d.ts +6 -0
  125. package/dist/session/PreferenceStore.js +18 -1
  126. package/dist/session/deck-memory.d.ts +116 -0
  127. package/dist/session/deck-memory.js +143 -0
  128. package/dist/session/reading-memory.d.ts +96 -0
  129. package/dist/session/reading-memory.js +133 -0
  130. package/docs/VERSIONING.md +21 -18
  131. package/docs/authoring/README.md +31 -9
  132. package/docs/authoring/agents.md +72 -18
  133. package/docs/authoring/cli-reference.json +2172 -0
  134. package/docs/authoring/cli.md +887 -0
  135. package/docs/authoring/components.md +15 -0
  136. package/docs/authoring/deck.md +612 -0
  137. package/docs/authoring/migrating.md +1195 -16
  138. package/docs/authoring/notation.md +49 -6
  139. package/docs/authoring/structure.md +80 -1
  140. package/docs/authoring/versioning.md +56 -3
  141. package/docs/authoring/visualizations.md +7 -2
  142. package/docs/course-agent/AGENTS.md +40 -0
  143. package/docs/course-agent/agents/rules-reviewer.md +33 -0
  144. package/docs/course-agent/skills/draft-lesson/SKILL.md +38 -0
  145. package/docs/course-agent/skills/migrate-course/SKILL.md +32 -0
  146. package/docs/course-agent/skills/release-content/SKILL.md +26 -0
  147. package/docs/diagram-scaling.md +148 -0
  148. package/docs/privacy.md +59 -0
  149. package/package.json +8 -2
  150. package/src/compiler/astro.ts +60 -21
  151. package/src/compiler/cli-main.ts +557 -0
  152. package/src/compiler/cli-reference.ts +285 -0
  153. package/src/compiler/cli-verbs.ts +270 -0
  154. package/src/compiler/cli-verify.ts +241 -0
  155. package/src/compiler/cli.ts +2119 -170
  156. package/src/compiler/collections.ts +284 -25
  157. package/src/compiler/content-release.ts +91 -0
  158. package/src/compiler/course-config.ts +267 -0
  159. package/src/compiler/decks.ts +455 -0
  160. package/src/compiler/exports/deck-fit.ts +127 -0
  161. package/src/compiler/exports/export-chapters.ts +105 -6
  162. package/src/compiler/exports/export-pages.ts +46 -2
  163. package/src/compiler/exports/latex/beamerthemeexplico.sty +124 -0
  164. package/src/compiler/exports/latex/cache.ts +183 -0
  165. package/src/compiler/exports/latex/capture.ts +5 -2
  166. package/src/compiler/exports/latex/compile.ts +18 -0
  167. package/src/compiler/exports/latex/deck.ts +419 -0
  168. package/src/compiler/exports/latex/document.ts +117 -21
  169. package/src/compiler/exports/latex/explico-common.sty +198 -0
  170. package/src/compiler/exports/latex/explico.cls +13 -183
  171. package/src/compiler/exports/latex/serialize.ts +25 -21
  172. package/src/compiler/exports/latex/texlive-packages.txt +6 -2
  173. package/src/compiler/exports/latex-export.ts +187 -45
  174. package/src/compiler/exports/markdown/serialize.ts +118 -9
  175. package/src/compiler/exports/markdown-export.ts +56 -11
  176. package/src/compiler/exports/standalone-html.ts +8 -7
  177. package/src/compiler/exports/static-tree.ts +175 -3
  178. package/src/compiler/knowledge-version.ts +56 -21
  179. package/src/compiler/lesson-derivation.ts +282 -16
  180. package/src/compiler/manifest.ts +568 -63
  181. package/src/compiler/page-versions.ts +401 -0
  182. package/src/compiler/resolution-report.ts +38 -7
  183. package/src/compiler/validate-content.ts +215 -0
  184. package/src/components/CourseContents.astro +124 -6
  185. package/src/components/CurriculumMap.astro +49 -1
  186. package/src/components/FloatIndex.astro +1 -1
  187. package/src/components/PartOverview.astro +51 -5
  188. package/src/components/assessments/AssessmentSet.astro +41 -15
  189. package/src/components/block-heading.ts +15 -6
  190. package/src/components/card-carry.ts +7 -4
  191. package/src/components/card-manager.ts +14 -2
  192. package/src/components/card-memory.ts +13 -9
  193. package/src/components/deck/DeckEnhancer.astro +13 -0
  194. package/src/components/deck/deck-context.ts +104 -0
  195. package/src/components/deck/deck-controller.ts +1287 -0
  196. package/src/components/deck/deck-map.ts +91 -0
  197. package/src/components/deck-lane.ts +163 -0
  198. package/src/components/diagram/Diagram.astro +131 -86
  199. package/src/components/disclosure/persisted-disclosure.ts +9 -1
  200. package/src/components/figure/Figure.astro +7 -2
  201. package/src/components/figure/FloatCaption.astro +5 -3
  202. package/src/components/fold/Fold.astro +2 -2
  203. package/src/components/notation/NotationFormula.astro +81 -11
  204. package/src/components/notation/NotationGlossary.astro +132 -1
  205. package/src/components/notation/NotationLayer.astro +15 -7
  206. package/src/components/starlight/AboutPanel.astro +186 -3
  207. package/src/components/starlight/CollapsibleSections.astro +24 -3
  208. package/src/components/starlight/DiagramEnhancer.astro +5 -1
  209. package/src/components/starlight/HeadingAnchorEnhancer.astro +1 -1
  210. package/src/components/starlight/LayoutHeader.astro +17 -0
  211. package/src/components/starlight/LayoutPageTitle.astro +110 -0
  212. package/src/components/starlight/LayoutSidebar.astro +807 -21
  213. package/src/components/starlight/LayoutSocialIcons.astro +62 -6
  214. package/src/components/starlight/LessonExportActions.astro +27 -9
  215. package/src/components/starlight/LessonFooter.astro +59 -0
  216. package/src/components/starlight/ReadingMemoryNotice.astro +114 -0
  217. package/src/components/starlight/TextSizeControl.astro +24 -13
  218. package/src/components/starlight/page-marks.ts +139 -0
  219. package/src/components/starlight/section-summary.ts +1 -1
  220. package/src/components/starlight/sidebar-editions.ts +245 -0
  221. package/src/components/table/Table.astro +15 -7
  222. package/src/content-config.ts +87 -1
  223. package/src/curriculum/competency-graph.ts +95 -0
  224. package/src/reference/base-library.mjs +19 -0
  225. package/src/reference/consistency.ts +137 -39
  226. package/src/reference/deck-remark.mjs +600 -0
  227. package/src/reference/deck-source.ts +273 -0
  228. package/src/reference/decks-validate.ts +604 -0
  229. package/src/reference/diagram-fit.ts +18 -4
  230. package/src/reference/diagram-layout.ts +3 -1
  231. package/src/reference/figure-symbols.ts +108 -31
  232. package/src/reference/folds-validate.ts +1 -1
  233. package/src/reference/gate-indices.ts +5 -3
  234. package/src/reference/gate-math.ts +169 -25
  235. package/src/reference/lab-katex-validate.ts +30 -15
  236. package/src/reference/lab-math-scope.ts +34 -3
  237. package/src/reference/math-glyphs.mjs +189 -25
  238. package/src/reference/page-notation.ts +69 -15
  239. package/src/reference/references.ts +28 -0
  240. package/src/reference/registry-scope.mjs +34 -0
  241. package/src/reference/registry.ts +41 -11
  242. package/src/reference/rehype-deck.mjs +286 -0
  243. package/src/reference/rehype-heading-anchors.mjs +48 -6
  244. package/src/reference/remark-notation.mjs +249 -40
  245. package/src/reference/source-lines.mjs +65 -0
  246. package/src/reference/types.ts +28 -0
  247. package/src/rules/catalog.ts +274 -4
  248. package/src/rules/course-rules.ts +21 -1
  249. package/src/rules/in-effect.ts +58 -11
  250. package/src/session/PreferenceStore.ts +23 -0
  251. package/src/session/deck-memory.ts +263 -0
  252. package/src/session/reading-memory.ts +243 -0
  253. package/src/styles/deck.css +1150 -0
  254. package/src/styles/global.css +958 -27
  255. package/src/styles/zones.css +277 -0
  256. /package/src/{components → reference}/float-name.ts +0 -0
@@ -54,14 +54,14 @@ function checkGlyphUniqueness(input, out) {
54
54
  glyphs.set(trimmed, keys);
55
55
  };
56
56
  for (const definition of input.registry.definitions) {
57
- if (definition.kind === "local") {
58
- record(definition.notation, definition.key, definition.lessonId);
57
+ if (definition.kind === "shared") {
58
+ record(definition.notation, definition.key, "");
59
59
  }
60
60
  }
61
61
  for (const bundle of input.registry.bundles) {
62
62
  for (const binding of bundle.bindings) {
63
63
  const definition = byId.get(binding.definitionId);
64
- if (definition) record(definition.notation, binding.key, bundle.lessonId);
64
+ if (definition?.kind === "shared") record(definition.notation, binding.key, bundle.lessonId);
65
65
  }
66
66
  }
67
67
  for (const [glyph, keys] of [...glyphs].sort(
@@ -69,12 +69,15 @@ function checkGlyphUniqueness(input, out) {
69
69
  )) {
70
70
  if (keys.size < 2) continue;
71
71
  if (input.lintIgnore.matches("glyph-unique-in-corpus", glyph)) continue;
72
- const detail = [...keys].sort(([a], [b]) => a.localeCompare(b)).map(([key, lessons]) => `${key} (${[...lessons].sort().join(", ")})`).join("; ");
72
+ const detail = [...keys].sort(([a], [b]) => a.localeCompare(b)).map(([key, lessons]) => {
73
+ const bound = [...lessons].filter((lesson) => lesson !== "").sort();
74
+ return `${key} (${bound.length > 0 ? bound.join(", ") : "no lesson binds it"})`;
75
+ }).join("; ");
73
76
  out.push({
74
77
  code: "glyph-unique-in-corpus",
75
78
  severity: "warning",
76
79
  glyph,
77
- message: `glyph ${JSON.stringify(glyph)} resolves to ${keys.size} meanings across the corpus: ${detail}`
80
+ message: `glyph ${JSON.stringify(glyph)} is ${keys.size} shared cards: ${detail}; course vocabulary gives a glyph one meaning \u2014 keep one card, or make the page-bound one a notation.local entry`
78
81
  });
79
82
  }
80
83
  }
@@ -144,34 +147,84 @@ function checkNotationSourceLocator(input, out) {
144
147
  }
145
148
  }
146
149
  }
147
- const GLOSS_PROMOTION_LIMIT = 3;
148
- function checkGlossWantsPromoting(input, out) {
149
- const owners = /* @__PURE__ */ new Map();
150
- const record = (ownerKey, gloss) => {
151
- const id = `${gloss.notation}\0${gloss.label.toLowerCase()}`;
152
- const current = owners.get(id) ?? { label: gloss.label, keys: /* @__PURE__ */ new Set() };
153
- current.keys.add(ownerKey);
154
- owners.set(id, current);
150
+ function checkDefinitionRepeated(input, out) {
151
+ const byKey = /* @__PURE__ */ new Map();
152
+ const chapters = input.notationInput.lessons.filter((lesson) => lesson.scopeLessonIds === void 0);
153
+ for (const lesson of [...chapters].sort((a, b) => a.lessonId.localeCompare(b.lessonId))) {
154
+ for (const definition of lesson.localDefinitions) {
155
+ const list = byKey.get(definition.key) ?? [];
156
+ if (!list.some((entry) => entry.lessonId === lesson.lessonId)) {
157
+ list.push({ lessonId: lesson.lessonId, file: lesson.source.file, definition });
158
+ }
159
+ byKey.set(definition.key, list);
160
+ }
161
+ }
162
+ const sharedByGlyph = /* @__PURE__ */ new Map();
163
+ for (const definition of input.notationInput.sharedDefinitions) {
164
+ if (!sharedByGlyph.has(definition.notation.trim())) sharedByGlyph.set(definition.notation.trim(), definition.key);
165
+ }
166
+ for (const [key, copies] of [...byKey].sort(([a], [b]) => a.localeCompare(b))) {
167
+ if (copies.length < 2) continue;
168
+ if (input.lintIgnore.matches("definition-repeated", key)) continue;
169
+ const first = copies[0];
170
+ const differing = ["notation", "label", "summary", "units", "sources"].filter(
171
+ (field) => copies.some((copy) => JSON.stringify(copy.definition[field] ?? null) !== JSON.stringify(first.definition[field] ?? null))
172
+ );
173
+ const lessons = copies.map((copy) => copy.lessonId).sort();
174
+ const owner = sharedByGlyph.get(first.definition.notation.trim());
175
+ const advice = owner !== void 0 && owner !== key ? ` \u2014 its glyph is already shared card ${owner}'s, so it is a reused letter (rule N4) and promoting it would put two shared cards on one glyph (glyph-unique-in-corpus): keep the copies local and acknowledge them in lint-ignore.yml ("definition-repeated:${key} \u2014 <why>"), or, if they are two meanings, give one another key` : ` \u2014 move one copy to content/notation/${key}.md and delete the others: every [[${key}]] and \\explain{${key}} keeps working; if they are two meanings, give one another key`;
176
+ out.push({
177
+ code: "definition-repeated",
178
+ severity: "warning",
179
+ key,
180
+ lessonId: first.lessonId,
181
+ file: first.file,
182
+ count: copies.length,
183
+ message: `local entry ${key} (${first.definition.notation}) is declared in ${copies.length} lessons (${lessons.join(", ")}); ` + (differing.length === 0 ? "the copies agree" : `the copies differ in ${differing.join(", ")}`) + advice
184
+ });
185
+ }
186
+ }
187
+ function checkMeaningRepeated(input, out) {
188
+ const normalize = (label) => label.toLowerCase().replace(/\s+/g, " ").trim();
189
+ const groups = /* @__PURE__ */ new Map();
190
+ const record = (notation, label, site) => {
191
+ const id = `${notation.trim()}\0${normalize(label)}`;
192
+ const group = groups.get(id) ?? { notation: notation.trim(), label, sites: [] };
193
+ if (!group.sites.some((known) => known.tier === site.tier && known.key === site.key && known.where === site.where)) {
194
+ group.sites.push(site);
195
+ }
196
+ groups.set(id, group);
155
197
  };
156
198
  for (const definition of input.notationInput.sharedDefinitions) {
157
- for (const gloss of definition.glosses) record(definition.key, gloss);
199
+ record(definition.notation, definition.label, { tier: "shared", key: definition.key, where: `card ${definition.key}` });
200
+ for (const gloss of definition.glosses) {
201
+ record(gloss.notation, gloss.label, { tier: "gloss", key: gloss.key, where: `gloss on ${definition.key}` });
202
+ }
158
203
  }
159
204
  for (const lesson of input.notationInput.lessons) {
205
+ if (lesson.scopeLessonIds !== void 0) continue;
160
206
  for (const definition of lesson.localDefinitions) {
161
- for (const gloss of definition.glosses) record(definition.key, gloss);
207
+ record(definition.notation, definition.label, {
208
+ tier: "local",
209
+ key: definition.key,
210
+ where: `local ${definition.key} on ${lesson.lessonId}`
211
+ });
212
+ for (const gloss of definition.glosses) {
213
+ record(gloss.notation, gloss.label, { tier: "gloss", key: gloss.key, where: `gloss on ${definition.key} (${lesson.lessonId})` });
214
+ }
162
215
  }
163
216
  }
164
- for (const [id, { label, keys }] of [...owners].sort(
165
- ([a], [b]) => a.localeCompare(b)
166
- )) {
167
- if (keys.size < GLOSS_PROMOTION_LIMIT) continue;
168
- const glyph = id.split("\0")[0] ?? "";
169
- if (input.lintIgnore.matches("gloss-wants-promoting", glyph)) continue;
217
+ for (const [, group] of [...groups].sort(([a], [b]) => a.localeCompare(b))) {
218
+ if (group.sites.length < 2) continue;
219
+ if (group.sites.every((site) => site.tier === "local" && site.key === group.sites[0].key)) continue;
220
+ if (input.lintIgnore.matches("meaning-repeated", group.notation)) continue;
221
+ const shared = group.sites.find((site) => site.tier === "shared");
170
222
  out.push({
171
- code: "gloss-wants-promoting",
223
+ code: "meaning-repeated",
172
224
  severity: "info",
173
- glyph,
174
- message: `gloss ${JSON.stringify(glyph)} (${label}) is declared on ${keys.size} entries (${[...keys].sort().join(", ")}); a meaning reused this widely wants promoting to a card`
225
+ glyph: group.notation,
226
+ count: group.sites.length,
227
+ message: `${group.notation} as ${JSON.stringify(group.label)} is defined ${group.sites.length} times: ${group.sites.map((site) => site.where).join("; ")}` + (shared ? ` \u2014 ${shared.key} is the shared card; bind it with [[${shared.key}]] (or \\explain{${shared.key}}{${group.notation}} in a formula) instead of declaring it again` : " \u2014 one shared card would serve every site; promote it and reference it")
175
228
  });
176
229
  }
177
230
  }
@@ -435,7 +488,8 @@ const CHECKS = [
435
488
  checkNotationUnits,
436
489
  checkWeakLocal,
437
490
  checkNotationSourceLocator,
438
- checkGlossWantsPromoting,
491
+ checkDefinitionRepeated,
492
+ checkMeaningRepeated,
439
493
  checkCardWantsDemoting,
440
494
  checkGlossNameShape,
441
495
  checkOperatorExplained,
@@ -457,7 +511,8 @@ function consistencyCounts(diagnostics) {
457
511
  "units-vocab": 0,
458
512
  "weak-local": 0,
459
513
  "notation-source-locator": 0,
460
- "gloss-wants-promoting": 0,
514
+ "definition-repeated": 0,
515
+ "meaning-repeated": 0,
461
516
  "card-wants-demoting": 0,
462
517
  "gloss-name-shape": 0,
463
518
  "operator-explained": 0,
@@ -473,5 +528,6 @@ function consistencyCounts(diagnostics) {
473
528
  }
474
529
  export {
475
530
  consistencyCounts,
531
+ glyphMatcher,
476
532
  runConsistencyChecks
477
533
  };
@@ -0,0 +1,123 @@
1
+ /**
2
+ * The deck a docs file is, or `undefined`. A lesson's: `{ scope: 'lesson',
3
+ * lessonSlug, lessonId, path, chapterPath }`, the chapter being the lesson's
4
+ * `.mdx` (or `.md`) beside it. A part's (`<part>/index.deck.mdx`): `{ scope:
5
+ * 'part', partDir, pageId, path }`, its page id `<part>.slides`.
6
+ */
7
+ export function deckOfFile(file: any): {
8
+ scope: string;
9
+ path: string;
10
+ partDir: string;
11
+ pageId: string;
12
+ } | {
13
+ chapterPath?: string | undefined;
14
+ scope: string;
15
+ path: string;
16
+ lessonSlug: string;
17
+ lessonId: string;
18
+ partDir?: undefined;
19
+ pageId?: undefined;
20
+ } | undefined;
21
+ /**
22
+ * The chapter file of a lesson of a part's deck's part (`motion/range` →
23
+ * `…/motion/range.mdx`, or `.md`), beside the deck, if there is one.
24
+ */
25
+ export function partChapterPath(deck: any, lessonSlug: any): string | undefined;
26
+ /**
27
+ * The chapter files whose scope a deck's symbols bind in, in order: a
28
+ * lesson's deck its chapter (none for a slides-first lesson); a part's deck
29
+ * every chapter of its part, in reading order (`manifest.parts[].lessons`).
30
+ */
31
+ export function deckScopeChapters(deck: any, manifest: any): any;
32
+ /** A chapter file's frontmatter and body, read once per change of the file. */
33
+ export function readChapter(chapterPath: any): any;
34
+ /**
35
+ * The manifest's deck for a deck file (`deckOfFile`) — a lesson's or a
36
+ * part's — or, given a lesson id, for that lesson, if there is one.
37
+ */
38
+ export function manifestDeckOf(manifest: any, owner: any): any;
39
+ /**
40
+ * Replace each `<Recall ref="eq-…" />` (or `fig-`, `tab-`, `dia-`) with the
41
+ * chapter's own float, parsed from the chapter with this page's parser.
42
+ * A recalled equation's math node and a recalled float's element carry
43
+ * `data.explicoRecall = { prefix, key, number, href }`; the imports a
44
+ * recalled float's components need are added to the deck's own.
45
+ */
46
+ /**
47
+ * What MDX's compile does to a tree before any course plugin sees it: a
48
+ * paragraph holding only JSX (and white space) becomes that JSX, as flow.
49
+ * An inline SVG's `<text x="…">0</text>` line parses as such a paragraph;
50
+ * kept, it would put a `<p>` inside the `<svg>`. `processor.parse` stops
51
+ * short of that step, so a chapter read for a recall takes it here
52
+ * (`remark-mark-and-unravel` in `@mdx-js/mdx`).
53
+ */
54
+ export function unravelJsxParagraphs(tree: any): any;
55
+ export function expandRecalls(tree: any, { processor, deck, deckEntry, manifest, base, fail }: {
56
+ processor: any;
57
+ deck: any;
58
+ deckEntry: any;
59
+ manifest: any;
60
+ base: any;
61
+ fail: any;
62
+ }): void;
63
+ /**
64
+ * The deck page's equations and floats, in its reading order, and what each
65
+ * shows: a recalled one the chapter's number, a labelled equation of the
66
+ * deck its own (1), (2) in label order (`manifest.decks[].equations`), and
67
+ * the deck's own floats no number.
68
+ */
69
+ export function collectDeckFloats(tree: any, deckEntry: any): {
70
+ equations: Map<any, any>;
71
+ floats: Map<any, any>;
72
+ };
73
+ /**
74
+ * Give the deck's `##` and `###` headings the anchors and frame numbers the
75
+ * manifest decided, in order; a different count fails the build (a stale
76
+ * manifest), as a chapter's headings do.
77
+ */
78
+ export function stampDeckHeadings(tree: any, deckEntry: any, fail: any): void;
79
+ /**
80
+ * On a part's deck, give each `<AssessmentSet>` the lesson whose checks it
81
+ * asks (`lesson`, the component's prop): the chapter its frame's section
82
+ * covers (`frames[].chapter`). A frame in no such section asks none, which
83
+ * the manifest reports as `deck-check-no-chapter`.
84
+ */
85
+ export function markDeckChecks(tree: any, deckEntry: any, fail: any): void;
86
+ /**
87
+ * The generated title frame: the deck's title, its course, its authors and
88
+ * the version its content is at (rules D10 and C5), in the words of a
89
+ * chapter's PDF (`versionPhrase` in compiler/page-versions.ts).
90
+ */
91
+ export function titleFrameNode(manifest: any, deckEntry: any): {
92
+ type: string;
93
+ data: {
94
+ hName: any;
95
+ hProperties: any;
96
+ };
97
+ children: any[];
98
+ };
99
+ /**
100
+ * The competencies a deck's outcomes frame lists: its lesson's, or on a
101
+ * part's deck every covered chapter's, in reading order, each once.
102
+ */
103
+ export function deckTeaches(manifest: any, deckEntry: any): any;
104
+ /** The generated outcomes frame: what the lesson's competencies say a student can now do. */
105
+ export function outcomesFrameNode(manifest: any, deckEntry: any, lesson: any): {
106
+ type: string;
107
+ data: {
108
+ hName: any;
109
+ hProperties: any;
110
+ };
111
+ children: any[];
112
+ } | undefined;
113
+ /**
114
+ * After notation ran: give each `###` frame its legend line — the symbols it
115
+ * shows for the first time in the deck (`first-use`), or all it shows
116
+ * (`every-frame`) — as math the page's KaTeX pass renders, each symbol bound
117
+ * to its card. `resolved` is the page's resolved notation (`key → entry`).
118
+ */
119
+ export function insertLegends(tree: any, { resolved, mode }: {
120
+ resolved: any;
121
+ mode: any;
122
+ }): void;
123
+ export const DECK_CAPTION_PATTERN: RegExp;