@gmb/bitmark-parser-generator 3.11.0 → 3.13.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 (140) hide show
  1. package/dist/browser/bitmark-parser-generator.min.js +1 -1
  2. package/dist/browser/bundle-report.html +2 -2
  3. package/dist/cjs/BitmarkParserGenerator.js +17 -7
  4. package/dist/cjs/BitmarkParserGenerator.js.map +1 -1
  5. package/dist/cjs/ast/BaseBuilder.js +5 -0
  6. package/dist/cjs/ast/BaseBuilder.js.map +1 -1
  7. package/dist/cjs/ast/Builder.js +147 -6
  8. package/dist/cjs/ast/Builder.js.map +1 -1
  9. package/dist/cjs/ast/ResourceBuilder.js +1 -0
  10. package/dist/cjs/ast/ResourceBuilder.js.map +1 -1
  11. package/dist/cjs/ast/writer/FileWriter.js +17 -7
  12. package/dist/cjs/ast/writer/FileWriter.js.map +1 -1
  13. package/dist/cjs/config/raw/bits.js +54 -0
  14. package/dist/cjs/config/raw/bits.js.map +1 -1
  15. package/dist/cjs/config/raw/cardSets.js +46 -0
  16. package/dist/cjs/config/raw/cardSets.js.map +1 -1
  17. package/dist/cjs/config/raw/groups.js +19 -0
  18. package/dist/cjs/config/raw/groups.js.map +1 -1
  19. package/dist/cjs/config/raw/properties.js +10 -0
  20. package/dist/cjs/config/raw/properties.js.map +1 -1
  21. package/dist/cjs/generated/build-info.js +1 -1
  22. package/dist/cjs/generated/parser/bitmark/bitmark-peggy-parser.js +1 -1
  23. package/dist/cjs/generated/parser/text/text-peggy-parser.js +1258 -710
  24. package/dist/cjs/generated/parser/text/text-peggy-parser.js.map +1 -1
  25. package/dist/cjs/generator/bitmark/BitmarkGenerator.js +265 -399
  26. package/dist/cjs/generator/bitmark/BitmarkGenerator.js.map +1 -1
  27. package/dist/cjs/generator/json/JsonGenerator.js +5 -0
  28. package/dist/cjs/generator/json/JsonGenerator.js.map +1 -1
  29. package/dist/cjs/generator/text/TextGenerator.js +32 -13
  30. package/dist/cjs/generator/text/TextGenerator.js.map +1 -1
  31. package/dist/cjs/model/ast/NodeType.js +7 -0
  32. package/dist/cjs/model/ast/NodeType.js.map +1 -1
  33. package/dist/cjs/model/config/enum/CardSetConfigKey.js +1 -0
  34. package/dist/cjs/model/config/enum/CardSetConfigKey.js.map +1 -1
  35. package/dist/cjs/model/config/enum/GroupConfigKey.js +1 -0
  36. package/dist/cjs/model/config/enum/GroupConfigKey.js.map +1 -1
  37. package/dist/cjs/model/config/enum/PropertyConfigKey.js +2 -0
  38. package/dist/cjs/model/config/enum/PropertyConfigKey.js.map +1 -1
  39. package/dist/cjs/model/enum/BitType.js +14 -0
  40. package/dist/cjs/model/enum/BitType.js.map +1 -1
  41. package/dist/cjs/model/enum/ResourceTag.js +1 -0
  42. package/dist/cjs/model/enum/ResourceTag.js.map +1 -1
  43. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserTypes.js.map +1 -1
  44. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserValidator.js +1 -1
  45. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserValidator.js.map +1 -1
  46. package/dist/cjs/parser/bitmark/peg/contentProcessors/CardContentProcessor.js +79 -16
  47. package/dist/cjs/parser/bitmark/peg/contentProcessors/CardContentProcessor.js.map +1 -1
  48. package/dist/cjs/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js +5 -0
  49. package/dist/cjs/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js.map +1 -1
  50. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js +6 -1
  51. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js.map +1 -1
  52. package/dist/cjs/utils/FileUtils.js +17 -7
  53. package/dist/cjs/utils/FileUtils.js.map +1 -1
  54. package/dist/esm/ast/BaseBuilder.js +5 -0
  55. package/dist/esm/ast/BaseBuilder.js.map +1 -1
  56. package/dist/esm/ast/Builder.js +147 -6
  57. package/dist/esm/ast/Builder.js.map +1 -1
  58. package/dist/esm/ast/ResourceBuilder.js +1 -0
  59. package/dist/esm/ast/ResourceBuilder.js.map +1 -1
  60. package/dist/esm/config/raw/bits.js +54 -0
  61. package/dist/esm/config/raw/bits.js.map +1 -1
  62. package/dist/esm/config/raw/cardSets.js +46 -0
  63. package/dist/esm/config/raw/cardSets.js.map +1 -1
  64. package/dist/esm/config/raw/groups.js +19 -0
  65. package/dist/esm/config/raw/groups.js.map +1 -1
  66. package/dist/esm/config/raw/properties.js +10 -0
  67. package/dist/esm/config/raw/properties.js.map +1 -1
  68. package/dist/esm/generated/build-info.js +1 -1
  69. package/dist/esm/generated/parser/bitmark/bitmark-peggy-parser.js +1 -1
  70. package/dist/esm/generated/parser/text/text-peggy-parser.js +1258 -710
  71. package/dist/esm/generated/parser/text/text-peggy-parser.js.map +1 -1
  72. package/dist/esm/generator/bitmark/BitmarkGenerator.js +265 -399
  73. package/dist/esm/generator/bitmark/BitmarkGenerator.js.map +1 -1
  74. package/dist/esm/generator/json/JsonGenerator.js +5 -0
  75. package/dist/esm/generator/json/JsonGenerator.js.map +1 -1
  76. package/dist/esm/generator/text/TextGenerator.js +32 -13
  77. package/dist/esm/generator/text/TextGenerator.js.map +1 -1
  78. package/dist/esm/model/ast/NodeType.js +7 -0
  79. package/dist/esm/model/ast/NodeType.js.map +1 -1
  80. package/dist/esm/model/config/enum/CardSetConfigKey.js +1 -0
  81. package/dist/esm/model/config/enum/CardSetConfigKey.js.map +1 -1
  82. package/dist/esm/model/config/enum/GroupConfigKey.js +1 -0
  83. package/dist/esm/model/config/enum/GroupConfigKey.js.map +1 -1
  84. package/dist/esm/model/config/enum/PropertyConfigKey.js +2 -0
  85. package/dist/esm/model/config/enum/PropertyConfigKey.js.map +1 -1
  86. package/dist/esm/model/enum/BitType.js +14 -0
  87. package/dist/esm/model/enum/BitType.js.map +1 -1
  88. package/dist/esm/model/enum/ResourceTag.js +1 -0
  89. package/dist/esm/model/enum/ResourceTag.js.map +1 -1
  90. package/dist/esm/parser/bitmark/peg/BitmarkPegParserTypes.js.map +1 -1
  91. package/dist/esm/parser/bitmark/peg/BitmarkPegParserValidator.js +1 -1
  92. package/dist/esm/parser/bitmark/peg/BitmarkPegParserValidator.js.map +1 -1
  93. package/dist/esm/parser/bitmark/peg/contentProcessors/CardContentProcessor.js +79 -16
  94. package/dist/esm/parser/bitmark/peg/contentProcessors/CardContentProcessor.js.map +1 -1
  95. package/dist/esm/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js +6 -1
  96. package/dist/esm/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js.map +1 -1
  97. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js +6 -1
  98. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js.map +1 -1
  99. package/dist/types/ast/BaseBuilder.d.ts +3 -0
  100. package/dist/types/ast/BaseBuilder.d.ts.map +1 -1
  101. package/dist/types/ast/Builder.d.ts +40 -2
  102. package/dist/types/ast/Builder.d.ts.map +1 -1
  103. package/dist/types/ast/ResourceBuilder.d.ts.map +1 -1
  104. package/dist/types/config/raw/bits.d.ts.map +1 -1
  105. package/dist/types/config/raw/cardSets.d.ts.map +1 -1
  106. package/dist/types/config/raw/groups.d.ts.map +1 -1
  107. package/dist/types/config/raw/properties.d.ts.map +1 -1
  108. package/dist/types/generated/parser/text/text-peggy-parser.d.ts.map +1 -1
  109. package/dist/types/generator/bitmark/BitmarkGenerator.d.ts +26 -43
  110. package/dist/types/generator/bitmark/BitmarkGenerator.d.ts.map +1 -1
  111. package/dist/types/generator/json/JsonGenerator.d.ts +1 -0
  112. package/dist/types/generator/json/JsonGenerator.d.ts.map +1 -1
  113. package/dist/types/generator/text/TextGenerator.d.ts +5 -1
  114. package/dist/types/generator/text/TextGenerator.d.ts.map +1 -1
  115. package/dist/types/model/ast/NodeType.d.ts +14 -0
  116. package/dist/types/model/ast/NodeType.d.ts.map +1 -1
  117. package/dist/types/model/ast/Nodes.d.ts +4 -1
  118. package/dist/types/model/ast/Nodes.d.ts.map +1 -1
  119. package/dist/types/model/config/enum/CardSetConfigKey.d.ts +2 -0
  120. package/dist/types/model/config/enum/CardSetConfigKey.d.ts.map +1 -1
  121. package/dist/types/model/config/enum/ConfigKey.d.ts +6 -0
  122. package/dist/types/model/config/enum/ConfigKey.d.ts.map +1 -1
  123. package/dist/types/model/config/enum/GroupConfigKey.d.ts +3 -0
  124. package/dist/types/model/config/enum/GroupConfigKey.d.ts.map +1 -1
  125. package/dist/types/model/config/enum/PropertyConfigKey.d.ts +6 -0
  126. package/dist/types/model/config/enum/PropertyConfigKey.d.ts.map +1 -1
  127. package/dist/types/model/enum/BitType.d.ts +28 -0
  128. package/dist/types/model/enum/BitType.d.ts.map +1 -1
  129. package/dist/types/model/enum/PropertyTag.d.ts +4 -0
  130. package/dist/types/model/enum/PropertyTag.d.ts.map +1 -1
  131. package/dist/types/model/enum/ResourceTag.d.ts +2 -0
  132. package/dist/types/model/enum/ResourceTag.d.ts.map +1 -1
  133. package/dist/types/model/json/BitJson.d.ts +45 -6
  134. package/dist/types/model/json/BitJson.d.ts.map +1 -1
  135. package/dist/types/parser/bitmark/peg/BitmarkPegParserTypes.d.ts +5 -2
  136. package/dist/types/parser/bitmark/peg/BitmarkPegParserTypes.d.ts.map +1 -1
  137. package/dist/types/parser/bitmark/peg/contentProcessors/CardContentProcessor.d.ts.map +1 -1
  138. package/dist/types/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.d.ts.map +1 -1
  139. package/dist/types/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.d.ts.map +1 -1
  140. package/package.json +40 -40
