@gmb/bitmark-parser-generator 1.34.0 → 2.0.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 (317) 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 +8 -3
  4. package/dist/cjs/BitmarkParserGenerator.js.map +1 -1
  5. package/dist/cjs/ast/Ast.js +1 -0
  6. package/dist/cjs/ast/Ast.js.map +1 -1
  7. package/dist/cjs/ast/BaseBuilder.js +91 -54
  8. package/dist/cjs/ast/BaseBuilder.js.map +1 -1
  9. package/dist/cjs/ast/Builder.js +780 -377
  10. package/dist/cjs/ast/Builder.js.map +1 -1
  11. package/dist/cjs/ast/ResourceBuilder.js +516 -252
  12. package/dist/cjs/ast/ResourceBuilder.js.map +1 -1
  13. package/dist/cjs/ast/rules/NodeValidator.js +61 -22
  14. package/dist/cjs/ast/rules/NodeValidator.js.map +1 -1
  15. package/dist/cjs/ast/writer/StreamWriter.js +13 -0
  16. package/dist/cjs/ast/writer/StreamWriter.js.map +1 -1
  17. package/dist/cjs/ast/writer/StringWriter.js +13 -0
  18. package/dist/cjs/ast/writer/StringWriter.js.map +1 -1
  19. package/dist/cjs/breakscaping/Breakscape.js +122 -95
  20. package/dist/cjs/breakscaping/Breakscape.js.map +1 -1
  21. package/dist/cjs/config/raw/bits.js +24 -5
  22. package/dist/cjs/config/raw/bits.js.map +1 -1
  23. package/dist/cjs/config/raw/properties.js +7 -2
  24. package/dist/cjs/config/raw/properties.js.map +1 -1
  25. package/dist/cjs/generated/build-info.js +1 -1
  26. package/dist/cjs/generated/build-info.js.map +1 -1
  27. package/dist/cjs/generated/parser/bitmark/bitmark-peggy-parser.js +312 -262
  28. package/dist/cjs/generated/parser/bitmark/bitmark-peggy-parser.js.map +1 -1
  29. package/dist/cjs/generator/AstWalkerGenerator.js +4 -1
  30. package/dist/cjs/generator/AstWalkerGenerator.js.map +1 -1
  31. package/dist/cjs/generator/bitmark/BitmarkGenerator.js +977 -336
  32. package/dist/cjs/generator/bitmark/BitmarkGenerator.js.map +1 -1
  33. package/dist/cjs/generator/json/JsonGenerator.js +361 -1964
  34. package/dist/cjs/generator/json/JsonGenerator.js.map +1 -1
  35. package/dist/cjs/generator/text/TextGenerator.js +26 -8
  36. package/dist/cjs/generator/text/TextGenerator.js.map +1 -1
  37. package/dist/cjs/index.js.map +1 -1
  38. package/dist/cjs/model/ast/NodeType.js +64 -42
  39. package/dist/cjs/model/ast/NodeType.js.map +1 -1
  40. package/dist/cjs/model/config/enum/PropertyConfigKey.js +1 -0
  41. package/dist/cjs/model/config/enum/PropertyConfigKey.js.map +1 -1
  42. package/dist/cjs/model/enum/BitType.js +2 -2
  43. package/dist/cjs/model/enum/BitType.js.map +1 -1
  44. package/dist/cjs/model/enum/PropertyFormat.js +3 -1
  45. package/dist/cjs/model/enum/PropertyFormat.js.map +1 -1
  46. package/dist/cjs/model/enum/TextFormat.js +1 -0
  47. package/dist/cjs/model/enum/TextFormat.js.map +1 -1
  48. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserHelper.js +22 -4
  49. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserHelper.js.map +1 -1
  50. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserProcessor.js +93 -88
  51. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserProcessor.js.map +1 -1
  52. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserTypes.js +3 -1
  53. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserTypes.js.map +1 -1
  54. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserValidator.js +10 -32
  55. package/dist/cjs/parser/bitmark/peg/BitmarkPegParserValidator.js.map +1 -1
  56. package/dist/cjs/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js +255 -0
  57. package/dist/cjs/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js.map +1 -0
  58. package/dist/cjs/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js +2 -1
  59. package/dist/cjs/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js.map +1 -1
  60. package/dist/cjs/parser/bitmark/peg/contentProcessors/CardContentProcessor.js +175 -129
  61. package/dist/cjs/parser/bitmark/peg/contentProcessors/CardContentProcessor.js.map +1 -1
  62. package/dist/cjs/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js +8 -2
  63. package/dist/cjs/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js.map +1 -1
  64. package/dist/cjs/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js +61 -0
  65. package/dist/cjs/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js.map +1 -0
  66. package/dist/cjs/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js +11 -5
  67. package/dist/cjs/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js.map +1 -1
  68. package/dist/cjs/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js +21 -17
  69. package/dist/cjs/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js.map +1 -1
  70. package/dist/cjs/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js +50 -0
  71. package/dist/cjs/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js.map +1 -0
  72. package/dist/cjs/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js +2 -15
  73. package/dist/cjs/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js.map +1 -1
  74. package/dist/cjs/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js +2 -4
  75. package/dist/cjs/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js.map +1 -1
  76. package/dist/cjs/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js +4 -1
  77. package/dist/cjs/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js.map +1 -1
  78. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js +2 -4
  79. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js.map +1 -1
  80. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js +5 -5
  81. package/dist/cjs/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js.map +1 -1
  82. package/dist/cjs/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js +5 -6
  83. package/dist/cjs/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js.map +1 -1
  84. package/dist/cjs/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js +23 -7
  85. package/dist/cjs/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js.map +1 -1
  86. package/dist/cjs/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js +5 -5
  87. package/dist/cjs/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js.map +1 -1
  88. package/dist/cjs/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js +3 -2
  89. package/dist/cjs/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js.map +1 -1
  90. package/dist/cjs/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js +19 -8
  91. package/dist/cjs/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js.map +1 -1
  92. package/dist/cjs/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js +4 -6
  93. package/dist/cjs/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js.map +1 -1
  94. package/dist/cjs/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js +4 -5
  95. package/dist/cjs/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js.map +1 -1
  96. package/dist/cjs/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js +14 -5
  97. package/dist/cjs/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js.map +1 -1
  98. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js +37 -21
  99. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js.map +1 -1
  100. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js +3 -2
  101. package/dist/cjs/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js.map +1 -1
  102. package/dist/cjs/parser/json/JsonParser.js +73 -759
  103. package/dist/cjs/parser/json/JsonParser.js.map +1 -1
  104. package/dist/cjs/parser/text/TextParser.js +75 -1
  105. package/dist/cjs/parser/text/TextParser.js.map +1 -1
  106. package/dist/cjs/utils/BitUtils.js +15 -13
  107. package/dist/cjs/utils/BitUtils.js.map +1 -1
  108. package/dist/cjs/utils/StringUtils.js +40 -0
  109. package/dist/cjs/utils/StringUtils.js.map +1 -1
  110. package/dist/esm/BitmarkParserGenerator.js +8 -3
  111. package/dist/esm/BitmarkParserGenerator.js.map +1 -1
  112. package/dist/esm/ast/Ast.js +1 -0
  113. package/dist/esm/ast/Ast.js.map +1 -1
  114. package/dist/esm/ast/BaseBuilder.js +91 -54
  115. package/dist/esm/ast/BaseBuilder.js.map +1 -1
  116. package/dist/esm/ast/Builder.js +780 -377
  117. package/dist/esm/ast/Builder.js.map +1 -1
  118. package/dist/esm/ast/ResourceBuilder.js +516 -252
  119. package/dist/esm/ast/ResourceBuilder.js.map +1 -1
  120. package/dist/esm/ast/rules/NodeValidator.js +61 -22
  121. package/dist/esm/ast/rules/NodeValidator.js.map +1 -1
  122. package/dist/esm/ast/writer/StreamWriter.js +13 -0
  123. package/dist/esm/ast/writer/StreamWriter.js.map +1 -1
  124. package/dist/esm/ast/writer/StringWriter.js +13 -0
  125. package/dist/esm/ast/writer/StringWriter.js.map +1 -1
  126. package/dist/esm/breakscaping/Breakscape.js +122 -95
  127. package/dist/esm/breakscaping/Breakscape.js.map +1 -1
  128. package/dist/esm/config/raw/bits.js +24 -5
  129. package/dist/esm/config/raw/bits.js.map +1 -1
  130. package/dist/esm/config/raw/properties.js +7 -2
  131. package/dist/esm/config/raw/properties.js.map +1 -1
  132. package/dist/esm/generated/build-info.js +1 -1
  133. package/dist/esm/generated/build-info.js.map +1 -1
  134. package/dist/esm/generated/parser/bitmark/bitmark-peggy-parser.js +312 -262
  135. package/dist/esm/generated/parser/bitmark/bitmark-peggy-parser.js.map +1 -1
  136. package/dist/esm/generator/AstWalkerGenerator.js +4 -1
  137. package/dist/esm/generator/AstWalkerGenerator.js.map +1 -1
  138. package/dist/esm/generator/bitmark/BitmarkGenerator.js +977 -336
  139. package/dist/esm/generator/bitmark/BitmarkGenerator.js.map +1 -1
  140. package/dist/esm/generator/json/JsonGenerator.js +361 -1964
  141. package/dist/esm/generator/json/JsonGenerator.js.map +1 -1
  142. package/dist/esm/generator/text/TextGenerator.js +26 -8
  143. package/dist/esm/generator/text/TextGenerator.js.map +1 -1
  144. package/dist/esm/index.js.map +1 -1
  145. package/dist/esm/model/ast/NodeType.js +64 -42
  146. package/dist/esm/model/ast/NodeType.js.map +1 -1
  147. package/dist/esm/model/config/enum/PropertyConfigKey.js +1 -0
  148. package/dist/esm/model/config/enum/PropertyConfigKey.js.map +1 -1
  149. package/dist/esm/model/enum/BitType.js +2 -2
  150. package/dist/esm/model/enum/BitType.js.map +1 -1
  151. package/dist/esm/model/enum/PropertyFormat.js +3 -1
  152. package/dist/esm/model/enum/PropertyFormat.js.map +1 -1
  153. package/dist/esm/model/enum/TextFormat.js +1 -0
  154. package/dist/esm/model/enum/TextFormat.js.map +1 -1
  155. package/dist/esm/parser/bitmark/peg/BitmarkPegParserHelper.js +22 -4
  156. package/dist/esm/parser/bitmark/peg/BitmarkPegParserHelper.js.map +1 -1
  157. package/dist/esm/parser/bitmark/peg/BitmarkPegParserProcessor.js +93 -88
  158. package/dist/esm/parser/bitmark/peg/BitmarkPegParserProcessor.js.map +1 -1
  159. package/dist/esm/parser/bitmark/peg/BitmarkPegParserTypes.js +3 -1
  160. package/dist/esm/parser/bitmark/peg/BitmarkPegParserTypes.js.map +1 -1
  161. package/dist/esm/parser/bitmark/peg/BitmarkPegParserValidator.js +10 -32
  162. package/dist/esm/parser/bitmark/peg/BitmarkPegParserValidator.js.map +1 -1
  163. package/dist/esm/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js +252 -0
  164. package/dist/esm/parser/bitmark/peg/contentProcessors/BodyContentProcessor.js.map +1 -0
  165. package/dist/esm/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js +2 -1
  166. package/dist/esm/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.js.map +1 -1
  167. package/dist/esm/parser/bitmark/peg/contentProcessors/CardContentProcessor.js +175 -129
  168. package/dist/esm/parser/bitmark/peg/contentProcessors/CardContentProcessor.js.map +1 -1
  169. package/dist/esm/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js +8 -2
  170. package/dist/esm/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.js.map +1 -1
  171. package/dist/esm/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js +58 -0
  172. package/dist/esm/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.js.map +1 -0
  173. package/dist/esm/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js +11 -5
  174. package/dist/esm/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.js.map +1 -1
  175. package/dist/esm/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js +21 -17
  176. package/dist/esm/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.js.map +1 -1
  177. package/dist/esm/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js +47 -0
  178. package/dist/esm/parser/bitmark/peg/contentProcessors/FooterContentProcessor.js.map +1 -0
  179. package/dist/esm/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js +2 -15
  180. package/dist/esm/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.js.map +1 -1
  181. package/dist/esm/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js +2 -4
  182. package/dist/esm/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.js.map +1 -1
  183. package/dist/esm/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js +4 -1
  184. package/dist/esm/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.js.map +1 -1
  185. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js +2 -4
  186. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.js.map +1 -1
  187. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js +5 -5
  188. package/dist/esm/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.js.map +1 -1
  189. package/dist/esm/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js +5 -6
  190. package/dist/esm/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.js.map +1 -1
  191. package/dist/esm/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js +23 -7
  192. package/dist/esm/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.js.map +1 -1
  193. package/dist/esm/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js +5 -5
  194. package/dist/esm/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.js.map +1 -1
  195. package/dist/esm/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js +3 -2
  196. package/dist/esm/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.js.map +1 -1
  197. package/dist/esm/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js +19 -8
  198. package/dist/esm/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.js.map +1 -1
  199. package/dist/esm/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js +4 -6
  200. package/dist/esm/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.js.map +1 -1
  201. package/dist/esm/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js +4 -5
  202. package/dist/esm/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.js.map +1 -1
  203. package/dist/esm/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js +14 -5
  204. package/dist/esm/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.js.map +1 -1
  205. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js +37 -21
  206. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.js.map +1 -1
  207. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js +3 -2
  208. package/dist/esm/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.js.map +1 -1
  209. package/dist/esm/parser/json/JsonParser.js +73 -759
  210. package/dist/esm/parser/json/JsonParser.js.map +1 -1
  211. package/dist/esm/parser/text/TextParser.js +75 -1
  212. package/dist/esm/parser/text/TextParser.js.map +1 -1
  213. package/dist/esm/utils/BitUtils.js +15 -13
  214. package/dist/esm/utils/BitUtils.js.map +1 -1
  215. package/dist/esm/utils/StringUtils.js +40 -0
  216. package/dist/esm/utils/StringUtils.js.map +1 -1
  217. package/dist/types/BitmarkParserGenerator.d.ts +8 -0
  218. package/dist/types/BitmarkParserGenerator.d.ts.map +1 -1
  219. package/dist/types/ast/Ast.d.ts.map +1 -1
  220. package/dist/types/ast/BaseBuilder.d.ts +31 -21
  221. package/dist/types/ast/BaseBuilder.d.ts.map +1 -1
  222. package/dist/types/ast/Builder.d.ts +283 -435
  223. package/dist/types/ast/Builder.d.ts.map +1 -1
  224. package/dist/types/ast/ResourceBuilder.d.ts +177 -164
  225. package/dist/types/ast/ResourceBuilder.d.ts.map +1 -1
  226. package/dist/types/ast/rules/NodeValidator.d.ts +3 -2
  227. package/dist/types/ast/rules/NodeValidator.d.ts.map +1 -1
  228. package/dist/types/ast/writer/StreamWriter.d.ts +2 -0
  229. package/dist/types/ast/writer/StreamWriter.d.ts.map +1 -1
  230. package/dist/types/ast/writer/StringWriter.d.ts +2 -0
  231. package/dist/types/ast/writer/StringWriter.d.ts.map +1 -1
  232. package/dist/types/ast/writer/Writer.d.ts +6 -0
  233. package/dist/types/ast/writer/Writer.d.ts.map +1 -1
  234. package/dist/types/breakscaping/Breakscape.d.ts +6 -1
  235. package/dist/types/breakscaping/Breakscape.d.ts.map +1 -1
  236. package/dist/types/config/raw/bits.d.ts.map +1 -1
  237. package/dist/types/config/raw/properties.d.ts.map +1 -1
  238. package/dist/types/generated/parser/bitmark/bitmark-peggy-parser.d.ts.map +1 -1
  239. package/dist/types/generator/AstWalkerGenerator.d.ts.map +1 -1
  240. package/dist/types/generator/bitmark/BitmarkGenerator.d.ts +91 -55
  241. package/dist/types/generator/bitmark/BitmarkGenerator.d.ts.map +1 -1
  242. package/dist/types/generator/json/JsonGenerator.d.ts +96 -108
  243. package/dist/types/generator/json/JsonGenerator.d.ts.map +1 -1
  244. package/dist/types/generator/text/TextGenerator.d.ts +14 -2
  245. package/dist/types/generator/text/TextGenerator.d.ts.map +1 -1
  246. package/dist/types/index.d.ts +2 -2
  247. package/dist/types/index.d.ts.map +1 -1
  248. package/dist/types/model/ast/NodeType.d.ts +122 -84
  249. package/dist/types/model/ast/NodeType.d.ts.map +1 -1
  250. package/dist/types/model/ast/Nodes.d.ts +66 -436
  251. package/dist/types/model/ast/Nodes.d.ts.map +1 -1
  252. package/dist/types/model/ast/TextNodes.d.ts +1 -1
  253. package/dist/types/model/ast/TextNodes.d.ts.map +1 -1
  254. package/dist/types/model/config/enum/ConfigKey.d.ts +2 -0
  255. package/dist/types/model/config/enum/ConfigKey.d.ts.map +1 -1
  256. package/dist/types/model/config/enum/PropertyConfigKey.d.ts +3 -0
  257. package/dist/types/model/config/enum/PropertyConfigKey.d.ts.map +1 -1
  258. package/dist/types/model/enum/BitType.d.ts +4 -4
  259. package/dist/types/model/enum/PropertyFormat.d.ts +4 -2
  260. package/dist/types/model/enum/PropertyFormat.d.ts.map +1 -1
  261. package/dist/types/model/enum/PropertyTag.d.ts +2 -0
  262. package/dist/types/model/enum/PropertyTag.d.ts.map +1 -1
  263. package/dist/types/model/enum/TextFormat.d.ts +2 -0
  264. package/dist/types/model/enum/TextFormat.d.ts.map +1 -1
  265. package/dist/types/model/json/BitJson.d.ts +32 -20
  266. package/dist/types/model/json/BitJson.d.ts.map +1 -1
  267. package/dist/types/model/json/BodyBitJson.d.ts +16 -12
  268. package/dist/types/model/json/BodyBitJson.d.ts.map +1 -1
  269. package/dist/types/model/json/ResourceJson.d.ts +2 -22
  270. package/dist/types/model/json/ResourceJson.d.ts.map +1 -1
  271. package/dist/types/parser/bitmark/peg/BitmarkPegParserHelper.d.ts +4 -2
  272. package/dist/types/parser/bitmark/peg/BitmarkPegParserHelper.d.ts.map +1 -1
  273. package/dist/types/parser/bitmark/peg/BitmarkPegParserProcessor.d.ts +3 -9
  274. package/dist/types/parser/bitmark/peg/BitmarkPegParserProcessor.d.ts.map +1 -1
  275. package/dist/types/parser/bitmark/peg/BitmarkPegParserTypes.d.ts +90 -74
  276. package/dist/types/parser/bitmark/peg/BitmarkPegParserTypes.d.ts.map +1 -1
  277. package/dist/types/parser/bitmark/peg/BitmarkPegParserValidator.d.ts +2 -2
  278. package/dist/types/parser/bitmark/peg/BitmarkPegParserValidator.d.ts.map +1 -1
  279. package/dist/types/parser/bitmark/peg/contentProcessors/BodyContentProcessor.d.ts +37 -0
  280. package/dist/types/parser/bitmark/peg/contentProcessors/BodyContentProcessor.d.ts.map +1 -0
  281. package/dist/types/parser/bitmark/peg/contentProcessors/BookChainContentProcessor.d.ts.map +1 -1
  282. package/dist/types/parser/bitmark/peg/contentProcessors/CardContentProcessor.d.ts +2 -2
  283. package/dist/types/parser/bitmark/peg/contentProcessors/CardContentProcessor.d.ts.map +1 -1
  284. package/dist/types/parser/bitmark/peg/contentProcessors/ClozeTagContentProcessor.d.ts.map +1 -1
  285. package/dist/types/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.d.ts +15 -0
  286. package/dist/types/parser/bitmark/peg/contentProcessors/ContentProcessorUtils.d.ts.map +1 -0
  287. package/dist/types/parser/bitmark/peg/contentProcessors/DefaultTagContentProcessor.d.ts.map +1 -1
  288. package/dist/types/parser/bitmark/peg/contentProcessors/ExampleTagContentProcessor.d.ts.map +1 -1
  289. package/dist/types/parser/bitmark/peg/contentProcessors/FooterContentProcessor.d.ts +16 -0
  290. package/dist/types/parser/bitmark/peg/contentProcessors/FooterContentProcessor.d.ts.map +1 -0
  291. package/dist/types/parser/bitmark/peg/contentProcessors/GapChainContentProcessor.d.ts.map +1 -1
  292. package/dist/types/parser/bitmark/peg/contentProcessors/ImageSourceChainContentProcessor.d.ts.map +1 -1
  293. package/dist/types/parser/bitmark/peg/contentProcessors/ItemLeadTagContentProcessor.d.ts.map +1 -1
  294. package/dist/types/parser/bitmark/peg/contentProcessors/MarkChainContentProcessor.d.ts.map +1 -1
  295. package/dist/types/parser/bitmark/peg/contentProcessors/MarkConfigChainContentProcessor.d.ts.map +1 -1
  296. package/dist/types/parser/bitmark/peg/contentProcessors/PersonChainContentProcessor.d.ts.map +1 -1
  297. package/dist/types/parser/bitmark/peg/contentProcessors/PropertyContentProcessor.d.ts.map +1 -1
  298. package/dist/types/parser/bitmark/peg/contentProcessors/RatingLevelChainContentProcessor.d.ts.map +1 -1
  299. package/dist/types/parser/bitmark/peg/contentProcessors/ReferenceTagContentProcessor.d.ts.map +1 -1
  300. package/dist/types/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.d.ts +2 -2
  301. package/dist/types/parser/bitmark/peg/contentProcessors/ResourceContentProcessor.d.ts.map +1 -1
  302. package/dist/types/parser/bitmark/peg/contentProcessors/ServingsChainContentProcessor.d.ts.map +1 -1
  303. package/dist/types/parser/bitmark/peg/contentProcessors/TechnicalTermChainContentProcessor.d.ts.map +1 -1
  304. package/dist/types/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.d.ts +5 -2
  305. package/dist/types/parser/bitmark/peg/contentProcessors/TitleTagContentProcessor.d.ts.map +1 -1
  306. package/dist/types/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.d.ts +1 -1
  307. package/dist/types/parser/bitmark/peg/contentProcessors/TrueFalseChainContentProcessor.d.ts.map +1 -1
  308. package/dist/types/parser/bitmark/peg/contentProcessors/TrueFalseTagContentProcessor.d.ts.map +1 -1
  309. package/dist/types/parser/json/JsonParser.d.ts +9 -72
  310. package/dist/types/parser/json/JsonParser.d.ts.map +1 -1
  311. package/dist/types/parser/text/TextParser.d.ts +16 -1
  312. package/dist/types/parser/text/TextParser.d.ts.map +1 -1
  313. package/dist/types/utils/BitUtils.d.ts +8 -8
  314. package/dist/types/utils/BitUtils.d.ts.map +1 -1
  315. package/dist/types/utils/StringUtils.d.ts +24 -0
  316. package/dist/types/utils/StringUtils.d.ts.map +1 -1
  317. package/package.json +1 -1
