@mathscan/math-exercise-engine 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -14,6 +14,10 @@ const AST_TYPES = {
14
14
  SPACE: "Space",
15
15
  /** Text with optional character-range highlighting */
16
16
  HIGHLIGHTED_TEXT: "HighlightedText",
17
+ /** Text with color and optional character-range coloring */
18
+ COLOR_TEXT: "ColorText",
19
+ /** Bold text with optional character-range bolding */
20
+ BOLD_TEXT: "BoldText",
17
21
  /** Inline input widget (string or numeric) */
18
22
  INLINE_INPUT: "InlineInput",
19
23
  // ═══════════════════════════════════════════════════════════════════════════
@@ -55,6 +59,10 @@ const JSON_TYPES = {
55
59
  SPACE: "space",
56
60
  /** Text with optional highlighting */
57
61
  HIGHLIGHTED_TEXT: "highlighted-text",
62
+ /** Text with color styling */
63
+ COLOR_TEXT: "color-text",
64
+ /** Bold text */
65
+ BOLD_TEXT: "bold-text",
58
66
  /** Reference to a widget */
59
67
  WIDGET_REF: "widget-ref",
60
68
  /** Line break element */
@@ -114,6 +122,14 @@ const TEXT_HIGHLIGHTER = createToken({
114
122
  name: "TEXT_HIGHLIGHTER",
115
123
  pattern: /TEXT_HIGHLIGHTER/
116
124
  });
125
+ const COLOR_TEXT = createToken({
126
+ name: "COLOR_TEXT",
127
+ pattern: /COLOR_TEXT/
128
+ });
129
+ const BOLD_TEXT = createToken({
130
+ name: "BOLD_TEXT",
131
+ pattern: /BOLD_TEXT/
132
+ });
117
133
  const HIGHLIGHT_TEXT = createToken({
118
134
  name: "HIGHLIGHT_TEXT",
119
135
  pattern: /HIGHLIGHT_TEXT/
@@ -229,6 +245,8 @@ const allTokens = [
229
245
  // Component keywords (before Identifier!)
230
246
  QUESTION_TEXT,
231
247
  TEXT_HIGHLIGHTER,
248
+ COLOR_TEXT,
249
+ BOLD_TEXT,
232
250
  HIGHLIGHT_TEXT,
233
251
  W_S_I,
234
252
  STRING_INPUT,
@@ -418,6 +436,10 @@ class MathExerciseParser extends CstParser {
418
436
  { ALT: () => this.CONSUME(RParen) },
419
437
  // TEXT_HIGHLIGHTER / HIGHLIGHT_TEXT (for highlighting)
420
438
  { ALT: () => this.SUBRULE(this.textHighlighter) },
439
+ // COLOR_TEXT (for colored text)
440
+ { ALT: () => this.SUBRULE(this.colorText) },
441
+ // BOLD_TEXT (for bold text)
442
+ { ALT: () => this.SUBRULE(this.boldText) },
421
443
  // W_S_I (inline input widget)
422
444
  { ALT: () => this.SUBRULE(this.inlineInput) }
423
445
  ]);
@@ -431,6 +453,18 @@ class MathExerciseParser extends CstParser {
431
453
  this.SUBRULE(this.parameterList);
432
454
  this.CONSUME(RBracket);
433
455
  });
456
+ this.colorText = this.RULE("colorText", () => {
457
+ this.CONSUME(COLOR_TEXT);
458
+ this.CONSUME(LBracket);
459
+ this.SUBRULE(this.parameterList);
460
+ this.CONSUME(RBracket);
461
+ });
462
+ this.boldText = this.RULE("boldText", () => {
463
+ this.CONSUME(BOLD_TEXT);
464
+ this.CONSUME(LBracket);
465
+ this.SUBRULE(this.parameterList);
466
+ this.CONSUME(RBracket);
467
+ });
434
468
  this.inlineInput = this.RULE("inlineInput", () => {
435
469
  this.OR([
436
470
  { ALT: () => this.CONSUME(W_S_I, { LABEL: "stringInput" }) },
@@ -573,6 +607,17 @@ const HighlightedTextInlineSchema = z.object({
573
607
  value: z.string(),
574
608
  highlight: z.tuple([z.number(), z.number()]).optional()
575
609
  });
610
+ const ColorTextInlineSchema = z.object({
611
+ type: z.literal(AST_TYPES.COLOR_TEXT),
612
+ value: z.string(),
613
+ color: z.string(),
614
+ highlight: z.tuple([z.number(), z.number()]).optional()
615
+ });
616
+ const BoldTextInlineSchema = z.object({
617
+ type: z.literal(AST_TYPES.BOLD_TEXT),
618
+ value: z.string(),
619
+ highlight: z.tuple([z.number(), z.number()]).optional()
620
+ });
576
621
  const InlineInputWidgetSchema = z.discriminatedUnion("inputType", [
577
622
  z.object({
578
623
  type: z.literal(AST_TYPES.INLINE_INPUT),
@@ -593,6 +638,8 @@ const InlineNodeSchema = z.union([
593
638
  FreeTextInlineSchema,
594
639
  SpaceInlineSchema,
595
640
  HighlightedTextInlineSchema,
641
+ ColorTextInlineSchema,
642
+ BoldTextInlineSchema,
596
643
  InlineInputWidgetSchema
597
644
  ]);
598
645
  function createFreeText(value) {
@@ -613,6 +660,21 @@ function createHighlightedText(value, highlight) {
613
660
  highlight
614
661
  });
615
662
  }
663
+ function createColorText(value, color, highlight) {
664
+ return ColorTextInlineSchema.parse({
665
+ type: AST_TYPES.COLOR_TEXT,
666
+ value,
667
+ color,
668
+ highlight
669
+ });
670
+ }
671
+ function createBoldText(value, highlight) {
672
+ return BoldTextInlineSchema.parse({
673
+ type: AST_TYPES.BOLD_TEXT,
674
+ value,
675
+ highlight
676
+ });
677
+ }
616
678
  function createStringInput(name, length, answer) {
617
679
  return InlineInputWidgetSchema.parse({
618
680
  type: AST_TYPES.INLINE_INPUT,
@@ -856,6 +918,12 @@ class NaturalDSLVisitor extends BaseCstVisitor {
856
918
  if (ctx.textHighlighter) {
857
919
  return this.visit(ctx.textHighlighter);
858
920
  }
921
+ if (ctx.colorText) {
922
+ return this.visit(ctx.colorText);
923
+ }
924
+ if (ctx.boldText) {
925
+ return this.visit(ctx.boldText);
926
+ }
859
927
  if (ctx.inlineInput) {
860
928
  return this.visit(ctx.inlineInput);
861
929
  }
@@ -870,6 +938,25 @@ class NaturalDSLVisitor extends BaseCstVisitor {
870
938
  }
871
939
  return createHighlightedText(value, highlight);
872
940
  }
941
+ colorText(ctx) {
942
+ const params = this.visit(ctx.parameterList);
943
+ const value = params.value;
944
+ const color = params.color;
945
+ let highlight = void 0;
946
+ if (params.start !== void 0 && params.end !== void 0) {
947
+ highlight = [params.start, params.end];
948
+ }
949
+ return createColorText(value, color, highlight);
950
+ }
951
+ boldText(ctx) {
952
+ const params = this.visit(ctx.parameterList);
953
+ const value = params.value;
954
+ let highlight = void 0;
955
+ if (params.start !== void 0 && params.end !== void 0) {
956
+ highlight = [params.start, params.end];
957
+ }
958
+ return createBoldText(value, highlight);
959
+ }
873
960
  inlineInput(ctx) {
874
961
  const params = this.visit(ctx.parameterList);
875
962
  const name = params.name;
@@ -1012,6 +1099,19 @@ const HighlightedTextSchema = z.object({
1012
1099
  value: z.string(),
1013
1100
  highlight: z.tuple([z.number(), z.number()]).optional()
1014
1101
  });
1102
+ const ColorTextSchema = z.object({
1103
+ id: z.string(),
1104
+ type: z.literal(JSON_TYPES.COLOR_TEXT),
1105
+ value: z.string(),
1106
+ color: z.string(),
1107
+ highlight: z.tuple([z.number(), z.number()]).optional()
1108
+ });
1109
+ const BoldTextSchema = z.object({
1110
+ id: z.string(),
1111
+ type: z.literal(JSON_TYPES.BOLD_TEXT),
1112
+ value: z.string(),
1113
+ highlight: z.tuple([z.number(), z.number()]).optional()
1114
+ });
1015
1115
  const LinebreakSchema = z.object({
1016
1116
  id: z.string(),
1017
1117
  type: z.literal(JSON_TYPES.LINEBREAK)
@@ -1028,6 +1128,8 @@ const LayoutItemSchema = z.lazy(
1028
1128
  TextItemSchema,
1029
1129
  WidgetRefSchema,
1030
1130
  HighlightedTextSchema,
1131
+ ColorTextSchema,
1132
+ BoldTextSchema,
1031
1133
  LinebreakSchema,
1032
1134
  GroupItemSchema,
1033
1135
  OperatorItemSchema
@@ -1110,6 +1212,12 @@ function isWidgetRef(item) {
1110
1212
  function isHighlightedText(item) {
1111
1213
  return item.type === JSON_TYPES.HIGHLIGHTED_TEXT;
1112
1214
  }
1215
+ function isColorText(item) {
1216
+ return item.type === JSON_TYPES.COLOR_TEXT;
1217
+ }
1218
+ function isBoldText(item) {
1219
+ return item.type === JSON_TYPES.BOLD_TEXT;
1220
+ }
1113
1221
  function isLinebreak(item) {
1114
1222
  return item.type === JSON_TYPES.LINEBREAK;
1115
1223
  }
@@ -1242,6 +1350,21 @@ function transformInline(inline, idGenerator) {
1242
1350
  value: inline.value,
1243
1351
  highlight: inline.highlight
1244
1352
  };
1353
+ case AST_TYPES.COLOR_TEXT:
1354
+ return {
1355
+ id: idGenerator.generate(JSON_TYPES.COLOR_TEXT),
1356
+ type: JSON_TYPES.COLOR_TEXT,
1357
+ value: inline.value,
1358
+ color: inline.color,
1359
+ highlight: inline.highlight
1360
+ };
1361
+ case AST_TYPES.BOLD_TEXT:
1362
+ return {
1363
+ id: idGenerator.generate(JSON_TYPES.BOLD_TEXT),
1364
+ type: JSON_TYPES.BOLD_TEXT,
1365
+ value: inline.value,
1366
+ highlight: inline.highlight
1367
+ };
1245
1368
  case AST_TYPES.INLINE_INPUT:
1246
1369
  return {
1247
1370
  id: idGenerator.generate(JSON_TYPES.WIDGET_REF),
@@ -5858,7 +5981,7 @@ function itemContainsLatin(item) {
5858
5981
  return false;
5859
5982
  }
5860
5983
  function isTextItem(item) {
5861
- return item.type === JSON_TYPES.TEXT || item.type === JSON_TYPES.HIGHLIGHTED_TEXT || item.type === JSON_TYPES.OPERATOR || item.type === JSON_TYPES.SPACE || item.type === JSON_TYPES.GROUP;
5984
+ return item.type === JSON_TYPES.TEXT || item.type === JSON_TYPES.HIGHLIGHTED_TEXT || item.type === JSON_TYPES.BOLD_TEXT || item.type === JSON_TYPES.COLOR_TEXT || item.type === JSON_TYPES.OPERATOR || item.type === JSON_TYPES.SPACE || item.type === JSON_TYPES.GROUP;
5862
5985
  }
5863
5986
  function groupLineItems(items) {
5864
5987
  const groups = [];
@@ -5905,13 +6028,39 @@ const LayoutRenderer = ({
5905
6028
  const dirAttr = !hasArabic ? "ltr" : void 0;
5906
6029
  if (item.highlight) {
5907
6030
  const [start, end] = item.highlight;
5908
- return /* @__PURE__ */ jsxs("span", { className: "highlighted-text", dir: dirAttr, children: [
6031
+ return /* @__PURE__ */ jsxs("span", { className: "highlighted-text text-item", dir: dirAttr, children: [
6032
+ item.value.slice(0, start),
6033
+ /* @__PURE__ */ jsx("mark", { className: "highlight text-item", children: item.value.slice(start, end) }),
6034
+ item.value.slice(end)
6035
+ ] });
6036
+ }
6037
+ return /* @__PURE__ */ jsx("mark", { className: "highlighted-text text-item", dir: dirAttr, children: item.value });
6038
+ }
6039
+ case JSON_TYPES.COLOR_TEXT: {
6040
+ const hasArabic = isArabic(item.value);
6041
+ const dirAttr = !hasArabic ? "ltr" : void 0;
6042
+ if (item.highlight) {
6043
+ const [start, end] = item.highlight;
6044
+ return /* @__PURE__ */ jsxs("span", { className: "color-text text-item", dir: dirAttr, children: [
6045
+ item.value.slice(0, start),
6046
+ /* @__PURE__ */ jsx("span", { className: "color-text-colored", style: { color: item.color }, children: item.value.slice(start, end) }),
6047
+ item.value.slice(end)
6048
+ ] });
6049
+ }
6050
+ return /* @__PURE__ */ jsx("span", { className: "color-text text-item", style: { color: item.color }, dir: dirAttr, children: item.value });
6051
+ }
6052
+ case JSON_TYPES.BOLD_TEXT: {
6053
+ const hasArabic = isArabic(item.value);
6054
+ const dirAttr = !hasArabic ? "ltr" : void 0;
6055
+ if (item.highlight) {
6056
+ const [start, end] = item.highlight;
6057
+ return /* @__PURE__ */ jsxs("span", { className: "bold-text text-item", dir: dirAttr, children: [
5909
6058
  item.value.slice(0, start),
5910
- /* @__PURE__ */ jsx("mark", { className: "highlight", children: item.value.slice(start, end) }),
6059
+ /* @__PURE__ */ jsx("strong", { className: "bold-text-strong text-item", children: item.value.slice(start, end) }),
5911
6060
  item.value.slice(end)
5912
6061
  ] });
5913
6062
  }
5914
- return /* @__PURE__ */ jsx("mark", { className: "highlighted-text", dir: dirAttr, children: item.value });
6063
+ return /* @__PURE__ */ jsx("strong", { className: "bold-text text-item", dir: dirAttr, children: item.value });
5915
6064
  }
5916
6065
  case JSON_TYPES.WIDGET_REF: {
5917
6066
  const widget = widgets[item.widgetId];
@@ -38139,6 +38288,10 @@ function compileWithAST(dsl) {
38139
38288
  }
38140
38289
  export {
38141
38290
  AST_TYPES,
38291
+ BoldTextInlineSchema,
38292
+ BoldTextSchema,
38293
+ ColorTextInlineSchema,
38294
+ ColorTextSchema,
38142
38295
  DragOptionsJSONSchema,
38143
38296
  DragOptionsToolSchema,
38144
38297
  EngineError,
@@ -38180,6 +38333,8 @@ export {
38180
38333
  WidgetRenderer,
38181
38334
  compile,
38182
38335
  compileWithAST,
38336
+ createBoldText,
38337
+ createColorText,
38183
38338
  createDragOptions,
38184
38339
  createExerciseDocument,
38185
38340
  createExpressionValidation,
@@ -38196,6 +38351,8 @@ export {
38196
38351
  extractVariables as extractExpressionVariables,
38197
38352
  findValidCombination,
38198
38353
  getMissingInputs,
38354
+ isBoldText,
38355
+ isColorText,
38199
38356
  isDragOptions,
38200
38357
  isDragOptionsJSON,
38201
38358
  isExerciseDocument,