postext 1.59.1 → 1.60.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 (79) hide show
  1. package/dist/__tests__/exercises/digital.test.js +19 -1
  2. package/dist/__tests__/exercises/digital.test.js.map +1 -1
  3. package/dist/__tests__/exercises/followups.test.d.ts +2 -0
  4. package/dist/__tests__/exercises/followups.test.d.ts.map +1 -0
  5. package/dist/__tests__/exercises/followups.test.js +235 -0
  6. package/dist/__tests__/exercises/followups.test.js.map +1 -0
  7. package/dist/__tests__/exercises/layout.test.js +31 -0
  8. package/dist/__tests__/exercises/layout.test.js.map +1 -1
  9. package/dist/__tests__/pipeline/spanHeadingMidPage.test.js +76 -0
  10. package/dist/__tests__/pipeline/spanHeadingMidPage.test.js.map +1 -1
  11. package/dist/canvas-backend/annotations.d.ts +4 -1
  12. package/dist/canvas-backend/annotations.d.ts.map +1 -1
  13. package/dist/canvas-backend/annotations.js +5 -0
  14. package/dist/canvas-backend/annotations.js.map +1 -1
  15. package/dist/canvas-backend/chip.d.ts.map +1 -1
  16. package/dist/canvas-backend/chip.js +4 -0
  17. package/dist/canvas-backend/chip.js.map +1 -1
  18. package/dist/canvas-backend/swatch.js +1 -1
  19. package/dist/canvas-backend/swatch.js.map +1 -1
  20. package/dist/defaults/exercises.d.ts.map +1 -1
  21. package/dist/defaults/exercises.js +15 -9
  22. package/dist/defaults/exercises.js.map +1 -1
  23. package/dist/exercises/build.d.ts.map +1 -1
  24. package/dist/exercises/build.js +1 -0
  25. package/dist/exercises/build.js.map +1 -1
  26. package/dist/exercises/configWarnings.d.ts.map +1 -1
  27. package/dist/exercises/configWarnings.js +6 -2
  28. package/dist/exercises/configWarnings.js.map +1 -1
  29. package/dist/exercises/designs.d.ts +5 -0
  30. package/dist/exercises/designs.d.ts.map +1 -1
  31. package/dist/exercises/designs.js +45 -16
  32. package/dist/exercises/designs.js.map +1 -1
  33. package/dist/exercises/expand.d.ts +2 -0
  34. package/dist/exercises/expand.d.ts.map +1 -1
  35. package/dist/exercises/expand.js +63 -19
  36. package/dist/exercises/expand.js.map +1 -1
  37. package/dist/exercises/grids.d.ts.map +1 -1
  38. package/dist/exercises/grids.js +76 -16
  39. package/dist/exercises/grids.js.map +1 -1
  40. package/dist/exercises/model.d.ts +4 -1
  41. package/dist/exercises/model.d.ts.map +1 -1
  42. package/dist/exercises/model.js +56 -15
  43. package/dist/exercises/model.js.map +1 -1
  44. package/dist/exercises/record.d.ts +5 -1
  45. package/dist/exercises/record.d.ts.map +1 -1
  46. package/dist/exercises/runtime.d.ts.map +1 -1
  47. package/dist/exercises/runtime.js +61 -13
  48. package/dist/exercises/runtime.js.map +1 -1
  49. package/dist/exercises/styles.d.ts +8 -0
  50. package/dist/exercises/styles.d.ts.map +1 -1
  51. package/dist/exercises/styles.js +16 -2
  52. package/dist/exercises/styles.js.map +1 -1
  53. package/dist/html-backend.d.ts.map +1 -1
  54. package/dist/html-backend.js +35 -23
  55. package/dist/html-backend.js.map +1 -1
  56. package/dist/htmlAnnotations.d.ts +5 -1
  57. package/dist/htmlAnnotations.d.ts.map +1 -1
  58. package/dist/htmlAnnotations.js +6 -0
  59. package/dist/htmlAnnotations.js.map +1 -1
  60. package/dist/measure/cache.js +3 -3
  61. package/dist/measure/cache.js.map +1 -1
  62. package/dist/measure/inlineIcon.d.ts +5 -2
  63. package/dist/measure/inlineIcon.d.ts.map +1 -1
  64. package/dist/measure/inlineIcon.js +8 -4
  65. package/dist/measure/inlineIcon.js.map +1 -1
  66. package/dist/measure/rich.d.ts.map +1 -1
  67. package/dist/measure/rich.js +72 -4
  68. package/dist/measure/rich.js.map +1 -1
  69. package/dist/parse/types.d.ts +7 -0
  70. package/dist/parse/types.d.ts.map +1 -1
  71. package/dist/pipeline/build.d.ts.map +1 -1
  72. package/dist/pipeline/build.js +38 -7
  73. package/dist/pipeline/build.js.map +1 -1
  74. package/dist/types.d.ts +18 -1
  75. package/dist/types.d.ts.map +1 -1
  76. package/dist/vdt.d.ts +8 -0
  77. package/dist/vdt.d.ts.map +1 -1
  78. package/dist/vdt.js.map +1 -1
  79. package/package.json +1 -1
