postext 1.58.2 → 1.59.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 (195) hide show
  1. package/dist/__tests__/exercises/config.test.d.ts +2 -0
  2. package/dist/__tests__/exercises/config.test.d.ts.map +1 -0
  3. package/dist/__tests__/exercises/config.test.js +63 -0
  4. package/dist/__tests__/exercises/config.test.js.map +1 -0
  5. package/dist/__tests__/exercises/digital.test.d.ts +2 -0
  6. package/dist/__tests__/exercises/digital.test.d.ts.map +1 -0
  7. package/dist/__tests__/exercises/digital.test.js +163 -0
  8. package/dist/__tests__/exercises/digital.test.js.map +1 -0
  9. package/dist/__tests__/exercises/languages.test.d.ts +2 -0
  10. package/dist/__tests__/exercises/languages.test.d.ts.map +1 -0
  11. package/dist/__tests__/exercises/languages.test.js +109 -0
  12. package/dist/__tests__/exercises/languages.test.js.map +1 -0
  13. package/dist/__tests__/exercises/layout.test.d.ts +2 -0
  14. package/dist/__tests__/exercises/layout.test.d.ts.map +1 -0
  15. package/dist/__tests__/exercises/layout.test.js +77 -0
  16. package/dist/__tests__/exercises/layout.test.js.map +1 -0
  17. package/dist/__tests__/exercises/model.test.d.ts +2 -0
  18. package/dist/__tests__/exercises/model.test.d.ts.map +1 -0
  19. package/dist/__tests__/exercises/model.test.js +90 -0
  20. package/dist/__tests__/exercises/model.test.js.map +1 -0
  21. package/dist/__tests__/exercises/parse.test.d.ts +2 -0
  22. package/dist/__tests__/exercises/parse.test.d.ts.map +1 -0
  23. package/dist/__tests__/exercises/parse.test.js +37 -0
  24. package/dist/__tests__/exercises/parse.test.js.map +1 -0
  25. package/dist/__tests__/exercises/refs.test.d.ts +2 -0
  26. package/dist/__tests__/exercises/refs.test.d.ts.map +1 -0
  27. package/dist/__tests__/exercises/refs.test.js +46 -0
  28. package/dist/__tests__/exercises/refs.test.js.map +1 -0
  29. package/dist/__tests__/exercises/solutions.test.d.ts +2 -0
  30. package/dist/__tests__/exercises/solutions.test.d.ts.map +1 -0
  31. package/dist/__tests__/exercises/solutions.test.js +53 -0
  32. package/dist/__tests__/exercises/solutions.test.js.map +1 -0
  33. package/dist/__tests__/exports.test.js +14 -0
  34. package/dist/__tests__/exports.test.js.map +1 -1
  35. package/dist/__tests__/parse/containers.test.js +2 -2
  36. package/dist/__tests__/parse/containers.test.js.map +1 -1
  37. package/dist/__tests__/pipeline/pageShorterThanLine.test.d.ts +2 -0
  38. package/dist/__tests__/pipeline/pageShorterThanLine.test.d.ts.map +1 -0
  39. package/dist/__tests__/pipeline/pageShorterThanLine.test.js +29 -0
  40. package/dist/__tests__/pipeline/pageShorterThanLine.test.js.map +1 -0
  41. package/dist/__tests__/pipeline/spanHeadingMidPage.test.js +11 -0
  42. package/dist/__tests__/pipeline/spanHeadingMidPage.test.js.map +1 -1
  43. package/dist/canvas-backend/blockRender.d.ts.map +1 -1
  44. package/dist/canvas-backend/blockRender.js +18 -0
  45. package/dist/canvas-backend/blockRender.js.map +1 -1
  46. package/dist/canvas-backend/chip.d.ts +3 -0
  47. package/dist/canvas-backend/chip.d.ts.map +1 -1
  48. package/dist/canvas-backend/chip.js +31 -1
  49. package/dist/canvas-backend/chip.js.map +1 -1
  50. package/dist/configWarnings.d.ts +3 -1
  51. package/dist/configWarnings.d.ts.map +1 -1
  52. package/dist/configWarnings.js +5 -1
  53. package/dist/configWarnings.js.map +1 -1
  54. package/dist/defaults/chipStyles.d.ts.map +1 -1
  55. package/dist/defaults/chipStyles.js +7 -0
  56. package/dist/defaults/chipStyles.js.map +1 -1
  57. package/dist/defaults/exercises.d.ts +111 -0
  58. package/dist/defaults/exercises.d.ts.map +1 -0
  59. package/dist/defaults/exercises.js +255 -0
  60. package/dist/defaults/exercises.js.map +1 -0
  61. package/dist/defaults/index.d.ts +2 -0
  62. package/dist/defaults/index.d.ts.map +1 -1
  63. package/dist/defaults/index.js +16 -0
  64. package/dist/defaults/index.js.map +1 -1
  65. package/dist/defaults/shared.d.ts +4 -0
  66. package/dist/defaults/shared.d.ts.map +1 -1
  67. package/dist/defaults/shared.js +6 -0
  68. package/dist/defaults/shared.js.map +1 -1
  69. package/dist/design/elementKeys.d.ts +2 -0
  70. package/dist/design/elementKeys.d.ts.map +1 -1
  71. package/dist/design/elementKeys.js +1 -1
  72. package/dist/design/elementKeys.js.map +1 -1
  73. package/dist/exercises/build.d.ts +60 -0
  74. package/dist/exercises/build.d.ts.map +1 -0
  75. package/dist/exercises/build.js +177 -0
  76. package/dist/exercises/build.js.map +1 -0
  77. package/dist/exercises/configWarnings.d.ts +11 -0
  78. package/dist/exercises/configWarnings.d.ts.map +1 -0
  79. package/dist/exercises/configWarnings.js +175 -0
  80. package/dist/exercises/configWarnings.js.map +1 -0
  81. package/dist/exercises/designs.d.ts +38 -0
  82. package/dist/exercises/designs.d.ts.map +1 -0
  83. package/dist/exercises/designs.js +143 -0
  84. package/dist/exercises/designs.js.map +1 -0
  85. package/dist/exercises/digital.d.ts +69 -0
  86. package/dist/exercises/digital.d.ts.map +1 -0
  87. package/dist/exercises/digital.js +58 -0
  88. package/dist/exercises/digital.js.map +1 -0
  89. package/dist/exercises/expand.d.ts +74 -0
  90. package/dist/exercises/expand.d.ts.map +1 -0
  91. package/dist/exercises/expand.js +1089 -0
  92. package/dist/exercises/expand.js.map +1 -0
  93. package/dist/exercises/grids.d.ts +62 -0
  94. package/dist/exercises/grids.d.ts.map +1 -0
  95. package/dist/exercises/grids.js +535 -0
  96. package/dist/exercises/grids.js.map +1 -0
  97. package/dist/exercises/model.d.ts +24 -0
  98. package/dist/exercises/model.d.ts.map +1 -0
  99. package/dist/exercises/model.js +360 -0
  100. package/dist/exercises/model.js.map +1 -0
  101. package/dist/exercises/record.d.ts +94 -0
  102. package/dist/exercises/record.d.ts.map +1 -0
  103. package/dist/exercises/record.js +9 -0
  104. package/dist/exercises/record.js.map +1 -0
  105. package/dist/exercises/runtime.d.ts +65 -0
  106. package/dist/exercises/runtime.d.ts.map +1 -0
  107. package/dist/exercises/runtime.js +1261 -0
  108. package/dist/exercises/runtime.js.map +1 -0
  109. package/dist/exercises/shuffle.d.ts +13 -0
  110. package/dist/exercises/shuffle.d.ts.map +1 -0
  111. package/dist/exercises/shuffle.js +56 -0
  112. package/dist/exercises/shuffle.js.map +1 -0
  113. package/dist/exercises/styles.d.ts +51 -0
  114. package/dist/exercises/styles.d.ts.map +1 -0
  115. package/dist/exercises/styles.js +221 -0
  116. package/dist/exercises/styles.js.map +1 -0
  117. package/dist/exercises/text.d.ts +31 -0
  118. package/dist/exercises/text.d.ts.map +1 -0
  119. package/dist/exercises/text.js +82 -0
  120. package/dist/exercises/text.js.map +1 -0
  121. package/dist/exercises/types.d.ts +125 -0
  122. package/dist/exercises/types.d.ts.map +1 -0
  123. package/dist/exercises/types.js +9 -0
  124. package/dist/exercises/types.js.map +1 -0
  125. package/dist/exercises/warnings.d.ts +16 -0
  126. package/dist/exercises/warnings.d.ts.map +1 -0
  127. package/dist/exercises/warnings.js +55 -0
  128. package/dist/exercises/warnings.js.map +1 -0
  129. package/dist/html-backend.d.ts +6 -0
  130. package/dist/html-backend.d.ts.map +1 -1
  131. package/dist/html-backend.js +67 -6
  132. package/dist/html-backend.js.map +1 -1
  133. package/dist/index.d.ts +6 -0
  134. package/dist/index.d.ts.map +1 -1
  135. package/dist/index.js +4 -0
  136. package/dist/index.js.map +1 -1
  137. package/dist/measure/cache.d.ts.map +1 -1
  138. package/dist/measure/cache.js +6 -1
  139. package/dist/measure/cache.js.map +1 -1
  140. package/dist/measure/rich.d.ts.map +1 -1
  141. package/dist/measure/rich.js +11 -1
  142. package/dist/measure/rich.js.map +1 -1
  143. package/dist/migrate/markdownRuns.js +1 -1
  144. package/dist/migrate/markdownRuns.js.map +1 -1
  145. package/dist/numbering.d.ts +3 -0
  146. package/dist/numbering.d.ts.map +1 -1
  147. package/dist/numbering.js +6 -0
  148. package/dist/numbering.js.map +1 -1
  149. package/dist/parse/blockParser.d.ts.map +1 -1
  150. package/dist/parse/blockParser.js +47 -4
  151. package/dist/parse/blockParser.js.map +1 -1
  152. package/dist/parse/exerciseGaps.d.ts +50 -0
  153. package/dist/parse/exerciseGaps.d.ts.map +1 -0
  154. package/dist/parse/exerciseGaps.js +151 -0
  155. package/dist/parse/exerciseGaps.js.map +1 -0
  156. package/dist/parse/index.d.ts +1 -1
  157. package/dist/parse/index.d.ts.map +1 -1
  158. package/dist/parse/index.js.map +1 -1
  159. package/dist/parse/sourceMapping.d.ts.map +1 -1
  160. package/dist/parse/sourceMapping.js +21 -0
  161. package/dist/parse/sourceMapping.js.map +1 -1
  162. package/dist/parse/types.d.ts +49 -1
  163. package/dist/parse/types.d.ts.map +1 -1
  164. package/dist/pipeline/build.d.ts.map +1 -1
  165. package/dist/pipeline/build.js +51 -9
  166. package/dist/pipeline/build.js.map +1 -1
  167. package/dist/pipeline/calloutLayout.d.ts.map +1 -1
  168. package/dist/pipeline/calloutLayout.js +1 -0
  169. package/dist/pipeline/calloutLayout.js.map +1 -1
  170. package/dist/pipeline/chips.d.ts.map +1 -1
  171. package/dist/pipeline/chips.js +2 -0
  172. package/dist/pipeline/chips.js.map +1 -1
  173. package/dist/pipeline/config.d.ts.map +1 -1
  174. package/dist/pipeline/config.js +6 -0
  175. package/dist/pipeline/config.js.map +1 -1
  176. package/dist/pipeline/contentWarnings.d.ts.map +1 -1
  177. package/dist/pipeline/contentWarnings.js +29 -1
  178. package/dist/pipeline/contentWarnings.js.map +1 -1
  179. package/dist/pipeline/continuation.d.ts.map +1 -1
  180. package/dist/pipeline/continuation.js +21 -6
  181. package/dist/pipeline/continuation.js.map +1 -1
  182. package/dist/pipeline/measureContentBlock.d.ts.map +1 -1
  183. package/dist/pipeline/measureContentBlock.js +3 -2
  184. package/dist/pipeline/measureContentBlock.js.map +1 -1
  185. package/dist/pipeline/outline.d.ts.map +1 -1
  186. package/dist/pipeline/outline.js +1 -0
  187. package/dist/pipeline/outline.js.map +1 -1
  188. package/dist/pipeline/textWrap.js +1 -1
  189. package/dist/pipeline/textWrap.js.map +1 -1
  190. package/dist/types.d.ts +303 -2
  191. package/dist/types.d.ts.map +1 -1
  192. package/dist/vdt.d.ts +67 -0
  193. package/dist/vdt.d.ts.map +1 -1
  194. package/dist/vdt.js.map +1 -1
  195. package/package.json +1 -1