@@ -8,19 +8,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { Ast } from '../../ast/Ast';
11
+ import { Breakscape } from '../../breakscaping/Breakscape';
11
12
  import { Config } from '../../config/Config';
12
13
  import { NodeType } from '../../model/ast/NodeType';
13
14
  import { BitType } from '../../model/enum/BitType';
14
15
  import { BitmarkVersion, DEFAULT_BITMARK_VERSION } from '../../model/enum/BitmarkVersion';
15
16
  import { BodyBitType } from '../../model/enum/BodyBitType';
16
17
  import { CardSetVersion } from '../../model/enum/CardSetVersion';
17
- import { PropertyAstKey } from '../../model/enum/PropertyAstKey';
18
+ import { PropertyFormat } from '../../model/enum/PropertyFormat';
18
19
  import { PropertyTag } from '../../model/enum/PropertyTag';
19
20
  import { ResourceTag } from '../../model/enum/ResourceTag';
20
21
  import { TextFormat } from '../../model/enum/TextFormat';
21
22
  import { BooleanUtils } from '../../utils/BooleanUtils';
22
23
  import { ObjectUtils } from '../../utils/ObjectUtils';
24
+ import { StringUtils } from '../../utils/StringUtils';
23
25
  import { AstWalkerGenerator } from '../AstWalkerGenerator';
26
+ import { TextGenerator } from '../text/TextGenerator';
24
27
  const DEFAULT_OPTIONS = {
25
28
  debugGenerationInline: false,
26
29
  };
@@ -50,6 +53,17 @@ class BitmarkGenerator extends AstWalkerGenerator {
50
53
  // State
51
54
  this.skipNLBetweenBitsValue = false;
52
55
  this.wroteSomething = false;
56
+ this.inTag = true;
57
+ // Keep TS happy
58
+ this.inTag;
59
+ // Bind callbacks
60
+ this.enter = this.enter.bind(this);
61
+ this.between = this.between.bind(this);
62
+ this.exit = this.exit.bind(this);
63
+ this.leaf = this.leaf.bind(this);
64
+ this.write = this.write.bind(this);
65
+ this.bodyBitCallback = this.bodyBitCallback.bind(this);
66
+ // Set options
53
67
  this.bitmarkVersion = (_a = BitmarkVersion.fromValue(options === null || options === void 0 ? void 0 : options.bitmarkVersion)) !== null && _a !== void 0 ? _a : DEFAULT_BITMARK_VERSION;
54
68
  this.options = Object.assign(Object.assign({}, DEFAULT_OPTIONS), options === null || options === void 0 ? void 0 : options.bitmarkOptions);
55
69
  this.debugGenerationInline = (_b = this.options.debugGenerationInline) !== null && _b !== void 0 ? _b : false;
@@ -66,11 +80,14 @@ class BitmarkGenerator extends AstWalkerGenerator {
66
80
  }
67
81
  // Calculate the prettify space
68
82
  this.prettifySpace = this.options.prettifyJson === true ? 2 : this.options.prettifyJson || undefined;
83
+ // Create the text generator
84
+ this.textGenerator = new TextGenerator(this.bitmarkVersion, {
85
+ writeCallback: this.write,
86
+ bodyBitCallback: this.bodyBitCallback,
87
+ debugGenerationInline: this.debugGenerationInline,
88
+ });
69
89
  this.writer = writer;
70
- this.enter = this.enter.bind(this);
71
- this.between = this.between.bind(this);
72
- this.exit = this.exit.bind(this);
73
- this.leaf = this.leaf.bind(this);
90
+ this.generateResourceHandlers();
74
91
  this.generatePropertyHandlers();
75
92
  }