@@ -29,6 +29,9 @@ const DEFAULT_OPTIONS = {
29
29
  };
30
30
  /**
31
31
  * Generate bitmark markup from a bitmark AST
32
+ *
33
+ * NOTE: Newlines - a newline is written BEFORE each content that requries a newline
34
+ *
32
35
  */
33
36
  class BitmarkGenerator extends AstWalkerGenerator {
34
37
  /**
@@ -51,10 +54,9 @@ class BitmarkGenerator extends AstWalkerGenerator {
51
54
  super();
52
55
  this.ast = new Ast();
53
56
  // State
57
+ this.firstBit = true;
54
58
  this.hasCardSet = false;
55
59
  this.hasFooter = false;
56
- this.skipNLBetweenBitsValue = false;
57
- this.wroteSomething = false;
58
60
  this.inTag = true;
59
61
  // Keep TS happy
60
62
  this.inTag;
@@ -127,10 +129,9 @@ class BitmarkGenerator extends AstWalkerGenerator {
127
129
  this.writer.closeSync();
128
130
  }
129
131
  resetState() {
132
+ this.firstBit = true;
130
133
  this.hasCardSet = false;
131
134
  this.hasFooter = false;
132
- this.skipNLBetweenBitsValue = false;
133
- this.wroteSomething = false;
134
135
  this.inTag = true;
135
136
  this.printed = false;
136
137
  }
@@ -147,12 +148,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
147
148
  // Non-Terminal nodes (branches)
148
149
  //
149
150
  // bitmark
150
- // bitmarkAst -> bits
151
- between_bits(_node, _left, _right, _route) {
152
- this.writeNL();
153
- this.writeNL();
154
- this.writeNL();
155
- }
156
151
  // bitmarkAst -> bits -> bitsValue
157
152
  enter_bitsValue(node, _route) {
158
153
  const bit = node.value;
@@ -160,6 +155,12 @@ class BitmarkGenerator extends AstWalkerGenerator {
160
155
  const bitResourcesConfig = Config.getBitResourcesConfig(bit.bitType, bit.resourceType);
161
156
  this.hasCardSet = this.haveValidCardSet(bit);
162
157
  this.hasFooter = this.haveValidFooter(bit);
158
+ // Separate the bits with 3 newlines
159
+ if (!this.firstBit) {
160
+ this.writeNL();
161
+ this.writeNL();
162
+ this.writeNL();
163
+ }
163
164
  // Write the bit tag opening
164
165
  this.writeOPD(bit.bitLevel);
165
166
  if (bit.isCommented)
@@ -195,22 +196,12 @@ class BitmarkGenerator extends AstWalkerGenerator {
195
196
  this.writeBreakscapedTagString(resourceType);
196
197
  }
197
198
  this.writeCL();
198
- this.writeNL();
199
+ // this.writeNL();
199
200
  // Continue traversal
200
201
  return true;
201
202
  }
202
- between_bitsValue(node, left, right, route) {
203
- // The following keys are combined with other keys so don't need newlines
204
- const noNlKeys = [
205
- NodeType.bitType,
206
- NodeType.textFormat,
207
- NodeType.level,
208
- NodeType.progress,
209
- NodeType.toc,
210
- NodeType.referenceEnd,
211
- NodeType.labelFalse,
212
- ];
213
- this.writeNlBetween(node, left, right, route, noNlKeys);
203
+ exit_bitsValue(_node, _route) {
204
+ this.firstBit = false;
214
205
  }
215
206
  // bitmarkAst -> bits -> bitsValue -> internalComment
216
207
  enter_internalComment(node, route) {
@@ -221,14 +212,12 @@ class BitmarkGenerator extends AstWalkerGenerator {
221
212
  return true;
222
213
  for (let i = 0; i < internalComment.length; i++) {
223
214
  const comment = internalComment[i];
224
- const last = i === internalComment.length - 1;
215
+ this.writeNL();
225
216
  this.writeProperty('internalComment', comment, {
226
217
  format: PropertyFormat.trimmedString,
227
218
  single: false,
228
219
  ignoreEmpty: true,
229
220
  });
230
- if (!last)
231
- this.writeNL();
232
221
  }
233
222
  // Stop traversal of this branch
234
223
  return false;
@@ -242,13 +231,18 @@ class BitmarkGenerator extends AstWalkerGenerator {
242
231
  return true;
243
232
  const bit = parent === null || parent === void 0 ? void 0 : parent.value;
244
233
  if (bit) {
245
- if (value != '')
234
+ const haveTrue = value != '';
235
+ const haveFalse = bit.labelFalse && bit.labelFalse[0] != '';
236
+ if (haveTrue || haveFalse) {
237
+ this.writeNL();
238
+ }
239
+ if (haveTrue)
246
240
  this.writeProperty(PropertyTag.labelTrue, value, {
247
241
  format: PropertyFormat.trimmedString,
248
242
  single: true,
249
243
  ignoreEmpty: true,
250
244
  });
251
- if (bit.labelFalse && bit.labelFalse[0] != '')
245
+ if (haveFalse)
252
246
  this.writeProperty(PropertyTag.labelFalse, bit.labelFalse, {
253
247
  format: PropertyFormat.trimmedString,
254
248
  single: true,
@@ -258,6 +252,10 @@ class BitmarkGenerator extends AstWalkerGenerator {
258
252
  // Stop traversal of this branch
259
253
  return false;
260
254
  }
255
+ enter_labelFalse(_node, _route) {
256
+ // Handled above in enter_labelTrue(), but this function needed to block automatic property handling
257
+ return true;
258
+ }
261
259
  // bitmarkAst -> bits -> bitsValue -> imageSource
262
260
  enter_imageSource(node, route) {
263
261
  const imageSource = node.value;
@@ -266,6 +264,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
266
264
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
267
265
  return true;
268
266
  const { url, mockupId, size, format, trim } = imageSource;
267
+ this.writeNL();
269
268
  this.writeProperty('imageSource', url, {
270
269
  format: PropertyFormat.trimmedString,
271
270
  single: true,
@@ -308,6 +307,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
308
307
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
309
308
  return true;
310
309
  const { technicalTerm, lang } = nodeValue;
310
+ this.writeNL();
311
311
  this.writeProperty('technicalTerm', technicalTerm, {
312
312
  format: PropertyFormat.trimmedString,
313
313
  single: true,
@@ -331,6 +331,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
331
331
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
332
332
  return true;
333
333
  const { servings, unit, unitAbbr, decimalPlaces, disableCalculation, hint } = nodeValue;
334
+ this.writeNL();
334
335
  this.writeProperty('servings', servings, {
335
336
  format: PropertyFormat.trimmedString,
336
337
  single: true,
@@ -384,6 +385,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
384
385
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
385
386
  return true;
386
387
  const { name, title, avatarImage } = person;
388
+ this.writeNL();
387
389
  this.writeProperty('person', name, {
388
390
  format: PropertyFormat.trimmedString,
389
391
  single: true,
@@ -402,6 +404,89 @@ class BitmarkGenerator extends AstWalkerGenerator {
402
404
  // Stop traversal of this branch
403
405
  return false;
404
406
  }
407
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> term -> text
408
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> definition -> text
409
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> alternativeDefinitions
410
+ // -> alternativeDefinitionsValue -> text
411
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue -> question -> text
412
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue -> answer -> text
413
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue -> alternativeAnswers ->
414
+ // -> alternativeAnswersValue -> text
415
+ enter_text(node, route) {
416
+ const parent = this.getParentNode(route);
417
+ if (!parent ||
418
+ (parent.key !== NodeType.term &&
419
+ parent.key !== NodeType.definition &&
420
+ parent.key !== NodeType.alternativeDefinitionsValue &&
421
+ parent.key !== NodeType.question &&
422
+ parent.key !== NodeType.answer &&
423
+ parent.key !== NodeType.alternativeAnswersValue)) {
424
+ return true;
425
+ }
426
+ if (node.value) {
427
+ this.writeNL();
428
+ this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
429
+ }
430
+ // Stop traversal of this branch
431
+ return false;
432
+ }
433
+ leaf_text(node, route) {
434
+ const parent = this.getParentNode(route);
435
+ if (!parent ||
436
+ (parent.key !== NodeType.term &&
437
+ parent.key !== NodeType.definition &&
438
+ parent.key !== NodeType.alternativeDefinitionsValue &&
439
+ parent.key !== NodeType.question &&
440
+ parent.key !== NodeType.answer &&
441
+ parent.key !== NodeType.alternativeAnswersValue &&
442
+ parent.key !== NodeType.reason)) {
443
+ return true;
444
+ }
445
+ if (StringUtils.isString(node.value)) {
446
+ const str = node.value;
447
+ this.writeNL();
448
+ this.write(Breakscape.breakscape(str, {
449
+ textFormat: TextFormat.text,
450
+ }));
451
+ }
452
+ // Stop traversal of this branch
453
+ return false;
454
+ }
455
+ // bitmarkAst -> bits -> bitsValue -> * -> term -> icon
456
+ // bitmarkAst -> bits -> bitsValue -> * -> definition -> icon
457
+ // bitmarkAst -> bits -> bitsValue -> * -> alternativeDefinitionsValue -> icon
458
+ enter_icon(node, route) {
459
+ const resource = node.value;
460
+ const parent = this.getParentNode(route);
461
+ if (!parent)
462
+ return true;
463
+ if (parent.key !== NodeType.term &&
464
+ parent.key !== NodeType.definition &&
465
+ parent.key !== NodeType.alternativeDefinitionsValue &&
466
+ parent.key !== NodeType.question &&
467
+ parent.key !== NodeType.answer &&
468
+ parent.key !== NodeType.alternativeAnswersValue) {
469
+ // Continue traversal of this branch
470
+ return true;
471
+ }
472
+ // This is a resource, so handle it with the common code
473
+ this.writeNL();
474
+ this.writeResource(ResourceTag.icon, resource.src);
475
+ // this.writePropertyStyleResource(ResourceTag.icon, resource as ResourceJson);
476
+ // Continue traversal of this branch (for the chained properties)
477
+ return true;
478
+ }
479
+ leaf_iconValue(node, _route) {
480
+ // Handle as a standard icon property
481
+ this.writeNL();
482
+ this.writeProperty('icon', node.value, {
483
+ format: PropertyFormat.trimmedString,
484
+ single: true,
485
+ ignoreEmpty: true,
486
+ });
487
+ // Stop traversal of this branch
488
+ return false;
489
+ }
405
490
  // bitmarkAst -> bits -> bitsValue -> ratingLevelStart
406
491
  enter_ratingLevelStart(node, route) {
407
492
  this.enterRatingLevelStartEndCommon(node, route);
@@ -423,6 +508,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
423
508
  return true;
424
509
  const { level, label } = n;
425
510
  const levelKey = node.key === NodeType.ratingLevelStart ? PropertyTag.ratingLevelStart : PropertyTag.ratingLevelEnd;
511
+ this.writeNL();
426
512
  this.writeProperty(levelKey, level, {
427
513
  format: PropertyFormat.trimmedString,
428
514
  single: true,
@@ -452,6 +538,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
452
538
  return true;
453
539
  const { mark, color, emphasis } = markConfig;
454
540
  if (mark) {
541
+ this.writeNL();
455
542
  this.writeProperty('mark', mark, {
456
543
  format: PropertyFormat.trimmedString,
457
544
  single: true,
@@ -471,74 +558,79 @@ class BitmarkGenerator extends AstWalkerGenerator {
471
558
  ignoreEmpty: true,
472
559
  });
473
560
  }
474
- this.writeNL();
475
561
  }
476
562
  // Stop traversal of this branch
477
563
  return false;
478
564
  }
479
565
  // bitmarkAst -> bits -> bitsValue -> partialAnswer
480
566
  enter_partialAnswer(node, _route) {
481
- this.writeProperty('partialAnswer', node.value, {
482
- format: PropertyFormat.trimmedString,
483
- single: true,
484
- ignoreEmpty: true,
485
- });
567
+ if (node.value) {
568
+ this.writeNL();
569
+ this.writeProperty('partialAnswer', node.value, {
570
+ format: PropertyFormat.trimmedString,
571
+ single: true,
572
+ ignoreEmpty: true,
573
+ });
574
+ }
486
575
  // Stop traversal of this branch
487
576
  return false;
488
577
  }
489
578
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> partialAnswer
490
579
  leaf_partialAnswer(node, _route) {
491
- this.writeProperty('partialAnswer', node.value, {
492
- format: PropertyFormat.trimmedString,
493
- single: true,
494
- ignoreEmpty: true,
495
- });
580
+ if (node.value) {
581
+ this.writeNL();
582
+ this.writeProperty('partialAnswer', node.value, {
583
+ format: PropertyFormat.trimmedString,
584
+ single: true,
585
+ ignoreEmpty: true,
586
+ });
587
+ }
496
588
  // Stop traversal of this branch
497
589
  return false;
498
590
  }
499
591
  // bitmarkAst -> bits -> bitsValue -> sampleSolution
500
592
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> sampleSolution
501
593
  enter_sampleSolution(node, _route) {
502
- this.writeProperty('sampleSolution', node.value, {
503
- format: PropertyFormat.trimmedString,
504
- single: true,
505
- ignoreEmpty: true,
506
- });
594
+ if (node.value) {
595
+ this.writeNL();
596
+ this.writeProperty('sampleSolution', node.value, {
597
+ format: PropertyFormat.trimmedString,
598
+ single: true,
599
+ ignoreEmpty: true,
600
+ });
601
+ }
507
602
  // Stop traversal of this branch
508
603
  return false;
509
604
  }
510
605
  leaf_sampleSolution(node, _route) {
511
- this.writeProperty('sampleSolution', node.value, {
512
- format: PropertyFormat.trimmedString,
513
- single: true,
514
- ignoreEmpty: true,
515
- });
606
+ if (node.value) {
607
+ this.writeNL();
608
+ this.writeProperty('sampleSolution', node.value, {
609
+ format: PropertyFormat.trimmedString,
610
+ single: true,
611
+ ignoreEmpty: true,
612
+ });
613
+ }
516
614
  // Stop traversal of this branch
517
615
  return false;
518
616
  }
519
617
  // bitmarkAst -> bits -> bitsValue -> reasonableNumOfChars
520
618
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> reasonableNumOfChars
521
619
  leaf_reasonableNumOfChars(node, _route) {
620
+ this.writeNL();
522
621
  this.writeProperty('reasonableNumOfChars', node.value, {
523
622
  format: PropertyFormat.trimmedString,
524
623
  single: true,
525
624
  ignoreEmpty: true,
526
625
  });
527
626
  }
528
- // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> additionalSolutions
529
- between_additionalSolutions(_node, _left, _right, route) {
530
- // Ignore values that are not at the bit level as they might be handled elsewhere
531
- const parent = this.getParentNode(route);
532
- if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.questionsValue)
533
- return;
534
- this.writeNL();
535
- }
536
627
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> additionalSolutions -> additionalSolutionsValue
537
628
  leaf_additionalSolutionsValue(node, route) {
538
629
  // Ignore values that are not at the bit level as they might be handled elsewhere
539
630
  const parent = this.getParentNode(route, 2);
540
631
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.questionsValue)
541
632
  return;
633
+ this.writeNL();
542
634
  this.writeProperty('additionalSolutions', node.value, {
543
635
  format: PropertyFormat.trimmedString,
544
636
  single: false,
@@ -557,6 +649,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
557
649
  return true; // Will be handled by pageNumber
558
650
  if (!this.isEmptyText((_c = parent === null || parent === void 0 ? void 0 : parent.value) === null || _c === void 0 ? void 0 : _c.marginNumber))
559
651
  return true; // Will be handled by marginNumber
652
+ this.writeNL_IfNotChain(route);
560
653
  this.writeOPC();
561
654
  this.textGenerator.generateSync(item, TextFormat.bitmarkMinusMinus);
562
655
  this.writeCL();
@@ -573,6 +666,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
573
666
  return true; // Will be handled by pageNumber
574
667
  if (!this.isEmptyText((_b = parent === null || parent === void 0 ? void 0 : parent.value) === null || _b === void 0 ? void 0 : _b.marginNumber))
575
668
  return true; // Will be handled by marginNumber
669
+ this.writeNL_IfNotChain(route);
576
670
  this.writeOPC();
577
671
  this.textGenerator.generateSync((_d = (_c = parent === null || parent === void 0 ? void 0 : parent.value) === null || _c === void 0 ? void 0 : _c.item) !== null && _d !== void 0 ? _d : '', TextFormat.bitmarkMinusMinus);
578
672
  this.writeCL();
@@ -590,6 +684,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
590
684
  return false; // Ignore empty
591
685
  if (!this.isEmptyText((_a = parent === null || parent === void 0 ? void 0 : parent.value) === null || _a === void 0 ? void 0 : _a.marginNumber))
592
686
  return true; // Will be handled by marginNumber
687
+ this.writeNL_IfNotChain(route);
593
688
  this.writeOPC();
594
689
  this.textGenerator.generateSync((_c = (_b = parent === null || parent === void 0 ? void 0 : parent.value) === null || _b === void 0 ? void 0 : _b.item) !== null && _c !== void 0 ? _c : '', TextFormat.bitmarkMinusMinus);
595
690
  this.writeCL();
@@ -608,6 +703,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
608
703
  const parent = this.getParentNode(route);
609
704
  if (this.isEmptyText(marginNumber))
610
705
  return false; // Ignore empty
706
+ this.writeNL_IfNotChain(route);
611
707
  this.writeOPC();
612
708
  this.textGenerator.generateSync((_b = (_a = parent === null || parent === void 0 ? void 0 : parent.value) === null || _a === void 0 ? void 0 : _a.item) !== null && _b !== void 0 ? _b : '', TextFormat.bitmarkMinusMinus);
613
709
  this.writeCL();
@@ -630,7 +726,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
630
726
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue && (parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.cardBitsValue)
631
727
  return true;
632
728
  this.inTag = false;
633
- // always write a NL before the body content if there is any?
729
+ // Always write a NL before the body content if there is any (see Handle body)
634
730
  const body = node.value;
635
731
  const textFormat = this.getTextFormat(route);
636
732
  const isBitmarkText = textFormat === TextFormat.bitmarkPlusPlus || textFormat === TextFormat.bitmarkMinusMinus;
@@ -640,7 +736,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
640
736
  if (Array.isArray(json) || ObjectUtils.isObject(json)) {
641
737
  const text = JSON.stringify(json, null, this.prettifySpace);
642
738
  if (text) {
643
- this.writeNL();
644
739
  this.writePlainTextDivider();
645
740
  this.writeNL();
646
741
  this.write(Breakscape.breakscape(text, {
@@ -661,27 +756,15 @@ class BitmarkGenerator extends AstWalkerGenerator {
661
756
  }
662
757
  else {
663
758
  // handle plain text
664
- this.writeNL();
665
759
  this.writePlainTextDivider();
666
760
  this.writeNL();
667
761
  const s = (StringUtils.isString(body.body) ? body.body : '');
668
762
  this.write(Breakscape.breakscape(`${s}`, {
669
763
  textFormat: TextFormat.text,
670
764
  }));
671
- this.writeNL();
672
765
  }
673
766
  // Stop traversal of this branch
674
767
  return false;
675
- // if ((body.body && body.body.length > 0) || body.bodyJson) {
676
- // this.writeNL();
677
- // // Write the plain text divider if not bitmark++/-- format
678
- // const textFormat = this.getTextFormat(route);
679
- // const isBitmarkText = textFormat === TextFormat.bitmarkPlusPlus || textFormat === TextFormat.bitmarkMinusMinus;
680
- // if (!isBitmarkText) {
681
- // this.writePlainTextDivider();
682
- // this.writeNL();
683
- // }
684
- // }
685
768
  }
686
769
  exit_body(_node, _route) {
687
770
  this.inTag = true;
@@ -747,6 +830,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
747
830
  const isBitmarkText = textFormat === TextFormat.bitmarkPlusPlus || textFormat === TextFormat.bitmarkMinusMinus;
748
831
  if (isBitmarkText) {
749
832
  // handle bitmark text
833
+ this.writeNL();
750
834
  this.write('==== footer ====');
751
835
  this.writeNL();
752
836
  // The text generator will write to the writer
@@ -841,7 +925,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
841
925
  if (!this.isCardAllowed(route))
842
926
  return true;
843
927
  this.writeCardSetStart();
844
- this.writeNL();
845
928
  // Continue traversal
846
929
  return true;
847
930
  }
@@ -849,41 +932,27 @@ class BitmarkGenerator extends AstWalkerGenerator {
849
932
  // Ignore cards if not allowed
850
933
  if (!this.isCardAllowed(route))
851
934
  return;
852
- this.writeNL();
853
935
  this.writeCardSetCardDivider();
854
- this.writeNL();
855
936
  }
856
937
  exit_cardNode(_node, route) {
857
938
  // Ignore cards if not allowed
858
939
  if (!this.isCardAllowed(route))
859
940
  return;
860
- this.writeNL();
861
941
  this.writeCardSetEnd();
862
942
  if (this.options.cardSetVersion === CardSetVersion.v1) {
863
- this.writeNL();
943
+ // this.writeNL();
864
944
  }
865
945
  }
866
- // bitmarkAst -> bits -> bitsValue -> cardNode -> cardBitsValue
867
- between_cardBitsValue(_node, _left, _right, _route) {
868
- this.writeNL();
869
- }
870
946
  // bitmarkAst -> bits -> bitsValue -> cardNode -> elements
871
947
  enter_elements(_node, _route) {
872
948
  //
873
949
  }
874
950
  between_elements(_node, _left, _right, _route) {
875
- this.writeNL();
876
951
  this.writeCardSetVariantDivider();
877
- this.writeNL();
878
- }
879
- exit_elements(_node, _route) {
880
- //
881
952
  }
882
953
  // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards
883
954
  between_flashcards(_node, _left, _right, _route) {
884
- this.writeNL();
885
955
  this.writeCardSetCardDivider();
886
- this.writeNL();
887
956
  }
888
957
  // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue
889
958
  between_flashcardsValue(_node, _left, right, route) {
@@ -892,67 +961,19 @@ class BitmarkGenerator extends AstWalkerGenerator {
892
961
  if (!this.isCardAllowed(route))
893
962
  return;
894
963
  if (right.key === NodeType.answer) {
895
- this.writeNL();
896
964
  this.writeCardSetSideDivider();
897
- this.writeNL();
898
965
  }
899
966
  else if (right.key === NodeType.alternativeAnswers && ((_a = right.value) === null || _a === void 0 ? void 0 : _a.length) !== 0) {
900
- this.writeNL();
901
967
  this.writeCardSetVariantDivider();
902
- this.writeNL();
903
968
  }
904
969
  }
905
- // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue -> answer
906
- enter_answer(node, route) {
907
- // Ignore responses that are not at the flashcardsValue level as they are handled elsewhere
908
- const parent = this.getParentNode(route);
909
- if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.flashcardsValue)
910
- return true;
911
- if (node.value) {
912
- this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
913
- }
914
- // Stop traversal of this branch
915
- return false;
916
- }
917
970
  // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue -> alternativeAnswers
918
971
  between_alternativeAnswers(_node, _route) {
919
- this.writeNL();
920
972
  this.writeCardSetVariantDivider();
921
- this.writeNL();
922
- }
923
- // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue -> alternativeAnswers -> alternativeAnswersValue
924
- enter_alternativeAnswersValue(node, route) {
925
- // Ignore responses that are not at the alternativeAnswers level as they are handled elsewhere
926
- const parent = this.getParentNode(route);
927
- if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.alternativeAnswers)
928
- return true;
929
- if (node.value) {
930
- // this.writeBreakscapedTagString(node.value);
931
- this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
932
- }
933
- // Stop traversal of this branch
934
- return false;
935
973
  }
936
974
  // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> alternativeDefintions
937
975
  between_alternativeDefinitions(_node, _route) {
938
- this.writeNL();
939
976
  this.writeCardSetVariantDivider();
940
- this.writeNL();
941
- }
942
- // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> alternativeDefinitions -> alternativeDefinitionsValue
943
- enter_alternativeDefinitionsValue(node, route) {
944
- // Ignore responses that are not at the alternativeAnswers level as they are handled elsewhere
945
- const parent = this.getParentNode(route);
946
- if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.alternativeDefinitions)
947
- return true;
948
- if (node.value) {
949
- // this.writeNL();
950
- // this.writeCardSetVariantDivider();
951
- // this.writeNL();
952
- this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
953
- }
954
- // Stop traversal of this branch
955
- return false;
956
977
  }
957
978
  // bitmarkAst -> bits -> bitsValue -> cardNode -> statements
958
979
  enter_statements(_node, _route) {
@@ -961,17 +982,13 @@ class BitmarkGenerator extends AstWalkerGenerator {
961
982
  between_statements(_node, _left, _right, route) {
962
983
  const isTrueFalse1 = this.isOfBitType(route, BitType.trueFalse1);
963
984
  if (!isTrueFalse1) {
964
- this.writeNL();
965
985
  this.writeCardSetCardDivider();
966
986
  }
967
- this.writeNL();
968
- }
969
- exit_statements(_node, _route) {
970
- //
971
987
  }
972
988
  // bitmarkAst -> bits -> bitsValue -> cardNode -> statements -> statementsValue
973
989
  enter_statementsValue(node, _route) {
974
990
  const statement = node.value;
991
+ this.writeNL();
975
992
  if (statement.isCorrect) {
976
993
  this.writeOPP();
977
994
  }
@@ -983,19 +1000,13 @@ class BitmarkGenerator extends AstWalkerGenerator {
983
1000
  // Continue traversal
984
1001
  return true;
985
1002
  }
986
- // bitmarkAst -> bits -> bitsValue -> choices
987
- // bitmarkAst -> bits -> bitsValue -> cardNode -> quizzes -> quizzesValue -> choices
988
- between_choices(_node, _left, _right, _route) {
989
- this.writeNL();
990
- }
991
- exit_choices(_node, _route) {
992
- this.writeNL();
993
- }
994
1003
  // bitmarkAst -> bits -> bitsValue -> choices -> choicesValue
995
1004
  // bitmarkAst -> bits -> bitsValue -> cardNode -> quizzes -> quizzesValue -> choices -> choicesValue
1005
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> feedbacks -> feedbacksValue -> choices -> choicesValue
996
1006
  enter_choicesValue(node, _route) {
997
1007
  const choice = node.value;
998
- if (choice.isCorrect) {
1008
+ this.writeNL();
1009
+ if (choice.isCorrect || choice.requireReason) {
999
1010
  this.writeOPP();
1000
1011
  }
1001
1012
  else {
@@ -1006,18 +1017,11 @@ class BitmarkGenerator extends AstWalkerGenerator {
1006
1017
  // Continue traversal
1007
1018
  return true;
1008
1019
  }
1009
- // bitmarkAst -> bits -> bitsValue -> responses
1010
- // bitmarkAst -> bits -> bitsValue -> cardNode -> quizzes -> quizzesValue -> responses
1011
- between_responses(_node, _left, _right, _route) {
1012
- this.writeNL();
1013
- }
1014
- exit_responses(_node, _route) {
1015
- this.writeNL();
1016
- }
1017
1020
  // bitmarkAst -> bits -> bitsValue -> responses -> responsesValue
1018
1021
  // bitmarkAst -> bits -> bitsValue -> cardNode -> quizzes -> quizzesValue -> responses -> responsesValue
1019
1022
  enter_responsesValue(node, _route) {
1020
1023
  const response = node.value;
1024
+ this.writeNL();
1021
1025
  if (response.isCorrect) {
1022
1026
  this.writeOPP();
1023
1027
  }
@@ -1029,23 +1033,22 @@ class BitmarkGenerator extends AstWalkerGenerator {
1029
1033
  // Continue traversal
1030
1034
  return true;
1031
1035
  }
1036
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> feedbacks
1037
+ between_feedbacks(_node, _left, _right, _route) {
1038
+ this.writeCardSetCardDivider();
1039
+ }
1040
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> feedbacks -> feedbacksValue -> reason
1041
+ enter_reason(_node, _route) {
1042
+ this.writeCardSetSideDivider();
1043
+ // Continue traversal
1044
+ return true;
1045
+ }
1032
1046
  // bitmarkAst -> bits -> bitsValue -> cardNode -> quizzes
1033
1047
  enter_quizzes(_node, _route) {
1034
1048
  //
1035
1049
  }
1036
1050
  between_quizzes(_node, _left, _right, _route) {
1037
- // this.writeNL();
1038
1051
  this.writeCardSetCardDivider();
1039
- this.writeNL();
1040
- }
1041
- exit_quizzes(_node, _route) {
1042
- //
1043
- }
1044
- // bitmarkAst -> bits -> bitsValue -> cardNode -> quizzes -> quizzesValue
1045
- between_quizzesValue(_node, _left, right, _route) {
1046
- if (right.key === NodeType.choices || right.key === NodeType.responses) {
1047
- this.writeNL();
1048
- }
1049
1052
  }
1050
1053
  // bitmarkAst -> bits -> bitsValue -> cardNode -> heading
1051
1054
  enter_heading(_node, _route) {
@@ -1055,12 +1058,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1055
1058
  // Ignore cards if not allowed
1056
1059
  if (!this.isCardAllowed(route))
1057
1060
  return;
1058
- this.writeNL();
1059
1061
  this.writeCardSetSideDivider();
1060
- this.writeNL();
1061
- }
1062
- exit_heading(_node, _route) {
1063
- //
1064
1062
  }
1065
1063
  // bitmarkAst -> bits -> bitsValue -> cardNode -> heading -> forValues
1066
1064
  enter_forValues(_node, _route) {
@@ -1070,33 +1068,20 @@ class BitmarkGenerator extends AstWalkerGenerator {
1070
1068
  // Ignore cards if not allowed
1071
1069
  if (!this.isCardAllowed(route))
1072
1070
  return;
1073
- this.writeNL();
1074
1071
  this.writeCardSetSideDivider();
1075
- this.writeNL();
1076
- }
1077
- exit_forValues(_node, _route) {
1078
- //
1079
1072
  }
1080
1073
  // bitmarkAst -> bits -> bitsValue -> cardNode -> pairs
1081
1074
  enter_pairs(_node, _route) {
1082
1075
  //
1083
1076
  }
1084
1077
  between_pairs(_node, _left, _right, _route) {
1085
- this.writeNL();
1086
1078
  this.writeCardSetCardDivider();
1087
- this.writeNL();
1088
- }
1089
- exit_pairs(_node, _route) {
1090
- //
1091
- }
1092
- // bitmarkAst -> bits -> bitsValue -> cardNode -> pairs -> pairsValue
1093
- between_pairsValue(_node, _left, _right, _route) {
1094
- //
1095
1079
  }
1096
1080
  // bitmarkAst -> bits -> bitsValue -> cardNode -> pairs -> pairsValue -> keyAudio
1097
1081
  enter_keyAudio(node, _route) {
1098
1082
  const resource = node.value;
1099
1083
  // This is a resource, so handle it with the common code
1084
+ this.writeNL();
1100
1085
  this.writeResource(ResourceTag.audio, resource.src);
1101
1086
  // Stop traversal of this branch
1102
1087
  return false;
@@ -1105,6 +1090,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1105
1090
  enter_keyImage(node, _route) {
1106
1091
  const resource = node.value;
1107
1092
  // This is a resource, so handle it with the common code
1093
+ this.writeNL();
1108
1094
  this.writeResource(ResourceTag.image, resource.src);
1109
1095
  // Stop traversal of this branch
1110
1096
  return false;
@@ -1114,16 +1100,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1114
1100
  //
1115
1101
  }
1116
1102
  between_matrix(_node, _left, _right, _route) {
1117
- this.writeNL();
1118
1103
  this.writeCardSetCardDivider();
1119
- this.writeNL();
1120
- }
1121
- exit_matrix(_node, _route) {
1122
- //
1123
- }
1124
- // bitmarkAst -> bits -> bitsValue -> cardNode -> matrix -> matrixValue
1125
- between_matrixValue(_node, _left, _right, _route) {
1126
- //
1127
1104
  }
1128
1105
  // bitmarkAst -> bits -> bitsValue -> cardNode -> pairs -> pairsValue -> values
1129
1106
  // bitmarkAst -> bits -> bitsValue -> cardNode -> matrix -> matrixValue -> cells -> cellsValue -> values
@@ -1131,17 +1108,13 @@ class BitmarkGenerator extends AstWalkerGenerator {
1131
1108
  // Ignore cards if not allowed
1132
1109
  if (!this.isCardAllowed(route))
1133
1110
  return;
1134
- this.writeNL();
1135
1111
  this.writeCardSetSideDivider();
1136
- this.writeNL();
1137
1112
  }
1138
1113
  between_values(_node, _left, _right, route) {
1139
1114
  // Ignore cards if not allowed
1140
1115
  if (!this.isCardAllowed(route))
1141
1116
  return;
1142
- this.writeNL();
1143
1117
  this.writeCardSetVariantDivider();
1144
- this.writeNL();
1145
1118
  }
1146
1119
  // bitmarkAst -> bits -> bitsValue -> cardNode -> pronunciationTable
1147
1120
  between_pronunciationTable(_node, _left, _right, route) {
@@ -1151,9 +1124,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1151
1124
  // Ignore cards if not allowed
1152
1125
  if (!this.isCardAllowed(route))
1153
1126
  return;
1154
- this.writeNL();
1155
1127
  this.writeCardSetCardDivider();
1156
- this.writeNL();
1157
1128
  }
1158
1129
  // bitmarkAst -> bits -> bitsValue -> cardNode -> table
1159
1130
  between_table(_node, _left, _right, route) {
@@ -1163,9 +1134,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1163
1134
  // Ignore cards if not allowed
1164
1135
  if (!this.isCardAllowed(route))
1165
1136
  return;
1166
- this.writeNL();
1167
1137
  this.writeCardSetCardDivider();
1168
- this.writeNL();
1169
1138
  }
1170
1139
  // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> data
1171
1140
  // bitmarkAst -> bits -> bitsValue -> cardNode -> pronunciationTable -> data
@@ -1173,9 +1142,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1173
1142
  const parent = this.getParentNode(route);
1174
1143
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.table && (parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.pronunciationTable)
1175
1144
  return;
1176
- this.writeNL();
1177
1145
  this.writeCardSetCardDivider();
1178
- this.writeNL();
1179
1146
  }
1180
1147
  // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> columns
1181
1148
  // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> columns
@@ -1187,19 +1154,19 @@ class BitmarkGenerator extends AstWalkerGenerator {
1187
1154
  // Ignore cards if not allowed
1188
1155
  if (!this.isCardAllowed(route))
1189
1156
  return;
1190
- this.writeNL();
1191
1157
  this.writeCardSetSideDivider();
1192
- this.writeNL();
1193
1158
  }
1194
1159
  // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> columns -> columnsValue
1195
1160
  // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> columns -> columnsValue
1196
1161
  leaf_columnsValue(node, _route) {
1162
+ this.writeNL();
1197
1163
  this.writeOPHASH();
1198
1164
  if (node.value)
1199
1165
  this.writeBreakscapedTagString(node.value);
1200
1166
  this.writeCL();
1201
1167
  }
1202
1168
  enter_columnsValue(node, _route) {
1169
+ this.writeNL();
1203
1170
  this.writeOPHASH();
1204
1171
  if (node.value) {
1205
1172
  this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
@@ -1215,15 +1182,14 @@ class BitmarkGenerator extends AstWalkerGenerator {
1215
1182
  // Ignore cards if not allowed
1216
1183
  if (!this.isCardAllowed(route))
1217
1184
  return;
1218
- this.writeNL();
1219
1185
  this.writeCardSetSideDivider();
1220
- this.writeNL();
1221
1186
  }
1222
1187
  // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> data -> dataValue -> dataValueValue
1223
1188
  leaf_dataValueValue(node, route) {
1224
1189
  const parent = this.getParentNode(route, 3);
1225
1190
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.table)
1226
1191
  return;
1192
+ this.writeNL();
1227
1193
  this.write(node.value);
1228
1194
  }
1229
1195
  // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> data -> dataValue -> dataValueValue
@@ -1239,17 +1205,18 @@ class BitmarkGenerator extends AstWalkerGenerator {
1239
1205
  // Pronunciation Table
1240
1206
  const cell = node.value;
1241
1207
  if (cell.title) {
1208
+ this.writeNL();
1242
1209
  this.writeOP();
1243
1210
  this.writeHash();
1244
1211
  this.textGenerator.generateSync(cell.title, TextFormat.bitmarkMinusMinus);
1245
1212
  this.writeCL();
1246
- this.writeNL();
1247
1213
  }
1248
1214
  if (cell.audio) {
1249
- this.writeResource(ResourceTag.audio, cell.audio.src);
1250
1215
  this.writeNL();
1216
+ this.writeResource(ResourceTag.audio, cell.audio.src);
1251
1217
  }
1252
1218
  if (cell.body) {
1219
+ this.writeNL();
1253
1220
  this.textGenerator.generateSync(cell.body, textFormat);
1254
1221
  }
1255
1222
  // Stop traversal of this branch
@@ -1257,6 +1224,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1257
1224
  }
1258
1225
  else {
1259
1226
  // Table
1227
+ this.writeNL();
1260
1228
  this.textGenerator.generateSync(node.value, textFormat);
1261
1229
  }
1262
1230
  }
@@ -1267,38 +1235,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1267
1235
  const parent = this.getParentNode(route);
1268
1236
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.cardNode)
1269
1237
  return;
1270
- this.writeNL();
1271
1238
  this.writeCardSetCardDivider();
1272
- this.writeNL();
1273
- }
1274
- // // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions
1275
- // protected between_definitions(_node: NodeInfo, _left: NodeInfo, _right: NodeInfo, route: NodeInfo[]): void {
1276
- // const parent = this.getParentNode(route);
1277
- // if (parent?.key !== NodeType.captionDefinitionList) return;
1278
- // this.writeNL();
1279
- // this.writeCardSetCardDivider();
1280
- // this.writeNL();
1281
- // }
1282
- // // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions -> definitionsValue
1283
- // protected between_definitionsValue(_node: NodeInfo, _left: NodeInfo, _right: NodeInfo, route: NodeInfo[]): void {
1284
- // const parent = this.getParentNode(route);
1285
- // if (parent?.key !== NodeType.definitions) return;
1286
- // // Ignore cards if not allowed
1287
- // if (!this.isCardAllowed(route)) return;
1288
- // this.writeNL();
1289
- // this.writeCardSetSideDivider();
1290
- // this.writeNL();
1291
- // }
1292
- // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> term
1293
- enter_term(node, route) {
1294
- const parent = this.getParentNode(route);
1295
- if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.definitionsValue)
1296
- return true;
1297
- if (node.value) {
1298
- this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
1299
- }
1300
- // Stop traversal of this branch
1301
- return false;
1302
1239
  }
1303
1240
  // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions -> definitionsValue -> term
1304
1241
  leaf_term(node, route) {
@@ -1306,28 +1243,19 @@ class BitmarkGenerator extends AstWalkerGenerator {
1306
1243
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.definitionsValue)
1307
1244
  return true;
1308
1245
  if (node.value) {
1246
+ this.writeNL();
1309
1247
  this.write(node.value);
1310
1248
  }
1311
1249
  // Stop traversal of this branch
1312
1250
  return false;
1313
1251
  }
1314
- // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> definition
1315
- enter_definition(node, route) {
1316
- const parent = this.getParentNode(route);
1317
- if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.definitionsValue)
1318
- return true;
1319
- if (node.value) {
1320
- this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
1321
- }
1322
- // Stop traversal of this branch
1323
- return false;
1324
- }
1325
1252
  // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions -> definitionsValue -> definition
1326
1253
  leaf_definition(node, route) {
1327
1254
  const parent = this.getParentNode(route);
1328
1255
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.definitionsValue)
1329
1256
  return true;
1330
1257
  if (node.value) {
1258
+ this.writeNL();
1331
1259
  this.write(node.value);
1332
1260
  }
1333
1261
  // Stop traversal of this branch
@@ -1339,9 +1267,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1339
1267
  const parent = this.getParentNode(route);
1340
1268
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.cardNode && (parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.captionDefinitionList)
1341
1269
  return;
1342
- this.writeNL();
1343
1270
  this.writeCardSetCardDivider();
1344
- this.writeNL();
1345
1271
  }
1346
1272
  // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue
1347
1273
  between_definitionsValue(_node, _left, right, route) {
@@ -1353,75 +1279,37 @@ class BitmarkGenerator extends AstWalkerGenerator {
1353
1279
  if (!this.isCardAllowed(route))
1354
1280
  return;
1355
1281
  if (right.key === NodeType.definition) {
1356
- this.writeNL();
1357
1282
  this.writeCardSetSideDivider();
1358
- this.writeNL();
1359
1283
  }
1360
1284
  else if (right.key === NodeType.alternativeDefinitions && ((_a = right.value) === null || _a === void 0 ? void 0 : _a.length) > 0) {
1361
- this.writeNL();
1362
1285
  this.writeCardSetVariantDivider();
1363
- this.writeNL();
1364
1286
  }
1365
1287
  }
1366
- // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions -> definitionsValue
1367
- // protected between_definitionsValue(_node: NodeInfo, _left: NodeInfo, right: NodeInfo, route: NodeInfo[]): void {
1368
- // const parent = this.getParentNode(route);
1369
- // if (parent?.key !== NodeType.definitions) return;
1370
- // // Ignore cards if not allowed
1371
- // if (!this.isCardAllowed(route)) return;
1372
- // if (right.key === NodeType.definition) {
1373
- // this.writeNL();
1374
- // this.writeCardSetSideDivider();
1375
- // this.writeNL();
1376
- // } else if (right.key === NodeType.alternativeDefinitions && right.value?.length > 0) {
1377
- // this.writeNL();
1378
- // this.writeCardSetVariantDivider();
1379
- // this.writeNL();
1380
- // }
1381
- // }
1382
1288
  // bitmarkAst -> bits -> bitsValue -> cardNode -> questions
1383
1289
  enter_questions(_node, _route) {
1384
1290
  //
1385
1291
  }
1386
1292
  between_questions(_node, _left, _right, _route) {
1387
1293
  this.writeCardSetCardDivider();
1388
- this.writeNL();
1389
- }
1390
- exit_questions(_node, _route) {
1391
- //
1392
- }
1393
- // bitmarkAst -> bits -> bitsValue -> cardNode -> questions -> questionsValue
1394
- between_questionsValue(node, left, right, route) {
1395
- // The following keys are combined with other keys so don't need newlines
1396
- const noNlKeys = [
1397
- //
1398
- ];
1399
- this.writeNlBetween(node, left, right, route, noNlKeys);
1400
- }
1401
- exit_questionsValue(_node, _route) {
1402
- this.writeNL();
1403
1294
  }
1404
1295
  // bitmarkAst -> bits -> bitsValue -> cardNode -> ingredients
1405
1296
  enter_ingredients(_node, _route) {
1406
1297
  //
1407
1298
  }
1408
1299
  between_ingredients(_node, _left, _right, _route) {
1409
- this.writeNL();
1410
1300
  this.writeCardSetCardDivider();
1411
- this.writeNL();
1412
- }
1413
- exit_ingredients(_node, _route) {
1414
- //
1415
1301
  }
1416
1302
  // bitmarkAst -> bits -> bitsValue -> cardNode -> ingredients -> ingredientsValue
1417
1303
  enter_ingredientsValue(node, _route) {
1418
1304
  const ingredient = node.value;
1419
1305
  if (ingredient.title != null) {
1306
+ this.writeNL();
1420
1307
  this.writeOPHASH();
1421
1308
  this.writeBreakscapedTagString(ingredient.title);
1422
1309
  this.writeCL();
1423
- this.writeNL();
1310
+ // this.writeNL();
1424
1311
  }
1312
+ this.writeNL();
1425
1313
  // [+] / [-]
1426
1314
  if (ingredient.checked) {
1427
1315
  this.writeOPP();
@@ -1465,8 +1353,10 @@ class BitmarkGenerator extends AstWalkerGenerator {
1465
1353
  ignoreEmpty: true,
1466
1354
  });
1467
1355
  // item
1468
- if (ingredient.item != null)
1356
+ if (ingredient.item != null) {
1357
+ this.writeNL();
1469
1358
  this.write(ingredient.item);
1359
+ }
1470
1360
  // Stop traversal of this branch
1471
1361
  return false;
1472
1362
  }
@@ -1476,35 +1366,20 @@ class BitmarkGenerator extends AstWalkerGenerator {
1476
1366
  }
1477
1367
  between_botResponses(_node, _left, _right, _route) {
1478
1368
  this.writeCardSetCardDivider();
1479
- this.writeNL();
1480
- }
1481
- exit_botResponses(_node, _route) {
1482
- //
1483
- }
1484
- // bitmarkAst -> bits -> bitsValue -> cardNode -> botResponses -> botResponsesValue
1485
- between_botResponsesValue(_node, _left, _right, _route) {
1486
- this.writeNL();
1487
- }
1488
- exit_botResponsesValue(_node, _route) {
1489
- this.writeNL();
1490
1369
  }
1491
1370
  // bitmarkAst -> bits -> bitsValue -> cardNode -> cardBits
1492
1371
  enter_cardBits(_node, _route) {
1493
1372
  //
1494
1373
  }
1495
1374
  between_cardBits(_node, _left, _right, _route) {
1496
- this.writeNL();
1497
1375
  this.writeCardSetCardDivider();
1498
- this.writeNL();
1499
- }
1500
- exit_cardBits(_node, _route) {
1501
- //
1502
1376
  }
1503
1377
  // bitmarkAst -> bits -> bitsValue -> cardNode -> botResponses -> botResponsesValue -> response
1504
1378
  leaf_response(node, route) {
1505
1379
  const parent = this.getParentNode(route);
1506
1380
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.botResponsesValue)
1507
1381
  return;
1382
+ this.writeNL();
1508
1383
  this.writeOPB();
1509
1384
  this.writeBreakscapedTagString(node.value);
1510
1385
  this.writeCL();
@@ -1514,6 +1389,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1514
1389
  const parent = this.getParentNode(route);
1515
1390
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.botResponsesValue)
1516
1391
  return;
1392
+ this.writeNL();
1517
1393
  this.writeProperty('reaction', node.value, {
1518
1394
  format: PropertyFormat.trimmedString,
1519
1395
  single: true,
@@ -1527,6 +1403,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1527
1403
  return;
1528
1404
  const feeback = node.value;
1529
1405
  if (feeback) {
1406
+ this.writeNL();
1530
1407
  this.write(feeback);
1531
1408
  }
1532
1409
  }
@@ -1534,12 +1411,13 @@ class BitmarkGenerator extends AstWalkerGenerator {
1534
1411
  enter_imagePlaceholder(node, _route) {
1535
1412
  const resource = node.value;
1536
1413
  // This is a resource, so handle it with the common code
1414
+ this.writeNL();
1537
1415
  this.writePropertyStyleResource(node.key, resource);
1538
1416
  // Continue traversal
1539
1417
  return true;
1540
1418
  }
1541
1419
  exit_imagePlaceholder(_node, _route) {
1542
- this.writeNL();
1420
+ // this.writeNL();
1543
1421
  }
1544
1422
  // bitmarkAst -> bits -> bitsValue -> posterImage
1545
1423
  // bitmarkAst -> bits -> bitsValue -> resource -> * -> posterImage
@@ -1638,9 +1516,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
1638
1516
  enter_book(_node, _route) {
1639
1517
  // Block standard property handling
1640
1518
  }
1641
- between_book(_node, _route) {
1642
- this.writeNL();
1643
- }
1644
1519
  enter_bookValue(node, _route) {
1645
1520
  const book = node.value;
1646
1521
  // const parent = this.getParentNode(route);
@@ -1711,10 +1586,11 @@ class BitmarkGenerator extends AstWalkerGenerator {
1711
1586
  // * -> itemLead --> item
1712
1587
  // * -> itemLead --> lead
1713
1588
  // * -> hint
1714
- enter_hint(node, _route) {
1589
+ enter_hint(node, route) {
1715
1590
  const value = node.value;
1716
1591
  const text = value;
1717
1592
  if (!this.isEmptyText(text)) {
1593
+ this.writeNL_IfNotChain(route);
1718
1594
  this.writeOPQ();
1719
1595
  this.textGenerator.generateSync(text, TextFormat.bitmarkMinusMinus);
1720
1596
  this.writeCL();
@@ -1723,10 +1599,11 @@ class BitmarkGenerator extends AstWalkerGenerator {
1723
1599
  return false;
1724
1600
  }
1725
1601
  // bitmarkAst -> bits -> bitsValue -> * -> instruction
1726
- enter_instruction(node, _route) {
1602
+ enter_instruction(node, route) {
1727
1603
  const value = node.value;
1728
1604
  const text = value;
1729
1605
  if (!this.isEmptyText(text)) {
1606
+ this.writeNL_IfNotChain(route);
1730
1607
  this.writeOPB();
1731
1608
  this.textGenerator.generateSync(text, TextFormat.bitmarkMinusMinus);
1732
1609
  this.writeCL();
@@ -1736,6 +1613,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1736
1613
  }
1737
1614
  // bitmarkAst -> bits -> bitsValue -> * -> lang
1738
1615
  enter_lang(node, _route) {
1616
+ this.writeNL();
1739
1617
  this.writeProperty('lang', node.value, {
1740
1618
  format: PropertyFormat.boolean,
1741
1619
  single: true,
@@ -1744,6 +1622,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1744
1622
  }
1745
1623
  // bitmarkAst -> bits -> bitsValue -> * -> refAuthor
1746
1624
  enter_refAuthor(node, _route) {
1625
+ this.writeNL();
1747
1626
  this.writeProperty('refAuthor', node.value, {
1748
1627
  format: PropertyFormat.trimmedString,
1749
1628
  single: false,
@@ -1752,6 +1631,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1752
1631
  }
1753
1632
  // bitmarkAst -> bits -> bitsValue -> * -> refBookTitle
1754
1633
  enter_refBookTitle(node, _route) {
1634
+ this.writeNL();
1755
1635
  this.writeProperty('refBookTitle', node.value, {
1756
1636
  format: PropertyFormat.trimmedString,
1757
1637
  single: true,
@@ -1760,6 +1640,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1760
1640
  }
1761
1641
  // bitmarkAst -> bits -> bitsValue -> * -> refPublisher
1762
1642
  enter_refPublisher(node, _route) {
1643
+ this.writeNL();
1763
1644
  this.writeProperty('refPublisher', node.value, {
1764
1645
  format: PropertyFormat.trimmedString,
1765
1646
  single: false,
@@ -1776,6 +1657,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1776
1657
  }
1777
1658
  // bitmarkAst -> bits -> bitsValue -> * -> citationStyle
1778
1659
  enter_citationStyle(node, _route) {
1660
+ this.writeNL();
1779
1661
  this.writeProperty('citationStyle', node.value, {
1780
1662
  format: PropertyFormat.trimmedString,
1781
1663
  single: true,
@@ -1792,6 +1674,8 @@ class BitmarkGenerator extends AstWalkerGenerator {
1792
1674
  const example = (_a = parent === null || parent === void 0 ? void 0 : parent.value.example) !== null && _a !== void 0 ? _a : null;
1793
1675
  // const __isDefaultExample = parent?.value.__isDefaultExample ?? false;
1794
1676
  if (example != null && example !== '') {
1677
+ // Write a newline if not in a chain
1678
+ this.writeNL_IfNotChain(route);
1795
1679
  this.writeOPA();
1796
1680
  this.writeString('example');
1797
1681
  this.writeColon();
@@ -1821,6 +1705,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1821
1705
  // bitmarkAst -> bits -> bitsValue -> elements -> elementsValue
1822
1706
  leaf_elementsValue(node, _route) {
1823
1707
  if (node.value) {
1708
+ this.writeNL();
1824
1709
  this.writeBreakscapedTagString(node.value);
1825
1710
  }
1826
1711
  }
@@ -1866,18 +1751,21 @@ class BitmarkGenerator extends AstWalkerGenerator {
1866
1751
  // bitmarkAst -> bits -> bitsValue -> * -> isCorrect
1867
1752
  // bitmarkAst -> bits -> bitsValue -> heading -> forKeys
1868
1753
  leaf_forKeys(node, _route) {
1754
+ this.writeNL();
1869
1755
  this.writeOPHASH();
1870
1756
  this.writeBreakscapedTagString(node.value);
1871
1757
  this.writeCL();
1872
1758
  }
1873
1759
  // bitmarkAst -> bits -> bitsValue -> heading -> forValues
1874
1760
  leaf_forValues(node, _route) {
1761
+ this.writeNL();
1875
1762
  this.writeOPHASH();
1876
1763
  this.writeBreakscapedTagString(node.value);
1877
1764
  this.writeCL();
1878
1765
  }
1879
1766
  // bitmarkAst -> bits -> bitsValue -> heading -> forValuesValue
1880
1767
  leaf_forValuesValue(node, _route) {
1768
+ this.writeNL();
1881
1769
  this.writeOPHASH();
1882
1770
  this.writeBreakscapedTagString(node.value);
1883
1771
  this.writeCL();
@@ -1886,6 +1774,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1886
1774
  // bitmarkAst -> bits -> bitsValue -> matrix -> matrixValue -> key
1887
1775
  leaf_key(node, _route) {
1888
1776
  if (node.value) {
1777
+ this.writeNL();
1889
1778
  this.writeBreakscapedTagString(node.value);
1890
1779
  }
1891
1780
  }
@@ -1893,6 +1782,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1893
1782
  // bitmarkAst -> bits -> bitsValue -> matrix -> matrixValue -> cells -> cellsValue -> values -> valuesValue
1894
1783
  leaf_valuesValue(node, _route) {
1895
1784
  if (node.value) {
1785
+ this.writeNL();
1896
1786
  this.writeBreakscapedTagString(node.value);
1897
1787
  }
1898
1788
  }
@@ -1904,23 +1794,10 @@ class BitmarkGenerator extends AstWalkerGenerator {
1904
1794
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.questionsValue && (parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.flashcardsValue)
1905
1795
  return;
1906
1796
  if (node.value) {
1797
+ this.writeNL();
1907
1798
  this.writeBreakscapedTagString(node.value);
1908
- // this.writeNL();
1909
1799
  }
1910
1800
  }
1911
- enter_question(node, route) {
1912
- // Ignore responses that are not at the questionsValue level as they are handled elsewhere
1913
- const parent = this.getParentNode(route);
1914
- if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.questionsValue && (parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.flashcardsValue)
1915
- return true;
1916
- if (node.value) {
1917
- this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
1918
- // this.writeString(node.value);
1919
- // this.writeNL();
1920
- }
1921
- // Stop traversal of this branch
1922
- return false;
1923
- }
1924
1801
  // bitmarkAst -> bits -> bitsValue -> statements -> text
1925
1802
  // bitmarkAst -> bits -> bitsValue -> resource -> ...
1926
1803
  // bitmarkAst -> bits -> bitsValue -> resource -> posterImage -> ...
@@ -2025,8 +1902,9 @@ class BitmarkGenerator extends AstWalkerGenerator {
2025
1902
  ignoreFalse: true,
2026
1903
  });
2027
1904
  }
2028
- enter_caption(node, _route) {
1905
+ enter_caption(node, route) {
2029
1906
  const value = node.value;
1907
+ this.writeNL_IfNotChain(route);
2030
1908
  this.writeProperty('caption', value, {
2031
1909
  format: PropertyFormat.bitmarkMinusMinus,
2032
1910
  single: true, // ??
@@ -2089,17 +1967,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
2089
1967
  //
2090
1968
  // Resources
2091
1969
  //
2092
- // bitmarkAst -> bits -> bitsValue -> resources
2093
- between_resources(_node, _left, _right, _route) {
2094
- this.writeNL();
2095
- }
2096
- exit_resources(_node, _left, _right, _route) {
2097
- this.writeNL();
2098
- }
2099
- // bitmarkAst -> bits -> bitsValue -> resourcesValue
2100
- between_resourcesValue(_node, _left, _right, _route) {
2101
- this.writeNL();
2102
- }
2103
1970
  //
2104
1971
  // Generated Node Handlers
2105
1972
  //
@@ -2134,6 +2001,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
2134
2001
  // url / src / href / app
2135
2002
  const url = resource.url || resource.src || resource.body || '';
2136
2003
  // Write the resource
2004
+ this.writeNL();
2137
2005
  this.writeResource(type, url);
2138
2006
  // Continue traversal
2139
2007
  return true;
@@ -2146,14 +2014,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
2146
2014
  /**
2147
2015
  * Generate the handlers for properties, as they are mostly the same, but not quite
2148
2016
  */
2149
- // protected enter_labelTrue(node: NodeInfo, _route: NodeInfo[],
2150
- // ): void {
2151
- // const bit = parent?.value as Bit;
2152
- // if (bit) {
2153
- // this.writeProperty('labelTrue', node.value ?? '', true);
2154
- // this.writeProperty('labelFalse', bit.labelFalse ?? '', true);
2155
- // }
2156
- // }
2157
2017
  generatePropertyHandlers() {
2158
2018
  var _a;
2159
2019
  const propertiesConfig = Config.getRawPropertiesConfig();
@@ -2180,6 +2040,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
2180
2040
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
2181
2041
  return;
2182
2042
  // Write the property
2043
+ this.writeNL(); // Only if NOT in chain (how do we know this?)
2183
2044
  this.writeProperty(propertyConfig.tag, node.value, {
2184
2045
  format: (_a = propertyConfig.format) !== null && _a !== void 0 ? _a : PropertyFormat.trimmedString,
2185
2046
  single: (_b = propertyConfig.single) !== null && _b !== void 0 ? _b : false,
@@ -2192,35 +2053,44 @@ class BitmarkGenerator extends AstWalkerGenerator {
2192
2053
  this[enterFuncName] = this[enterFuncName].bind(this);
2193
2054
  }
2194
2055
  }
2195
- writeNlBetween(node, left, _right, _route,
2196
- // The following keys are combined with other keys so don't need newlines
2197
- noNlKeys) {
2198
- const bit = node.value;
2199
- if (bit.book) {
2200
- // If the book node exists, remove the newline caused by reference as it will be bound to book
2201
- noNlKeys.push(NodeType.reference);
2202
- }
2203
- // Check if a no newline key is to the left in this 'between' callback
2204
- const noNl = (() => {
2205
- if (!this.wroteSomething || this.skipNLBetweenBitsValue) {
2206
- return true;
2207
- }
2208
- for (const keyType of noNlKeys) {
2209
- if (left.key === keyType /*|| right.key === keyType*/)
2210
- return true;
2211
- }
2212
- return false;
2213
- })();
2214
- if (!noNl) {
2215
- this.writeNL();
2216
- }
2217
- this.skipNLBetweenBitsValue = false;
2218
- this.wroteSomething = false;
2219
- }
2220
2056
  // END NODE HANDLERS
2221
2057
  //
2222
2058
  // UTILITY FUNCTIONS
2223
2059
  //
2060
+ /**
2061
+ * Check if in a chain.
2062
+ *
2063
+ * Return false if at the root of the bit or a card bit, otherwise true.
2064
+ * This is useful to determine if a newline should be written before certain properties.
2065
+ *
2066
+ * @param route
2067
+ * @returns
2068
+ */
2069
+ isChain(route) {
2070
+ const parent = this.getParentNode(route);
2071
+ // Root of bit
2072
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) === NodeType.bitsValue)
2073
+ return false;
2074
+ // Root of card bits
2075
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) === NodeType.cardBitsValue)
2076
+ return false;
2077
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) === NodeType.feedbacksValue)
2078
+ return false;
2079
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) === NodeType.quizzesValue)
2080
+ return false;
2081
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) === NodeType.pairsValue)
2082
+ return false;
2083
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) === NodeType.matrixValue)
2084
+ return false;
2085
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) === NodeType.definitionsValue)
2086
+ return false;
2087
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) === NodeType.questionsValue)
2088
+ return false;
2089
+ // Root of sub-card bits
2090
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) === NodeType.reason)
2091
+ return false;
2092
+ return true;
2093
+ }
2224
2094
  haveValidCardSet(bit) {
2225
2095
  const bitConfig = Config.getBitConfig(bit.bitType);
2226
2096
  if (!bitConfig)
@@ -2352,17 +2222,20 @@ class BitmarkGenerator extends AstWalkerGenerator {
2352
2222
  this.write('#');
2353
2223
  }
2354
2224
  writePlainTextDivider() {
2225
+ this.writeNL();
2355
2226
  this.write('==== text ====');
2356
2227
  }
2357
2228
  writeCardSetStart() {
2229
+ this.writeNL();
2358
2230
  if (this.options.cardSetVersion === CardSetVersion.v1) {
2359
- this.write('\n===');
2231
+ this.write('===');
2360
2232
  }
2361
2233
  else {
2362
- this.write('\n====');
2234
+ this.write('====');
2363
2235
  }
2364
2236
  }
2365
2237
  writeCardSetEnd() {
2238
+ this.writeNL();
2366
2239
  if (this.options.cardSetVersion === CardSetVersion.v1) {
2367
2240
  this.write('===');
2368
2241
  }
@@ -2371,6 +2244,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
2371
2244
  }
2372
2245
  }
