@diplodoc/transform 4.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 (355) hide show
  1. package/CHANGELOG.diplodoc.md +38 -0
  2. package/CHANGELOG.md +404 -0
  3. package/LICENSE +21 -0
  4. package/README.md +41 -0
  5. package/README.ru.md +36 -0
  6. package/dist/css/yfm.css +736 -0
  7. package/dist/css/yfm.css.map +7 -0
  8. package/dist/css/yfm.min.css +2 -0
  9. package/dist/css/yfm.min.css.map +7 -0
  10. package/dist/js/code.d.ts +1 -0
  11. package/dist/js/cut.d.ts +1 -0
  12. package/dist/js/index.d.ts +5 -0
  13. package/dist/js/polyfill.d.ts +1 -0
  14. package/dist/js/tabs.d.ts +1 -0
  15. package/dist/js/term/index.d.ts +1 -0
  16. package/dist/js/term/utils.d.ts +10 -0
  17. package/dist/js/utils.d.ts +2 -0
  18. package/dist/js/yfm.js +432 -0
  19. package/dist/js/yfm.js.map +7 -0
  20. package/dist/js/yfm.min.js +2 -0
  21. package/dist/js/yfm.min.js.map +7 -0
  22. package/lib/getObject.d.ts +2 -0
  23. package/lib/getObject.js +11 -0
  24. package/lib/getObject.js.map +1 -0
  25. package/lib/headings.d.ts +4 -0
  26. package/lib/headings.js +73 -0
  27. package/lib/headings.js.map +1 -0
  28. package/lib/highlight.d.ts +3 -0
  29. package/lib/highlight.js +29 -0
  30. package/lib/highlight.js.map +1 -0
  31. package/lib/index.d.ts +7 -0
  32. package/lib/index.js +35 -0
  33. package/lib/index.js.map +1 -0
  34. package/lib/liquid/conditions.d.ts +4 -0
  35. package/lib/liquid/conditions.js +181 -0
  36. package/lib/liquid/conditions.js.map +1 -0
  37. package/lib/liquid/cycles.d.ts +4 -0
  38. package/lib/liquid/cycles.js +160 -0
  39. package/lib/liquid/cycles.js.map +1 -0
  40. package/lib/liquid/errors.d.ts +3 -0
  41. package/lib/liquid/errors.js +13 -0
  42. package/lib/liquid/errors.js.map +1 -0
  43. package/lib/liquid/evaluation.d.ts +3 -0
  44. package/lib/liquid/evaluation.js +138 -0
  45. package/lib/liquid/evaluation.js.map +1 -0
  46. package/lib/liquid/filters.d.ts +9 -0
  47. package/lib/liquid/filters.js +22 -0
  48. package/lib/liquid/filters.js.map +1 -0
  49. package/lib/liquid/index.d.ts +9 -0
  50. package/lib/liquid/index.js +87 -0
  51. package/lib/liquid/index.js.map +1 -0
  52. package/lib/liquid/lexical.d.ts +14 -0
  53. package/lib/liquid/lexical.js +79 -0
  54. package/lib/liquid/lexical.js.map +1 -0
  55. package/lib/liquid/services/argv.d.ts +15 -0
  56. package/lib/liquid/services/argv.js +17 -0
  57. package/lib/liquid/services/argv.js.map +1 -0
  58. package/lib/liquid/sourceMap.d.ts +24 -0
  59. package/lib/liquid/sourceMap.js +56 -0
  60. package/lib/liquid/sourceMap.js.map +1 -0
  61. package/lib/liquid/substitutions.d.ts +2 -0
  62. package/lib/liquid/substitutions.js +36 -0
  63. package/lib/liquid/substitutions.js.map +1 -0
  64. package/lib/liquid/utils.d.ts +8 -0
  65. package/lib/liquid/utils.js +24 -0
  66. package/lib/liquid/utils.js.map +1 -0
  67. package/lib/log.d.ts +18 -0
  68. package/lib/log.js +54 -0
  69. package/lib/log.js.map +1 -0
  70. package/lib/md.d.ts +14 -0
  71. package/lib/md.js +96 -0
  72. package/lib/md.js.map +1 -0
  73. package/lib/plugins/anchors/collect.d.ts +5 -0
  74. package/lib/plugins/anchors/collect.js +81 -0
  75. package/lib/plugins/anchors/collect.js.map +1 -0
  76. package/lib/plugins/anchors/constants.d.ts +2 -0
  77. package/lib/plugins/anchors/constants.js +6 -0
  78. package/lib/plugins/anchors/constants.js.map +1 -0
  79. package/lib/plugins/anchors/index.d.ts +7 -0
  80. package/lib/plugins/anchors/index.js +134 -0
  81. package/lib/plugins/anchors/index.js.map +1 -0
  82. package/lib/plugins/changelog/collect.d.ts +8 -0
  83. package/lib/plugins/changelog/collect.js +50 -0
  84. package/lib/plugins/changelog/collect.js.map +1 -0
  85. package/lib/plugins/changelog/index.d.ts +6 -0
  86. package/lib/plugins/changelog/index.js +131 -0
  87. package/lib/plugins/changelog/index.js.map +1 -0
  88. package/lib/plugins/changelog/types.d.ts +10 -0
  89. package/lib/plugins/changelog/types.js +3 -0
  90. package/lib/plugins/changelog/types.js.map +1 -0
  91. package/lib/plugins/checkbox/checkbox.d.ts +7 -0
  92. package/lib/plugins/checkbox/checkbox.js +91 -0
  93. package/lib/plugins/checkbox/checkbox.js.map +1 -0
  94. package/lib/plugins/checkbox/index.d.ts +8 -0
  95. package/lib/plugins/checkbox/index.js +12 -0
  96. package/lib/plugins/checkbox/index.js.map +1 -0
  97. package/lib/plugins/code.d.ts +3 -0
  98. package/lib/plugins/code.js +61 -0
  99. package/lib/plugins/code.js.map +1 -0
  100. package/lib/plugins/cut.d.ts +3 -0
  101. package/lib/plugins/cut.js +70 -0
  102. package/lib/plugins/cut.js.map +1 -0
  103. package/lib/plugins/deflist.d.ts +3 -0
  104. package/lib/plugins/deflist.js +8 -0
  105. package/lib/plugins/deflist.js.map +1 -0
  106. package/lib/plugins/file/const.d.ts +27 -0
  107. package/lib/plugins/file/const.js +47 -0
  108. package/lib/plugins/file/const.js.map +1 -0
  109. package/lib/plugins/file/file.d.ts +8 -0
  110. package/lib/plugins/file/file.js +63 -0
  111. package/lib/plugins/file/file.js.map +1 -0
  112. package/lib/plugins/file/index.d.ts +4 -0
  113. package/lib/plugins/file/index.js +9 -0
  114. package/lib/plugins/file/index.js.map +1 -0
  115. package/lib/plugins/images/collect.d.ts +8 -0
  116. package/lib/plugins/images/collect.js +43 -0
  117. package/lib/plugins/images/collect.js.map +1 -0
  118. package/lib/plugins/images/index.d.ts +10 -0
  119. package/lib/plugins/images/index.js +81 -0
  120. package/lib/plugins/images/index.js.map +1 -0
  121. package/lib/plugins/imsize/const.d.ts +7 -0
  122. package/lib/plugins/imsize/const.js +12 -0
  123. package/lib/plugins/imsize/const.js.map +1 -0
  124. package/lib/plugins/imsize/helpers.d.ts +6 -0
  125. package/lib/plugins/imsize/helpers.js +64 -0
  126. package/lib/plugins/imsize/helpers.js.map +1 -0
  127. package/lib/plugins/imsize/index.d.ts +8 -0
  128. package/lib/plugins/imsize/index.js +12 -0
  129. package/lib/plugins/imsize/index.js.map +1 -0
  130. package/lib/plugins/imsize/plugin.d.ts +3 -0
  131. package/lib/plugins/imsize/plugin.js +188 -0
  132. package/lib/plugins/imsize/plugin.js.map +1 -0
  133. package/lib/plugins/includes/collect.d.ts +8 -0
  134. package/lib/plugins/includes/collect.js +49 -0
  135. package/lib/plugins/includes/collect.js.map +1 -0
  136. package/lib/plugins/includes/index.d.ts +8 -0
  137. package/lib/plugins/includes/index.js +98 -0
  138. package/lib/plugins/includes/index.js.map +1 -0
  139. package/lib/plugins/links/collect.d.ts +7 -0
  140. package/lib/plugins/links/collect.js +74 -0
  141. package/lib/plugins/links/collect.js.map +1 -0
  142. package/lib/plugins/links/constants.d.ts +1 -0
  143. package/lib/plugins/links/constants.js +5 -0
  144. package/lib/plugins/links/constants.js.map +1 -0
  145. package/lib/plugins/links/index.d.ts +24 -0
  146. package/lib/plugins/links/index.js +178 -0
  147. package/lib/plugins/links/index.js.map +1 -0
  148. package/lib/plugins/meta.d.ts +3 -0
  149. package/lib/plugins/meta.js +8 -0
  150. package/lib/plugins/meta.js.map +1 -0
  151. package/lib/plugins/monospace.d.ts +3 -0
  152. package/lib/plugins/monospace.js +109 -0
  153. package/lib/plugins/monospace.js.map +1 -0
  154. package/lib/plugins/notes.d.ts +3 -0
  155. package/lib/plugins/notes.js +103 -0
  156. package/lib/plugins/notes.js.map +1 -0
  157. package/lib/plugins/sup.d.ts +3 -0
  158. package/lib/plugins/sup.js +8 -0
  159. package/lib/plugins/sup.js.map +1 -0
  160. package/lib/plugins/table/index.d.ts +3 -0
  161. package/lib/plugins/table/index.js +215 -0
  162. package/lib/plugins/table/index.js.map +1 -0
  163. package/lib/plugins/tabs.d.ts +4 -0
  164. package/lib/plugins/tabs.js +4 -0
  165. package/lib/plugins/tabs.js.map +1 -0
  166. package/lib/plugins/term/constants.d.ts +1 -0
  167. package/lib/plugins/term/constants.js +5 -0
  168. package/lib/plugins/term/constants.js.map +1 -0
  169. package/lib/plugins/term/index.d.ts +3 -0
  170. package/lib/plugins/term/index.js +108 -0
  171. package/lib/plugins/term/index.js.map +1 -0
  172. package/lib/plugins/term/termDefinitions.d.ts +4 -0
  173. package/lib/plugins/term/termDefinitions.js +125 -0
  174. package/lib/plugins/term/termDefinitions.js.map +1 -0
  175. package/lib/plugins/typings.d.ts +12 -0
  176. package/lib/plugins/typings.js +3 -0
  177. package/lib/plugins/typings.js.map +1 -0
  178. package/lib/plugins/utils.d.ts +6 -0
  179. package/lib/plugins/utils.js +30 -0
  180. package/lib/plugins/utils.js.map +1 -0
  181. package/lib/plugins/video/const.d.ts +10 -0
  182. package/lib/plugins/video/const.js +22 -0
  183. package/lib/plugins/video/const.js.map +1 -0
  184. package/lib/plugins/video/index.d.ts +8 -0
  185. package/lib/plugins/video/index.js +104 -0
  186. package/lib/plugins/video/index.js.map +1 -0
  187. package/lib/plugins/video/parsers.d.ts +6 -0
  188. package/lib/plugins/video/parsers.js +64 -0
  189. package/lib/plugins/video/parsers.js.map +1 -0
  190. package/lib/plugins/video/types.d.ts +34 -0
  191. package/lib/plugins/video/types.js +3 -0
  192. package/lib/plugins/video/types.js.map +1 -0
  193. package/lib/plugins/video/utils.d.ts +2 -0
  194. package/lib/plugins/video/utils.js +25 -0
  195. package/lib/plugins/video/utils.js.map +1 -0
  196. package/lib/plugins.d.ts +3 -0
  197. package/lib/plugins.js +36 -0
  198. package/lib/plugins.js.map +1 -0
  199. package/lib/sanitize.d.ts +12 -0
  200. package/lib/sanitize.js +572 -0
  201. package/lib/sanitize.js.map +1 -0
  202. package/lib/title.d.ts +7 -0
  203. package/lib/title.js +18 -0
  204. package/lib/title.js.map +1 -0
  205. package/lib/typings.d.ts +57 -0
  206. package/lib/typings.js +3 -0
  207. package/lib/typings.js.map +1 -0
  208. package/lib/utils.d.ts +13 -0
  209. package/lib/utils.js +79 -0
  210. package/lib/utils.js.map +1 -0
  211. package/lib/utilsFS.d.ts +27 -0
  212. package/lib/utilsFS.js +89 -0
  213. package/lib/utilsFS.js.map +1 -0
  214. package/lib/yfmlint/index.d.ts +26 -0
  215. package/lib/yfmlint/index.js +72 -0
  216. package/lib/yfmlint/index.js.map +1 -0
  217. package/lib/yfmlint/markdownlint-custom-rule/index.d.ts +9 -0
  218. package/lib/yfmlint/markdownlint-custom-rule/index.js +22 -0
  219. package/lib/yfmlint/markdownlint-custom-rule/index.js.map +1 -0
  220. package/lib/yfmlint/markdownlint-custom-rule/yfm001.d.ts +2 -0
  221. package/lib/yfmlint/markdownlint-custom-rule/yfm001.js +28 -0
  222. package/lib/yfmlint/markdownlint-custom-rule/yfm001.js.map +1 -0
  223. package/lib/yfmlint/markdownlint-custom-rule/yfm002.d.ts +2 -0
  224. package/lib/yfmlint/markdownlint-custom-rule/yfm002.js +33 -0
  225. package/lib/yfmlint/markdownlint-custom-rule/yfm002.js.map +1 -0
  226. package/lib/yfmlint/markdownlint-custom-rule/yfm003.d.ts +2 -0
  227. package/lib/yfmlint/markdownlint-custom-rule/yfm003.js +33 -0
  228. package/lib/yfmlint/markdownlint-custom-rule/yfm003.js.map +1 -0
  229. package/lib/yfmlint/markdownlint-custom-rule/yfm004.d.ts +2 -0
  230. package/lib/yfmlint/markdownlint-custom-rule/yfm004.js +28 -0
  231. package/lib/yfmlint/markdownlint-custom-rule/yfm004.js.map +1 -0
  232. package/lib/yfmlint/markdownlint-custom-rule/yfm005.d.ts +2 -0
  233. package/lib/yfmlint/markdownlint-custom-rule/yfm005.js +28 -0
  234. package/lib/yfmlint/markdownlint-custom-rule/yfm005.js.map +1 -0
  235. package/lib/yfmlint/markdownlint-custom-rule/yfm006.d.ts +2 -0
  236. package/lib/yfmlint/markdownlint-custom-rule/yfm006.js +28 -0
  237. package/lib/yfmlint/markdownlint-custom-rule/yfm006.js.map +1 -0
  238. package/lib/yfmlint/markdownlint-custom-rule/yfm007.d.ts +2 -0
  239. package/lib/yfmlint/markdownlint-custom-rule/yfm007.js +29 -0
  240. package/lib/yfmlint/markdownlint-custom-rule/yfm007.js.map +1 -0
  241. package/lib/yfmlint/markdownlint-custom-rule/yfm008.d.ts +2 -0
  242. package/lib/yfmlint/markdownlint-custom-rule/yfm008.js +28 -0
  243. package/lib/yfmlint/markdownlint-custom-rule/yfm008.js.map +1 -0
  244. package/lib/yfmlint/markdownlint-custom-rule/yfm009.d.ts +2 -0
  245. package/lib/yfmlint/markdownlint-custom-rule/yfm009.js +47 -0
  246. package/lib/yfmlint/markdownlint-custom-rule/yfm009.js.map +1 -0
  247. package/lib/yfmlint/typings.d.ts +12 -0
  248. package/lib/yfmlint/typings.js +3 -0
  249. package/lib/yfmlint/typings.js.map +1 -0
  250. package/lib/yfmlint/utils.d.ts +9 -0
  251. package/lib/yfmlint/utils.js +22 -0
  252. package/lib/yfmlint/utils.js.map +1 -0
  253. package/lib/yfmlint/yfmlint.d.ts +3 -0
  254. package/lib/yfmlint/yfmlint.js +69 -0
  255. package/lib/yfmlint/yfmlint.js.map +1 -0
  256. package/package.json +106 -0
  257. package/src/.eslintrc +10 -0
  258. package/src/js/code.ts +65 -0
  259. package/src/js/cut.ts +57 -0
  260. package/src/js/index.ts +6 -0
  261. package/src/js/polyfill.js +27 -0
  262. package/src/js/term/index.ts +79 -0
  263. package/src/js/term/utils.ts +151 -0
  264. package/src/js/utils.ts +9 -0
  265. package/src/scss/_anchor.scss +33 -0
  266. package/src/scss/_code.scss +23 -0
  267. package/src/scss/_common.scss +407 -0
  268. package/src/scss/_cut.scss +42 -0
  269. package/src/scss/_file.scss +35 -0
  270. package/src/scss/_highlight.scss +96 -0
  271. package/src/scss/_note.scss +73 -0
  272. package/src/scss/_print.scss +20 -0
  273. package/src/scss/_term.scss +79 -0
  274. package/src/scss/_variables.scss +16 -0
  275. package/src/scss/yfm.scss +11 -0
  276. package/src/transform/getObject.ts +10 -0
  277. package/src/transform/headings.ts +88 -0
  278. package/src/transform/highlight.ts +33 -0
  279. package/src/transform/index.ts +50 -0
  280. package/src/transform/liquid/conditions.ts +259 -0
  281. package/src/transform/liquid/cycles.ts +244 -0
  282. package/src/transform/liquid/errors.ts +10 -0
  283. package/src/transform/liquid/evaluation.ts +145 -0
  284. package/src/transform/liquid/filters.ts +19 -0
  285. package/src/transform/liquid/index.ts +141 -0
  286. package/src/transform/liquid/lexical.ts +86 -0
  287. package/src/transform/liquid/services/argv.ts +23 -0
  288. package/src/transform/liquid/sourceMap.ts +72 -0
  289. package/src/transform/liquid/substitutions.ts +40 -0
  290. package/src/transform/liquid/utils.ts +30 -0
  291. package/src/transform/log.ts +60 -0
  292. package/src/transform/md.ts +123 -0
  293. package/src/transform/plugins/anchors/collect.ts +101 -0
  294. package/src/transform/plugins/anchors/constants.ts +2 -0
  295. package/src/transform/plugins/anchors/index.ts +166 -0
  296. package/src/transform/plugins/changelog/collect.ts +66 -0
  297. package/src/transform/plugins/changelog/index.ts +164 -0
  298. package/src/transform/plugins/changelog/types.ts +10 -0
  299. package/src/transform/plugins/checkbox/checkbox.ts +107 -0
  300. package/src/transform/plugins/checkbox/index.ts +15 -0
  301. package/src/transform/plugins/code.ts +79 -0
  302. package/src/transform/plugins/cut.ts +98 -0
  303. package/src/transform/plugins/deflist.ts +5 -0
  304. package/src/transform/plugins/file/README.md +34 -0
  305. package/src/transform/plugins/file/const.ts +46 -0
  306. package/src/transform/plugins/file/file.ts +82 -0
  307. package/src/transform/plugins/file/index.ts +10 -0
  308. package/src/transform/plugins/images/collect.ts +60 -0
  309. package/src/transform/plugins/images/index.ts +119 -0
  310. package/src/transform/plugins/imsize/const.ts +7 -0
  311. package/src/transform/plugins/imsize/helpers.ts +75 -0
  312. package/src/transform/plugins/imsize/index.ts +14 -0
  313. package/src/transform/plugins/imsize/plugin.ts +214 -0
  314. package/src/transform/plugins/includes/collect.ts +73 -0
  315. package/src/transform/plugins/includes/index.ts +127 -0
  316. package/src/transform/plugins/links/collect.ts +92 -0
  317. package/src/transform/plugins/links/constants.ts +1 -0
  318. package/src/transform/plugins/links/index.ts +218 -0
  319. package/src/transform/plugins/meta.ts +5 -0
  320. package/src/transform/plugins/monospace.ts +141 -0
  321. package/src/transform/plugins/notes.ts +134 -0
  322. package/src/transform/plugins/sup.ts +5 -0
  323. package/src/transform/plugins/table/index.ts +290 -0
  324. package/src/transform/plugins/tabs.ts +3 -0
  325. package/src/transform/plugins/term/constants.ts +1 -0
  326. package/src/transform/plugins/term/index.ts +139 -0
  327. package/src/transform/plugins/term/termDefinitions.ts +177 -0
  328. package/src/transform/plugins/typings.ts +14 -0
  329. package/src/transform/plugins/utils.ts +38 -0
  330. package/src/transform/plugins/video/const.ts +20 -0
  331. package/src/transform/plugins/video/index.ts +134 -0
  332. package/src/transform/plugins/video/parsers.ts +65 -0
  333. package/src/transform/plugins/video/types.ts +27 -0
  334. package/src/transform/plugins/video/utils.ts +24 -0
  335. package/src/transform/plugins.ts +35 -0
  336. package/src/transform/sanitize.ts +596 -0
  337. package/src/transform/title.ts +22 -0
  338. package/src/transform/typings.ts +64 -0
  339. package/src/transform/utils.ts +91 -0
  340. package/src/transform/utilsFS.ts +128 -0
  341. package/src/transform/yfmlint/README.md +48 -0
  342. package/src/transform/yfmlint/index.ts +124 -0
  343. package/src/transform/yfmlint/markdownlint-custom-rule/index.ts +9 -0
  344. package/src/transform/yfmlint/markdownlint-custom-rule/yfm001.ts +36 -0
  345. package/src/transform/yfmlint/markdownlint-custom-rule/yfm002.ts +33 -0
  346. package/src/transform/yfmlint/markdownlint-custom-rule/yfm003.ts +33 -0
  347. package/src/transform/yfmlint/markdownlint-custom-rule/yfm004.ts +27 -0
  348. package/src/transform/yfmlint/markdownlint-custom-rule/yfm005.ts +27 -0
  349. package/src/transform/yfmlint/markdownlint-custom-rule/yfm006.ts +26 -0
  350. package/src/transform/yfmlint/markdownlint-custom-rule/yfm007.ts +28 -0
  351. package/src/transform/yfmlint/markdownlint-custom-rule/yfm008.ts +26 -0
  352. package/src/transform/yfmlint/markdownlint-custom-rule/yfm009.ts +54 -0
  353. package/src/transform/yfmlint/typings.ts +13 -0
  354. package/src/transform/yfmlint/utils.ts +31 -0
  355. package/src/transform/yfmlint/yfmlint.ts +73 -0