76
93
  /**
@@ -110,6 +127,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
110
127
  resetState() {
111
128
  this.skipNLBetweenBitsValue = false;
112
129
  this.wroteSomething = false;
130
+ this.inTag = true;
113
131
  this.printed = false;
114
132
  }
115
133
  walkAndWrite(ast) {
@@ -140,12 +158,12 @@ class BitmarkGenerator extends AstWalkerGenerator {
140
158
  this.writeOPD(bit.bitLevel);
141
159
  if (bit.isCommented)
142
160
  this.writeString('|');
143
- this.writeString(bit.bitType);
161
+ this.writeBreakscapedTagString(bit.bitType);
144
162
  if (bit.textFormat) {
145
163
  const write = this.isWriteTextFormat(bit.textFormat, bitConfig.textFormatDefault);
146
164
  if (write) {
147
165
  this.writeColon();
148
- this.writeString(bit.textFormat);
166
+ this.writeBreakscapedTagString(bit.textFormat);
149
167
  }
150
168
  }
151
169
  // Use the bitConfig to see if we need to write the resourceType attachment
@@ -168,10 +186,12 @@ class BitmarkGenerator extends AstWalkerGenerator {
168
186
  }
169
187
  if (resourceType) {
170
188
  this.writeAmpersand();
171
- this.writeString(resourceType);
189
+ this.writeBreakscapedTagString(resourceType);
172
190
  }
173
191
  this.writeCL();
174
192
  this.writeNL();
193
+ // Continue traversal
194
+ return true;
175
195
  }
176
196
  between_bitsValue(node, left, right, route) {
177
197
  // The following keys are combined with other keys so don't need newlines
@@ -192,14 +212,20 @@ class BitmarkGenerator extends AstWalkerGenerator {
192
212
  // Ignore values that are not at the bit level as they might be handled elsewhere
193
213
  const parent = this.getParentNode(route);
194
214
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
195
- return;
215
+ return true;
196
216
  for (let i = 0; i < internalComment.length; i++) {
197
217
  const comment = internalComment[i];
198
218
  const last = i === internalComment.length - 1;
199
- this.writeProperty('internalComment', comment);
219
+ this.writeProperty('internalComment', comment, {
220
+ format: PropertyFormat.trimmedString,
221
+ single: false,
222
+ ignoreEmpty: true,
223
+ });
200
224
  if (!last)
201
225
  this.writeNL();
202
226
  }
227
+ // Stop traversal of this branch
228
+ return false;
203
229
  }
204
230
  // bitmarkAst -> bits -> bitsValue -> labelTrue / labelFalse
205
231
  enter_labelTrue(node, route) {
@@ -207,14 +233,24 @@ class BitmarkGenerator extends AstWalkerGenerator {
207
233
  // Ignore example that is not at the bit level as it are handled elsewhere
208
234
  const parent = this.getParentNode(route);
209
235
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
210
- return;
236
+ return true;
211
237
  const bit = parent === null || parent === void 0 ? void 0 : parent.value;
212
238
  if (bit) {
213
239
  if (value != '')
214
- this.writeProperty(PropertyTag.labelTrue, value, true);
240
+ this.writeProperty(PropertyTag.labelTrue, value, {
241
+ format: PropertyFormat.trimmedString,
242
+ single: true,
243
+ ignoreEmpty: true,
244
+ });
215
245
  if (bit.labelFalse && bit.labelFalse[0] != '')
216
- this.writeProperty(PropertyTag.labelFalse, bit.labelFalse, true);
246
+ this.writeProperty(PropertyTag.labelFalse, bit.labelFalse, {
247
+ format: PropertyFormat.trimmedString,
248
+ single: true,
249
+ ignoreEmpty: true,
250
+ });
217
251
  }
252
+ // Stop traversal of this branch
253
+ return false;
218
254
  }
219
255
  // bitmarkAst -> bits -> bitsValue -> imageSource
220
256
  enter_imageSource(node, route) {
@@ -222,19 +258,41 @@ class BitmarkGenerator extends AstWalkerGenerator {
222
258
  // Ignore values that are not at the bit level as they might be handled elsewhere
223
259
  const parent = this.getParentNode(route);
224
260
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
225
- return;
261
+ return true;
226
262
  const { url, mockupId, size, format, trim } = imageSource;
227
- this.writeProperty('imageSource', url, true);
263
+ this.writeProperty('imageSource', url, {
264
+ format: PropertyFormat.trimmedString,
265
+ single: true,
266
+ ignoreEmpty: true,
267
+ });
228
268
  if (url) {
229
269
  if (mockupId)
230
- this.writeProperty('mockupId', mockupId, true);
270
+ this.writeProperty('mockupId', mockupId, {
271
+ format: PropertyFormat.trimmedString,
272
+ single: true,
273
+ ignoreEmpty: true,
274
+ });
231
275
  if (size)
232
- this.writeProperty('size', size, true);
276
+ this.writeProperty('size', size, {
277
+ format: PropertyFormat.trimmedString,
278
+ single: true,
279
+ ignoreEmpty: true,
280
+ });
233
281
  if (format)
234
- this.writeProperty('format', format, true);
282
+ this.writeProperty('format', format, {
283
+ format: PropertyFormat.trimmedString,
284
+ single: true,
285
+ ignoreEmpty: true,
286
+ });
235
287
  if (BooleanUtils.isBoolean(trim))
236
- this.writeProperty('trim', trim, true);
288
+ this.writeProperty('trim', trim, {
289
+ format: PropertyFormat.trimmedString,
290
+ single: true,
291
+ ignoreEmpty: true,
292
+ });
237
293
  }
294
+ // Stop traversal of this branch
295
+ return false;
238
296
  }
239
297
  // bitmarkAst -> bits -> bitsValue -> technicalTerm
240
298
  enter_technicalTerm(node, route) {
@@ -242,11 +300,22 @@ class BitmarkGenerator extends AstWalkerGenerator {
242
300
  // Ignore values that are not at the bit level as they might be handled elsewhere
243
301
  const parent = this.getParentNode(route);
244
302
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
245
- return;
303
+ return true;
246
304
  const { technicalTerm, lang } = nodeValue;
247
- this.writeProperty('technicalTerm', technicalTerm, true);
248
- if (lang != null)
249
- this.writeProperty('lang', lang);
305
+ this.writeProperty('technicalTerm', technicalTerm, {
306
+ format: PropertyFormat.trimmedString,
307
+ single: true,
308
+ ignoreEmpty: true,
309
+ });
310
+ if (lang != null) {
311
+ this.writeProperty('lang', lang, {
312
+ format: PropertyFormat.trimmedString,
313
+ single: true,
314
+ ignoreEmpty: true,
315
+ });
316
+ }
317
+ // Stop traversal of this branch
318
+ return false;
250
319
  }
251
320
  // bitmarkAst -> bits -> bitsValue -> servings
252
321
  enter_servings(node, route) {
@@ -254,17 +323,52 @@ class BitmarkGenerator extends AstWalkerGenerator {
254
323
  // Ignore values that are not at the bit level as they might be handled elsewhere
255
324
  const parent = this.getParentNode(route);
256
325
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
257
- return;
258
- const { servings, unit, unitAbbr, decimalPlaces, disableCalculation } = nodeValue;
259
- this.writeProperty('servings', servings, true);
260
- if (unit != null)
261
- this.writeProperty('unit', unit);
262
- if (unitAbbr != null)
263
- this.writeProperty('unitAbbr', unitAbbr);
264
- if (decimalPlaces != null)
265
- this.writeProperty('decimalPlaces', decimalPlaces);
266
- if (disableCalculation != null)
267
- this.writeProperty('disableCalculation', disableCalculation);
326
+ return true;
327
+ const { servings, unit, unitAbbr, decimalPlaces, disableCalculation, hint } = nodeValue;
328
+ this.writeProperty('servings', servings, {
329
+ format: PropertyFormat.trimmedString,
330
+ single: true,
331
+ ignoreEmpty: true,
332
+ });
333
+ if (unit != null) {
334
+ this.writeProperty('unit', unit, {
335
+ format: PropertyFormat.trimmedString,
336
+ single: true,
337
+ ignoreEmpty: true,
338
+ });
339
+ }
340
+ if (unitAbbr != null) {
341
+ this.writeProperty('unitAbbr', unitAbbr, {
342
+ format: PropertyFormat.trimmedString,
343
+ single: true,
344
+ ignoreEmpty: true,
345
+ });
346
+ }
347
+ if (decimalPlaces != null) {
348
+ this.writeProperty('decimalPlaces', decimalPlaces, {
349
+ format: PropertyFormat.trimmedString,
350
+ single: true,
351
+ ignoreEmpty: true,
352
+ });
353
+ }
354
+ if (disableCalculation != null) {
355
+ this.writeProperty('disableCalculation', disableCalculation, {
356
+ format: PropertyFormat.trimmedString,
357
+ single: true,
358
+ ignoreEmpty: true,
359
+ });
360
+ }
361
+ if (hint != null) {
362
+ this.writeOPQ();
363
+ this.writeBreakscapedTagString(hint);
364
+ this.writeCL();
365
+ // this.writeProperty('hint', hint, {
366
+ // format: PropertyFormat.trimmedString,
367
+ // single: true,
368
+ // ignoreEmpty: true,
369
+ // });
370
+ }
371
+ return false;
268
372
  }
269
373
  // bitmarkAst -> bits -> bitsValue -> person
270
374
  enter_person(node, route) {
@@ -272,15 +376,25 @@ class BitmarkGenerator extends AstWalkerGenerator {
272
376
  // Ignore values that are not at the bit level as they might be handled elsewhere
273
377
  const parent = this.getParentNode(route);
274
378
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
275
- return;
379
+ return true;
276
380
  const { name, title, avatarImage } = person;
277
- this.writeProperty('person', name, true);
381
+ this.writeProperty('person', name, {
382
+ format: PropertyFormat.trimmedString,
383
+ single: true,
384
+ ignoreEmpty: true,
385
+ });
278
386
  if (title) {
279
- this.writeProperty('title', title, true);
387
+ this.writeProperty('title', title, {
388
+ format: PropertyFormat.trimmedString,
389
+ single: true,
390
+ ignoreEmpty: true,
391
+ });
280
392
  }
281
393
  if (avatarImage) {
282
- this.writeResource(avatarImage);
394
+ this.writeResource(ResourceTag.image, avatarImage.src);
283
395
  }
396
+ // Stop traversal of this branch
397
+ return false;
284
398
  }
285
399
  // bitmarkAst -> bits -> bitsValue -> ratingLevelStart
286
400
  enter_ratingLevelStart(node, route) {
@@ -300,45 +414,110 @@ class BitmarkGenerator extends AstWalkerGenerator {
300
414
  // Ignore values that are not at the bit level as they might be handled elsewhere
301
415
  const parent = this.getParentNode(route);
302
416
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
303
- return;
417
+ return true;
304
418
  const { level, label } = n;
305
419
  const levelKey = node.key === NodeType.ratingLevelStart ? PropertyTag.ratingLevelStart : PropertyTag.ratingLevelEnd;
306
- this.writeProperty(levelKey, level, true);
420
+ this.writeProperty(levelKey, level, {
421
+ format: PropertyFormat.trimmedString,
422
+ single: true,
423
+ ignoreEmpty: true,
424
+ });
307
425
  if (label) {
308
- this.writeProperty('label', label, true);
426
+ this.writeProperty('label', label, {
427
+ format: PropertyFormat.bitmarkMinusMinus,
428
+ single: true,
429
+ ignoreEmpty: true,
430
+ });
309
431
  }
432
+ return false;
433
+ }
434
+ // bitmarkAst -> bits -> bitsValue -> markConfig
435
+ enter_markConfig(_node, _route) {
436
+ // Handler so markConfig is not processed by the default property handler
437
+ // Continue traversal
438
+ return true;
310
439
  }
311
- // bitmarkAst -> bits -> bitsValue -> markConfigValue
440
+ // bitmarkAst -> bits -> bitsValue -> markConfig -> markConfigValue
312
441
  enter_markConfigValue(node, route) {
313
442
  const markConfig = node.value;
314
443
  // Ignore values that are not at the correct level as they might be handled elsewhere
315
444
  const parent = this.getParentNode(route);
316
445
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.markConfig)
317
- return;
446
+ return true;
318
447
  const { mark, color, emphasis } = markConfig;
319
448
  if (mark) {
320
- this.writeProperty('mark', mark, true);
321
- if (color)
322
- this.writeProperty('color', color, true);
323
- if (emphasis)
324
- this.writeProperty('emphasis', emphasis, true);
449
+ this.writeProperty('mark', mark, {
450
+ format: PropertyFormat.trimmedString,
451
+ single: true,
452
+ ignoreEmpty: true,
453
+ });
454
+ if (color) {
455
+ this.writeProperty('color', color, {
456
+ format: PropertyFormat.trimmedString,
457
+ single: true,
458
+ ignoreEmpty: true,
459
+ });
460
+ }
461
+ if (emphasis) {
462
+ this.writeProperty('emphasis', emphasis, {
463
+ format: PropertyFormat.trimmedString,
464
+ single: true,
465
+ ignoreEmpty: true,
466
+ });
467
+ }
325
468
  this.writeNL();
326
469
  }
470
+ // Stop traversal of this branch
471
+ return false;
327
472
  }
328
473
  // bitmarkAst -> bits -> bitsValue -> partialAnswer
474
+ enter_partialAnswer(node, _route) {
475
+ this.writeProperty('partialAnswer', node.value, {
476
+ format: PropertyFormat.trimmedString,
477
+ single: true,
478
+ ignoreEmpty: true,
479
+ });
480
+ // Stop traversal of this branch
481
+ return false;
482
+ }
329
483
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> partialAnswer
330
484
  leaf_partialAnswer(node, _route) {
331
- this.writeProperty('partialAnswer', node.value);
485
+ this.writeProperty('partialAnswer', node.value, {
486
+ format: PropertyFormat.trimmedString,
487
+ single: true,
488
+ ignoreEmpty: true,
489
+ });
490
+ // Stop traversal of this branch
491
+ return false;
332
492
  }
333
493
  // bitmarkAst -> bits -> bitsValue -> sampleSolution
334
494
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> sampleSolution
495
+ enter_sampleSolution(node, _route) {
496
+ this.writeProperty('sampleSolution', node.value, {
497
+ format: PropertyFormat.trimmedString,
498
+ single: true,
499
+ ignoreEmpty: true,
500
+ });
501
+ // Stop traversal of this branch
502
+ return false;
503
+ }
335
504
  leaf_sampleSolution(node, _route) {
336
- this.writeProperty('sampleSolution', node.value);
505
+ this.writeProperty('sampleSolution', node.value, {
506
+ format: PropertyFormat.trimmedString,
507
+ single: true,
508
+ ignoreEmpty: true,
509
+ });
510
+ // Stop traversal of this branch
511
+ return false;
337
512
  }
338
513
  // bitmarkAst -> bits -> bitsValue -> reasonableNumOfChars
339
514
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> reasonableNumOfChars
340
515
  leaf_reasonableNumOfChars(node, _route) {
341
- this.writeProperty('reasonableNumOfChars', node.value);
516
+ this.writeProperty('reasonableNumOfChars', node.value, {
517
+ format: PropertyFormat.trimmedString,
518
+ single: true,
519
+ ignoreEmpty: true,
520
+ });
342
521
  }
343
522
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> additionalSolutions
344
523
  between_additionalSolutions(_node, _left, _right, route) {
@@ -354,53 +533,244 @@ class BitmarkGenerator extends AstWalkerGenerator {
354
533
  const parent = this.getParentNode(route, 2);
355
534
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.questionsValue)
356
535
  return;
357
- this.writeProperty('additionalSolutions', node.value);
358
- }
359
- // bitmarkAst -> bits -> bitsValue -> itemLead
360
- enter_itemLead(node, _route) {
361
- const itemLead = node.value;
362
- if (itemLead && (itemLead.item || itemLead.lead || itemLead.pageNumber || itemLead.marginNumber)) {
363
- // Always write item if item or lead is set
364
- this.writeOPC();
365
- this.writeString(itemLead.item || '');
366
- this.writeCL();
367
- if (itemLead.lead || itemLead.pageNumber || itemLead.marginNumber) {
368
- this.writeOPC();
369
- this.writeString(itemLead.lead || '');
370
- this.writeCL();
371
- }
372
- if (itemLead.pageNumber || itemLead.marginNumber) {
373
- this.writeOPC();
374
- this.writeString(itemLead.pageNumber || '');
375
- this.writeCL();
376
- }
377
- if (itemLead.marginNumber) {
378
- this.writeOPC();
379
- this.writeString(itemLead.marginNumber || '');
380
- this.writeCL();
381
- }
382
- }
536
+ this.writeProperty('additionalSolutions', node.value, {
537
+ format: PropertyFormat.trimmedString,
538
+ single: false,
539
+ });
540
+ }
541
+ // bitmarkAst -> bits -> bitsValue -> item
542
+ enter_item(node, route) {
543
+ var _a, _b, _c;
544
+ const item = node.value;
545
+ const parent = this.getParentNode(route);
546
+ if (this.isEmptyText(item))
547
+ return false; // Ignore empty
548
+ if (!this.isEmptyText((_a = parent === null || parent === void 0 ? void 0 : parent.value) === null || _a === void 0 ? void 0 : _a.lead))
549
+ return true; // Will be handled by lead
550
+ if (!this.isEmptyText((_b = parent === null || parent === void 0 ? void 0 : parent.value) === null || _b === void 0 ? void 0 : _b.pageNumber))
551
+ return true; // Will be handled by pageNumber
552
+ if (!this.isEmptyText((_c = parent === null || parent === void 0 ? void 0 : parent.value) === null || _c === void 0 ? void 0 : _c.marginNumber))
553
+ return true; // Will be handled by marginNumber
554
+ this.writeOPC();
555
+ this.textGenerator.generateSync(item, TextFormat.bitmarkMinusMinus);
556
+ this.writeCL();
557
+ return true;
558
+ }
559
+ // bitmarkAst -> bits -> bitsValue -> lead
560
+ enter_lead(node, route) {
561
+ var _a, _b, _c, _d;
562
+ const lead = node.value;
563
+ const parent = this.getParentNode(route);
564
+ if (this.isEmptyText(lead))
565
+ return false; // Ignore empty
566
+ if (!this.isEmptyText((_a = parent === null || parent === void 0 ? void 0 : parent.value) === null || _a === void 0 ? void 0 : _a.pageNumber))
567
+ return true; // Will be handled by pageNumber
568
+ if (!this.isEmptyText((_b = parent === null || parent === void 0 ? void 0 : parent.value) === null || _b === void 0 ? void 0 : _b.marginNumber))
569
+ return true; // Will be handled by marginNumber
570
+ this.writeOPC();
571
+ 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);
572
+ this.writeCL();
573
+ this.writeOPC();
574
+ this.textGenerator.generateSync(lead, TextFormat.bitmarkMinusMinus);
575
+ this.writeCL();
576
+ return true;
577
+ }
578
+ // bitmarkAst -> bits -> bitsValue -> pageNumber
579
+ enter_pageNumber(node, route) {
580
+ var _a, _b, _c, _d, _e;
581
+ const pageNumber = node.value;
582
+ const parent = this.getParentNode(route);
583
+ if (this.isEmptyText(pageNumber))
584
+ return false; // Ignore empty
585
+ if (!this.isEmptyText((_a = parent === null || parent === void 0 ? void 0 : parent.value) === null || _a === void 0 ? void 0 : _a.marginNumber))
586
+ return true; // Will be handled by marginNumber
587
+ this.writeOPC();
588
+ 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);
589
+ this.writeCL();
590
+ this.writeOPC();
591
+ this.textGenerator.generateSync((_e = (_d = parent === null || parent === void 0 ? void 0 : parent.value) === null || _d === void 0 ? void 0 : _d.lead) !== null && _e !== void 0 ? _e : '', TextFormat.bitmarkMinusMinus);
592
+ this.writeCL();
593
+ this.writeOPC();
594
+ this.textGenerator.generateSync(pageNumber !== null && pageNumber !== void 0 ? pageNumber : '', TextFormat.bitmarkMinusMinus);
595
+ this.writeCL();
596
+ return true;
597
+ }
598
+ // bitmarkAst -> bits -> bitsValue -> marginNumber
599
+ enter_marginNumber(node, route) {
600
+ var _a, _b, _c, _d, _e, _f;
601
+ const marginNumber = node.value;
602
+ const parent = this.getParentNode(route);
603
+ if (this.isEmptyText(marginNumber))
604
+ return false; // Ignore empty
605
+ this.writeOPC();
606
+ 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);
607
+ this.writeCL();
608
+ this.writeOPC();
609
+ this.textGenerator.generateSync((_d = (_c = parent === null || parent === void 0 ? void 0 : parent.value) === null || _c === void 0 ? void 0 : _c.lead) !== null && _d !== void 0 ? _d : '', TextFormat.bitmarkMinusMinus);
610
+ this.writeCL();
611
+ this.writeOPC();
612
+ this.textGenerator.generateSync((_f = (_e = parent === null || parent === void 0 ? void 0 : parent.value) === null || _e === void 0 ? void 0 : _e.pageNumber) !== null && _f !== void 0 ? _f : '', TextFormat.bitmarkMinusMinus);
613
+ this.writeCL();
614
+ this.writeOPC();
615
+ this.textGenerator.generateSync(marginNumber, TextFormat.bitmarkMinusMinus);
616
+ this.writeCL();
617
+ return true;
383
618
  }
384
619
  // bitmarkAst -> bits -> bitsValue -> body
385
- enter_body(node, _route) {
620
+ enter_body(node, route) {
621
+ var _a;
622
+ // Ignore values that are not at the bit level as they might be handled elsewhere
623
+ const parent = this.getParentNode(route);
624
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue && (parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.cardBitsValue)
625
+ return true;
626
+ this.inTag = false;
386
627
  // always write a NL before the body content if there is any?
387
628
  const body = node.value;
388
- if ((body.bodyParts && body.bodyParts.length > 0) || body.bodyJson) {
629
+ const textFormat = this.getTextFormat(route);
630
+ const isBitmarkText = textFormat === TextFormat.bitmarkPlusPlus || textFormat === TextFormat.bitmarkMinusMinus;
631
+ // Handle body
632
+ if (textFormat === TextFormat.json) {
633
+ const json = (_a = body.body) !== null && _a !== void 0 ? _a : null;
634
+ if (Array.isArray(json) || ObjectUtils.isObject(json)) {
635
+ const text = JSON.stringify(json, null, this.prettifySpace);
636
+ if (text) {
637
+ this.writeNL();
638
+ this.writePlainTextDivider();
639
+ this.writeNL();
640
+ this.write(Breakscape.breakscape(text, {
641
+ textFormat: TextFormat.text,
642
+ }));
643
+ }
644
+ }
645
+ }
646
+ else if (isBitmarkText) {
647
+ // handle bitmark text
389
648
  this.writeNL();
649
+ // The text generator will write to the writer
650
+ const b = (Array.isArray(body.body) ? body.body : []);
651
+ this.textGenerator.generateSync(b, textFormat);
390
652
  }
653
+ else {
654
+ // handle plain text
655
+ this.writeNL();
656
+ this.writePlainTextDivider();
657
+ this.writeNL();
658
+ const s = (StringUtils.isString(body.body) ? body.body : '');
659
+ this.write(Breakscape.breakscape(`${s}`, {
660
+ textFormat: TextFormat.text,
661
+ }));
662
+ this.writeNL();
663
+ }
664
+ // Stop traversal of this branch
665
+ return false;
666
+ // if ((body.body && body.body.length > 0) || body.bodyJson) {
667
+ // this.writeNL();
668
+ // // Write the plain text divider if not bitmark++/-- format
669
+ // const textFormat = this.getTextFormat(route);
670
+ // const isBitmarkText = textFormat === TextFormat.bitmarkPlusPlus || textFormat === TextFormat.bitmarkMinusMinus;
671
+ // if (!isBitmarkText) {
672
+ // this.writePlainTextDivider();
673
+ // this.writeNL();
674
+ // }
675
+ // }
676
+ }
677
+ exit_body(_node, _route) {
678
+ this.inTag = true;
679
+ }
680
+ bodyBitCallback(bodyBit, _index, _route) {
681
+ // console.log('bodyBitCallback', bodyBit, index, route);
682
+ var _a;
683
+ // Walk the body bit AST
684
+ const nodeType = (_a = NodeType.fromValue(bodyBit.type)) !== null && _a !== void 0 ? _a : NodeType.bodyBit;
685
+ this.ast.walk(bodyBit, nodeType, this, undefined);
686
+ return ''; // Return empty string as we are writing to the writer
687
+ }
688
+ // bodyBit -> gap
689
+ enter_gap(node, _route) {
690
+ const gap = node.value;
691
+ if (gap.solutions && gap.solutions.length === 0) {
692
+ // If there are no solutions, we need to write the special cloze gap [_] to indicate this
693
+ this.writeOPU();
694
+ this.writeCL();
695
+ }
696
+ else {
697
+ for (const solution of gap.solutions) {
698
+ this.writeOPU();
699
+ this.writeBreakscapedTagString(solution);
700
+ this.writeCL();
701
+ }
702
+ }
703
+ // Continue traversal
704
+ return true;
705
+ }
706
+ // bodyBit -> mark
707
+ enter_mark(node, _route) {
708
+ const mark = node.value;
709
+ this.writeOPE();
710
+ this.writeBreakscapedTagString(mark.solution);
711
+ this.writeCL();
712
+ // Continue traversal
713
+ return true;
714
+ }
715
+ // bodyBit -> select
716
+ enter_select(_node, _route) {
717
+ // Continue traversal
718
+ return true;
719
+ }
720
+ // bodyBit -> highlight
721
+ enter_highlight(_node, _route) {
722
+ // Continue traversal
723
+ return true;
724
+ }
725
+ // bitmarkAst -> bits -> footer
726
+ enter_footer(node, route) {
727
+ const parent = this.getParentNode(route);
728
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
729
+ return true;
730
+ const footer = node.value;
731
+ const textFormat = this.getTextFormat(route);
732
+ // Handle footer
733
+ if (textFormat === TextFormat.json) {
734
+ // Json footer?!
735
+ // Not valid, ignore
736
+ }
737
+ else if (footer.footer && footer.footer.length > 0) {
738
+ const isBitmarkText = textFormat === TextFormat.bitmarkPlusPlus || textFormat === TextFormat.bitmarkMinusMinus;
739
+ if (isBitmarkText) {
740
+ // handle bitmark text
741
+ this.write('~~~~');
742
+ this.writeNL();
743
+ // The text generator will write to the writer
744
+ this.textGenerator.generateSync(footer.footer, TextFormat.text);
745
+ }
746
+ else {
747
+ // Plain text footer?!
748
+ // Not valid, ignore (plain text cannot have a card set / footer marker, so cannot have a footer!
749
+ }
750
+ }
751
+ // Stop traversal of this branch
752
+ return false;
391
753
  }
392
754
  // bitmarkAst -> bits -> bitsValue -> body -> bodyParts -> bodyPartsValue -> data -> solutions
393
- enter_solutions(node, _route) {
755
+ enter_solutions(node, route) {
756
+ const parent = this.getParentNode(route);
757
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
758
+ return true;
394
759
  const solutions = node.value;
395
760
  if (solutions && solutions.length === 0) {
396
761
  // If there are no solutions, we need to write the special cloze gap [_] to indicate this
397
762
  this.writeOPU();
398
763
  this.writeCL();
399
764
  }
765
+ // Continue traversal
766
+ return true;
400
767
  }
401
768
  // bitmarkAst -> bits -> bitsValue -> body -> bodyParts -> bodyPartsValue -> data -> solution
402
769
  leaf_solution(node, route) {
403
770
  var _a;
771
+ const parent = this.getParentNode(route);
772
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
773
+ return;
404
774
  const solution = node.value;
405
775
  // Ignore values that are not at the correct level as they might be handled elsewhere
406
776
  const bodyPartsValue = (_a = this.getParentNode(route, 2)) === null || _a === void 0 ? void 0 : _a.value;
@@ -408,20 +778,22 @@ class BitmarkGenerator extends AstWalkerGenerator {
408
778
  return;
409
779
  if (solution) {
410
780
  this.writeOPE();
411
- this.writeString(solution);
781
+ this.writeBreakscapedTagString(solution);
412
782
  this.writeCL();
413
783
  }
414
784
  }
415
- // bitmarkAst -> bits -> bitsValue -> body -> bodyParts -> bodyPartsValue -> data -> mark
785
+ // bitmarkAst -> bits -> bitsValue -> body -> bodyBit -> mark -> mark
416
786
  leaf_mark(node, route) {
417
- var _a;
418
- const mark = node.value;
419
- // Ignore values that are not at the correct level as they might be handled elsewhere
420
- const bodyPartsValue = (_a = this.getParentNode(route, 2)) === null || _a === void 0 ? void 0 : _a.value;
421
- if ((bodyPartsValue === null || bodyPartsValue === void 0 ? void 0 : bodyPartsValue.type) !== BodyBitType.mark)
787
+ const root = route[0];
788
+ if ((root === null || root === void 0 ? void 0 : root.key) !== NodeType.mark)
422
789
  return;
790
+ const mark = node.value;
423
791
  if (mark) {
424
- this.writeProperty('mark', mark, true);
792
+ this.writeProperty('mark', mark, {
793
+ format: PropertyFormat.trimmedString,
794
+ single: true,
795
+ ignoreEmpty: true,
796
+ });
425
797
  }
426
798
  }
427
799
  // bitmarkAst -> bits -> bitsValue -> body -> bodyParts -> bodyPartsValue -> data -> options -> optionsValue
@@ -435,6 +807,8 @@ class BitmarkGenerator extends AstWalkerGenerator {
435
807
  }
436
808
  this.write(selectOption.text);
437
809
  this.writeCL();
810
+ // Continue traversal
811
+ return true;
438
812
  }
439
813
  // bitmarkAst -> bits -> bitsValue -> body -> bodyParts -> bodyPartsValue -> data -> texts -> textsValue
440
814
  enter_textsValue(node, _route) {
@@ -447,15 +821,19 @@ class BitmarkGenerator extends AstWalkerGenerator {
447
821
  }
448
822
  this.write(highlightText.text);
449
823
  this.writeCL();
824
+ // Continue traversal
825
+ return true;
450
826
  }
451
827
  // bitmarkAst -> bits -> bitsValue -> cardNode
452
828
  enter_cardNode(_node, route) {
453
829
  // Ignore cards for xxx-1
454
830
  const isBitType1 = this.isOfBitType1(route);
455
831
  if (isBitType1)
456
- return;
832
+ return true;
457
833
  this.writeCardSetStart();
458
834
  this.writeNL();
835
+ // Continue traversal
836
+ return true;
459
837
  }
460
838
  between_cardNode(_node, _left, _right, route) {
461
839
  // Ignore cards for xxx-1
@@ -497,26 +875,29 @@ class BitmarkGenerator extends AstWalkerGenerator {
497
875
  }
498
876
  // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue
499
877
  between_flashcardsValue(_node, _left, right, _route) {
878
+ var _a;
500
879
  if (right.key === NodeType.answer) {
501
880
  this.writeNL();
502
881
  this.writeCardSetSideDivider();
503
882
  this.writeNL();
504
883
  }
505
- else if (right.key === NodeType.alternativeAnswers) {
884
+ else if (right.key === NodeType.alternativeAnswers && ((_a = right.value) === null || _a === void 0 ? void 0 : _a.length) !== 0) {
506
885
  this.writeNL();
507
886
  this.writeCardSetVariantDivider();
508
887
  this.writeNL();
509
888
  }
510
889
  }
511
890
  // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue -> answer
512
- leaf_answer(node, route) {
891
+ enter_answer(node, route) {
513
892
  // Ignore responses that are not at the flashcardsValue level as they are handled elsewhere
514
893
  const parent = this.getParentNode(route);
515
894
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.flashcardsValue)
516
- return;
895
+ return true;
517
896
  if (node.value) {
518
- this.writeString(node.value);
897
+ this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
519
898
  }
899
+ // Stop traversal of this branch
900
+ return false;
520
901
  }
521
902
  // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue -> alternativeAnswers
522
903
  between_alternativeAnswers(_node, _route) {
@@ -525,30 +906,38 @@ class BitmarkGenerator extends AstWalkerGenerator {
525
906
  this.writeNL();
526
907
  }
527
908
  // bitmarkAst -> bits -> bitsValue -> cardNode -> flashcards -> flashcardsValue -> alternativeAnswers -> alternativeAnswersValue
528
- leaf_alternativeAnswersValue(node, route) {
909
+ enter_alternativeAnswersValue(node, route) {
529
910
  // Ignore responses that are not at the alternativeAnswers level as they are handled elsewhere
530
911
  const parent = this.getParentNode(route);
531
912
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.alternativeAnswers)
532
- return;
913
+ return true;
533
914
  if (node.value) {
534
- this.writeString(node.value);
915
+ // this.writeBreakscapedTagString(node.value);
916
+ this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
535
917
  }
918
+ // Stop traversal of this branch
919
+ return false;
536
920
  }
537
- // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> alternativeDefinitions
921
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> alternativeDefintions
538
922
  between_alternativeDefinitions(_node, _route) {
539
923
  this.writeNL();
540
924
  this.writeCardSetVariantDivider();
541
925
  this.writeNL();
542
926
  }
543
927
  // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> alternativeDefinitions -> alternativeDefinitionsValue
544
- leaf_alternativeDefinitionsValue(node, route) {
545
- // Ignore responses that are not at the alternativeDefinitions level as they are handled elsewhere
928
+ enter_alternativeDefinitionsValue(node, route) {
929
+ // Ignore responses that are not at the alternativeAnswers level as they are handled elsewhere
546
930
  const parent = this.getParentNode(route);
547
931
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.alternativeDefinitions)
548
- return;
932
+ return true;
549
933
  if (node.value) {
550
- this.writeString(node.value);
934
+ // this.writeNL();
935
+ // this.writeCardSetVariantDivider();
936
+ // this.writeNL();
937
+ this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
551
938
  }
939
+ // Stop traversal of this branch
940
+ return false;
552
941
  }
553
942
  // bitmarkAst -> bits -> bitsValue -> cardNode -> statements
554
943
  enter_statements(_node, _route) {
@@ -574,8 +963,10 @@ class BitmarkGenerator extends AstWalkerGenerator {
574
963
  else {
575
964
  this.writeOPM();
576
965
  }
577
- this.write(statement.text);
966
+ this.write(statement.statement);
578
967
  this.writeCL();
968
+ // Continue traversal
969
+ return true;
579
970
  }
580
971
  // bitmarkAst -> bits -> bitsValue -> choices
581
972
  // bitmarkAst -> bits -> bitsValue -> cardNode -> quizzes -> quizzesValue -> choices
@@ -595,8 +986,10 @@ class BitmarkGenerator extends AstWalkerGenerator {
595
986
  else {
596
987
  this.writeOPM();
597
988
  }
598
- this.write(choice.text);
989
+ this.write(choice.choice);
599
990
  this.writeCL();
991
+ // Continue traversal
992
+ return true;
600
993
  }
601
994
  // bitmarkAst -> bits -> bitsValue -> responses
602
995
  // bitmarkAst -> bits -> bitsValue -> cardNode -> quizzes -> quizzesValue -> responses
@@ -616,8 +1009,10 @@ class BitmarkGenerator extends AstWalkerGenerator {
616
1009
  else {
617
1010
  this.writeOPM();
618
1011
  }
619
- this.write(response.text);
1012
+ this.write(response.response);
620
1013
  this.writeCL();
1014
+ // Continue traversal
1015
+ return true;
621
1016
  }
622
1017
  // bitmarkAst -> bits -> bitsValue -> cardNode -> quizzes
623
1018
  enter_quizzes(_node, _route) {
@@ -681,13 +1076,17 @@ class BitmarkGenerator extends AstWalkerGenerator {
681
1076
  enter_keyAudio(node, _route) {
682
1077
  const resource = node.value;
683
1078
  // This is a resource, so handle it with the common code
684
- this.writeResource(resource);
1079
+ this.writeResource(ResourceTag.audio, resource.src);
1080
+ // Stop traversal of this branch
1081
+ return false;
685
1082
  }
686
1083
  // bitmarkAst -> bits -> bitsValue -> cardNode -> pairs -> pairsValue -> keyImage
687
1084
  enter_keyImage(node, _route) {
688
1085
  const resource = node.value;
689
1086
  // This is a resource, so handle it with the common code
690
- this.writeResource(resource);
1087
+ this.writeResource(ResourceTag.image, resource.src);
1088
+ // Stop traversal of this branch
1089
+ return false;
691
1090
  }
692
1091
  // bitmarkAst -> bits -> bitsValue -> cardNode -> matrix
693
1092
  enter_matrix(_node, _route) {
@@ -726,8 +1125,8 @@ class BitmarkGenerator extends AstWalkerGenerator {
726
1125
  this.writeCardSetCardDivider();
727
1126
  this.writeNL();
728
1127
  }
729
- // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> rows
730
- between_rows(_node, _left, _right, route) {
1128
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> data
1129
+ between_data(_node, _left, _right, route) {
731
1130
  const parent = this.getParentNode(route);
732
1131
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.table)
733
1132
  return;
@@ -751,20 +1150,23 @@ class BitmarkGenerator extends AstWalkerGenerator {
751
1150
  leaf_columnsValue(node, _route) {
752
1151
  this.writeOPHASH();
753
1152
  if (node.value)
754
- this.writeString(node.value);
1153
+ this.writeBreakscapedTagString(node.value);
755
1154
  this.writeCL();
756
1155
  }
757
- // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> rows -> rowsValue
758
- between_rowsValue(_node, _left, _right, route) {
759
- const parent = this.getParentNode(route);
760
- if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.rows)
1156
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> data -> dataValue
1157
+ between_dataValue(_node, _left, _right, route) {
1158
+ const parent = this.getParentNode(route, 2);
1159
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.table)
761
1160
  return;
762
1161
  this.writeNL();
763
1162
  this.writeCardSetSideDivider();
764
1163
  this.writeNL();
765
1164
  }
766
- // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> rows -> rowsValue -> rowsValueValue
767
- leaf_rowsValueValue(node, _route) {
1165
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> table -> data -> dataValue -> dataValueValue
1166
+ leaf_dataValueValue(node, route) {
1167
+ const parent = this.getParentNode(route, 3);
1168
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.table)
1169
+ return;
768
1170
  if (node.value)
769
1171
  this.write(node.value);
770
1172
  }
@@ -793,23 +1195,49 @@ class BitmarkGenerator extends AstWalkerGenerator {
793
1195
  // this.writeCardSetSideDivider();
794
1196
  // this.writeNL();
795
1197
  // }
796
- // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions -> definitionsValue -> term
797
1198
  // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> term
1199
+ enter_term(node, route) {
1200
+ const parent = this.getParentNode(route);
1201
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.definitionsValue)
1202
+ return true;
1203
+ if (node.value) {
1204
+ this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
1205
+ }
1206
+ // Stop traversal of this branch
1207
+ return false;
1208
+ }
1209
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions -> definitionsValue -> term
798
1210
  leaf_term(node, route) {
799
1211
  const parent = this.getParentNode(route);
800
1212
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.definitionsValue)
801
- return;
802
- if (node.value)
1213
+ return true;
1214
+ if (node.value) {
803
1215
  this.write(node.value);
1216
+ }
1217
+ // Stop traversal of this branch
1218
+ return false;
804
1219
  }
805
- // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions -> definitionsValue -> description
806
- // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> description
807
- leaf_description(node, route) {
1220
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue -> definition
1221
+ enter_definition(node, route) {
808
1222
  const parent = this.getParentNode(route);
809
1223
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.definitionsValue)
810
- return;
811
- if (node.value)
1224
+ return true;
1225
+ if (node.value) {
1226
+ this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
1227
+ }
1228
+ // Stop traversal of this branch
1229
+ return false;
1230
+ }
1231
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions -> definitionsValue -> definition
1232
+ leaf_definition(node, route) {
1233
+ const parent = this.getParentNode(route);
1234
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.definitionsValue)
1235
+ return true;
1236
+ if (node.value) {
812
1237
  this.write(node.value);
1238
+ }
1239
+ // Stop traversal of this branch
1240
+ return false;
813
1241
  }
814
1242
  // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions
815
1243
  // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions
@@ -821,23 +1249,37 @@ class BitmarkGenerator extends AstWalkerGenerator {
821
1249
  this.writeCardSetCardDivider();
822
1250
  this.writeNL();
823
1251
  }
824
- // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions -> definitionsValue
825
1252
  // bitmarkAst -> bits -> bitsValue -> cardNode -> definitions -> definitionsValue
826
1253
  between_definitionsValue(_node, _left, right, route) {
1254
+ var _a;
827
1255
  const parent = this.getParentNode(route);
828
1256
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.definitions)
829
1257
  return;
830
- if (right.key === NodeType.description) {
1258
+ if (right.key === NodeType.definition) {
831
1259
  this.writeNL();
832
1260
  this.writeCardSetSideDivider();
833
1261
  this.writeNL();
834
1262
  }
835
- else if (right.key === NodeType.alternativeDefinitions) {
1263
+ else if (right.key === NodeType.alternativeDefinitions && ((_a = right.value) === null || _a === void 0 ? void 0 : _a.length) > 0) {
836
1264
  this.writeNL();
837
1265
  this.writeCardSetVariantDivider();
838
1266
  this.writeNL();
839
1267
  }
840
1268
  }
1269
+ // bitmarkAst -> bits -> bitsValue -> cardNode -> captionDefinitionList -> definitions -> definitionsValue
1270
+ // protected between_definitionsValue(_node: NodeInfo, _left: NodeInfo, right: NodeInfo, route: NodeInfo[]): void {
1271
+ // const parent = this.getParentNode(route);
1272
+ // if (parent?.key !== NodeType.definitions) return;
1273
+ // if (right.key === NodeType.definition) {
1274
+ // this.writeNL();
1275
+ // this.writeCardSetSideDivider();
1276
+ // this.writeNL();
1277
+ // } else if (right.key === NodeType.alternativeDefinitions && right.value?.length > 0) {
1278
+ // this.writeNL();
1279
+ // this.writeCardSetVariantDivider();
1280
+ // this.writeNL();
1281
+ // }
1282
+ // }
841
1283
  // bitmarkAst -> bits -> bitsValue -> cardNode -> questions
842
1284
  enter_questions(_node, _route) {
843
1285
  //
@@ -877,7 +1319,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
877
1319
  const ingredient = node.value;
878
1320
  if (ingredient.title != null) {
879
1321
  this.writeOPHASH();
880
- this.writeString(ingredient.title);
1322
+ this.writeBreakscapedTagString(ingredient.title);
881
1323
  this.writeCL();
882
1324
  this.writeNL();
883
1325
  }
@@ -892,24 +1334,42 @@ class BitmarkGenerator extends AstWalkerGenerator {
892
1334
  // [!43]
893
1335
  if (ingredient.quantity != null) {
894
1336
  this.writeOPB();
895
- this.writeString(`${ingredient.quantity}`);
1337
+ this.writeBreakscapedTagString(`${ingredient.quantity}`);
896
1338
  this.writeCL();
897
1339
  }
898
1340
  // [@unit:kilograms]
899
1341
  if (ingredient.unit != null)
900
- this.writeProperty('unit', ingredient.unit, true);
1342
+ this.writeProperty('unit', ingredient.unit, {
1343
+ format: PropertyFormat.trimmedString,
1344
+ single: true,
1345
+ ignoreEmpty: true,
1346
+ });
901
1347
  // [@unitAbbr:kg]
902
1348
  if (ingredient.unitAbbr != null)
903
- this.writeProperty('unitAbbr', ingredient.unitAbbr, true);
1349
+ this.writeProperty('unitAbbr', ingredient.unitAbbr, {
1350
+ format: PropertyFormat.trimmedString,
1351
+ single: true,
1352
+ ignoreEmpty: true,
1353
+ });
904
1354
  // [@decimalPlaces:1]
905
1355
  if (ingredient.decimalPlaces != null)
906
- this.writeProperty('decimalPlaces', ingredient.decimalPlaces, true);
1356
+ this.writeProperty('decimalPlaces', ingredient.decimalPlaces, {
1357
+ format: PropertyFormat.trimmedString,
1358
+ single: true,
1359
+ ignoreEmpty: true,
1360
+ });
907
1361
  // [@disableCalculation]
908
1362
  if (ingredient.disableCalculation)
909
- this.writeProperty('disableCalculation', true, true);
1363
+ this.writeProperty('disableCalculation', true, {
1364
+ format: PropertyFormat.trimmedString,
1365
+ single: true,
1366
+ ignoreEmpty: true,
1367
+ });
910
1368
  // item
911
1369
  if (ingredient.item != null)
912
1370
  this.write(ingredient.item);
1371
+ // Stop traversal of this branch
1372
+ return false;
913
1373
  }
914
1374
  // bitmarkAst -> bits -> bitsValue -> cardNode -> botResponses
915
1375
  enter_botResponses(_node, _route) {
@@ -942,37 +1402,42 @@ class BitmarkGenerator extends AstWalkerGenerator {
942
1402
  //
943
1403
  }
944
1404
  // bitmarkAst -> bits -> bitsValue -> cardNode -> botResponses -> botResponsesValue -> response
945
- leaf_response(node, _route) {
1405
+ leaf_response(node, route) {
1406
+ const parent = this.getParentNode(route);
1407
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.botResponsesValue)
1408
+ return;
946
1409
  this.writeOPB();
947
- this.writeString(node.value);
1410
+ this.writeBreakscapedTagString(node.value);
948
1411
  this.writeCL();
949
1412
  }
950
1413
  // bitmarkAst -> bits -> bitsValue -> cardNode -> botResponses -> botResponsesValue -> reaction
951
- leaf_reaction(node, _route) {
952
- this.writeProperty('reaction', node.value, true);
1414
+ leaf_reaction(node, route) {
1415
+ const parent = this.getParentNode(route);
1416
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.botResponsesValue)
1417
+ return;
1418
+ this.writeProperty('reaction', node.value, {
1419
+ format: PropertyFormat.trimmedString,
1420
+ single: true,
1421
+ ignoreEmpty: true,
1422
+ });
953
1423
  }
954
1424
  // bitmarkAst -> bits -> bitsValue -> cardNode -> botResponses -> botResponsesValue -> feedback
955
- leaf_feedback(node, _route) {
1425
+ leaf_feedback(node, route) {
1426
+ const parent = this.getParentNode(route);
1427
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.botResponsesValue)
1428
+ return;
956
1429
  const feeback = node.value;
957
1430
  if (feeback) {
958
1431
  this.write(feeback);
959
1432
  }
960
1433
  }
961
- // bitmarkAst -> bits -> bitsValue -> resources
962
- between_resources(_node, _left, _right, _route) {
963
- this.writeNL();
964
- }
965
- // bitmarkAst -> bits -> bitsValue -> resourcesValue
966
- enter_resourcesValue(node, _route) {
967
- const resource = node.value;
968
- // This is a resource, so handle it with the common code
969
- this.writeResource(resource);
970
- }
971
1434
  // bitmarkAst -> bits -> bitsValue -> imagePlaceholder
972
1435
  enter_imagePlaceholder(node, _route) {
973
1436
  const resource = node.value;
974
1437
  // This is a resource, so handle it with the common code
975
1438
  this.writePropertyStyleResource(node.key, resource);
1439
+ // Continue traversal
1440
+ return true;
976
1441
  }
977
1442
  exit_imagePlaceholder(_node, _route) {
978
1443
  this.writeNL();
@@ -985,16 +1450,26 @@ class BitmarkGenerator extends AstWalkerGenerator {
985
1450
  // Bit poster image
986
1451
  const posterImage = node.value;
987
1452
  if (posterImage) {
988
- this.writeProperty('posterImage', posterImage);
1453
+ this.writeProperty('posterImage', posterImage, {
1454
+ format: PropertyFormat.trimmedString,
1455
+ single: true,
1456
+ ignoreEmpty: true,
1457
+ });
989
1458
  }
990
1459
  }
991
1460
  else {
992
1461
  // Resource poster image
993
1462
  const posterImage = node.value;
994
- if (posterImage && posterImage.value) {
995
- this.writeProperty('posterImage', posterImage.value);
1463
+ if (posterImage && posterImage.src) {
1464
+ this.writeProperty('posterImage', posterImage.src, {
1465
+ format: PropertyFormat.trimmedString,
1466
+ single: true,
1467
+ ignoreEmpty: true,
1468
+ });
996
1469
  }
997
1470
  }
1471
+ // Continue traversal
1472
+ return true;
998
1473
  }
999
1474
  // bitmarkAst -> bits -> bitsValue -> resource -> thumbnails
1000
1475
  // [src1x,src2x,src3x,src4x,width,height,alt,zoomDisabled,caption]
@@ -1008,21 +1483,24 @@ class BitmarkGenerator extends AstWalkerGenerator {
1008
1483
  break;
1009
1484
  const thumbnail = thumbnails[i];
1010
1485
  const key = thumbnailKeys[i];
1011
- this.writeProperty(key, thumbnail.value, true);
1486
+ this.writeProperty(key, thumbnail.src, {
1487
+ format: PropertyFormat.trimmedString,
1488
+ single: true,
1489
+ ignoreEmpty: true,
1490
+ });
1012
1491
  }
1013
1492
  }
1493
+ // Stop traversal of this branch
1494
+ return false;
1014
1495
  }
1015
- //
1016
- // Terminal nodes (leaves)
1017
- //
1018
1496
  // bitmarkAst -> bits -> bitsValue -> bitType
1019
1497
  // bitmarkAst -> bits -> bitsValue -> textFormat
1020
1498
  // bitmarkAst -> bits -> title
1021
- leaf_title(node, route) {
1022
- const parent = this.getParentNode(route);
1499
+ enter_title(node, route) {
1023
1500
  // Ensure this is at the bit level
1501
+ const parent = this.getParentNode(route);
1024
1502
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
1025
- return;
1503
+ return true;
1026
1504
  const value = node.value;
1027
1505
  const title = value;
1028
1506
  const bit = parent === null || parent === void 0 ? void 0 : parent.value;
@@ -1031,12 +1509,18 @@ class BitmarkGenerator extends AstWalkerGenerator {
1031
1509
  this.writeOP();
1032
1510
  for (let i = 0; i < +level; i++)
1033
1511
  this.writeHash();
1034
- this.writeString(title);
1512
+ this.textGenerator.generateSync(title, TextFormat.bitmarkMinusMinus);
1035
1513
  this.writeCL();
1036
1514
  }
1515
+ // Stop traversal of this branch
1516
+ return false;
1037
1517
  }
1038
1518
  // bitmarkAst -> bits -> subtitle
1039
- leaf_subtitle(node, _route) {
1519
+ enter_subtitle(node, route) {
1520
+ // Ensure this is at the bit level
1521
+ const parent = this.getParentNode(route);
1522
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
1523
+ return true;
1040
1524
  const value = node.value;
1041
1525
  const subtitle = value;
1042
1526
  const level = 2;
@@ -1044,23 +1528,29 @@ class BitmarkGenerator extends AstWalkerGenerator {
1044
1528
  this.writeOP();
1045
1529
  for (let i = 0; i < level; i++)
1046
1530
  this.writeHash();
1047
- this.writeString(subtitle);
1531
+ this.textGenerator.generateSync(subtitle, TextFormat.bitmarkMinusMinus);
1048
1532
  this.writeCL();
1049
1533
  }
1534
+ // Stop traversal of this branch
1535
+ return false;
1050
1536
  }
1051
1537
  // bitmarkAst -> bits -> bitsValue -> book
1052
1538
  leaf_book(node, route) {
1053
1539
  const parent = this.getParentNode(route);
1054
1540
  const bit = parent === null || parent === void 0 ? void 0 : parent.value;
1055
1541
  if (bit && node.value) {
1056
- this.writeProperty('book', node.value);
1542
+ this.writeProperty('book', node.value, {
1543
+ format: PropertyFormat.trimmedString,
1544
+ single: true,
1545
+ ignoreEmpty: false,
1546
+ });
1057
1547
  if (bit.reference) {
1058
1548
  this.writeOPRANGLE();
1059
- this.writeString(bit.reference);
1549
+ this.writeBreakscapedTagString(bit.reference);
1060
1550
  this.writeCL();
1061
1551
  if (bit.referenceEnd) {
1062
1552
  this.writeOPRANGLE();
1063
- this.writeString(bit.referenceEnd);
1553
+ this.writeBreakscapedTagString(bit.referenceEnd);
1064
1554
  this.writeCL();
1065
1555
  }
1066
1556
  }
@@ -1070,7 +1560,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1070
1560
  leaf_anchor(node, _route) {
1071
1561
  if (node.value) {
1072
1562
  this.writeOPDANGLE();
1073
- this.writeString(node.value);
1563
+ this.writeBreakscapedTagString(node.value);
1074
1564
  this.writeCL();
1075
1565
  }
1076
1566
  }
@@ -1082,7 +1572,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1082
1572
  // Only write reference if it is not chained to 'book'
1083
1573
  if (!bit.book) {
1084
1574
  this.writeOPRANGLE();
1085
- this.writeString(node.value);
1575
+ this.writeBreakscapedTagString(node.value);
1086
1576
  this.writeCL();
1087
1577
  }
1088
1578
  }
@@ -1090,101 +1580,80 @@ class BitmarkGenerator extends AstWalkerGenerator {
1090
1580
  // * -> itemLead --> item
1091
1581
  // * -> itemLead --> lead
1092
1582
  // * -> hint
1093
- leaf_hint(node, _route) {
1583
+ enter_hint(node, _route) {
1094
1584
  const value = node.value;
1095
1585
  const text = value;
1096
- if (text) {
1586
+ if (!this.isEmptyText(text)) {
1097
1587
  this.writeOPQ();
1098
- this.writeString(text);
1588
+ this.textGenerator.generateSync(text, TextFormat.bitmarkMinusMinus);
1099
1589
  this.writeCL();
1100
1590
  }
1591
+ // Stop traversal of this branch
1592
+ return false;
1101
1593
  }
1102
1594
  // bitmarkAst -> bits -> bitsValue -> * -> instruction
1103
- leaf_instruction(node, _route) {
1595
+ enter_instruction(node, _route) {
1104
1596
  const value = node.value;
1105
1597
  const text = value;
1106
- if (text) {
1598
+ if (!this.isEmptyText(text)) {
1107
1599
  this.writeOPB();
1108
- this.writeString(text);
1600
+ this.textGenerator.generateSync(text, TextFormat.bitmarkMinusMinus);
1109
1601
  this.writeCL();
1110
1602
  }
1603
+ // Stop traversal of this branch
1604
+ return false;
1111
1605
  }
1112
- // bitmarkAst -> bits -> bitsValue -> * -> example
1113
- leaf_example(node, route) {
1114
- var _a, _b;
1115
- const value = node.value;
1116
- const parent = this.getParentNode(route);
1117
- const isExample = (_a = parent === null || parent === void 0 ? void 0 : parent.value.isExample) !== null && _a !== void 0 ? _a : false;
1118
- const isDefaultExample = (_b = parent === null || parent === void 0 ? void 0 : parent.value.isDefaultExample) !== null && _b !== void 0 ? _b : false;
1606
+ // bitmarkAst -> bits -> bitsValue -> * -> isExample / example
1607
+ leaf_isExample(node, route) {
1608
+ var _a;
1609
+ const isExample = node.value;
1119
1610
  if (!isExample)
1120
1611
  return;
1121
- if (isDefaultExample) {
1122
- this.writeOPA();
1123
- this.writeString('example');
1124
- this.writeCL();
1125
- }
1126
- else if (value != null) {
1612
+ const parent = this.getParentNode(route);
1613
+ const example = (_a = parent === null || parent === void 0 ? void 0 : parent.value.example) !== null && _a !== void 0 ? _a : null;
1614
+ // const __isDefaultExample = parent?.value.__isDefaultExample ?? false;
1615
+ if (example != null && example !== '') {
1127
1616
  this.writeOPA();
1128
1617
  this.writeString('example');
1129
1618
  this.writeColon();
1130
- if (value === true) {
1619
+ if (example === true) {
1131
1620
  this.writeString('true');
1132
1621
  }
1133
- else if (value === false) {
1622
+ else if (example === false) {
1134
1623
  this.writeString('false');
1135
1624
  }
1625
+ else if (Array.isArray(example)) {
1626
+ // TextAst
1627
+ this.textGenerator.generateSync(example, TextFormat.bitmarkMinusMinus);
1628
+ }
1136
1629
  else {
1137
1630
  // String
1138
- this.writeString(value);
1631
+ this.writeBreakscapedTagString(example);
1139
1632
  }
1140
1633
  this.writeCL();
1141
1634
  }
1142
- }
1143
- // bitmarkAst -> bits -> body -> bodyValue -> bodyText
1144
- leaf_bodyText(node, _route) {
1145
- const value = node.value;
1146
- const text = value;
1147
- if (text) {
1148
- this.writeString(text);
1149
- }
1150
- }
1151
- // bitmarkAst -> bits -> body -> bodyValue -> bodyJson
1152
- enter_bodyJson(node, _route) {
1153
- const value = node.value;
1154
- if (Array.isArray(value) || ObjectUtils.isObject(value)) {
1155
- const text = JSON.stringify(value, null, this.prettifySpace);
1156
- if (text) {
1157
- this.writeString(text);
1158
- }
1159
- }
1160
- // Stop traversal of this branch to avoid processing the bodyJson
1161
- return false;
1162
- }
1163
- // bitmarkAst -> bits -> footer
1164
- enter_footer(_node, _route) {
1165
- this.write('~~~~');
1166
- this.writeNL();
1167
- }
1168
- // bitmarkAst -> bits -> footer -> footerText
1169
- leaf_footerText(node, _route) {
1170
- const value = node.value;
1171
- const text = value;
1172
- if (text) {
1173
- this.writeString(text);
1635
+ else {
1636
+ // Don't write example if it is null.
1637
+ // this.writeOPA();
1638
+ // this.writeString('example');
1639
+ // this.writeCL();
1174
1640
  }
1175
1641
  }
1176
1642
  // bitmarkAst -> bits -> bitsValue -> elements -> elementsValue
1177
1643
  leaf_elementsValue(node, _route) {
1178
1644
  if (node.value) {
1179
- this.writeString(node.value);
1645
+ this.writeBreakscapedTagString(node.value);
1180
1646
  }
1181
1647
  }
1182
1648
  // bitmarkAst -> bits -> bitsValue -> body -> bodyValue -> gap -> solutions -> solution
1183
1649
  // ? -> solutions -> solution
1184
- leaf_solutionsValue(node, _route) {
1650
+ leaf_solutionsValue(node, route) {
1651
+ const parent = this.getParentNode(route, 2);
1652
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
1653
+ return;
1185
1654
  if (node.value != null) {
1186
1655
  this.writeOPU();
1187
- this.writeString(node.value);
1656
+ this.writeBreakscapedTagString(node.value);
1188
1657
  this.writeCL();
1189
1658
  }
1190
1659
  }
@@ -1193,7 +1662,7 @@ class BitmarkGenerator extends AstWalkerGenerator {
1193
1662
  leaf_prefix(node, _route) {
1194
1663
  if (node.value) {
1195
1664
  this.writeOPPRE();
1196
- this.writeString(node.value);
1665
+ this.writeBreakscapedTagString(node.value);
1197
1666
  this.writeCL();
1198
1667
  }
1199
1668
  }
@@ -1202,39 +1671,50 @@ class BitmarkGenerator extends AstWalkerGenerator {
1202
1671
  leaf_postfix(node, _route) {
1203
1672
  if (node.value) {
1204
1673
  this.writeOPPOST();
1205
- this.writeString(node.value);
1674
+ this.writeBreakscapedTagString(node.value);
1206
1675
  this.writeCL();
1207
1676
  }
1208
1677
  }
1209
1678
  // bitmarkAst -> bits -> bitsValue -> * -> isCaseSensitive
1210
1679
  leaf_isCaseSensitive(node, _route) {
1211
- this.writeProperty('isCaseSensitive', node.value, true, false, true);
1680
+ this.writeProperty('isCaseSensitive', node.value, {
1681
+ format: PropertyFormat.boolean,
1682
+ single: true,
1683
+ ignoreFalse: false,
1684
+ ignoreTrue: true,
1685
+ });
1212
1686
  }
1213
1687
  // bitmarkAst -> bits -> bitsValue -> * -> isCorrect
1214
1688
  // bitmarkAst -> bits -> bitsValue -> heading -> forKeys
1215
1689
  leaf_forKeys(node, _route) {
1216
1690
  this.writeOPHASH();
1217
- this.writeString(node.value);
1691
+ this.writeBreakscapedTagString(node.value);
1692
+ this.writeCL();
1693
+ }
1694
+ // bitmarkAst -> bits -> bitsValue -> heading -> forValues
1695
+ leaf_forValues(node, _route) {
1696
+ this.writeOPHASH();
1697
+ this.writeBreakscapedTagString(node.value);
1218
1698
  this.writeCL();
1219
1699
  }
1220
1700
  // bitmarkAst -> bits -> bitsValue -> heading -> forValuesValue
1221
1701
  leaf_forValuesValue(node, _route) {
1222
1702
  this.writeOPHASH();
1223
- this.writeString(node.value);
1703
+ this.writeBreakscapedTagString(node.value);
1224
1704
  this.writeCL();
1225
1705
  }
1226
1706
  // bitmarkAst -> bits -> bitsValue -> pairs -> pairsValue -> key
1227
1707
  // bitmarkAst -> bits -> bitsValue -> matrix -> matrixValue -> key
1228
1708
  leaf_key(node, _route) {
1229
1709
  if (node.value) {
1230
- this.writeString(node.value);
1710
+ this.writeBreakscapedTagString(node.value);
1231
1711
  }
1232
1712
  }
1233
1713
  // bitmarkAst -> bits -> bitsValue -> pairs -> pairsValue -> values -> valuesValue
1234
1714
  // bitmarkAst -> bits -> bitsValue -> matrix -> matrixValue -> cells -> cellsValue -> values -> valuesValue
1235
1715
  leaf_valuesValue(node, _route) {
1236
1716
  if (node.value) {
1237
- this.writeString(node.value);
1717
+ this.writeBreakscapedTagString(node.value);
1238
1718
  }
1239
1719
  }
1240
1720
  // bitmarkAst -> bits -> bitsValue -> questions -> questionsValue -> question
@@ -1245,9 +1725,22 @@ class BitmarkGenerator extends AstWalkerGenerator {
1245
1725
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.questionsValue && (parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.flashcardsValue)
1246
1726
  return;
1247
1727
  if (node.value) {
1248
- this.writeString(node.value);
1728
+ this.writeBreakscapedTagString(node.value);
1729
+ // this.writeNL();
1730
+ }
1731
+ }
1732
+ enter_question(node, route) {
1733
+ // Ignore responses that are not at the questionsValue level as they are handled elsewhere
1734
+ const parent = this.getParentNode(route);
1735
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.questionsValue && (parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.flashcardsValue)
1736
+ return true;
1737
+ if (node.value) {
1738
+ this.textGenerator.generateSync(node.value, TextFormat.bitmarkMinusMinus);
1739
+ // this.writeString(node.value);
1249
1740
  // this.writeNL();
1250
1741
  }
1742
+ // Stop traversal of this branch
1743
+ return false;
1251
1744
  }
1252
1745
  // bitmarkAst -> bits -> bitsValue -> statements -> text
1253
1746
  // bitmarkAst -> bits -> bitsValue -> resource -> ...
@@ -1255,25 +1748,53 @@ class BitmarkGenerator extends AstWalkerGenerator {
1255
1748
  // bitmarkAst -> bits -> bitsValue -> resource -> thumbnails -> thumbnailsValue -> ...
1256
1749
  // [src1x,src2x,src3x,src4x,width,height,alt,zoomDisabled,caption]
1257
1750
  leaf_src1x(node, _route) {
1258
- this.writeProperty('src1x', node.value);
1751
+ this.writeProperty('src1x', node.value, {
1752
+ format: PropertyFormat.trimmedString,
1753
+ single: true,
1754
+ ignoreEmpty: true,
1755
+ });
1259
1756
  }
1260
1757
  leaf_src2x(node, _route) {
1261
- this.writeProperty('src2x', node.value);
1758
+ this.writeProperty('src2x', node.value, {
1759
+ format: PropertyFormat.trimmedString,
1760
+ single: true,
1761
+ ignoreEmpty: true,
1762
+ });
1262
1763
  }
1263
1764
  leaf_src3x(node, _route) {
1264
- this.writeProperty('src3x', node.value);
1765
+ this.writeProperty('src3x', node.value, {
1766
+ format: PropertyFormat.trimmedString,
1767
+ single: true,
1768
+ ignoreEmpty: true,
1769
+ });
1265
1770
  }
1266
1771
  leaf_src4x(node, _route) {
1267
- this.writeProperty('src4x', node.value);
1772
+ this.writeProperty('src4x', node.value, {
1773
+ format: PropertyFormat.trimmedString,
1774
+ single: true,
1775
+ ignoreEmpty: true,
1776
+ });
1268
1777
  }
1269
1778
  leaf_width(node, _route) {
1270
- this.writeProperty('width', node.value);
1779
+ this.writeProperty('width', node.value, {
1780
+ format: PropertyFormat.trimmedString,
1781
+ single: true,
1782
+ ignoreEmpty: true,
1783
+ });
1271
1784
  }
1272
1785
  leaf_height(node, _route) {
1273
- this.writeProperty('height', node.value);
1786
+ this.writeProperty('height', node.value, {
1787
+ format: PropertyFormat.trimmedString,
1788
+ single: true,
1789
+ ignoreEmpty: true,
1790
+ });
1274
1791
  }
1275
1792
  leaf_alt(node, _route) {
1276
- this.writeProperty('alt', node.value);
1793
+ this.writeProperty('alt', node.value, {
1794
+ format: PropertyFormat.trimmedString,
1795
+ single: true,
1796
+ ignoreEmpty: true,
1797
+ });
1277
1798
  }
1278
1799
  leaf_zoomDisabled(node, route) {
1279
1800
  const bitType = this.getBitType(route);
@@ -1283,32 +1804,65 @@ class BitmarkGenerator extends AstWalkerGenerator {
1283
1804
  BitType.imagesLogoGrave,
1284
1805
  BitType.prototypeImages,
1285
1806
  ])) {
1286
- this.writeProperty('zoomDisabled', node.value, undefined, false, true);
1807
+ this.writeProperty('zoomDisabled', node.value, {
1808
+ format: PropertyFormat.boolean,
1809
+ single: true,
1810
+ ignoreFalse: false,
1811
+ ignoreTrue: true,
1812
+ });
1287
1813
  }
1288
1814
  else {
1289
- this.writeProperty('zoomDisabled', node.value, undefined, true, false);
1815
+ this.writeProperty('zoomDisabled', node.value, {
1816
+ format: PropertyFormat.boolean,
1817
+ single: true,
1818
+ ignoreFalse: true,
1819
+ ignoreTrue: false,
1820
+ });
1290
1821
  }
1291
1822
  }
1292
1823
  leaf_license(node, _route) {
1293
- this.writeProperty('license', node.value);
1824
+ this.writeProperty('license', node.value, {
1825
+ format: PropertyFormat.trimmedString,
1826
+ single: true,
1827
+ ignoreEmpty: true,
1828
+ });
1294
1829
  }
1295
1830
  leaf_copyright(node, _route) {
1296
- this.writeProperty('copyright', node.value);
1831
+ this.writeProperty('copyright', node.value, {
1832
+ format: PropertyFormat.trimmedString,
1833
+ single: true,
1834
+ ignoreEmpty: true,
1835
+ });
1297
1836
  }
1298
1837
  leaf_provider(_node, _route) {
1299
1838
  // provider is included in the url (it is the domain) and should not be written as a property
1300
1839
  // this.writeProperty('provider', node.value);
1301
1840
  }
1302
1841
  leaf_showInIndex(node, _route) {
1303
- this.writeProperty('showInIndex', node.value);
1842
+ this.writeProperty('showInIndex', node.value, {
1843
+ format: PropertyFormat.boolean,
1844
+ single: true,
1845
+ ignoreEmpty: true,
1846
+ ignoreFalse: true,
1847
+ });
1304
1848
  }
1305
- leaf_caption(node, _route) {
1849
+ enter_caption(node, _route) {
1306
1850
  const value = node.value;
1307
- this.writeProperty('caption', value);
1851
+ this.writeProperty('caption', value, {
1852
+ format: PropertyFormat.bitmarkMinusMinus,
1853
+ single: true, // ??
1854
+ ignoreEmpty: true,
1855
+ });
1856
+ // Stop traversal of this branch
1857
+ return false;
1308
1858
  }
1309
1859
  leaf_search(node, _route) {
1310
1860
  const value = node.value;
1311
- this.writeProperty('search', value);
1861
+ this.writeProperty('search', value, {
1862
+ format: PropertyFormat.trimmedString,
1863
+ single: true,
1864
+ ignoreEmpty: true,
1865
+ });
1312
1866
  }
1313
1867
  // bitmarkAst -> bits -> bitsValue -> resource -> ...
1314
1868
  // bitmarkAst -> bits -> bitsValue -> resource -> posterImage -> ...
@@ -1319,23 +1873,97 @@ class BitmarkGenerator extends AstWalkerGenerator {
1319
1873
  const parent = this.getParentNode(route);
1320
1874
  if ((parent === null || parent === void 0 ? void 0 : parent.key) === NodeType.bitsValue)
1321
1875
  return;
1322
- this.writeProperty('duration', node.value);
1876
+ this.writeProperty('duration', node.value, {
1877
+ format: PropertyFormat.trimmedString,
1878
+ single: true,
1879
+ ignoreEmpty: true,
1880
+ });
1323
1881
  }
1324
1882
  leaf_mute(node, _route) {
1325
- this.writeProperty('mute', node.value);
1883
+ this.writeProperty('mute', node.value, {
1884
+ format: PropertyFormat.boolean,
1885
+ single: true,
1886
+ ignoreEmpty: true,
1887
+ });
1326
1888
  }
1327
1889
  leaf_autoplay(node, _route) {
1328
- this.writeProperty('autoplay', node.value);
1890
+ this.writeProperty('autoplay', node.value, {
1891
+ format: PropertyFormat.boolean,
1892
+ single: true,
1893
+ ignoreEmpty: true,
1894
+ });
1329
1895
  }
1330
1896
  leaf_allowSubtitles(node, _route) {
1331
- this.writeProperty('allowSubtitles', node.value);
1897
+ this.writeProperty('allowSubtitles', node.value, {
1898
+ format: PropertyFormat.boolean,
1899
+ single: true,
1900
+ ignoreEmpty: true,
1901
+ });
1332
1902
  }
1333
1903
  leaf_showSubtitles(node, _route) {
1334
- this.writeProperty('showSubtitles', node.value);
1904
+ this.writeProperty('showSubtitles', node.value, {
1905
+ format: PropertyFormat.boolean,
1906
+ single: true,
1907
+ ignoreEmpty: true,
1908
+ });
1909
+ }
1910
+ //
1911
+ // Resources
1912
+ //
1913
+ // bitmarkAst -> bits -> bitsValue -> resources
1914
+ between_resources(_node, _left, _right, _route) {
1915
+ this.writeNL();
1916
+ }
1917
+ exit_resources(_node, _left, _right, _route) {
1918
+ this.writeNL();
1919
+ }
1920
+ // bitmarkAst -> bits -> bitsValue -> resourcesValue
1921
+ between_resourcesValue(_node, _left, _right, _route) {
1922
+ this.writeNL();
1335
1923
  }
1336
1924
  //
1337
1925
  // Generated Node Handlers
1338
1926
  //
1927
+ /**
1928
+ * Generate the handlers for resources, as they are mostly the same, but not quite
1929
+ */
1930
+ generateResourceHandlers() {
1931
+ for (const tag of ResourceTag.keys()) {
1932
+ // skip unknown
1933
+ if (tag === ResourceTag.keyFromValue(ResourceTag.unknown))
1934
+ continue;
1935
+ const enterFuncName = `enter_${tag}`;
1936
+ // Skip if the function already exists, allows for custom handlers
1937
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1938
+ if (typeof this[enterFuncName] === 'function') {
1939
+ continue;
1940
+ }
1941
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1942
+ this[enterFuncName] = (node, route) => {
1943
+ const resource = node.value;
1944
+ if (resource == null)
1945
+ return false;
1946
+ // Ignore any property that is not at the bit level as that will be handled by a different handler
1947
+ const parent = this.getParentNode(route);
1948
+ if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.resourcesValue)
1949
+ return true;
1950
+ // Get the resource alias
1951
+ const alias = ResourceTag.fromValue(parent.value.__typeAlias);
1952
+ const type = alias !== null && alias !== void 0 ? alias : ResourceTag.fromValue(parent.value.type);
1953
+ if (!type)
1954
+ return false;
1955
+ // url / src / href / app
1956
+ const url = resource.url || resource.src || resource.body || '';
1957
+ // Write the resource
1958
+ this.writeResource(type, url);
1959
+ // Continue traversal
1960
+ return true;
1961
+ };
1962
+ // Bind this
1963
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1964
+ this[enterFuncName] = this[enterFuncName].bind(this);
1965
+ }
1966
+ }
1339
1967
  /**
1340
1968
  * Generate the handlers for properties, as they are mostly the same, but not quite
1341
1969
  */