@@ -55,6 +55,24 @@ export function textElement(id, content, xPt, yPt, wPt, hPt, sizePt, extra = {})
55
55
  };
56
56
  }
57
57
  const r = (n) => String(Math.round(n * 100) / 100);
58
+ /** Where the groups of an area's squares stand (see {@link AreaSpec.cells}):
59
+ * each one's first cell, column and row of cells, a cell and the rows of
60
+ * a group apart. */
61
+ function cellGroups(cells, cols, lines) {
62
+ const at = [];
63
+ let c = 0;
64
+ let r = 0;
65
+ for (const n0 of cells) {
66
+ const n = Math.max(1, Math.min(cols, Math.floor(n0)));
67
+ if (c > 0 && c + n > cols) {
68
+ c = 0;
69
+ r += lines + 0.5;
70
+ }
71
+ at.push({ c, r, n });
72
+ c += n + 1;
73
+ }
74
+ return { at, rows: r + lines };
75
+ }
58
76
  /** The elements and height of a writing area. */
59
77
  export function areaElements(a) {
60
78
  const n = Math.max(1, Math.floor(a.lines));
@@ -74,21 +92,29 @@ export function areaElements(a) {
74
92
  case 'grid':
75
93
  case 'tianzige': {
76
94
  const cols = Math.max(1, Math.floor(w / sp));
77
- const gw = cols * sp;
95
+ // The groups of squares (`cells`), else one as wide as the measure.
96
+ const groups = a.cells && a.cells.length > 0 ? cellGroups(a.cells, cols, n) : { at: [{ c: 0, r: 0, n: cols }], rows: n };
97
+ h = groups.rows * sp;
98
+ const gw = Math.max(...groups.at.map((g) => (g.c + g.n) * sp));
78
99
  let d = '';
79
- for (let i = 0; i <= n; i++)
80
- d += `M0 ${r(i * sp)}H${r(gw)}`;
81
- for (let j = 0; j <= cols; j++)
82
- d += `M${r(j * sp)} 0V${r(h)}`;
83
- els.push(pathElement('area', d, gw, h, a.color, a.weightPt));
84
- if (a.kind === 'tianzige') {
85
- let x = '';
100
+ let x = '';
101
+ for (const g of groups.at) {
102
+ const x0 = g.c * sp;
103
+ const y0 = g.r * sp;
104
+ const x1 = (g.c + g.n) * sp;
105
+ const y1 = (g.r + n) * sp;
106
+ for (let i = 0; i <= n; i++)
107
+ d += `M${r(x0)} ${r(y0 + i * sp)}H${r(x1)}`;
108
+ for (let j = 0; j <= g.n; j++)
109
+ d += `M${r(x0 + j * sp)} ${r(y0)}V${r(y1)}`;
86
110
  for (let i = 0; i < n; i++)
87
- x += `M0 ${r((i + 0.5) * sp)}H${r(gw)}`;
88
- for (let j = 0; j < cols; j++)
89
- x += `M${r((j + 0.5) * sp)} 0V${r(h)}`;
90
- els.push(pathElement('cross', x, gw, h, a.color, a.weightPt * 0.6, { dash: [PT(a.weightPt * 3), PT(a.weightPt * 3)] }));
111
+ x += `M${r(x0)} ${r(y0 + (i + 0.5) * sp)}H${r(x1)}`;
112
+ for (let j = 0; j < g.n; j++)
113
+ x += `M${r(x0 + (j + 0.5) * sp)} ${r(y0)}V${r(y1)}`;
91
114
  }
115
+ els.push(pathElement('area', d, gw, h, a.color, a.weightPt));
116
+ if (a.kind === 'tianzige')
117
+ els.push(pathElement('cross', x, gw, h, a.color, a.weightPt * 0.6, { dash: [PT(a.weightPt * 3), PT(a.weightPt * 3)] }));
92
118
  break;
93
119
  }
94
120
  case 'seyes': {
@@ -117,13 +143,16 @@ export function areaElements(a) {
117
143
  }
118
144
  if (a.answers && a.answerColor && (a.kind === 'grid' || a.kind === 'tianzige')) {
119
145
  // On squares a model answer is written a character to a square, row
120
- // after row, as a pupil writes on 田字格 or squared paper.
146
+ // after row (group after group), as a pupil writes on 田字格 or
147
+ // squared paper.
121
148
  const cols = Math.max(1, Math.floor(w / sp));
122
- const chars = graphemesOf(a.answers.join(''));
123
- chars.slice(0, cols * n).forEach((ch, k) => {
149
+ const groups = a.cells && a.cells.length > 0 ? cellGroups(a.cells, cols, n).at : [{ c: 0, r: 0, n: cols }];
150
+ const squares = groups.flatMap((g) => Array.from({ length: g.n * n }, (_, k) => ({ x: (g.c + (k % g.n)) * sp, y: (g.r + Math.floor(k / g.n)) * sp })));
151
+ const chars = graphemesOf(a.answers.join('')).filter((ch) => !(a.cells && ch.trim() === ''));
152
+ chars.slice(0, squares.length).forEach((ch, k) => {
124
153
  if (ch.trim() === '')
125
154
  return;
126
- els.push(textElement(`answer${k}`, ch, (k % cols) * sp, Math.floor(k / cols) * sp, sp, sp, sp * 0.62, {
155
+ els.push(textElement(`answer${k}`, ch, squares[k].x, squares[k].y, sp, sp, sp * 0.62, {
127
156
  color: a.answerColor, overflow: 'clip', ...(a.answerFont ? { fontFamily: a.answerFont } : {}),
128
157
  }));
129
158
  });
@@ -1 +1 @@
1
- {"version":3,"file":"designs.js","sourceRoot":"","sources":["../../src/exercises/designs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"designs.js","sourceRoot":"","sources":["../../src/exercises/designs.ts"],"names":[],"mappings":"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"}
@@ -32,6 +32,8 @@ export interface ExpandContext {
32
32
  measurePt: number;
33
33
  /** A right-to-left document (its designs are mirrored). */
34
34
  rtl?: boolean;
35
+ /** A vertical page (縦組み): items are numbered ①, ②. */
36
+ vertical?: boolean;
35
37
  /** The text's font family: drawn letters (grids, matching) use it. */
36
38
  bodyFont?: string;
37
39
  /** Ids of the configured box styles (a style's `box` must name one). */
@@ -1 +1 @@
1
- {"version":3,"file":"expand.d.ts","sourceRoot":"","sources":["../../src/exercises/expand.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAuD,MAAM,mBAAmB,CAAC;AAE3G,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACzI,OAAO,KAAK,EAAE,gBAAgB,EAAkD,MAAM,0BAA0B,CAAC;AAIjH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAM/D,OAAO,KAAK,EAAoB,cAAc,EAAgB,MAAM,aAAa,CAAC;AAElF;;;yBAGyB;AACzB,eAAO,MAAM,uBAAuB,aAAgB,CAAC;AAErD,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B;+EAC2E;IAC3E,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;uDACmD;IACnD,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,eAAe,EAAE,oBAAoB,EAAE,CAAC;IACxC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAyCD;4CAC4C;AAC5C,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,aAAa,GAAG;IAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CA6BnL;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,GAAG,EAAE,aAAa,GAAG,iBAAiB,CAmGtG;AAi1BD,sDAAsD;AACtD,wBAAgB,KAAK,CAAC,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAShF"}
1
+ {"version":3,"file":"expand.d.ts","sourceRoot":"","sources":["../../src/exercises/expand.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAuD,MAAM,mBAAmB,CAAC;AAE3G,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACzI,OAAO,KAAK,EAAE,gBAAgB,EAAkD,MAAM,0BAA0B,CAAC;AAIjH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAM/D,OAAO,KAAK,EAAoB,cAAc,EAAgB,MAAM,aAAa,CAAC;AAElF;;;yBAGyB;AACzB,eAAO,MAAM,uBAAuB,aAAgB,CAAC;AAErD,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B;+EAC2E;IAC3E,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;uDACmD;IACnD,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,eAAe,EAAE,oBAAoB,EAAE,CAAC;IACxC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAyCD;4CAC4C;AAC5C,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,aAAa,GAAG;IAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CA6BnL;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,GAAG,EAAE,aAAa,GAAG,iBAAiB,CAmGtG;AAi4BD,sDAAsD;AACtD,wBAAgB,KAAK,CAAC,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAShF"}
@@ -11,7 +11,7 @@ import { pickExerciseStyle, solutionsOf } from '../defaults/exercises.js';
11
11
  import { counterStyleOf, formatCounter } from '../numbering.js';
12
12
  import { readExercises, containerEndOf } from './model.js';
13
13
  import { EMPTY_RUN, joinRuns, runOf, sliceRun, textRun, trimRun, blockOfRun } from './text.js';
14
- import { exerciseBoxStyles, exerciseChipStyles, exerciseParagraphStyles, exerciseStyleIds } from './styles.js';
14
+ import { exerciseBoxStyles, exerciseChipStyles, exerciseParagraphStyles, exerciseStyleIds, shapedNumberBand } from './styles.js';
15
15
  import { areaElements, drawnBox } from './designs.js';
16
16
  import { seededRandom, shuffledOrder } from './shuffle.js';
17
17
  import { gridBox } from './grids.js';
@@ -217,7 +217,7 @@ function bookSolutions(entries, style, book, heading, at, newId, ctx) {
217
217
  }
218
218
  const lines = [ex.key, ...(sol.layout === 'full' ? ex.solution ?? [] : [])].filter(Boolean);
219
219
  lines.forEach((line, k) => {
220
- const lead = k === 0 ? textRun(`${e.number}${style.number.suffix || '.'}`, at, { bold: true }) : EMPTY_RUN;
220
+ const lead = k === 0 ? textRun(`${e.number}${style.number.suffix || '.'}`, at, { bold: style.number.fontWeight >= 600 }) : EMPTY_RUN;
221
221
  out.push(blockOfRun('paragraph', joinRuns(lead, tabRun(at), textRun(line, at)), { sourceStart: at, sourceEnd: at }));
222
222
  });
223
223
  }
@@ -286,6 +286,17 @@ class Emitter {
286
286
  num(n) {
287
287
  return formatCounter(n, counterStyleOf('decimal', this.ctx.locale), this.ctx.locale, this.ctx.digits);
288
288
  }
289
+ /** An item's label: `1.`; on a vertical page a circled number (`①`),
290
+ * which stands upright in the column where a Latin full stop would not
291
+ * (#1244). */
292
+ item(n) {
293
+ return this.ctx.vertical ? formatCounter(n, 'circled-decimal', this.ctx.locale) : `${this.num(n)}.`;
294
+ }
295
+ /** Item and solution numbers are bold when the exercise number is (its
296
+ * `number.fontWeight`): a face with no bold cut sets both regular. */
297
+ get numberBold() {
298
+ return this.style.number.fontWeight >= 600;
299
+ }
289
300
  label(k) {
290
301
  return optionLabel(this.style, k, this.ctx.locale, this.ctx.digits);
291
302
  }
@@ -334,17 +345,25 @@ class Emitter {
334
345
  const box = this.style.box && this.ctx.boxIds.has(this.style.box) ? this.style.box : undefined;
335
346
  return Math.max(1, this.ctx.measurePt - (box ? this.ctx.boxInsets?.get(box) ?? 0 : 0));
336
347
  }
348
+ /** The band of the shaped number in ems of the instruction, whose size
349
+ * the number's em and the icons' sizes are read against. */
350
+ numberBand() {
351
+ const ins = this.style.instruction.fontSize;
352
+ const textPt = ins ? dimPt(ins, this.ctx.bodySizePt) : this.ctx.bodySizePt;
353
+ return shapedNumberBand(dimPt(this.style.number.fontSize, textPt) / Math.max(0.01, textPt));
354
+ }
337
355
  get dpiFree() {
338
356
  return { size: this.ctx.bodySizePt, line: this.ctx.lineHeightPt, measure: this.measure };
339
357
  }
340
358
  /** A writing area of `lines` lines, the answers written in a teacher's
341
359
  * edition. */
342
- area(lines, slot, answers, kind, widthPt, shown = false) {
360
+ area(lines, slot, answers, kind, widthPt, shown = false, cells) {
343
361
  const a = this.style.area;
344
362
  const k = kind ?? a.kind;
345
363
  const spacing = a.spacing ? dimPt(a.spacing, this.dpiFree.size) : this.dpiFree.line * (k === 'grid' || k === 'tianzige' ? 1.2 : 1.35);
346
364
  const { elements, heightPt } = areaElements({
347
365
  kind: k, lines, spacingPt: spacing, widthPt: widthPt ?? this.dpiFree.measure, color: a.color, weightPt: dimPt(a.weight, this.dpiFree.size),
366
+ ...(cells && cells.length > 0 ? { cells } : {}),
348
367
  ...((this.teacher || shown) && answers ? { answers, answerColor: this.style.answers.color, answerSizePt: this.dpiFree.size * 0.95, ...(this.style.answers.fontFamily ?? this.ctx.bodyFont ? { answerFont: this.style.answers.fontFamily ?? this.ctx.bodyFont } : {}) } : {}),
349
368
  });
350
369
  const id = `${this.ids.frame}-area-${this.ex.ordinal}-${slot}`;
@@ -427,7 +446,8 @@ class Emitter {
427
446
  const tight = /[\u3001\u3002\uFF0C\uFF0E\uFF1A]$/u.test(n.suffix);
428
447
  if (n.show && this.number) {
429
448
  const text = `${n.label ? `${n.label} ` : ''}${this.number}${n.suffix}`;
430
- lead.push(chipRun(this.ids.number, textRun(text, this.at), this.at));
449
+ // A number stands upright under an italic instruction (#1244).
450
+ lead.push(chipRun(this.ids.number, textRun(text, this.at), this.at, { upright: true }));
431
451
  }
432
452
  const level = ex.attrs.level !== undefined ? Math.max(0, Math.min(this.style.level.max, parseInt(ex.attrs.level, 10) || 0)) : 0;
433
453
  if (level > 0) {
@@ -435,15 +455,21 @@ class Emitter {
435
455
  lead.push(chipRun(this.ids.level, textRun(marks, this.at), this.at));
436
456
  }
437
457
  // Activity icons are inline symbols (#1058): a picture of the book or a
438
- // glyph in its own face, in its own colour, read as their `alt`.
458
+ // glyph in its own face, in its own colour, read as their `alt`. Beside
459
+ // a shaped number they share its band (#1248): as tall as the shape
460
+ // unless they give their own size, centred on it either way.
461
+ const band = n.show && this.number && n.shape !== 'none' ? this.numberBand() : undefined;
439
462
  for (const name of (ex.attrs.icon ?? '').split(/\s+/).filter(Boolean)) {
440
463
  const icon = this.style.icons[name];
441
464
  if (!icon || (!icon.resourceId && !icon.glyph))
442
465
  continue;
466
+ const size = icon.size !== undefined && icon.size > 0 ? icon.size : band?.height;
467
+ const drop = band ? band.drop - (band.height - (size ?? band.height)) / 2 : 0;
443
468
  const symbol = {
444
469
  alt: icon.alt ?? '',
445
470
  ...(icon.resourceId ? { resource: icon.resourceId } : { glyph: icon.glyph, ...(icon.fontFamily ? { font: icon.fontFamily } : {}) }),
446
- ...(icon.size !== undefined && icon.size > 0 ? { size: icon.size } : {}),
471
+ ...(size !== undefined ? { size: round3(size) } : {}),
472
+ ...(drop > 0 ? { drop: round3(drop) } : {}),
447
473
  };
448
474
  const color = icon.color?.paletteId ?? icon.color?.hex ?? '';
449
475
  lead.push(textRun(SWATCH_PLACEHOLDER, this.at, { swatch: { color, icon: symbol } }));
@@ -567,14 +593,14 @@ class Emitter {
567
593
  out.push(set);
568
594
  // An open question: lines under each item of the list.
569
595
  if (ex.kind === 'open' && b.type === 'listItem' && (b.depth ?? 1) <= 1) {
570
- out.push(...this.area(this.openLines(), `t${lists.indexOf(k) + 1}`, this.openAnswer(lists.indexOf(k)), this.openArea()));
596
+ out.push(...this.area(this.openLines(), `t${lists.indexOf(k) + 1}`, this.openAnswer(lists.indexOf(k)), this.openArea(), undefined, false, this.openCells()));
571
597
  }
572
598
  }
573
599
  flush();
574
600
  if (bankAt !== undefined && !bankPlaced)
575
601
  out.push(BANK_SLOT);
576
602
  if (ex.kind === 'open' && lists.length === 0)
577
- out.push(...this.area(this.openLines(), 't1', this.openAnswer(0), this.openArea()));
603
+ out.push(...this.area(this.openLines(), 't1', this.openAnswer(0), this.openArea(), undefined, false, this.openCells()));
578
604
  if (ex.kind === 'gaps' || ex.kind === 'choice' || ex.kind === 'mark')
579
605
  this.keyOfGaps();
580
606
  return out;
@@ -583,7 +609,16 @@ class Emitter {
583
609
  * style's. */
584
610
  openArea() {
585
611
  const k = this.ex.attrs.area?.trim();
586
- return k === 'lines' || k === 'dots' || k === 'grid' || k === 'seyes' || k === 'tianzige' || k === 'box' || k === 'none' ? k : undefined;
612
+ if (k === 'lines' || k === 'dots' || k === 'grid' || k === 'seyes' || k === 'tianzige' || k === 'box' || k === 'none')
613
+ return k;
614
+ // Cells asked of an area of lines: squares.
615
+ return this.openCells() && this.style.area.kind !== 'grid' && this.style.area.kind !== 'tianzige' ? 'grid' : undefined;
616
+ }
617
+ /** The squares an open question's area is sized to (`cells=4`), or set
618
+ * in groups side by side (`cells="2 2 3"`, a word's 田字格 each). */
619
+ openCells() {
620
+ const cells = (this.ex.attrs.cells ?? '').split(/[\s,]+/).map((n) => parseInt(n, 10)).filter((n) => Number.isFinite(n) && n > 0);
621
+ return cells.length > 0 ? cells : undefined;
587
622
  }
588
623
  openLines() {
589
624
  const n = parseInt(this.ex.attrs.lines ?? '', 10);
@@ -816,7 +851,7 @@ class Emitter {
816
851
  const stem = this.passThrough(this.blocks[q.stem], q.stem);
817
852
  const at = stem.sourceStart;
818
853
  const n = this.ex.questions.filter((x) => x.stem !== undefined).indexOf(q) + 1;
819
- blocks.push(...this.paragraphs(this.ids.item, [joinRuns(textRun(`${this.num(n)}.`, at, { bold: true }), tabRun(at), runOf(stem))]));
854
+ blocks.push(...this.paragraphs(this.ids.item, [joinRuns(textRun(this.item(n), at, { bold: this.numberBold }), tabRun(at), runOf(stem))]));
820
855
  }
821
856
  const optionStyle = q.stem !== undefined ? this.ids.optionUnder : this.ids.option;
822
857
  // `columns=3` on the fence, or a row layout: the options side by side.
@@ -841,21 +876,26 @@ class Emitter {
841
876
  const at = this.blocks[opt.block].sourceStart;
842
877
  const slot = `tf${k + 1}`;
843
878
  this.slots.push({ key: slot, kind: 'truefalse', correct: [opt.correct ? 1 : 2] });
844
- const parts = [textRun(`${this.num(k + 1)}.`, at), tabRun(at), this.optionText(opt.block), tabRun(at)];
879
+ const marks = [];
845
880
  if (this.style.trueFalse.look === 'bracket') {
846
- // One bracket at the line's end to write the answer in: full width
847
- // in Chinese and Japanese, `( )`.
881
+ // One bracket to write the answer in: full width in Chinese and
882
+ // Japanese, `( )`.
848
883
  const wide = this.book.language === 'zh' || this.book.language === 'ja';
849
884
  const answer = textRun(opt.correct ? t : f, at);
850
885
  const shown = this.answered(k === 0);
851
- parts.push(textRun(wide ? '\uFF08' : '(', at), chipRun(shown ? this.ids.answer : this.ids.icon, answer, at, {
886
+ marks.push(textRun(wide ? '\uFF08' : '(', at), chipRun(shown ? this.ids.answer : this.ids.icon, answer, at, {
852
887
  widthText: `${t.length > f.length ? t : f}\u2003`, ...(shown ? {} : { blank: true, blankLabel: this.book.words.blank }), ...this.hit(slot, k === 0),
853
888
  }), textRun(wide ? '\uFF09' : ')', at));
854
889
  }
855
890
  else {
856
- parts.push(textRun(`${t}\u00A0`, at), chipRun(this.answered(k === 0) && opt.correct ? this.ids.tickOn : this.ids.tick, textRun('\u00A0', at), at, this.hit(`${slot}t`, k === 0)));
857
- parts.push(textRun(`\u2003${f}\u00A0`, at), chipRun(this.answered(k === 0) && !opt.correct ? this.ids.tickOn : this.ids.tick, textRun('\u00A0', at), at, this.hit(`${slot}f`, k === 0)));
891
+ marks.push(textRun(`${t}\u00A0`, at), chipRun(this.answered(k === 0) && opt.correct ? this.ids.tickOn : this.ids.tick, textRun('\u00A0', at), at, this.hit(`${slot}t`, k === 0)));
892
+ marks.push(textRun(`\u2003${f}\u00A0`, at), chipRun(this.answered(k === 0) && !opt.correct ? this.ids.tickOn : this.ids.tick, textRun('\u00A0', at), at, this.hit(`${slot}f`, k === 0)));
858
893
  }
894
+ // Before the statement (`place: 'start'`, a Brazilian `( ) frase`),
895
+ // else flush with the line's end.
896
+ const parts = this.style.trueFalse.place === 'start'
897
+ ? [textRun(this.item(k + 1), at), tabRun(at), ...marks, textRun(SPACE, at), this.optionText(opt.block)]
898
+ : [textRun(this.item(k + 1), at), tabRun(at), this.optionText(opt.block), tabRun(at), ...marks];
859
899
  runs.push(joinRuns(...parts));
860
900
  this.key.push(textRun(`${this.num(k + 1)} ${opt.correct ? t : f}`, this.at));
861
901
  });
@@ -895,7 +935,7 @@ class Emitter {
895
935
  const p = lefts[i];
896
936
  if (p) {
897
937
  const pos = posOf.get(pairs.indexOf(p));
898
- parts.push(textRun(`${this.num(i + 1)}. `, this.at), this.gapsOf(p.left), textRun(' ', this.at));
938
+ parts.push(textRun(`${this.item(i + 1)} `, this.at), this.gapsOf(p.left), textRun(' ', this.at));
899
939
  parts.push(chipRun(this.answered(i === 0) ? this.ids.blankAnswer : this.ids.blank, textRun(this.bareLabel(pos) || this.num(pos + 1), this.at), this.at, {
900
940
  widthText: '\u2003\u2003', ...(this.answered(i === 0) ? {} : { blank: true, blankLabel: this.book.words.blank }), ...this.hit(`p${i + 1}`, i === 0),
901
941
  }));
@@ -928,7 +968,7 @@ class Emitter {
928
968
  const at = this.blocks[s.block].sourceStart;
929
969
  const order = shuffledOrder(s.pieces.length, seededRandom(this.book.seed, this.ex.ordinal, 'scramble', k));
930
970
  const words = order.flatMap((j, pos) => (pos > 0 ? [textRun(' / ', at), s.pieces[j]] : [s.pieces[j]]));
931
- out.push(...this.paragraphs(this.ids.item, [joinRuns(textRun(`${this.num(k + 1)}.`, at), tabRun(at), ...words)]));
971
+ out.push(...this.paragraphs(this.ids.item, [joinRuns(textRun(this.item(k + 1), at), tabRun(at), ...words)]));
932
972
  const sentence = s.pieces.map((p) => plain(p)).join(' ');
933
973
  out.push(...this.area(1, `sc${k + 1}`, [sentence], this.style.area.kind === 'none' ? 'lines' : this.style.area.kind, undefined, this.example && k === 0));
934
974
  this.key.push(textRun(`${this.num(k + 1)} ${sentence}`, at));
@@ -989,7 +1029,7 @@ class Emitter {
989
1029
  if (this.key.length === 0)
990
1030
  this.exerciseBlocks();
991
1031
  const sol = solutionsOf(this.style, this.book);
992
- const lead = listed && this.number ? [textRun(`${this.number}${this.style.number.suffix || '.'}`, this.at, { bold: true }), tabRun(this.at)] : [];
1032
+ const lead = listed && this.number ? [textRun(`${this.number}${this.style.number.suffix || '.'}`, this.at, { bold: this.numberBold }), tabRun(this.at)] : [];
993
1033
  const keyRun = this.key.length > 0 ? joinRuns(...this.key.flatMap((r, k) => (k > 0 ? [textRun(this.sep, this.at), r] : [r]))) : EMPTY_RUN;
994
1034
  const out = [];
995
1035
  const worked = [];
@@ -1075,6 +1115,10 @@ class Emitter {
1075
1115
  };
1076
1116
  }
1077
1117
  }
1118
+ /** `v` to three decimals: a stable cache key. */
1119
+ function round3(v) {
1120
+ return Math.round(v * 1000) / 1000;
1121
+ }
1078
1122
  /** A length in points, `em` read against `sizePt`. */
1079
1123
  export function dimPt(d, sizePt) {
1080
1124
  switch (d.unit) {