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