@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,98 @@
1
+ import type Core from 'markdown-it/lib/parser_core';
2
+ import type Token from 'markdown-it/lib/token';
3
+ import {MarkdownItPluginCb} from './typings';
4
+ import {MatchTokenFunction, nestedCloseTokenIdxFactory as closeTokenFactory} from './utils';
5
+
6
+ const CUT_REGEXP = /^{%\s*cut\s*["|'](.*)["|']\s*%}/;
7
+
8
+ const matchCloseToken: MatchTokenFunction = (tokens, i) => {
9
+ return (
10
+ tokens[i].type === 'paragraph_open' &&
11
+ tokens[i + 1].type === 'inline' &&
12
+ tokens[i + 1].content.trim() === '{% endcut %}'
13
+ );
14
+ };
15
+
16
+ const matchOpenToken = (tokens: Token[], i: number) => {
17
+ return (
18
+ tokens[i].type === 'paragraph_open' &&
19
+ tokens[i + 1].type === 'inline' &&
20
+ tokens[i + 1].content.match(CUT_REGEXP)
21
+ );
22
+ };
23
+
24
+ const findCloseTokenIdx = closeTokenFactory('Cut', matchOpenToken, matchCloseToken);
25
+
26
+ const cut: MarkdownItPluginCb = (md, {path, log}) => {
27
+ const plugin: Core.RuleCore = (state) => {
28
+ const tokens = state.tokens;
29
+ let i = 0;
30
+
31
+ while (i < tokens.length) {
32
+ const match = matchOpenToken(tokens, i);
33
+
34
+ if (match) {
35
+ const closeTokenIdx = findCloseTokenIdx(tokens, i + 4, path, log);
36
+
37
+ if (!closeTokenIdx) {
38
+ i += 3;
39
+ continue;
40
+ }
41
+
42
+ const newOpenToken = new state.Token('yfm_cut_open', 'div', 1);
43
+ newOpenToken.attrSet('class', 'yfm-cut');
44
+ newOpenToken.map = tokens[i].map;
45
+
46
+ const titleOpen = new state.Token('yfm_cut_title_open', 'div', 1);
47
+ titleOpen.attrSet('class', 'yfm-cut-title');
48
+
49
+ const titleInline = state.md.parseInline(
50
+ match[1] === undefined ? 'ad' : match[1],
51
+ state.env,
52
+ )[0];
53
+
54
+ const titleClose = new state.Token('yfm_cut_title_close', 'div', -1);
55
+
56
+ const contentOpen = new state.Token('yfm_cut_content_open', 'div', 1);
57
+ contentOpen.attrSet('class', 'yfm-cut-content');
58
+
59
+ if (newOpenToken.map) {
60
+ const contentOpenStart = newOpenToken.map[0] + 1;
61
+ const contentOpenEnd = newOpenToken.map[0] + 2;
62
+
63
+ contentOpen.map = [contentOpenStart, contentOpenEnd];
64
+ }
65
+
66
+ const contentClose = new state.Token('yfm_cut_content_close', 'div', -1);
67
+
68
+ const newCloseToken = new state.Token('yfm_cut_close', 'div', -1);
69
+ newCloseToken.map = tokens[closeTokenIdx].map;
70
+
71
+ const insideTokens = [
72
+ newOpenToken,
73
+ titleOpen,
74
+ titleInline,
75
+ titleClose,
76
+ contentOpen,
77
+ ...tokens.slice(i + 3, closeTokenIdx),
78
+ contentClose,
79
+ newCloseToken,
80
+ ];
81
+
82
+ tokens.splice(i, closeTokenIdx - i + 3, ...insideTokens);
83
+
84
+ i++;
85
+ } else {
86
+ i++;
87
+ }
88
+ }
89
+ };
90
+
91
+ try {
92
+ md.core.ruler.before('curly_attributes', 'cut', plugin);
93
+ } catch (e) {
94
+ md.core.ruler.push('cut', plugin);
95
+ }
96
+ };
97
+
98
+ export = cut;
@@ -0,0 +1,5 @@
1
+ // @ts-expect-error
2
+ import deflist from 'markdown-it-deflist';
3
+ import {MarkdownItPluginCb} from './typings';
4
+
5
+ export = deflist as MarkdownItPluginCb;
@@ -0,0 +1,34 @@
1
+ # YFM File plugin
2
+
3
+ ```md
4
+ {% file src="path/to/file" name='readme.md' %}
5
+
6
+ ==>
7
+
8
+ <a href="path/to/file" download="readme.md" class="yfm-file"><span class="yfm-file__icon"></span>readme.md</a>
9
+ ```
10
+
11
+ ## Attributes
12
+
13
+ |Name|Required|Description|
14
+ |---|---|---|
15
+ |`src`|yes|URL of the file. Will be mapped to [`href` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-href)|
16
+ |`name`|yes|Name of the file. Will be mapped to [`download` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download)|
17
+ |`lang`|-|Language of the file content. Will be mapped to [`hreflang` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-hreflang)|
18
+ |`referrerpolicy`|-|[`referrerpolicy` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-referrerpolicy)|
19
+ |`rel`|-|[`rel` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-rel)|
20
+ |`target`|-|[`target` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-target)|
21
+ |`type`|-|[`type` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-type)|
22
+
23
+ > _Note: other attributes will be ignored_
24
+
25
+ ## Plugin options
26
+
27
+ |Name|Type|Description|
28
+ |---|---|---|
29
+ |`fileExtraAttrs`|`[string, string][]`|Adds additional attributes to rendered hyperlink|
30
+
31
+ ## CSS public variables
32
+
33
+ * `--yfm-file-icon` – sets custom file icon image
34
+ * `--yfm-file-icon-color` – sets custom file icon color
@@ -0,0 +1,46 @@
1
+ export enum FileSpecialAttr {
2
+ Src = 'src',
3
+ Name = 'name',
4
+ Lang = 'lang',
5
+ }
6
+
7
+ // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attributes
8
+ export enum LinkHtmlAttr {
9
+ Download = 'download',
10
+ Href = 'href',
11
+ HrefLang = 'hreflang',
12
+ Media = 'media',
13
+ Ping = 'ping',
14
+ ReferrerPolicy = 'referrerpolicy',
15
+ Rel = 'rel',
16
+ Target = 'target',
17
+ Type = 'type',
18
+ }
19
+
20
+ export const FILE_TO_LINK_ATTRS_MAP: Record<FileSpecialAttr, LinkHtmlAttr> = {
21
+ [FileSpecialAttr.Src]: LinkHtmlAttr.Href,
22
+ [FileSpecialAttr.Name]: LinkHtmlAttr.Download,
23
+ [FileSpecialAttr.Lang]: LinkHtmlAttr.HrefLang,
24
+ };
25
+
26
+ export const RULE_NAME = 'yfm_file_inline';
27
+ export const KNOWN_ATTRS: readonly string[] = [
28
+ FileSpecialAttr.Src,
29
+ FileSpecialAttr.Name,
30
+ FileSpecialAttr.Lang,
31
+ LinkHtmlAttr.ReferrerPolicy,
32
+ LinkHtmlAttr.Rel,
33
+ LinkHtmlAttr.Target,
34
+ LinkHtmlAttr.Type,
35
+ ];
36
+ export const REQUIRED_ATTRS: readonly string[] = [FileSpecialAttr.Src, FileSpecialAttr.Name];
37
+
38
+ export const FILE_TOKEN = 'yfm_file';
39
+
40
+ export const PREFIX = '{% file ';
41
+ export const PREFIX_LENGTH = PREFIX.length;
42
+
43
+ export enum FileClassName {
44
+ Link = 'yfm-file',
45
+ Icon = 'yfm-file__icon',
46
+ }
@@ -0,0 +1,82 @@
1
+ import type MarkdownIt from 'markdown-it';
2
+ import type ParserInline from 'markdown-it/lib/parser_inline';
3
+ import type Renderer from 'markdown-it/lib/renderer';
4
+
5
+ import {
6
+ FileClassName,
7
+ FileSpecialAttr,
8
+ FILE_TOKEN,
9
+ FILE_TO_LINK_ATTRS_MAP,
10
+ KNOWN_ATTRS,
11
+ PREFIX,
12
+ PREFIX_LENGTH,
13
+ REQUIRED_ATTRS,
14
+ } from './const';
15
+
16
+ export type FileOptions = {
17
+ fileExtraAttrs: [string, string][];
18
+ };
19
+
20
+ export const fileRenderer = (md: MarkdownIt): Renderer.RenderRule => {
21
+ const iconHtml = `<span class="${md.utils.escapeHtml(FileClassName.Icon)}"></span>`;
22
+ return (tokens, idx, _opts, _env, self) => {
23
+ const token = tokens[idx];
24
+ return `<a${self.renderAttrs(token)}>${iconHtml}${md.utils.escapeHtml(token.content)}</a>`;
25
+ };
26
+ };
27
+
28
+ export const fileParser = (_md: MarkdownIt, opts?: FileOptions): ParserInline.RuleInline => {
29
+ return (state, silent) => {
30
+ if (state.src.substring(state.pos, state.pos + PREFIX_LENGTH) !== PREFIX) return false;
31
+
32
+ // the rest of line after '{% file '
33
+ const searchStr = state.src.slice(state.pos + PREFIX_LENGTH, state.posMax);
34
+ // loking for pattern 'src="..." name="..." etc="value" %}'
35
+ const matchResult = searchStr.match(/^((?:\s*\w+=(?:"[^"]+"|'[^']+')\s)+)\s*%}/);
36
+ if (!matchResult) return false;
37
+
38
+ const paramsGroupLength = matchResult[0].length; // '(src="..." name="...")'.length
39
+ const paramsStr = matchResult[1]; // 'src="..." name="..."'
40
+
41
+ // find pairs of key="foo" or key='bar'
42
+ const params = paramsStr.match(/\w+=(?:"[^"]+"|'[^']+')/g);
43
+ if (!params) return false;
44
+
45
+ const attrsObj: Record<string, string> = {};
46
+ params.forEach((param) => {
47
+ const indexKey = param.indexOf('=');
48
+ const key = param.slice(0, indexKey);
49
+ const value = param.slice(indexKey + 2, -1);
50
+ if (KNOWN_ATTRS.includes(key) && value) {
51
+ attrsObj[key] = value;
52
+ }
53
+ });
54
+
55
+ const hasAllRequiredAttrs = REQUIRED_ATTRS.every((attr) => attr in attrsObj);
56
+ if (!hasAllRequiredAttrs) return false;
57
+
58
+ if (!silent) {
59
+ const token = state.push(FILE_TOKEN, '', 0);
60
+ token.block = false;
61
+ token.markup = PREFIX;
62
+ token.content = attrsObj[FileSpecialAttr.Name];
63
+ token.attrs = Object.entries(attrsObj);
64
+ token.attrSet('class', FileClassName.Link);
65
+
66
+ for (const attr of token.attrs) {
67
+ if (attr[0] in FILE_TO_LINK_ATTRS_MAP) {
68
+ attr[0] = FILE_TO_LINK_ATTRS_MAP[attr[0] as FileSpecialAttr];
69
+ }
70
+ }
71
+
72
+ if (Array.isArray(opts?.fileExtraAttrs)) {
73
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
74
+ token.attrs.push(...opts!.fileExtraAttrs);
75
+ }
76
+ }
77
+
78
+ state.pos = state.pos + PREFIX_LENGTH + paramsGroupLength;
79
+
80
+ return true;
81
+ };
82
+ };
@@ -0,0 +1,10 @@
1
+ import type {PluginWithOptions} from 'markdown-it';
2
+ import {FILE_TOKEN, RULE_NAME} from './const';
3
+ import {FileOptions, fileParser, fileRenderer} from './file';
4
+
5
+ const filePlugin: PluginWithOptions<FileOptions> = (md, opts) => {
6
+ md.inline.ruler.push(RULE_NAME, fileParser(md, opts));
7
+ md.renderer.rules[FILE_TOKEN] = fileRenderer(md);
8
+ };
9
+
10
+ export = filePlugin;
@@ -0,0 +1,60 @@
1
+ import MarkdownIt from 'markdown-it';
2
+ import {relative} from 'path';
3
+
4
+ import {isLocalUrl} from '../../utils';
5
+ import {resolveRelativePath} from '../../utilsFS';
6
+ import imsize from '../imsize';
7
+ import {MarkdownItPluginOpts} from '../typings';
8
+
9
+ type Options = MarkdownItPluginOpts & {
10
+ destPath: string;
11
+ copyFile: (path: string, dest: string) => void;
12
+ singlePage: boolean;
13
+ };
14
+
15
+ const collect = (input: string, options: Options) => {
16
+ const md = new MarkdownIt().use(imsize);
17
+
18
+ const {root, path, destPath = '', copyFile, singlePage} = options;
19
+ const tokens = md.parse(input, {});
20
+ let result = input;
21
+
22
+ tokens.forEach((token) => {
23
+ if (token.type !== 'inline') {
24
+ return;
25
+ }
26
+
27
+ const children = token.children || [];
28
+
29
+ children.forEach((childToken) => {
30
+ if (childToken.type !== 'image') {
31
+ return;
32
+ }
33
+
34
+ const src = childToken.attrGet('src') || '';
35
+
36
+ if (!isLocalUrl(src)) {
37
+ return;
38
+ }
39
+
40
+ const targetPath = resolveRelativePath(path, src);
41
+ const targetDestPath = resolveRelativePath(destPath, src);
42
+
43
+ if (singlePage && !path.includes('_includes/')) {
44
+ const newSrc = relative(root, resolveRelativePath(path, src));
45
+
46
+ result = result.replace(src, newSrc);
47
+ }
48
+
49
+ copyFile(targetPath, targetDestPath);
50
+ });
51
+ });
52
+
53
+ if (singlePage) {
54
+ return result;
55
+ }
56
+
57
+ return null;
58
+ };
59
+
60
+ export = collect;
@@ -0,0 +1,119 @@
1
+ import {readFileSync} from 'fs';
2
+ import {join, sep} from 'path';
3
+ import {bold} from 'chalk';
4
+
5
+ import {resolveRelativePath, isFileExists} from '../../utilsFS';
6
+ import {isLocalUrl, isExternalHref} from '../../utils';
7
+ import Token from 'markdown-it/lib/token';
8
+ import {MarkdownItPluginCb, MarkdownItPluginOpts} from '../typings';
9
+ import {StateCore} from '../../typings';
10
+
11
+ interface ImageOpts extends MarkdownItPluginOpts {
12
+ assetsPublicPath: string;
13
+ }
14
+
15
+ function replaceImageSrc(
16
+ token: Token,
17
+ state: StateCore,
18
+ {assetsPublicPath = sep, root = '', path: optsPath, log}: ImageOpts,
19
+ ) {
20
+ const src = token.attrGet('src') || '';
21
+ const currentPath = state.env.path || optsPath;
22
+
23
+ if (!isLocalUrl(src)) {
24
+ return;
25
+ }
26
+
27
+ const path = resolveRelativePath(currentPath, src);
28
+
29
+ if (isFileExists(path)) {
30
+ state.md.assets?.push(path);
31
+ } else {
32
+ log.error(`Asset not found: ${bold(src)} in ${bold(currentPath)}`);
33
+ }
34
+
35
+ const relativeToRoot = path.replace(root + sep, '');
36
+ const publicSrc = join(assetsPublicPath, relativeToRoot);
37
+
38
+ token.attrSet('src', publicSrc);
39
+ }
40
+
41
+ interface SVGOpts extends MarkdownItPluginOpts {
42
+ notFoundCb: (s: string) => void;
43
+ }
44
+
45
+ function convertSvg(
46
+ token: Token,
47
+ state: StateCore,
48
+ {path: optsPath, log, notFoundCb, root}: SVGOpts,
49
+ ) {
50
+ const currentPath = state.env.path || optsPath;
51
+ const path = resolveRelativePath(currentPath, token.attrGet('src') || '');
52
+
53
+ try {
54
+ const content = readFileSync(path, 'utf8');
55
+ const svgToken = new state.Token('image_svg', '', 0);
56
+ svgToken.attrSet('content', content);
57
+
58
+ return svgToken;
59
+ } catch (e) {
60
+ log.error(`SVG ${path} from ${currentPath} not found`);
61
+
62
+ if (notFoundCb) {
63
+ notFoundCb(path.replace(root, ''));
64
+ }
65
+
66
+ return token;
67
+ }
68
+ }
69
+
70
+ type Opts = SVGOpts & ImageOpts;
71
+
72
+ const index: MarkdownItPluginCb<Opts> = (md, opts) => {
73
+ md.assets = [];
74
+
75
+ const plugin = (state: StateCore) => {
76
+ const tokens = state.tokens;
77
+ let i = 0;
78
+
79
+ while (i < tokens.length) {
80
+ if (tokens[i].type !== 'inline') {
81
+ i++;
82
+ continue;
83
+ }
84
+
85
+ const childrenTokens = tokens[i].children || [];
86
+ let j = 0;
87
+
88
+ while (j < childrenTokens.length) {
89
+ if (childrenTokens[j].type === 'image') {
90
+ const imgSrc = childrenTokens[j].attrGet('src') || '';
91
+
92
+ if (imgSrc.endsWith('.svg') && !isExternalHref(imgSrc)) {
93
+ childrenTokens[j] = convertSvg(childrenTokens[j], state, opts);
94
+ } else {
95
+ replaceImageSrc(childrenTokens[j], state, opts);
96
+ }
97
+ }
98
+
99
+ j++;
100
+ }
101
+
102
+ i++;
103
+ }
104
+ };
105
+
106
+ try {
107
+ md.core.ruler.before('includes', 'images', plugin);
108
+ } catch (e) {
109
+ md.core.ruler.push('images', plugin);
110
+ }
111
+
112
+ md.renderer.rules.image_svg = (tokens, index) => {
113
+ const token = tokens[index];
114
+
115
+ return token.attrGet('content') || '';
116
+ };
117
+ };
118
+
119
+ export = index;
@@ -0,0 +1,7 @@
1
+ export enum ImsizeAttr {
2
+ Src = 'src',
3
+ Alt = 'alt',
4
+ Title = 'title',
5
+ Width = 'width',
6
+ Height = 'height',
7
+ }
@@ -0,0 +1,75 @@
1
+ /* eslint-disable no-param-reassign */
2
+ export function parseImageSize(str: string, pos: number, max: number) {
3
+ const result = {
4
+ ok: false,
5
+ pos: 0,
6
+ width: '',
7
+ height: '',
8
+ };
9
+
10
+ if (pos >= max) {
11
+ return result;
12
+ }
13
+
14
+ let code = str.charCodeAt(pos);
15
+
16
+ if (code !== 0x3d /* = */) {
17
+ return result;
18
+ }
19
+
20
+ pos++;
21
+
22
+ // size must follow = without any white spaces as follows
23
+ // (1) =300x200
24
+ // (2) =300x
25
+ // (3) =x200
26
+ code = str.charCodeAt(pos);
27
+ if (code !== 0x78 /* x */ && (code < 0x30 || code > 0x39) /* [0-9] */) {
28
+ return result;
29
+ }
30
+
31
+ // parse width
32
+ const resultW = parseNextNumber(str, pos, max);
33
+ pos = resultW.pos;
34
+
35
+ // next charactor must be 'x'
36
+ code = str.charCodeAt(pos);
37
+ if (code !== 0x78 /* x */) {
38
+ return result;
39
+ }
40
+
41
+ pos++;
42
+
43
+ // parse height
44
+ const resultH = parseNextNumber(str, pos, max);
45
+ pos = resultH.pos;
46
+
47
+ result.width = resultW.value;
48
+ result.height = resultH.value;
49
+ result.pos = pos;
50
+ result.ok = true;
51
+
52
+ return result;
53
+ }
54
+
55
+ function parseNextNumber(str: string, pos: number, max: number) {
56
+ let code;
57
+ const start = pos;
58
+ const result = {
59
+ pos,
60
+ ok: false,
61
+ value: '',
62
+ };
63
+
64
+ code = str.charCodeAt(pos);
65
+
66
+ while ((pos < max && code >= 0x30 /* 0 */ && code <= 0x39) /* 9 */ || code === 0x25 /* % */) {
67
+ code = str.charCodeAt(++pos);
68
+ }
69
+
70
+ result.ok = true;
71
+ result.pos = pos;
72
+ result.value = str.slice(start, pos);
73
+
74
+ return result;
75
+ }
@@ -0,0 +1,14 @@
1
+ import {PluginSimple} from 'markdown-it';
2
+ import {imageWithSize} from './plugin';
3
+
4
+ /**
5
+ * Imsize plugin for markdown-it.
6
+ * This plugin overloads original image renderer.
7
+ * Forked from https://github.com/tatsy/markdown-it-imsize
8
+ */
9
+
10
+ const imsize: PluginSimple = (md) => {
11
+ md.inline.ruler.before('emphasis', 'image', imageWithSize(md));
12
+ };
13
+
14
+ export = imsize;