@@ -1352,36 +1980,15 @@ class BitmarkGenerator extends AstWalkerGenerator {
1352
1980
  const propertiesConfig = Config.getRawPropertiesConfig();
1353
1981
  for (const propertyConfig of Object.values(propertiesConfig)) {
1354
1982
  const astKey = (_a = propertyConfig.astKey) !== null && _a !== void 0 ? _a : propertyConfig.tag;
1355
- // Special cases (handled outside of the automatically generated handlers)
1356
- if (astKey === PropertyTag.internalComment)
1357
- continue;
1358
- if (astKey === PropertyTag.example)
1359
- continue;
1360
- if (astKey === PropertyTag.labelTrue)
1361
- continue;
1362
- if (astKey === PropertyTag.labelFalse)
1363
- continue;
1364
- if (astKey === PropertyTag.posterImage)
1365
- continue;
1366
- if (astKey === PropertyTag.imageSource)
1367
- continue;
1368
- if (astKey === PropertyTag.imagePlaceholder)
1369
- continue;
1370
- if (astKey === PropertyTag.technicalTerm)
1371
- continue;
1372
- if (astKey === PropertyTag.servings)
1373
- continue;
1374
- if (astKey === PropertyTag.person)
1375
- continue;
1376
- if (astKey === PropertyAstKey.ast_markConfig)
1377
- continue;
1378
- if (astKey === PropertyTag.ratingLevelStart)
1379
- continue;
1380
- if (astKey === PropertyTag.ratingLevelEnd)
1381
- continue;
1382
1983
  const enterFuncName = `enter_${astKey}`;
1984
+ // Skip if the function already exists, allows for custom handlers
1985
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1986
+ if (typeof this[enterFuncName] === 'function') {
1987
+ continue;
1988
+ }
1383
1989
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1384
1990
  this[enterFuncName] = (node, route) => {
1991
+ var _a, _b;
1385
1992
  const value = node.value;
1386
1993
  if (value == null)
1387
1994
  return;
@@ -1391,7 +1998,12 @@ class BitmarkGenerator extends AstWalkerGenerator {
1391
1998
  if ((parent === null || parent === void 0 ? void 0 : parent.key) !== NodeType.bitsValue)
1392
1999
  return;
1393
2000
  // Write the property
1394
- this.writeProperty(propertyConfig.tag, node.value, propertyConfig.single, propertyConfig.defaultValue === 'false', propertyConfig.defaultValue === 'true');
2001
+ this.writeProperty(propertyConfig.tag, node.value, {
2002
+ format: (_a = propertyConfig.format) !== null && _a !== void 0 ? _a : PropertyFormat.trimmedString,
2003
+ single: (_b = propertyConfig.single) !== null && _b !== void 0 ? _b : false,
2004
+ ignoreFalse: propertyConfig.defaultValue === 'false',
2005
+ ignoreTrue: propertyConfig.defaultValue === 'true',
2006
+ });
1395
2007
  };
1396
2008
  // Bind this
1397
2009
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -1427,6 +2039,13 @@ class BitmarkGenerator extends AstWalkerGenerator {
1427
2039
  //
1428
2040
  // WRITE FUNCTIONS
1429
2041
  //
2042
+ writeBreakscapedTagString(s) {
2043
+ if (s != null) {
2044
+ this.write(Breakscape.breakscape(`${s}`, {
2045
+ textFormat: TextFormat.bitmarkMinusMinus,
2046
+ }));
2047
+ }
2048
+ }
1430
2049
  writeString(s) {
1431
2050
  if (s != null)
1432
2051
  this.write(`${s}`);
@@ -1495,7 +2114,8 @@ class BitmarkGenerator extends AstWalkerGenerator {
1495
2114
  this.write('[');
1496
2115
  }
1497
2116
  writeCL() {
1498
- this.write(']');
2117
+ // HACK to fix breakscaping when string ends with a ^ (must add a space)
2118
+ this.writer.getLastWrite().endsWith('^') ? this.write(' ]') : this.write(']');
1499
2119
  }
1500
2120
  writeAmpersand() {
1501
2121
  this.write('&');
@@ -1509,6 +2129,9 @@ class BitmarkGenerator extends AstWalkerGenerator {
1509
2129
  writeHash() {
1510
2130
  this.write('#');
1511
2131
  }
2132
+ writePlainTextDivider() {
2133
+ this.write('$$$$');
2134
+ }
1512
2135
  writeCardSetStart() {
1513
2136
  if (this.options.cardSetVersion === CardSetVersion.v1) {
1514
2137
  this.write('\n===');
@@ -1557,84 +2180,86 @@ class BitmarkGenerator extends AstWalkerGenerator {
1557
2180
  this.write('\n');
1558
2181
  }
1559
2182
  writePropertyStyleResource(key, resource) {
1560
- const resourceAsArticle = resource;
2183
+ var _a;
1561
2184
  if (key && resource) {
2185
+ const resourceTag = (_a = ResourceTag.keyFromValue(resource.type)) !== null && _a !== void 0 ? _a : '';
2186
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2187
+ const resourceData = resource[resourceTag];
2188
+ const src = resourceData ? resourceData.src || resourceData.url || resourceData.body || '' : '';
1562
2189
  this.writeOPA();
1563
- this.writeString(key);
1564
- if (resource.type === ResourceTag.article && resourceAsArticle.value) {
1565
- this.writeColon();
1566
- // this.writeNL();
1567
- this.writeString(resourceAsArticle.value);
2190
+ this.writeBreakscapedTagString(key);
2191
+ this.writeColon();
2192
+ this.writeBreakscapedTagString(src);
2193
+ if (resource.type === ResourceTag.article) {
1568
2194
  this.writeNL();
1569
2195
  }
1570
- else if (resource.value) {
1571
- this.writeColon();
1572
- this.writeString(resource.value);
1573
- }
1574
2196
  this.writeCL();
1575
2197
  }
1576
2198
  }
1577
- writeResource(resource) {
1578
- var _a;
1579
- const resourceAsArticle = resource;
1580
- if (resource) {
1581
- // All resources should now be valid as they are validated in the AST
1582
- // TODO: remove code below
1583
- // // Check if a resource has a value, if not, we should not write it (or any of its chained properties)
1584
- // let valid = false;
1585
- // if (resource.value) {
1586
- // valid = true;
1587
- // }
1588
- // // Resource is not valid, cancel walking it's tree.
1589
- // if (!valid) return false;
2199
+ writeResource(type, value) {
2200
+ // const resourceAsArticle = resource as ArticleResource;
2201
+ if (type) {
1590
2202
  // Standard case
1591
2203
  this.writeOPAMP();
1592
- this.writeString((_a = resource.typeAlias) !== null && _a !== void 0 ? _a : resource.type);
1593
- if (resource.type === ResourceTag.article && resourceAsArticle.value) {
1594
- this.writeColon();
1595
- // this.writeNL();
1596
- this.writeString(resourceAsArticle.value);
2204
+ this.writeBreakscapedTagString(type);
2205
+ this.writeColon();
2206
+ this.writeBreakscapedTagString(value);
2207
+ if (type === ResourceTag.article) {
1597
2208
  this.writeNL();
1598
2209
  }
1599
- else if (resource.value) {
1600
- this.writeColon();
1601
- this.writeString(resource.value);
1602
- }
1603
2210
  this.writeCL();
1604
2211
  }
1605
2212
  }
1606
- writeProperty(name, values, singleOnly, ignoreFalse, ignoreTrue) {
2213
+ writeProperty(name, values, options) {
2214
+ var _a;
1607
2215
  let valuesArray;
1608
2216
  let wroteSomething = false;
1609
2217
  if (values !== undefined) {
1610
- if (!Array.isArray(values)) {
1611
- valuesArray = [values];
2218
+ const isBitmarkText = options.format === PropertyFormat.bitmarkMinusMinus || options.format === PropertyFormat.bitmarkPlusPlus;
2219
+ if (isBitmarkText) {
2220
+ // Write bitmark text
2221
+ if (options.ignoreEmpty && isBitmarkText && this.isEmptyText(values))
2222
+ return;
2223
+ this.writeOPA();
2224
+ this.writeBreakscapedTagString(name);
2225
+ this.writeColon();
2226
+ this.textGenerator.generateSync(values, (_a = TextFormat.fromValue(options.format)) !== null && _a !== void 0 ? _a : TextFormat.bitmarkMinusMinus);
2227
+ this.writeCL();
2228
+ wroteSomething = true;
1612
2229
  }
1613
2230
  else {
1614
- valuesArray = values;
1615
- }
1616
- if (valuesArray.length > 0) {
1617
- if (singleOnly)
1618
- valuesArray = valuesArray.slice(valuesArray.length - 1);
1619
- let propertyIndex = 0;
1620
- for (const val of valuesArray) {
1621
- if (val !== undefined) {
1622
- if (ignoreFalse && val === false)
1623
- continue;
1624
- if (ignoreTrue && val === true)
1625
- continue;
1626
- if (propertyIndex > 0)
1627
- this.writeNL();
1628
- this.writeOPA();
1629
- this.writeString(name);
1630
- this.writeColon();
1631
- this.writeString(`${val}`);
1632
- this.writeCL();
1633
- wroteSomething = true;
1634
- propertyIndex++;
2231
+ // Write any other property type
2232
+ if (!Array.isArray(values)) {
2233
+ valuesArray = [values];
2234
+ }
2235
+ else {
2236
+ valuesArray = values;
2237
+ }
2238
+ if (valuesArray.length > 0) {
2239
+ if (options.single)
2240
+ valuesArray = valuesArray.slice(valuesArray.length - 1);
2241
+ let propertyIndex = 0;
2242
+ for (const val of valuesArray) {
2243
+ if (val !== undefined) {
2244
+ if (options.ignoreFalse && val === false)
2245
+ continue;
2246
+ if (options.ignoreTrue && val === true)
2247
+ continue;
2248
+ if (options.ignoreEmpty && val === '')
2249
+ continue;
2250
+ if (propertyIndex > 0)
2251
+ this.writeNL();
2252
+ this.writeOPA();
2253
+ this.writeBreakscapedTagString(name);
2254
+ this.writeColon();
2255
+ this.writeBreakscapedTagString(`${val}`);
2256
+ this.writeCL();
2257
+ wroteSomething = true;
2258
+ propertyIndex++;
2259
+ }
1635
2260
  }
1636
2261
  }
1637
- }
2262
+ } // isBitmarkText
1638
2263
  }
1639
2264
  if (!wroteSomething) {
1640
2265
  this.skipNLBetweenBitsValue = true;
@@ -1656,11 +2281,27 @@ class BitmarkGenerator extends AstWalkerGenerator {
1656
2281
  //
1657
2282
  // Helper functions
1658
2283
  //
2284
+ isEmptyText(text) {
2285
+ if (!text)
2286
+ return true;
2287
+ if (Array.isArray(text))
2288
+ return text.length === 0;
2289
+ return true; // true as not valid TextAst?
2290
+ }
1659
2291
  isWriteTextFormat(bitsValue, textFormatDefault) {
1660
2292
  const isDefault = TextFormat.fromValue(bitsValue) === textFormatDefault;
1661
2293
  const writeFormat = !isDefault || this.options.explicitTextFormat;
1662
2294
  return !!writeFormat;
1663
2295
  }
2296
+ getTextFormat(route) {
2297
+ for (const node of route) {
2298
+ if (node.key === NodeType.bitsValue) {
2299
+ const n = node.value;
2300
+ return n === null || n === void 0 ? void 0 : n.textFormat;
2301
+ }
2302
+ }
2303
+ return undefined;
2304
+ }
1664
2305
  isOfBitType1(route) {
1665
2306
  return this.isOfBitType(route, [BitType.trueFalse1, BitType.multipleChoice1, BitType.multipleResponse1]);
1666
2307
  }