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
package/dist/types.d.ts CHANGED
@@ -752,11 +752,19 @@ export interface OutlineIndexMark {
752
752
  * unknown) or from a laid-out document (page labels known); consumed by
753
753
  * `:::toc` and `:::index`. */
754
754
  export interface OutlineEntry {
755
+ /** `kind: 'exercise'` (#1229): an exercise's key and worked solution, and
756
+ * the title of the chapter it is in, for `:::solutions{scope="book"}`;
757
+ * `number` is the exercise's. */
758
+ exercise?: {
759
+ key: string;
760
+ solution?: string[];
761
+ chapter: string;
762
+ };
755
763
  /** `'indexMark'`: an index mark (`:index…`), listed by `:::index`, never
756
764
  * by `:::toc` (`listed` is false). `'anchor'`: an anchor set in the text
757
765
  * (`:anchor{#id}`, `[text]{#id}`, `:::callout{#id}`), a target of
758
766
  * cross-references only (#261). */
759
- kind: 'heading' | 'part' | 'indexMark' | 'anchor';
767
+ kind: 'heading' | 'part' | 'indexMark' | 'anchor' | 'exercise';
760
768
  /** Heading level (1–6); `0` for a part. */
761
769
  level: number;
762
770
  /** Title as plain text (forced title breaks flattened to spaces). */
@@ -3995,6 +4003,281 @@ export interface ResolvedCalloutStyleConfig {
3995
4003
  /** See {@link CalloutStyleConfig.design}; absent without one. */
3996
4004
  design?: ResolvedCalloutDesignConfig;
3997
4005
  }
4006
+ /** The shape an exercise number is set in: bare, in a disc, in a square or
4007
+ * in a square with round corners. */
4008
+ export type ExerciseNumberShape = 'none' | 'disc' | 'square' | 'rounded';
4009
+ /** How an exercise's number prints (`exerciseStyles[].number`). */
4010
+ export interface ExerciseNumberStyle {
4011
+ /** Print the number. Default `true`. */
4012
+ show?: boolean;
4013
+ /** A word before the number ("Exercise 3"): `true` takes the document
4014
+ * language's word, a string is the word itself. Default `false`. */
4015
+ label?: boolean | string;
4016
+ /** Default `'none'`. */
4017
+ shape?: ExerciseNumberShape;
4018
+ /** The number's colour. Default white on a shape, else the main colour. */
4019
+ color?: ColorValue;
4020
+ /** The shape's fill. Default the main colour. */
4021
+ background?: ColorValue;
4022
+ fontFamily?: string;
4023
+ /** Size of the number, `em` being the instruction's. Default `1em`. */
4024
+ fontSize?: Dimension;
4025
+ /** Default `700`. */
4026
+ fontWeight?: number;
4027
+ /** Printed after a bare number (and its label). Default `'.'`; a shaped
4028
+ * number takes none. */
4029
+ suffix?: string;
4030
+ /** What the number reads, `{n}` the exercise's own count, `{h1}`/`{h2}`
4031
+ * the chapter's and section's numbers (as resource templates read them).
4032
+ * Default `'{n}'`. */
4033
+ template?: string;
4034
+ /** Where the count starts again. Default `'h1'`: each chapter. */
4035
+ resetOn?: ResourceCounterReset;
4036
+ /** The counter the style advances; styles naming one counter share it.
4037
+ * Default `'exercise'`. */
4038
+ counter?: string;
4039
+ /** Numerals of `{n}`. Default `'decimal'`. */
4040
+ format?: ResourceCounterFormat;
4041
+ }
4042
+ /** The instruction's typography (`exerciseStyles[].instruction`): the
4043
+ * exercise's leading paragraphs. Unset fields take the text's. */
4044
+ export interface ExerciseInstructionStyle {
4045
+ /** Default `true`. */
4046
+ bold?: boolean;
4047
+ italic?: boolean;
4048
+ color?: ColorValue;
4049
+ fontFamily?: string;
4050
+ fontSize?: Dimension;
4051
+ }
4052
+ /** The labels a question's options are counted with. */
4053
+ export type ExerciseOptionLabels = ResourceCounterFormat | 'none';
4054
+ /** How the options of a choice exercise print (`exerciseStyles[].options`). */
4055
+ export interface ExerciseOptionsStyle {
4056
+ /** Default by language: `'alpha-lower'`, `'alpha-upper'` in Chinese,
4057
+ * `'katakana'` in Japanese, `'abjad'` in Arabic. */
4058
+ labels?: ExerciseOptionLabels;
4059
+ /** Before the label. Default `''`. */
4060
+ prefix?: string;
4061
+ /** After the label. Default `')'` (`'.'` in Chinese, none in Japanese). */
4062
+ suffix?: string;
4063
+ /** A box or a ring to tick before each option. Default `'none'`. */
4064
+ marker?: 'none' | 'box' | 'circle';
4065
+ /** `'stack'`: one option a line, its turnover lines hung under its text;
4066
+ * `'row'`: the options side by side, `columns` to a line. Default
4067
+ * `'stack'`. */
4068
+ layout?: 'stack' | 'row';
4069
+ /** Options to a line in a `'row'` layout. Default: all of them. */
4070
+ columns?: number;
4071
+ /** Print the options in a shuffled order (the same in every output).
4072
+ * Default `false`: as written. */
4073
+ shuffle?: boolean;
4074
+ /** The options' indent from the text's edge. Default `1em`. */
4075
+ indent?: Dimension;
4076
+ /** A bracket after a question's stem to write the letter in (`( )`,
4077
+ * Chinese and Japanese tests). Default `false`. */
4078
+ bracket?: boolean;
4079
+ }
4080
+ /** How a `[[…]]` prints in the pupil's text (`exerciseStyles[].blank`). */
4081
+ export interface ExerciseBlankStyle {
4082
+ /** A line to write on, a dotted line, a box, or nothing. Default
4083
+ * `'line'`. */
4084
+ look?: 'line' | 'dots' | 'box' | 'none';
4085
+ /** `'answer'`: as wide as the gap's own answer; `'longest'`: as wide as
4086
+ * the exercise's longest answer, so no blank gives its answer away; or a
4087
+ * length. Default `'longest'`. */
4088
+ width?: 'answer' | 'longest' | Dimension;
4089
+ /** Room added to the answer's width. Default `1.5em`. */
4090
+ extra?: Dimension;
4091
+ /** The narrowest blank. Default `3em`. */
4092
+ minWidth?: Dimension;
4093
+ /** The line's colour. Default the text's. */
4094
+ color?: ColorValue;
4095
+ /** The line's weight. Default `0.6pt`. */
4096
+ weight?: Dimension;
4097
+ }
4098
+ /** How a true/false statement prints (`exerciseStyles[].trueFalse`). */
4099
+ export interface ExerciseTrueFalseStyle {
4100
+ /** The two answers. Default by language: T F, V F, R F, √ ×, ○ ×, ✓ ✗. */
4101
+ labels?: [string, string];
4102
+ /** `'boxes'`: a box beside each label at the line's end; `'bracket'`:
4103
+ * one bracket to write the answer in. Default `'boxes'`. */
4104
+ look?: 'boxes' | 'bracket';
4105
+ }
4106
+ /** How a match exercise prints (`exerciseStyles[].match`). */
4107
+ export interface ExerciseMatchStyle {
4108
+ /** `'dots'`: two columns with a dot each side to join with a line;
4109
+ * `'letters'`: the right column lettered, a bracket by each left item to
4110
+ * write the letter in. Default `'dots'`. */
4111
+ look?: 'dots' | 'letters';
4112
+ /** Room between the two columns. Default `4em`. */
4113
+ gap?: Dimension;
4114
+ /** The dots' diameter. Default `0.35em`. */
4115
+ dotSize?: Dimension;
4116
+ color?: ColorValue;
4117
+ }
4118
+ /** The word bank of a gaps, sort or match exercise (`exerciseStyles[].bank`). */
4119
+ export interface ExerciseBankStyle {
4120
+ /** A `calloutStyles` id for the bank's box. Default a box outlined in the
4121
+ * main colour. */
4122
+ box?: string;
4123
+ /** Default `'shuffle'`. */
4124
+ order?: 'shuffle' | 'alpha' | 'written';
4125
+ /** Between two words. Default four spaces. */
4126
+ separator?: string;
4127
+ }
4128
+ /** A writing area (`exerciseStyles[].area`): under an open question. */
4129
+ export interface ExerciseAreaStyle {
4130
+ /** Ruled lines, a row of dots, a squared grid, French Seyès ruling,
4131
+ * 田字格 squares, an empty box, or nothing. Default `'lines'`. */
4132
+ kind?: 'lines' | 'dots' | 'grid' | 'seyes' | 'tianzige' | 'box' | 'none';
4133
+ /** How many lines tall. Default `3`; a fence's `lines` overrides. */
4134
+ lines?: number;
4135
+ /** The distance between two lines. Default the text's line height. */
4136
+ spacing?: Dimension;
4137
+ /** Default a light grey. */
4138
+ color?: ColorValue;
4139
+ /** Default `0.5pt`. */
4140
+ weight?: Dimension;
4141
+ }
4142
+ /** The cells of a word search, a crossword and an operation in columns
4143
+ * (`exerciseStyles[].grid`). */
4144
+ export interface ExerciseGridStyle {
4145
+ /** A cell's side. Default `1.6em`. */
4146
+ cell?: Dimension;
4147
+ fontFamily?: string;
4148
+ fontSize?: Dimension;
4149
+ color?: ColorValue;
4150
+ /** The cells' rules. Default a mid grey. */
4151
+ rule?: ColorValue;
4152
+ ruleWidth?: Dimension;
4153
+ /** A crossword's blocked cells. Default the text colour. */
4154
+ blocked?: ColorValue;
4155
+ /** Letters set in capitals. Default `true`. */
4156
+ uppercase?: boolean;
4157
+ }
4158
+ /** Operations in columns (`exerciseStyles[].arithmetic`). */
4159
+ export interface ExerciseArithmeticStyle {
4160
+ /** Long division: `'bracket'` (⟌, the English-speaking world, China,
4161
+ * Japan, India), `'potence'` (the divisor right of the dividend under an
4162
+ * L, the quotient under it: Spain, France, Italy, Portugal, Latin
4163
+ * America), `'inline'` (`864 : 4 = 216` with the steps under it:
4164
+ * Germany). Default by language. */
4165
+ division?: 'bracket' | 'potence' | 'inline';
4166
+ /** Operations to a row. Default `4`. */
4167
+ columns?: number;
4168
+ }
4169
+ /** Difficulty marks (`exerciseStyles[].level`): `level=2` prints ●●○. */
4170
+ export interface ExerciseLevelStyle {
4171
+ /** Default `'●'`. */
4172
+ glyph?: string;
4173
+ /** For the levels not reached. Default `'○'`; `''` prints none. */
4174
+ empty?: string;
4175
+ /** Default `3`. */
4176
+ max?: number;
4177
+ color?: ColorValue;
4178
+ }
4179
+ /** An activity icon an exercise names (`icon="oral"`). */
4180
+ export interface ExerciseIcon {
4181
+ /** A bitmap or SVG resource. */
4182
+ resourceId?: string;
4183
+ /** A character, set in `fontFamily`. */
4184
+ glyph?: string;
4185
+ fontFamily?: string;
4186
+ color?: ColorValue;
4187
+ /** What it stands for, read aloud and in the tagged PDF. */
4188
+ alt?: string;
4189
+ /** Its height in ems of the instruction. Default the height of a
4190
+ * capital (`0.75`). */
4191
+ size?: number;
4192
+ }
4193
+ /** How answers print where they are shown: a teacher's edition and the
4194
+ * solutions (`exerciseStyles[].answers`). */
4195
+ export interface ExerciseAnswersStyle {
4196
+ /** Default a magenta red, as a teacher's book overprints them. */
4197
+ color?: ColorValue;
4198
+ fontFamily?: string;
4199
+ italic?: boolean;
4200
+ }
4201
+ /** Where the solutions print. */
4202
+ export type ExerciseSolutionPlacement = 'none' | 'after' | 'inverted' | 'chapterEnd' | 'directive';
4203
+ /** Where and how solutions print (`exercises.solutions`, a style's
4204
+ * `solutions` over it). */
4205
+ export interface ExerciseSolutionsConfig {
4206
+ /** Default `'none'`: none in print; the digital outputs have them. */
4207
+ placement?: ExerciseSolutionPlacement;
4208
+ /** A `calloutStyles` id for a solution's box. Default a frameless box in
4209
+ * smaller type. */
4210
+ box?: string;
4211
+ /** The heading of the solutions at the end of a chapter. Default the
4212
+ * document language's word ("Solutions"). */
4213
+ heading?: string;
4214
+ /** `'key'`: the answers alone (1 b · 2 water); `'full'`: the key, then
4215
+ * each worked solution. Default `'full'`. */
4216
+ layout?: 'key' | 'full';
4217
+ }
4218
+ /** How an exercise behaves in the HTML and EPUB outputs
4219
+ * (`exerciseStyles[].digital`). */
4220
+ export interface ExerciseDigitalStyle {
4221
+ /** Default a green. */
4222
+ correctColor?: ColorValue;
4223
+ /** Default a red. */
4224
+ wrongColor?: ColorValue;
4225
+ }
4226
+ /**
4227
+ * A named exercise style (#1226), picked with `:::exercise{style="…"}`: the
4228
+ * form of a family of exercises. The first style is the default; one,
4229
+ * `exercise`, ships when none is declared. Every field is optional.
4230
+ */
4231
+ export interface ExerciseStyleConfig {
4232
+ id: string;
4233
+ /** Human-readable name (editor UI only). */
4234
+ name?: string;
4235
+ /** The id of a style this one is based on. */
4236
+ extends?: string;
4237
+ /** A `calloutStyles` id for the exercise's frame. Default none: the
4238
+ * exercise is set in the text. */
4239
+ box?: string;
4240
+ number?: ExerciseNumberStyle;
4241
+ instruction?: ExerciseInstructionStyle;
4242
+ options?: ExerciseOptionsStyle;
4243
+ blank?: ExerciseBlankStyle;
4244
+ trueFalse?: ExerciseTrueFalseStyle;
4245
+ match?: ExerciseMatchStyle;
4246
+ bank?: ExerciseBankStyle;
4247
+ area?: ExerciseAreaStyle;
4248
+ grid?: ExerciseGridStyle;
4249
+ arithmetic?: ExerciseArithmeticStyle;
4250
+ level?: ExerciseLevelStyle;
4251
+ icons?: Record<string, ExerciseIcon>;
4252
+ answers?: ExerciseAnswersStyle;
4253
+ solutions?: ExerciseSolutionsConfig;
4254
+ digital?: ExerciseDigitalStyle;
4255
+ /** Room above and below the exercise. Default `1em` / `1em`. */
4256
+ marginTop?: Dimension;
4257
+ marginBottom?: Dimension;
4258
+ /** Room between two items (options, questions, pairs). Default `0.25em`. */
4259
+ itemSpacing?: Dimension;
4260
+ }
4261
+ /** The book's exercise settings (#1226). */
4262
+ export interface ExercisesConfig {
4263
+ /** `'teacher'` prints every answer in its slot in `answers.color`: a
4264
+ * teacher's book from the pupil's text. Default `'student'`. */
4265
+ edition?: 'student' | 'teacher';
4266
+ solutions?: ExerciseSolutionsConfig;
4267
+ /** What shuffles are drawn from: change it for another version of a
4268
+ * test. Default `1`. */
4269
+ seed?: number;
4270
+ /** The HTML and EPUB outputs. */
4271
+ digital?: {
4272
+ /** Answerable exercises. Default `true`. */
4273
+ interactive?: boolean;
4274
+ /** Keep the reader's answers in the browser. Default `true`. */
4275
+ persist?: boolean;
4276
+ /** `'button'`: checked on demand; `'instant'`: as answered. Default
4277
+ * `'button'`. */
4278
+ check?: 'button' | 'instant';
4279
+ };
4280
+ }
3998
4281
  /**
3999
4282
  * A named chip style, selected by the inline `:chip[text]{style="<id>"}`
4000
4283
  * (a chip without `style`, or with an id no style declares, takes the first
@@ -4065,7 +4348,16 @@ export interface ChipStyleConfig {
4065
4348
  * is a dotted word in the line: `:chip[gato]{style="dots"}`. Absent:
4066
4349
  * filled. */
4067
4350
  dotted?: TextDotsStyle;
4068
- }
4351
+ /** Draw the outline as a line under the text only — solid, dotted or
4352
+ * dashed, `borderWidth` thick in `borderColor` — instead of round the
4353
+ * box: a blank to write on (#1227). Absent: the whole outline. */
4354
+ underline?: ChipUnderline;
4355
+ /** The narrowest the box is, outline and padding included: the text is
4356
+ * centred in the room left (#1227). Absent: as wide as its text. */
4357
+ minWidth?: Dimension;
4358
+ }
4359
+ /** `chipStyles[].underline`. */
4360
+ export type ChipUnderline = 'solid' | 'dotted' | 'dashed';
4069
4361
  /**
4070
4362
  * A named highlight style, selected by the inline `:mark[text]{style="<id>"}`
4071
4363
  * (#888; a mark without `style`, or with an id no style declares, takes the
@@ -4151,6 +4443,9 @@ export interface ResolvedChipStyleConfig {
4151
4443
  gap: Dimension;
4152
4444
  /** Unset: the letters are filled. */
4153
4445
  dotted?: TextDotsStyle;
4446
+ /** Unset: the whole outline. */
4447
+ underline?: ChipUnderline;
4448
+ minWidth?: Dimension;
4154
4449
  }
4155
4450
  /** Parity constraint for a forced page break.
4156
4451
  *
@@ -8082,6 +8377,12 @@ export interface PostextConfig {
8082
8377
  /** Named callout styles for `:::callout{type="…"}` containers. Defaults
8083
8378
  * to a single neutral `note` style when unset. */
8084
8379
  calloutStyles?: CalloutStyleConfig[];
8380
+ /** Named exercise styles for `:::exercise{style="…"}` (#1226). One
8381
+ * plain `exercise` style ships when unset. */
8382
+ exerciseStyles?: ExerciseStyleConfig[];
8383
+ /** The book's exercise settings: edition, solutions, shuffles, digital
8384
+ * behaviour (#1226). */
8385
+ exercises?: ExercisesConfig;
8085
8386
  /** Named chip styles for the inline `:chip[text]{style="…"}`. Defaults
8086
8387
  * to a single `chip` style when unset. */
8087
8388
  chipStyles?: ChipStyleConfig[];