@@ -0,0 +1,259 @@
1
+ import {bold} from 'chalk';
2
+
3
+ import evalExp from './evaluation';
4
+ import {tagLine} from './lexical';
5
+ import {log} from '../log';
6
+ import {getPreparedLeftContent, removeIndentBlock} from './utils';
7
+ import {createSourceMapApi, getLineNumber} from './sourceMap';
8
+
9
+ type Options = {
10
+ firstLineNumber: number;
11
+ lastLineNumber: number;
12
+ resFirstLineNumber: number;
13
+ resLastLineNumber: number;
14
+ linesTotal: number;
15
+ sourceMap: Record<number, number>;
16
+ };
17
+
18
+ function changeSourceMap({
19
+ firstLineNumber,
20
+ lastLineNumber,
21
+ resFirstLineNumber,
22
+ resLastLineNumber,
23
+ linesTotal,
24
+ sourceMap,
25
+ }: Options) {
26
+ if (!sourceMap) {
27
+ return;
28
+ }
29
+
30
+ const {isInlineTag, getSourceMapValue, moveLines, removeLines} = createSourceMapApi({
31
+ firstLineNumber,
32
+ lastLineNumber,
33
+ sourceMap,
34
+ });
35
+
36
+ if (isInlineTag) {
37
+ return;
38
+ }
39
+
40
+ let offsetRestLines;
41
+ if (resFirstLineNumber) {
42
+ // Move condition's content to the top
43
+ const offsetContentLines = firstLineNumber - resFirstLineNumber;
44
+ moveLines({
45
+ start: resFirstLineNumber,
46
+ end: resLastLineNumber - 1,
47
+ offset: offsetContentLines,
48
+ withReplace: true,
49
+ });
50
+
51
+ // Remove the rest lines of the condition block
52
+ removeLines({start: firstLineNumber, end: resFirstLineNumber - 1});
53
+ removeLines({start: resLastLineNumber, end: lastLineNumber});
54
+
55
+ // Calculate an offset of the rest lines
56
+ offsetRestLines = getSourceMapValue(resLastLineNumber - 1) - lastLineNumber;
57
+ } else {
58
+ // Remove the whole condition block
59
+ removeLines({start: firstLineNumber, end: lastLineNumber});
60
+
61
+ // Calculate offset of the rest lines
62
+ offsetRestLines = firstLineNumber - lastLineNumber - 1;
63
+ }
64
+
65
+ // Offset the rest lines
66
+ moveLines({start: lastLineNumber + 1, end: linesTotal, offset: offsetRestLines});
67
+ }
68
+
69
+ function getElseProp<B extends keyof Elses>({elses}: {elses: Elses[]}, propName: B, index = 0) {
70
+ if (!elses.length || index >= elses.length) {
71
+ return undefined;
72
+ }
73
+
74
+ return elses[index][propName];
75
+ }
76
+
77
+ type Opts = {
78
+ ifTag: Tag;
79
+ vars: Record<string, unknown>;
80
+ content: string;
81
+ match: RegExpExecArray;
82
+ lastIndex: number;
83
+ sourceMap: Record<number, number>;
84
+ linesTotal: number;
85
+ };
86
+
87
+ function inlineConditions({ifTag, vars, content, match, lastIndex, sourceMap, linesTotal}: Opts) {
88
+ let res = '';
89
+ const firstLineNumber = getLineNumber(content, ifTag.startPos);
90
+ const lastLineNumber = getLineNumber(content, lastIndex);
91
+ let resFirstLineNumber = 0;
92
+ let resLastLineNumber = 0;
93
+
94
+ if (evalExp(ifTag.condition, vars)) {
95
+ const ifRawLastIndex = ifTag.startPos + ifTag.ifRaw.length;
96
+ const contentLastIndex = getElseProp(ifTag, 'startPos') || match.index;
97
+
98
+ res = content.substring(ifRawLastIndex, contentLastIndex);
99
+ resFirstLineNumber = getLineNumber(content, ifRawLastIndex + 1);
100
+ resLastLineNumber = getLineNumber(content, contentLastIndex + 1);
101
+ } else {
102
+ ifTag.elses.some(({condition, startPos, raw}, index) => {
103
+ const isTruthy = !condition || evalExp(condition, vars);
104
+
105
+ if (isTruthy) {
106
+ const elseRawLastIndex = startPos + raw.length;
107
+ const contentLastIndex = getElseProp(ifTag, 'startPos', index + 1) || match.index;
108
+
109
+ res = content.substring(elseRawLastIndex, contentLastIndex);
110
+ resFirstLineNumber = getLineNumber(content, elseRawLastIndex + 1);
111
+ resLastLineNumber = getLineNumber(content, contentLastIndex + 1);
112
+
113
+ return true;
114
+ }
115
+
116
+ return false;
117
+ });
118
+ }
119
+
120
+ changeSourceMap({
121
+ firstLineNumber,
122
+ lastLineNumber,
123
+ resFirstLineNumber,
124
+ resLastLineNumber,
125
+ linesTotal,
126
+ sourceMap,
127
+ });
128
+
129
+ const preparedLeftContent = getPreparedLeftContent({
130
+ content,
131
+ tagStartPos: ifTag.startPos,
132
+ tagContent: res,
133
+ });
134
+
135
+ let shift = 0;
136
+ if (
137
+ res === '' &&
138
+ preparedLeftContent[preparedLeftContent.length - 1] === '\n' &&
139
+ content[lastIndex] === '\n'
140
+ ) {
141
+ shift = 1;
142
+ }
143
+
144
+ if (res !== '') {
145
+ if (res[0] === '\n') {
146
+ res = res.substring(1);
147
+ }
148
+
149
+ res = removeIndentBlock(res);
150
+
151
+ if (res[res.length - 1] === '\n') {
152
+ res = res.slice(0, -1);
153
+ }
154
+ }
155
+
156
+ const leftPart = preparedLeftContent + res;
157
+
158
+ return {
159
+ result: leftPart + content.substring(lastIndex + shift),
160
+ idx: leftPart.length,
161
+ };
162
+ }
163
+
164
+ type Elses = {startPos: number; raw: string; condition?: string};
165
+
166
+ type Tag = {
167
+ isOpen: Boolean;
168
+ condition: string;
169
+ startPos: number;
170
+ ifRaw: string;
171
+ elses: Elses[];
172
+ };
173
+
174
+ export = function conditions(
175
+ originInput: string,
176
+ vars: Record<string, unknown>,
177
+ path?: string,
178
+ settings?: {
179
+ sourceMap: Record<number, number>;
180
+ },
181
+ ) {
182
+ const sourceMap = settings?.sourceMap || {};
183
+
184
+ const R_LIQUID = /({%-?([\s\S]*?)-?%})/g;
185
+
186
+ let match;
187
+ const tagStack: Tag[] = [];
188
+ let input = originInput;
189
+ let linesTotal = originInput.split('\n').length;
190
+
191
+ while ((match = R_LIQUID.exec(input)) !== null) {
192
+ if (!match[1]) {
193
+ continue;
194
+ }
195
+
196
+ const tagMatch = match[2].trim().match(tagLine);
197
+ if (!tagMatch) {
198
+ continue;
199
+ }
200
+
201
+ const [type, args] = tagMatch.slice(1);
202
+
203
+ switch (type) {
204
+ case 'if':
205
+ tagStack.push({
206
+ isOpen: true,
207
+ condition: args,
208
+ startPos: match.index,
209
+ ifRaw: match[1],
210
+ elses: [],
211
+ });
212
+ break;
213
+ case 'else':
214
+ tagStack[tagStack.length - 1].elses.push({
215
+ startPos: match.index,
216
+ raw: match[1],
217
+ });
218
+ break;
219
+ case 'elsif':
220
+ tagStack[tagStack.length - 1].elses.push({
221
+ condition: args,
222
+ startPos: match.index,
223
+ raw: match[1],
224
+ });
225
+ break;
226
+ case 'endif': {
227
+ const ifTag = tagStack.pop();
228
+
229
+ if (!ifTag) {
230
+ log.error(
231
+ `If block must be opened before close${path ? ` in ${bold(path)}` : ''}`,
232
+ );
233
+ break;
234
+ }
235
+
236
+ const {idx, result} = inlineConditions({
237
+ ifTag,
238
+ vars,
239
+ content: input,
240
+ match,
241
+ lastIndex: R_LIQUID.lastIndex,
242
+ sourceMap,
243
+ linesTotal,
244
+ });
245
+ R_LIQUID.lastIndex = idx;
246
+ input = result;
247
+ linesTotal = result.split('\n').length;
248
+
249
+ break;
250
+ }
251
+ }
252
+ }
253
+
254
+ if (tagStack.length !== 0) {
255
+ log.error(`Condition block must be closed${path ? ` in ${bold(path)}` : ''}`);
256
+ }
257
+
258
+ return input;
259
+ };
@@ -0,0 +1,244 @@
1
+ import {bold} from 'chalk';
2
+
3
+ import {evalExp} from './evaluation';
4
+ import {tagLine, variable} from './lexical';
5
+ import {log} from '../log';
6
+ import {getPreparedLeftContent} from './utils';
7
+ import {createSourceMapApi, getLineNumber} from './sourceMap';
8
+ import applyLiquid from './index';
9
+
10
+ type Options = {
11
+ firstLineNumber: number;
12
+ lastLineNumber: number;
13
+ resFirstLineNumber: number;
14
+ resLastLineNumber: number;
15
+ contentLinesTotal: number;
16
+ linesTotal: number;
17
+ sourceMap: Record<number, number>;
18
+ };
19
+
20
+ function changeSourceMap({
21
+ firstLineNumber,
22
+ lastLineNumber,
23
+ resFirstLineNumber,
24
+ resLastLineNumber,
25
+ contentLinesTotal,
26
+ linesTotal,
27
+ sourceMap,
28
+ }: Options) {
29
+ if (!sourceMap) {
30
+ return;
31
+ }
32
+
33
+ const {isInlineTag, moveLines, removeLine} = createSourceMapApi({
34
+ firstLineNumber,
35
+ lastLineNumber,
36
+ sourceMap,
37
+ });
38
+
39
+ if (isInlineTag || !resFirstLineNumber) {
40
+ return;
41
+ }
42
+
43
+ const offsetRestLines = contentLinesTotal - (lastLineNumber - firstLineNumber + 1);
44
+
45
+ // Move condition's content to the top
46
+ const offsetContentLines = firstLineNumber - resFirstLineNumber;
47
+ moveLines({
48
+ start: resFirstLineNumber,
49
+ end: resLastLineNumber - 1,
50
+ offset: offsetContentLines,
51
+ withReplace: true,
52
+ });
53
+
54
+ // Remove tags
55
+ removeLine(firstLineNumber);
56
+ removeLine(lastLineNumber);
57
+
58
+ // Offset the rest lines
59
+ moveLines({start: lastLineNumber + 1, end: linesTotal, offset: offsetRestLines});
60
+ }
61
+
62
+ type Args2 = {
63
+ forTag: Tag;
64
+ vars: Record<string, unknown>;
65
+ content: string;
66
+ match: RegExpExecArray;
67
+ path?: string;
68
+ lastIndex: number;
69
+ sourceMap: Record<number, number>;
70
+ linesTotal: number;
71
+ };
72
+
73
+ function inlineConditions({
74
+ forTag,
75
+ vars,
76
+ content,
77
+ match,
78
+ path,
79
+ lastIndex,
80
+ sourceMap,
81
+ linesTotal,
82
+ }: Args2) {
83
+ let res = '';
84
+ const firstLineNumber = getLineNumber(content, forTag.startPos);
85
+ const lastLineNumber = getLineNumber(content, lastIndex);
86
+
87
+ const forRawLastIndex = forTag.startPos + forTag.forRaw.length;
88
+ const contentLastIndex = match.index;
89
+
90
+ const forTemplate = content.substring(forRawLastIndex, contentLastIndex);
91
+ const resFirstLineNumber = getLineNumber(content, forRawLastIndex + 1);
92
+ const resLastLineNumber = getLineNumber(content, contentLastIndex + 1);
93
+
94
+ let collection = evalExp(forTag.collectionName, vars);
95
+ if (!collection || !Array.isArray(collection)) {
96
+ collection = [];
97
+ log.error(`${bold(forTag.collectionName)} is undefined or not iterable`);
98
+ }
99
+
100
+ collection.forEach((item) => {
101
+ const newVars = {...vars, [forTag.variableName]: item};
102
+ res += applyLiquid(forTemplate, newVars, path).trimRight();
103
+ });
104
+
105
+ const contentLinesTotal = res.split('\n').length - 1;
106
+
107
+ changeSourceMap({
108
+ firstLineNumber,
109
+ lastLineNumber,
110
+ resFirstLineNumber,
111
+ resLastLineNumber,
112
+ linesTotal,
113
+ sourceMap,
114
+ contentLinesTotal,
115
+ });
116
+
117
+ const preparedLeftContent = getPreparedLeftContent({
118
+ content,
119
+ tagStartPos: forTag.startPos,
120
+ tagContent: res,
121
+ });
122
+
123
+ let shift = 0;
124
+ if (
125
+ res === '' &&
126
+ preparedLeftContent[preparedLeftContent.length - 1] === '\n' &&
127
+ content[lastIndex] === '\n'
128
+ ) {
129
+ shift = 1;
130
+ }
131
+
132
+ if (res !== '') {
133
+ if (res[0] === ' ' || res[0] === '\n') {
134
+ res = res.substring(1);
135
+ }
136
+ }
137
+
138
+ const leftPart = preparedLeftContent + res;
139
+
140
+ return {
141
+ result: leftPart + content.substring(lastIndex + shift),
142
+ idx: leftPart.length,
143
+ };
144
+ }
145
+
146
+ type Tag = {
147
+ item: string;
148
+ variableName: string;
149
+ collectionName: string;
150
+ startPos: number;
151
+ forRaw: string;
152
+ };
153
+
154
+ export = function cycles(
155
+ originInput: string,
156
+ vars: Record<string, unknown>,
157
+ path?: string,
158
+ settings: {sourceMap?: Record<number, number>} = {},
159
+ ) {
160
+ const {sourceMap} = settings;
161
+
162
+ const R_LIQUID = /({%-?([\s\S]*?)-?%})/g;
163
+ const FOR_SYNTAX = new RegExp(`(\\w+)\\s+in\\s+(${variable.source})`);
164
+
165
+ let match;
166
+ const tagStack: Tag[] = [];
167
+ let input = originInput;
168
+ let countSkippedInnerTags = 0;
169
+ let linesTotal = originInput.split('\n').length;
170
+
171
+ while ((match = R_LIQUID.exec(input)) !== null) {
172
+ if (!match[1]) {
173
+ continue;
174
+ }
175
+
176
+ const tagMatch = match[2].trim().match(tagLine);
177
+ if (!tagMatch) {
178
+ continue;
179
+ }
180
+
181
+ const [type, args] = tagMatch.slice(1);
182
+
183
+ switch (type) {
184
+ case 'for': {
185
+ if (tagStack.length) {
186
+ countSkippedInnerTags += 1;
187
+ break;
188
+ }
189
+
190
+ const matches = args.match(FOR_SYNTAX);
191
+ if (!matches) {
192
+ log.error(`Incorrect syntax in if condition${path ? ` in ${bold(path)}` : ''}`);
193
+ break;
194
+ }
195
+
196
+ const [variableName, collectionName] = matches.slice(1);
197
+ tagStack.push({
198
+ item: args,
199
+ variableName,
200
+ collectionName,
201
+ startPos: match.index,
202
+ forRaw: match[1],
203
+ });
204
+ break;
205
+ }
206
+ case 'endfor': {
207
+ if (countSkippedInnerTags > 0) {
208
+ countSkippedInnerTags -= 1;
209
+ break;
210
+ }
211
+ const forTag = tagStack.pop();
212
+
213
+ if (!forTag) {
214
+ log.error(
215
+ `For block must be opened before close${path ? ` in ${bold(path)}` : ''}`,
216
+ );
217
+ break;
218
+ }
219
+
220
+ const {idx, result} = inlineConditions({
221
+ forTag,
222
+ vars,
223
+ content: input,
224
+ match,
225
+ path,
226
+ lastIndex: R_LIQUID.lastIndex,
227
+ sourceMap: sourceMap || {},
228
+ linesTotal,
229
+ });
230
+ R_LIQUID.lastIndex = idx;
231
+ input = result;
232
+ linesTotal = result.split('\n').length;
233
+
234
+ break;
235
+ }
236
+ }
237
+ }
238
+
239
+ if (tagStack.length !== 0) {
240
+ log.error(`For block must be closed${path ? ` in ${bold(path)}` : ''}`);
241
+ }
242
+
243
+ return input;
244
+ };
@@ -0,0 +1,10 @@
1
+ import {bold} from 'chalk';
2
+
3
+ export class SkippedEvalError extends Error {
4
+ constructor(message: string, exp: string) {
5
+ super();
6
+
7
+ this.name = 'SkippedEvalError';
8
+ this.message = `${message}: ${bold(exp)}`;
9
+ }
10
+ }
@@ -0,0 +1,145 @@
1
+ import * as lexical from './lexical';
2
+ import getObject from '../getObject';
3
+ import {log} from '../log';
4
+ import filters from './filters';
5
+ import {SkippedEvalError} from './errors';
6
+
7
+ type Scope = Record<string, unknown>;
8
+
9
+ type WithFilter = (l: string, filter: (s: string) => boolean, exp: string) => boolean;
10
+ type NoFilter = (l: string, r: string, exp: string) => boolean;
11
+ type DotOperator = (
12
+ l: Record<string, (...args: unknown[]) => unknown>,
13
+ r: string,
14
+ exp: string,
15
+ ) => boolean;
16
+
17
+ const operators: Record<string, WithFilter | NoFilter | DotOperator> = {
18
+ '==': ((l, r) => l === r) as NoFilter,
19
+ '!=': ((l, r) => l !== r) as NoFilter,
20
+ '>': ((l, r) => l !== null && r !== null && l > r) as NoFilter,
21
+ '<': ((l, r) => l !== null && r !== null && l < r) as NoFilter,
22
+ '>=': ((l, r) => l !== null && r !== null && l >= r) as NoFilter,
23
+ '<=': ((l, r) => l !== null && r !== null && l <= r) as NoFilter,
24
+ contains: ((l, r) => l !== null && r !== null && l.includes(r)) as NoFilter,
25
+ and: ((l, r) => isTruthy(l) && isTruthy(r)) as NoFilter,
26
+ or: ((l, r) => isTruthy(l) || isTruthy(r)) as NoFilter,
27
+ '|': ((l, filter, exp) => {
28
+ try {
29
+ return filter(l);
30
+ } catch (e) {
31
+ if (!filter) {
32
+ throw new SkippedEvalError('Cannot apply an unsupported filter', exp);
33
+ }
34
+
35
+ throw new SkippedEvalError('There are some problems with the filter', exp);
36
+ }
37
+ }) as WithFilter,
38
+ '.': ((l, r, exp) => {
39
+ const parsed = lexical.getParsedMethod(r);
40
+
41
+ try {
42
+ if (!parsed) throw new Error();
43
+ const {name, args} = parsed;
44
+
45
+ return l[name](...args);
46
+ } catch (e) {
47
+ if (!l) {
48
+ throw new SkippedEvalError(
49
+ `Cannot apply the function '${name}' on an undefined variable`,
50
+ exp,
51
+ );
52
+ }
53
+
54
+ throw new SkippedEvalError('There are some problems with the function', exp);
55
+ }
56
+ }) as DotOperator,
57
+ };
58
+
59
+ function evalValue(originStr: string, scope: Scope) {
60
+ const str = originStr && originStr.trim();
61
+ if (!str) {
62
+ return undefined;
63
+ }
64
+
65
+ if (lexical.isLiteral(str)) {
66
+ return lexical.parseLiteral(str);
67
+ }
68
+ if (lexical.isVariable(str)) {
69
+ return getObject(str, scope);
70
+ }
71
+
72
+ throw new TypeError(`cannot eval '${str}' as value`);
73
+ }
74
+
75
+ function isTruthy(val: unknown) {
76
+ return !isFalsy(val);
77
+ }
78
+
79
+ function isFalsy(val: unknown) {
80
+ return val === false || undefined === val || val === null;
81
+ }
82
+
83
+ export function evalExp(
84
+ exp: string,
85
+ scope: Record<string, unknown>,
86
+ ): string[] | boolean | string | undefined | ((input: string) => number | string) {
87
+ const operatorREs = lexical.operators;
88
+ let match;
89
+
90
+ if (Object.getOwnPropertyNames(filters).includes(exp.trim())) {
91
+ return filters[exp.trim() as keyof typeof filters];
92
+ }
93
+
94
+ if (lexical.isSupportedMethod(exp)) {
95
+ return exp;
96
+ }
97
+
98
+ try {
99
+ for (let i = 0; i < operatorREs.length; i++) {
100
+ const operatorRE = operatorREs[i];
101
+ const expRE = new RegExp(
102
+ `^(${lexical.quoteBalanced.source})(${operatorRE.source})(${lexical.quoteBalanced.source})$`,
103
+ );
104
+ if ((match = exp.match(expRE))) {
105
+ const l = evalExp(match[1], scope);
106
+ const operator = match[2].trim();
107
+ const op = operators[operator];
108
+ const r = evalExp(match[3], scope);
109
+
110
+ if (
111
+ operator !== '.' ||
112
+ (operator === '.' && lexical.isSupportedMethod(r as string))
113
+ ) {
114
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
115
+ return op(l as any, r as any, exp);
116
+ }
117
+ }
118
+ }
119
+
120
+ if ((match = exp.match(lexical.rangeLine))) {
121
+ const low = evalValue(match[1], scope);
122
+ const high = evalValue(match[2], scope);
123
+ const range = [];
124
+
125
+ for (let j = low; j <= high; j++) {
126
+ range.push(j);
127
+ }
128
+
129
+ return range;
130
+ }
131
+
132
+ return evalValue(exp, scope);
133
+ } catch (e) {
134
+ if (e instanceof SkippedEvalError) {
135
+ log.warn(`Skip error: ${e}`);
136
+ return undefined;
137
+ }
138
+
139
+ log.error(`Error: ${e}`);
140
+ }
141
+
142
+ return undefined;
143
+ }
144
+
145
+ export default (exp: string, scope: Record<string, unknown>) => Boolean(evalExp(exp, scope));
@@ -0,0 +1,19 @@
1
+ export function length(input: string) {
2
+ return input.length;
3
+ }
4
+
5
+ export function capitalize(input: string) {
6
+ return String(input).replace(/^([a-z])/, (_m, chr) => chr.toUpperCase());
7
+ }
8
+
9
+ export function escapeMarkdown(input: string) {
10
+ return String(input).replace(/([\\`*_{}[\]()#+\-.!|])/g, '\\$1');
11
+ }
12
+
13
+ const index = {
14
+ length,
15
+ capitalize,
16
+ escapeMarkdown,
17
+ };
18
+
19
+ export default index;