2373
2246
  writeCardSetCardDivider() {
2247
+ this.writeNL();
2374
2248
  if (this.options.cardSetVersion === CardSetVersion.v1) {
2375
2249
  this.write('===');
2376
2250
  }
@@ -2379,6 +2253,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
2379
2253
  }
2380
2254
  }
2381
2255
  writeCardSetSideDivider() {
2256
+ this.writeNL();
2382
2257
  if (this.options.cardSetVersion === CardSetVersion.v1) {
2383
2258
  this.write('==');
2384
2259
  }
@@ -2387,6 +2262,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
2387
2262
  }
2388
2263
  }
2389
2264
  writeCardSetVariantDivider() {
2265
+ this.writeNL();
2390
2266
  if (this.options.cardSetVersion === CardSetVersion.v1) {
2391
2267
  this.write('--');
2392
2268
  }
@@ -2394,6 +2270,11 @@ class BitmarkGenerator extends AstWalkerGenerator {
2394
2270
  this.write('++');
2395
2271
  }
2396
2272
  }
2273
+ writeNL_IfNotChain(route) {
2274
+ if (!this.isChain(route)) {
2275
+ this.writeNL();
2276
+ }
2277
+ }
2397
2278
  writeNL() {
2398
2279
  if (this.options.debugGenerationInline) {
2399
2280
  this.write('\\n');
@@ -2413,7 +2294,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
2413
2294
  this.writeColon();
2414
2295
  this.writeBreakscapedTagString(src);
2415
2296
  if (resource.type === ResourceTag.article) {
2416
- this.writeNL();
2297
+ // this.writeNL();
2417
2298
  }
2418
2299
  this.writeCL();
2419
2300
  }
@@ -2427,7 +2308,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
2427
2308
  this.writeColon();
2428
2309
  this.writeBreakscapedTagString(value);
2429
2310
  if (type === ResourceTag.article) {
2430
- this.writeNL();
2311
+ // this.writeNL();
2431
2312
  }
2432
2313
  this.writeCL();
2433
2314
  }