@@ -0,0 +1,360 @@
1
+ /**
2
+ * Reading the exercises of a document (#1225): each `:::exercise` fence's
3
+ * blocks read into an {@link ExerciseModel} — its kind (written or told by
4
+ * its content), instruction, items, answers, solutions and hints. Pure: the
5
+ * blocks are not changed.
6
+ */
7
+ import { EXERCISE_KINDS } from './types.js';
8
+ import { runOf, sliceRun, splitRun, trimRun } from './text.js';
9
+ /** Whether the blocks hold an exercise. */
10
+ export function hasExercises(blocks) {
11
+ return blocks.some((b) => b.type === 'containerStart' && b.containerName === 'exercise');
12
+ }
13
+ /** The index of the marker closing the container opened at `start`. */
14
+ export function containerEndOf(blocks, start) {
15
+ const id = blocks[start].containerId;
16
+ for (let k = start + 1; k < blocks.length; k++) {
17
+ const b = blocks[k];
18
+ if (b.type === 'containerEnd' && b.containerId === id)
19
+ return k;
20
+ }
21
+ return blocks.length - 1;
22
+ }
23
+ /** The pair separator of a `match` item: ` -> `, `→`, `⟶`. */
24
+ export const PAIR_RE = /\s*(?:->|→|⟶)\s*/;
25
+ /** What separates the items of a `sort` category. */
26
+ const CATEGORY_ITEM_RE = /\s*[,;、,;،؛]\s*/;
27
+ /** The colon after a category or a crossword word. */
28
+ const COLON_RE = /\s*[::]\s*/;
29
+ /** The kinds a fence may name, with a few spellings authors reach for. */
30
+ const KIND_ALIASES = {
31
+ multiplechoice: 'choice', mcq: 'choice', quiz: 'choice', test: 'choice',
32
+ tf: 'truefalse', 'true-false': 'truefalse', truefalse: 'truefalse',
33
+ cloze: 'gaps', gap: 'gaps', blanks: 'gaps', fill: 'gaps',
34
+ matching: 'match', pairs: 'match', ordering: 'order', sequence: 'order',
35
+ sorting: 'sort', classify: 'sort', categories: 'sort',
36
+ free: 'open', essay: 'open', answer: 'open', 'word-search': 'wordsearch', 'crossword-puzzle': 'crossword',
37
+ operations: 'arithmetic', column: 'arithmetic', vertical: 'arithmetic',
38
+ };
39
+ export function exerciseKindOf(type) {
40
+ if (type === undefined)
41
+ return undefined;
42
+ const t = type.trim().toLowerCase();
43
+ if (EXERCISE_KINDS.includes(t))
44
+ return t;
45
+ return KIND_ALIASES[t];
46
+ }
47
+ const isListItem = (b) => b.type === 'listItem';
48
+ const isTask = (b) => b.type === 'listItem' && b.listKind === 'task';
49
+ /** The kind the content tells when the fence names none. */
50
+ function inferredKind(blocks, body, gaps) {
51
+ if (body.some((k) => isTask(blocks[k])))
52
+ return 'choice';
53
+ if (body.some((k) => isListItem(blocks[k]) && PAIR_RE.test(blocks[k].text)))
54
+ return 'match';
55
+ if (gaps > 0)
56
+ return 'gaps';
57
+ return 'open';
58
+ }
59
+ /** The digits of `n` in the script `like` is written in (Arabic-Indic and
60
+ * Persian digits kept). */
61
+ function digitsLike(n, like) {
62
+ if (/[٠-٩]/.test(like))
63
+ return n.replace(/[0-9]/g, (d) => String.fromCharCode(0x0660 + Number(d)));
64
+ if (/[۰-۹]/.test(like))
65
+ return n.replace(/[0-9]/g, (d) => String.fromCharCode(0x06f0 + Number(d)));
66
+ return n;
67
+ }
68
+ const ascii = (s) => s
69
+ .replace(/[٠-٩]/g, (d) => String(d.charCodeAt(0) - 0x0660))
70
+ .replace(/[۰-۹]/g, (d) => String(d.charCodeAt(0) - 0x06f0));
71
+ const OPERATION_RE = /^\s*(\d+)\s*([+\-−×xX*·⋅÷:/])\s*(\d+)\s*(?:=\s*)?$/u;
72
+ /** The sign an operation prints, from the one written: a German `216 · 4`
73
+ * keeps its dot, a `864 : 4` its colon; ASCII stand-ins become the signs. */
74
+ const PRINTED_SIGN = { '-': '−', x: '×', X: '×', '*': '×', '⋅': '·', '/': '÷' };
75
+ /** An operation item (`345 + 278`), its result worked out: whole numbers. */
76
+ export function readOperation(text, block) {
77
+ const m = OPERATION_RE.exec(ascii(text));
78
+ if (!m)
79
+ return undefined;
80
+ const [a, b] = [m[1], m[3]];
81
+ const sign = m[2];
82
+ const op = sign === '+' ? '+' : sign === '-' || sign === '−' ? '-' : sign === '÷' || sign === ':' || sign === '/' ? '÷' : '×';
83
+ const x = BigInt(a);
84
+ const y = BigInt(b);
85
+ let result;
86
+ let remainder;
87
+ if (op === '+')
88
+ result = x + y;
89
+ else if (op === '-')
90
+ result = x - y;
91
+ else if (op === '×')
92
+ result = x * y;
93
+ else {
94
+ if (y === 0n)
95
+ return undefined;
96
+ result = x / y;
97
+ remainder = x % y;
98
+ }
99
+ const raw = text.trim();
100
+ return {
101
+ block,
102
+ a: digitsLike(a, raw),
103
+ b: digitsLike(b, raw),
104
+ op,
105
+ sign: PRINTED_SIGN[sign] ?? sign,
106
+ result: digitsLike(result.toString(), raw),
107
+ ...(remainder !== undefined && remainder !== 0n ? { remainder: digitsLike(remainder.toString(), raw) } : {}),
108
+ };
109
+ }
110
+ /** Read every exercise of `blocks`, in order. A `:::solution` or `:::hint`
111
+ * outside an exercise, and an exercise inside another, are reported. */
112
+ export function readExercises(blocks) {
113
+ const exercises = [];
114
+ const issues = [];
115
+ for (let i = 0; i < blocks.length; i++) {
116
+ const b = blocks[i];
117
+ if (b.type !== 'containerStart')
118
+ continue;
119
+ if (b.containerName === 'solution' || b.containerName === 'hint') {
120
+ issues.push({ kind: 'solutionOutside', sourceStart: b.sourceStart, sourceEnd: b.sourceEnd });
121
+ continue;
122
+ }
123
+ if (b.containerName !== 'exercise')
124
+ continue;
125
+ const end = containerEndOf(blocks, i);
126
+ exercises.push(readExercise(blocks, i, end, exercises.length, issues));
127
+ i = end;
128
+ }
129
+ return { exercises, issues };
130
+ }
131
+ function readExercise(blocks, start, end, ordinal, issues) {
132
+ const open = blocks[start];
133
+ const attrs = open.containerAttrs ?? {};
134
+ const id = open.containerId;
135
+ const solutions = [];
136
+ const hints = [];
137
+ const banks = [];
138
+ const instruction = [];
139
+ const body = [];
140
+ let leading = true;
141
+ for (let k = start + 1; k < end; k++) {
142
+ const b = blocks[k];
143
+ if (b.type === 'containerStart' && (b.containerName === 'solution' || b.containerName === 'hint')) {
144
+ const close = containerEndOf(blocks, k);
145
+ (b.containerName === 'solution' ? solutions : hints).push({ start: k, end: close });
146
+ k = close;
147
+ continue;
148
+ }
149
+ if (b.type === 'containerStart' && b.containerName === 'exercise') {
150
+ issues.push({ kind: 'exerciseNested', exercise: id, sourceStart: b.sourceStart, sourceEnd: b.sourceEnd });
151
+ const close = containerEndOf(blocks, k);
152
+ for (let j = k + 1; j < close; j++)
153
+ body.push(j);
154
+ k = close;
155
+ leading = false;
156
+ continue;
157
+ }
158
+ if (b.type === 'directive' && b.directiveName === 'bank') {
159
+ banks.push(k);
160
+ leading = false;
161
+ continue;
162
+ }
163
+ const gapless = !b.spans.some((s) => s.chip?.gap);
164
+ if (leading && b.type === 'paragraph' && gapless) {
165
+ instruction.push(k);
166
+ continue;
167
+ }
168
+ leading = false;
169
+ body.push(k);
170
+ }
171
+ const gaps = [];
172
+ for (const k of body) {
173
+ blocks[k].spans.forEach((s, span) => {
174
+ if (s.chip?.gap)
175
+ gaps.push({ block: k, span, gap: s.chip.gap, n: gaps.length + 1 });
176
+ });
177
+ }
178
+ const written = exerciseKindOf(attrs.type);
179
+ if (attrs.type !== undefined && !written) {
180
+ issues.push({ kind: 'exerciseUnknownType', exercise: id, detail: attrs.type, sourceStart: open.sourceStart, sourceEnd: open.sourceEnd });
181
+ }
182
+ const kind = written ?? inferredKind(blocks, body, gaps.length);
183
+ const model = {
184
+ id, ordinal, kind, attrs, start, end, instruction, body, items: new Set(), solutions, hints, banks, gaps,
185
+ questions: [], pairs: [], sequence: [], sentences: [], categories: [], entries: [], operations: [],
186
+ sourceStart: open.sourceStart, sourceEnd: blocks[end].sourceEnd,
187
+ };
188
+ readItems(blocks, model, issues);
189
+ if (gradedWithoutAnswer(model)) {
190
+ issues.push({ kind: 'exerciseNoAnswer', exercise: id, sourceStart: open.sourceStart, sourceEnd: open.sourceEnd });
191
+ }
192
+ return model;
193
+ }
194
+ /** A graded exercise with nothing to grade: no right option, no gap, no
195
+ * pair… */
196
+ function gradedWithoutAnswer(m) {
197
+ switch (m.kind) {
198
+ case 'choice': return m.questions.length === 0 ? m.gaps.length === 0 : m.questions.some((q) => !q.options.some((o) => o.correct));
199
+ case 'truefalse': return m.questions.length === 0;
200
+ case 'gaps':
201
+ case 'mark': return m.gaps.length === 0;
202
+ case 'match': return !m.pairs.some((p) => p.left.text !== '');
203
+ case 'order': return m.sequence.length < 2;
204
+ case 'scramble': return m.sentences.length === 0;
205
+ case 'sort': return m.categories.length === 0;
206
+ case 'wordsearch':
207
+ case 'crossword': return m.entries.length === 0;
208
+ case 'arithmetic': return m.operations.length === 0;
209
+ case 'open': return false;
210
+ }
211
+ }
212
+ /** The text of a list item after its marker (the parser keeps only the
213
+ * item's own text). */
214
+ const itemRun = (b) => trimRun(runOf(b));
215
+ function readItems(blocks, m, issues) {
216
+ const select = m.attrs.select?.trim().toLowerCase();
217
+ const unread = (k) => {
218
+ const b = blocks[k];
219
+ issues.push({ kind: 'exerciseUnreadItem', exercise: m.id, detail: b.text, sourceStart: b.sourceStart, sourceEnd: b.sourceEnd });
220
+ };
221
+ switch (m.kind) {
222
+ case 'choice': {
223
+ let current;
224
+ let currentDepth = -1;
225
+ for (let j = 0; j < m.body.length; j++) {
226
+ const k = m.body[j];
227
+ const b = blocks[k];
228
+ if (isTask(b)) {
229
+ const depth = b.depth ?? 0;
230
+ if (!current || depth !== currentDepth) {
231
+ // A list item right before at the depth above is the stem.
232
+ const prev = j > 0 ? blocks[m.body[j - 1]] : undefined;
233
+ const stem = prev && isListItem(prev) && !isTask(prev) && (prev.depth ?? 0) === depth - 1 ? m.body[j - 1] : undefined;
234
+ current = { ...(stem !== undefined ? { stem } : {}), options: [], multiple: false };
235
+ currentDepth = depth;
236
+ m.questions.push(current);
237
+ }
238
+ current.options.push({ block: k, correct: b.checked === true });
239
+ m.items.add(k);
240
+ continue;
241
+ }
242
+ if (isListItem(b) && (b.depth ?? 0) < currentDepth) {
243
+ current = undefined;
244
+ currentDepth = -1;
245
+ }
246
+ else if (!isListItem(b)) {
247
+ current = undefined;
248
+ currentDepth = -1;
249
+ }
250
+ }
251
+ for (const q of m.questions) {
252
+ if (q.stem !== undefined)
253
+ m.items.add(q.stem);
254
+ const right = q.options.filter((o) => o.correct).length;
255
+ q.multiple = select === 'many' || select === 'multiple' || (select !== 'one' && select !== 'single' && right > 1);
256
+ }
257
+ return;
258
+ }
259
+ case 'truefalse':
260
+ for (const k of m.body) {
261
+ const b = blocks[k];
262
+ if (!isTask(b))
263
+ continue;
264
+ m.questions.push({ options: [{ block: k, correct: b.checked === true }], multiple: false });
265
+ m.items.add(k);
266
+ }
267
+ return;
268
+ case 'match':
269
+ for (const k of m.body) {
270
+ const b = blocks[k];
271
+ if (!isListItem(b))
272
+ continue;
273
+ const run = itemRun(b);
274
+ const at = PAIR_RE.exec(run.text);
275
+ if (!at) {
276
+ unread(k);
277
+ continue;
278
+ }
279
+ m.pairs.push({ block: k, left: trimRun(sliceRun(run, 0, at.index)), right: trimRun(sliceRun(run, at.index + at[0].length)) });
280
+ m.items.add(k);
281
+ }
282
+ return;
283
+ case 'order': {
284
+ // The items of the list's top level (depth 1).
285
+ const top = Math.min(...m.body.filter((k) => isListItem(blocks[k])).map((k) => blocks[k].depth ?? 1));
286
+ const lists = m.body.filter((k) => isListItem(blocks[k]) && (blocks[k].depth ?? 1) === top);
287
+ m.sequence.push(...lists);
288
+ lists.forEach((k) => m.items.add(k));
289
+ return;
290
+ }
291
+ case 'scramble':
292
+ for (const k of m.body) {
293
+ const b = blocks[k];
294
+ if (!isListItem(b))
295
+ continue;
296
+ const run = itemRun(b);
297
+ const pieces = /\s\/\s|\//.test(run.text) ? splitRun(run, /\s*\/\s*/) : splitRun(run, /\s+/);
298
+ m.sentences.push({ block: k, pieces: pieces.filter((p) => p.text !== '') });
299
+ m.items.add(k);
300
+ }
301
+ return;
302
+ case 'sort':
303
+ for (const k of m.body) {
304
+ const b = blocks[k];
305
+ if (!isListItem(b))
306
+ continue;
307
+ const run = itemRun(b);
308
+ const at = COLON_RE.exec(run.text);
309
+ if (!at) {
310
+ unread(k);
311
+ continue;
312
+ }
313
+ const cat = {
314
+ block: k,
315
+ name: trimRun(sliceRun(run, 0, at.index)),
316
+ items: splitRun(sliceRun(run, at.index + at[0].length), CATEGORY_ITEM_RE).filter((r) => r.text !== ''),
317
+ };
318
+ m.categories.push(cat);
319
+ m.items.add(k);
320
+ }
321
+ return;
322
+ case 'wordsearch':
323
+ case 'crossword':
324
+ for (const k of m.body) {
325
+ const b = blocks[k];
326
+ if (!isListItem(b))
327
+ continue;
328
+ const run = itemRun(b);
329
+ const at = COLON_RE.exec(run.text);
330
+ const word = (at ? run.text.slice(0, at.index) : run.text).replace(/[\s\-‐]+/gu, '');
331
+ if (!word) {
332
+ unread(k);
333
+ continue;
334
+ }
335
+ const entry = { block: k, word, ...(at ? { clue: trimRun(sliceRun(run, at.index + at[0].length)) } : {}) };
336
+ m.entries.push(entry);
337
+ m.items.add(k);
338
+ }
339
+ return;
340
+ case 'arithmetic':
341
+ for (const k of m.body) {
342
+ const b = blocks[k];
343
+ if (!isListItem(b))
344
+ continue;
345
+ const op = readOperation(b.text, k);
346
+ if (!op) {
347
+ unread(k);
348
+ continue;
349
+ }
350
+ m.operations.push(op);
351
+ m.items.add(k);
352
+ }
353
+ return;
354
+ case 'gaps':
355
+ case 'mark':
356
+ case 'open':
357
+ return;
358
+ }
359
+ }
360
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/exercises/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * What an exercise leaves for the digital outputs (#1230): its slots — the
3
+ * places it is answered on the page — and what each accepts, its key, its
4
+ * worked solution and hints as text. The layout carries one record per
5
+ * exercise laid out (`VDTDocument.exercises`); the HTML and EPUB outputs
6
+ * write them into the page for the exercise script.
7
+ */
8
+ import type { ExerciseKind } from './types.js';
9
+ /** How a slot is answered. */
10
+ export type ExerciseSlotKind =
11
+ /** Typed into a blank; `accept` lists the right answers. */
12
+ 'gap'
13
+ /** One option (or several, `multiple`) of `options` ticked; `correct`
14
+ * are the right ones, 1-based in printed order. Its options are the
15
+ * slots `<key>o<n>`. */
16
+ | 'choice'
17
+ /** A statement: `correct` is `[1]` when true, `[2]` when false; its
18
+ * boxes the slots `<key>t` and `<key>f` (or itself, typed, in the
19
+ * bracket look). */
20
+ | 'truefalse'
21
+ /** A word to mark; `correct` `[1]` (a word of the text not to mark has
22
+ * no slot). */
23
+ | 'mark'
24
+ /** A left item of a match: `correct` is the 1-based printed position of
25
+ * its partner in the right column; in the letters look, `accept` its
26
+ * printed label. */
27
+ | 'pair'
28
+ /** An item to number (order): `accept` is its rank. */
29
+ | 'rank'
30
+ /** A word of a sort exercise's bank: `accept` is its category. */
31
+ | 'category'
32
+ /** Text written on an area (open, scramble, sort): `accept` the model
33
+ * answers, which an open question only shows. */
34
+ | 'text'
35
+ /** A cell of a grid (crossword, operation): `accept` its character. */
36
+ | 'cell'
37
+ /** A word to find in a word search: `accept` its cells, `r,c` each. */
38
+ | 'word';
39
+ export interface ExerciseSlot {
40
+ key: string;
41
+ kind: ExerciseSlotKind;
42
+ accept?: string[];
43
+ correct?: number[];
44
+ options?: number;
45
+ multiple?: boolean;
46
+ /** The container id of the drawn box the slot stands on (an area, a
47
+ * grid): the digital outputs find its frame by it. */
48
+ box?: number;
49
+ /** A cell's place in its grid: row and column from 0. */
50
+ cell?: [number, number];
51
+ /** A writing area's line spacing, points. */
52
+ linePt?: number;
53
+ }
54
+ /** A grid's geometry, for the digital outputs to place its cells. */
55
+ export interface ExerciseGridInfo {
56
+ box: number;
57
+ kind: 'match' | 'wordsearch' | 'crossword' | 'arithmetic';
58
+ rows: number;
59
+ cols: number;
60
+ /** A cell's side over the box's width (the grid starts at the box's top
61
+ * left, in the flow's direction). */
62
+ cellPt: number;
63
+ /** The grid's left and top inside its box, points. */
64
+ xPt: number;
65
+ yPt: number;
66
+ /** Match: the middle of each row, points from the box's top, and the
67
+ * left and right dots' x. */
68
+ rowsPt?: number[];
69
+ dotsPt?: [number, number];
70
+ }
71
+ export interface ExerciseRecord {
72
+ /** The fence's container id (the box's `containerId` in the layout). */
73
+ id: number;
74
+ ordinal: number;
75
+ number: string;
76
+ kind: ExerciseKind;
77
+ style: string;
78
+ slots: ExerciseSlot[];
79
+ /** The key as one line of text. */
80
+ key: string;
81
+ /** The worked solution's paragraphs, as text. */
82
+ solution?: string[];
83
+ hints?: string[];
84
+ /** The fence's `{#id}`. */
85
+ anchor?: string;
86
+ /** What a reference to it prints ("Exercise 3"). */
87
+ anchorText?: string;
88
+ /** The fence's `title`. */
89
+ title?: string;
90
+ /** A mark exercise's `mark` (`circle`, `underline`…). */
91
+ mark?: string;
92
+ grids?: ExerciseGridInfo[];
93
+ }
94
+ //# sourceMappingURL=record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../src/exercises/record.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,8BAA8B;AAC9B,MAAM,MAAM,gBAAgB;AAC1B,4DAA4D;AAC1D,KAAK;AACP;;yBAEyB;GACvB,QAAQ;AACV;;qBAEqB;GACnB,WAAW;AACb;gBACgB;GACd,MAAM;AACR;;qBAEqB;GACnB,MAAM;AACR,uDAAuD;GACrD,MAAM;AACR,kEAAkE;GAChE,UAAU;AACZ;kDACkD;GAChD,MAAM;AACR,uEAAuE;GACrE,MAAM;AACR,uEAAuE;GACrE,MAAM,CAAC;AAEX,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;2DACuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qEAAqE;AACrE,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,CAAC;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb;0CACsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ;kCAC8B;IAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,mCAAmC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC5B"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * What an exercise leaves for the digital outputs (#1230): its slots — the
3
+ * places it is answered on the page — and what each accepts, its key, its
4
+ * worked solution and hints as text. The layout carries one record per
5
+ * exercise laid out (`VDTDocument.exercises`); the HTML and EPUB outputs
6
+ * write them into the page for the exercise script.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../../src/exercises/record.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The exercise script (#1230, #1231): makes the exercises of an HTML or EPUB
3
+ * output answerable, checks the answers and keeps them.
4
+ *
5
+ * The HTML output marks where an exercise is answered — its slots
6
+ * (`.pt-ex-slot[data-pt-ex][data-pt-slot]`, the chips of blanks, options,
7
+ * words) and its boxes (`.pt-ex-box[data-pt-box]`, the outer frame, the
8
+ * writing areas and grids) — and writes the records once, in
9
+ * `<script type="application/json" class="pt-exercises">`. The script lays
10
+ * its controls over those places: an input in a blank or a grid cell, a
11
+ * toggle on an option, lines between the dots of a match, a capsule in a
12
+ * word search, a text area on a writing area, a chooser on a word to sort;
13
+ * and a bar per exercise with Check, Show solution and Try again, a score
14
+ * read out to assistive technology (`aria-live`) and right or wrong marks
15
+ * that do not rest on colour alone (✓ and ✗).
16
+ *
17
+ * The whole runtime is one function with nothing from outside it, so the
18
+ * same code runs from the package (`attachExercises`) and as a standalone
19
+ * script (`EXERCISE_SCRIPT`, its source text). It keeps to syntax every
20
+ * reading system and transpiler leaves as it is: no spread, no `for…of`,
21
+ * no `async`.
22
+ */
23
+ import type { ExerciseData } from './digital.js';
24
+ import type { ExerciseRecord, ExerciseSlot } from './record.js';
25
+ export interface AttachExercisesOptions {
26
+ /** What the answers are kept under (with each exercise's anchor or id):
27
+ * a book and chapter, say. Default: the page's path. */
28
+ storageKey?: string;
29
+ /** Keep the answers in `localStorage`. Default: the document's
30
+ * `exercises.digital.persist`. */
31
+ persist?: boolean;
32
+ /** `'button'`: checked on demand; `'instant'`: as answered. Default: the
33
+ * document's `exercises.digital.check`. */
34
+ check?: 'button' | 'instant';
35
+ /** The exercise data, for a host that patches the pages and so holds
36
+ * it itself (`HtmlRenderIndex.exercises`); otherwise read from the
37
+ * `script.pt-exercises` elements under the root. */
38
+ data?: ExerciseData;
39
+ }
40
+ /** What a reader answered in a slot: text typed, the options ticked
41
+ * (1-based), a true/false (1 or 2), a mark, a right item of a match, the
42
+ * ends of the words found in a word search (`r,c-r,c`). */
43
+ export type ExerciseValue = string | number | number[] | boolean | string[] | null | undefined;
44
+ /** An answer as the exercise script compares it (see `attachExercises`). */
45
+ export declare const normalizeAnswer: (text: string) => string;
46
+ /** Whether a slot counts in an exercise's score. */
47
+ export declare const isGradedSlot: (slot: ExerciseSlot, record: Pick<ExerciseRecord, 'kind'>) => boolean;
48
+ /** Whether `value` answers `slot` rightly (`true`), wrongly (`false`), or
49
+ * is no answer or not graded (`null`). `trueFalse` are the style's true
50
+ * and false labels, for a typed true/false. */
51
+ export declare const checkExerciseSlot: (slot: ExerciseSlot, value: ExerciseValue, record: Pick<ExerciseRecord, 'kind'>, trueFalse?: [string, string]) => boolean | null;
52
+ /** What a slot shows when the solution is shown. */
53
+ export declare const exerciseSolutionValue: (slot: ExerciseSlot, record: Pick<ExerciseRecord, 'kind'>, trueFalse?: [string, string]) => ExerciseValue;
54
+ /** Makes the exercises of the HTML output under `root` answerable (see the
55
+ * module comment). Call it once the markup is in place, again after the
56
+ * markup changes (calling the previous call's return value first).
57
+ * Returns a function that takes every control off and puts the page's
58
+ * markup back as it was. */
59
+ export declare function attachExercises(root: Element | ShadowRoot | Document, options?: AttachExercisesOptions): () => void;
60
+ /** The exercise script as a standalone script, for an output with no host
61
+ * page to call `attachExercises`: the HTML file of the command line, an
62
+ * EPUB content document. It attaches to the document once it is parsed;
63
+ * the answers are kept under the page's path. */
64
+ export declare const EXERCISE_SCRIPT: string;
65
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/exercises/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC;6DACyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;uCACmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;gDAC4C;IAC5C,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC7B;;yDAEqD;IACrD,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED;;4DAE4D;AAC5D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;AA4+B/F,4EAA4E;AAC5E,eAAO,MAAM,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAgC,CAAC;AAEjF,oDAAoD;AACpD,eAAO,MAAM,YAAY,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,KAAK,OAA0B,CAAC;AAEpH;;gDAEgD;AAChD,eAAO,MAAM,iBAAiB,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,GAAG,IAAwB,CAAC;AAErL,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,aAAqC,CAAC;AAEtK;;;;6BAI6B;AAC7B,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM,IAAI,CAEnH;AAED;;;kDAGkD;AAClD,eAAO,MAAM,eAAe,QAM3B,CAAC"}