@@ -2435,7 +2316,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
2435
2316
  writeProperty(name, values, options) {
2436
2317
  var _a;
2437
2318
  let valuesArray;
2438
- let wroteSomething = false;
2439
2319
  if (values !== undefined) {
2440
2320
  const isBitmarkText = options.format === PropertyFormat.bitmarkMinusMinus || options.format === PropertyFormat.bitmarkPlusPlus;
2441
2321
  if (isBitmarkText) {
@@ -2447,7 +2327,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
2447
2327
  this.writeColon();
2448
2328
  this.textGenerator.generateSync(values, (_a = TextFormat.fromValue(options.format)) !== null && _a !== void 0 ? _a : TextFormat.bitmarkMinusMinus);
2449
2329
  this.writeCL();
2450
- wroteSomething = true;
2451
2330
  }
2452
2331
  else {
2453
2332
  // Write any other property type
@@ -2460,7 +2339,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
2460
2339
  if (valuesArray.length > 0) {
2461
2340
  if (options.single)
2462
2341
  valuesArray = valuesArray.slice(valuesArray.length - 1);
2463
- let propertyIndex = 0;
2464
2342
  for (const val of valuesArray) {
2465
2343
  if (val !== undefined) {
2466
2344
  if (options.ignoreFalse && val === false)
@@ -2469,23 +2347,17 @@ class BitmarkGenerator extends AstWalkerGenerator {
2469
2347
  continue;
2470
2348
  if (options.ignoreEmpty && val === '')
2471
2349
  continue;
2472
- if (propertyIndex > 0)
2473
- this.writeNL();
2474
2350
  this.writeOPA();
2475
2351
  this.writeBreakscapedTagString(name);
2476
2352
  this.writeColon();
2477
2353
  this.writeBreakscapedTagString(`${val}`);
2478
2354
  this.writeCL();
2479
- wroteSomething = true;
2480
- propertyIndex++;
2355
+ // propertyIndex++;
2481
2356
  }
2482
2357
  }
2483
2358
  }
2484
2359
  } // isBitmarkText
2485
2360
  }
2486
- if (!wroteSomething) {
2487
- this.skipNLBetweenBitsValue = true;
2488
- }
2489
2361
  }
2490
2362
  writeInlineDebug(key, state) {
2491
2363
  let tag = key;
@@ -2553,8 +2425,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
2553
2425
  * @param value - The string value to be written.
2554
2426
  */
2555
2427
  write(value) {
2556
- if (value)
2557
- this.wroteSomething = true;
2558
2428
  this.writer.write(value);
2559
2429
  return this;
2560
2430
  }
@@ -2563,8 +2433,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
2563
2433
  * @param value - The line to write. When omitted, only the endOfLineString is written.
2564
2434
  */
2565
2435
  writeLine(value) {
2566
- if (value)
2567
- this.wroteSomething = true;
2568
2436
  this.writer.writeLine(value);
2569
2437
  return this;
2570
2438
  }
@@ -2574,8 +2442,6 @@ class BitmarkGenerator extends AstWalkerGenerator {
2574
2442
  * @param delimiter - An optional delimiter to be written at the end of each line, except for the last one.
2575
2443
  */
2576
2444
  writeLines(values, delimiter) {
2577
- if (values.length > 0 && values.reduce((acc, v) => (v ? true : acc), false))
2578
- this.wroteSomething = true;
2579
2445
  this.writer.writeLines(values, delimiter);
2580
2446
  return this;
2581
2447
  }