@cherry-markdown/cherry-markdown-dev 0.8.58-dev

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 (319) hide show
  1. package/package.json +149 -0
  2. package/src/Cherry.config.js +625 -0
  3. package/src/Cherry.js +1104 -0
  4. package/src/CherryStatic.js +70 -0
  5. package/src/Editor.js +748 -0
  6. package/src/Engine.js +381 -0
  7. package/src/Event.js +140 -0
  8. package/src/Factory.js +180 -0
  9. package/src/Logger.js +31 -0
  10. package/src/Previewer.js +1183 -0
  11. package/src/Sanitizer.js +4 -0
  12. package/src/Sanitizer.node.js +7 -0
  13. package/src/UrlCache.js +98 -0
  14. package/src/addons/advance/cherry-table-echarts-plugin.js +170 -0
  15. package/src/addons/cherry-code-block-mermaid-plugin.js +158 -0
  16. package/src/addons/cherry-code-block-plantuml-plugin.js +106 -0
  17. package/src/core/HookCenter.js +297 -0
  18. package/src/core/HooksConfig.js +100 -0
  19. package/src/core/ParagraphBase.js +332 -0
  20. package/src/core/SentenceBase.js +65 -0
  21. package/src/core/SyntaxBase.js +194 -0
  22. package/src/core/hooks/AutoLink.js +232 -0
  23. package/src/core/hooks/BackgroundColor.js +46 -0
  24. package/src/core/hooks/Blockquote.js +70 -0
  25. package/src/core/hooks/Br.js +85 -0
  26. package/src/core/hooks/CodeBlock.js +446 -0
  27. package/src/core/hooks/Color.js +46 -0
  28. package/src/core/hooks/CommentReference.js +96 -0
  29. package/src/core/hooks/Detail.js +108 -0
  30. package/src/core/hooks/Emoji.config.js +1825 -0
  31. package/src/core/hooks/Emoji.js +119 -0
  32. package/src/core/hooks/Emphasis.js +113 -0
  33. package/src/core/hooks/Footnote.js +125 -0
  34. package/src/core/hooks/FrontMatter.js +51 -0
  35. package/src/core/hooks/Header.js +234 -0
  36. package/src/core/hooks/HighLight.js +37 -0
  37. package/src/core/hooks/Hr.js +52 -0
  38. package/src/core/hooks/HtmlBlock.js +184 -0
  39. package/src/core/hooks/Image.js +174 -0
  40. package/src/core/hooks/InlineCode.js +48 -0
  41. package/src/core/hooks/InlineMath.js +107 -0
  42. package/src/core/hooks/Link.js +160 -0
  43. package/src/core/hooks/List.js +264 -0
  44. package/src/core/hooks/MathBlock.js +103 -0
  45. package/src/core/hooks/Panel.js +145 -0
  46. package/src/core/hooks/Paragraph.js +84 -0
  47. package/src/core/hooks/Ruby.js +34 -0
  48. package/src/core/hooks/Size.js +51 -0
  49. package/src/core/hooks/Strikethrough.js +54 -0
  50. package/src/core/hooks/Sub.js +47 -0
  51. package/src/core/hooks/SuggestList.js +333 -0
  52. package/src/core/hooks/Suggester.js +707 -0
  53. package/src/core/hooks/Sup.js +47 -0
  54. package/src/core/hooks/Table.js +275 -0
  55. package/src/core/hooks/Toc.js +292 -0
  56. package/src/core/hooks/Transfer.js +47 -0
  57. package/src/core/hooks/Underline.js +37 -0
  58. package/src/index.core.js +29 -0
  59. package/src/index.engine.core.js +68 -0
  60. package/src/index.engine.js +28 -0
  61. package/src/index.js +32 -0
  62. package/src/libs/mermaidAPI.8.4.8.js +1 -0
  63. package/src/libs/mermaidAPI.8.5.2.js +42 -0
  64. package/src/libs/rawdeflate.js +1663 -0
  65. package/src/locales/en_US.js +139 -0
  66. package/src/locales/index.js +25 -0
  67. package/src/locales/ru_RU.js +139 -0
  68. package/src/locales/zh_CN.js +142 -0
  69. package/src/sass/base.scss +26 -0
  70. package/src/sass/bubble_formula.scss +166 -0
  71. package/src/sass/ch-icon.scss +118 -0
  72. package/src/sass/cherry.scss +1116 -0
  73. package/src/sass/components/bubble.scss +173 -0
  74. package/src/sass/components/shortcut_key_config.scss +108 -0
  75. package/src/sass/formula_utils_bubble.scss +82 -0
  76. package/src/sass/icon_template.scss +24 -0
  77. package/src/sass/icons/uEA03-list.svg +19 -0
  78. package/src/sass/icons/uEA04-check.svg +14 -0
  79. package/src/sass/icons/uEA09-square.svg +10 -0
  80. package/src/sass/icons/uEA0A-bold.svg +20 -0
  81. package/src/sass/icons/uEA0B-code.svg +18 -0
  82. package/src/sass/icons/uEA0C-color.svg +13 -0
  83. package/src/sass/icons/uEA0D-header.svg +8 -0
  84. package/src/sass/icons/uEA0E-image.svg +15 -0
  85. package/src/sass/icons/uEA0F-italic.svg +8 -0
  86. package/src/sass/icons/uEA10-link.svg +16 -0
  87. package/src/sass/icons/uEA11-ol.svg +21 -0
  88. package/src/sass/icons/uEA12-size.svg +11 -0
  89. package/src/sass/icons/uEA13-strike.svg +16 -0
  90. package/src/sass/icons/uEA14-table.svg +12 -0
  91. package/src/sass/icons/uEA15-ul.svg +17 -0
  92. package/src/sass/icons/uEA16-underline.svg +13 -0
  93. package/src/sass/icons/uEA17-word.svg +16 -0
  94. package/src/sass/icons/uEA18-blockquote.svg +11 -0
  95. package/src/sass/icons/uEA19-font.svg +10 -0
  96. package/src/sass/icons/uEA1F-insertClass.svg +39 -0
  97. package/src/sass/icons/uEA20-insertFlow.svg +8 -0
  98. package/src/sass/icons/uEA21-insertFormula.svg +23 -0
  99. package/src/sass/icons/uEA22-insertGantt.svg +13 -0
  100. package/src/sass/icons/uEA23-insertGraph.svg +13 -0
  101. package/src/sass/icons/uEA24-insertPie.svg +19 -0
  102. package/src/sass/icons/uEA25-insertSeq.svg +20 -0
  103. package/src/sass/icons/uEA26-insertState.svg +35 -0
  104. package/src/sass/icons/uEA27-line.svg +11 -0
  105. package/src/sass/icons/uEA28-preview.svg +18 -0
  106. package/src/sass/icons/uEA29-previewClose.svg +24 -0
  107. package/src/sass/icons/uEA2A-toc.svg +24 -0
  108. package/src/sass/icons/uEA2D-sub.svg +15 -0
  109. package/src/sass/icons/uEA2E-sup.svg +15 -0
  110. package/src/sass/icons/uEA2F-h1.svg +16 -0
  111. package/src/sass/icons/uEA30-h2.svg +20 -0
  112. package/src/sass/icons/uEA31-h3.svg +23 -0
  113. package/src/sass/icons/uEA32-h4.svg +16 -0
  114. package/src/sass/icons/uEA33-h5.svg +20 -0
  115. package/src/sass/icons/uEA34-h6.svg +17 -0
  116. package/src/sass/icons/uEA35-video.svg +20 -0
  117. package/src/sass/icons/uEA36-insert.svg +25 -0
  118. package/src/sass/icons/uEA37-little_table.svg +30 -0
  119. package/src/sass/icons/uEA38-pdf.svg +27 -0
  120. package/src/sass/icons/uEA39-checklist.svg +22 -0
  121. package/src/sass/icons/uEA40-close.svg +12 -0
  122. package/src/sass/icons/uEA41-fullscreen.svg +81 -0
  123. package/src/sass/icons/uEA42-minscreen.svg +77 -0
  124. package/src/sass/icons/uEA43-insertChart.svg +23 -0
  125. package/src/sass/icons/uEA44-question.svg +25 -0
  126. package/src/sass/icons/uEA45-settings.svg +32 -0
  127. package/src/sass/icons/uEA46-ok.svg +7 -0
  128. package/src/sass/icons/uEA47-br.svg +22 -0
  129. package/src/sass/icons/uEA48-normal.svg +15 -0
  130. package/src/sass/icons/uEA49-undo.svg +19 -0
  131. package/src/sass/icons/uEA50-redo.svg +21 -0
  132. package/src/sass/icons/uEA51-copy.svg +6 -0
  133. package/src/sass/icons/uEA52-phone.svg +5 -0
  134. package/src/sass/icons/uEA53-cherry-table-delete.svg +17 -0
  135. package/src/sass/icons/uEA54-cherry-table-insert-bottom.svg +16 -0
  136. package/src/sass/icons/uEA55-cherry-table-insert-left.svg +15 -0
  137. package/src/sass/icons/uEA56-cherry-table-insert-right.svg +16 -0
  138. package/src/sass/icons/uEA57-cherry-table-insert-top.svg +16 -0
  139. package/src/sass/icons/uEA58-sort-s.svg +13 -0
  140. package/src/sass/icons/uEA59-pinyin.svg +1 -0
  141. package/src/sass/icons/uEA5A-create.svg +24 -0
  142. package/src/sass/icons/uEA5B-download.svg +34 -0
  143. package/src/sass/icons/uEA5C-edit.svg +3 -0
  144. package/src/sass/icons/uEA5D-export.svg +53 -0
  145. package/src/sass/icons/uEA5E-folder-open.svg +3 -0
  146. package/src/sass/icons/uEA5F-folder.svg +3 -0
  147. package/src/sass/icons/uEA60-help.svg +5 -0
  148. package/src/sass/icons/uEA61-pen-fill.svg +13 -0
  149. package/src/sass/icons/uEA62-pen.svg +3 -0
  150. package/src/sass/icons/uEA64-tips.svg +5 -0
  151. package/src/sass/icons/uEA65-warn.svg +5 -0
  152. package/src/sass/icons/uEA66-mistake.svg +4 -0
  153. package/src/sass/icons/uEA67-success.svg +4 -0
  154. package/src/sass/icons/uEA68-danger.svg +4 -0
  155. package/src/sass/icons/uEA69-info.svg +5 -0
  156. package/src/sass/icons/uEA6A-primary.svg +5 -0
  157. package/src/sass/icons/uEA6B-warning.svg +5 -0
  158. package/src/sass/icons/uEA6C-justify.svg +19 -0
  159. package/src/sass/icons/uEA6D-justifyCenter.svg +19 -0
  160. package/src/sass/icons/uEA6E-justifyLeft.svg +19 -0
  161. package/src/sass/icons/uEA6F-justifyRight.svg +19 -0
  162. package/src/sass/icons/uEA70-chevronsLeft.svg +1 -0
  163. package/src/sass/icons/uEA71-chevronsRight.svg +1 -0
  164. package/src/sass/icons/uEA72-trendingUp.svg +1 -0
  165. package/src/sass/icons/uEA74-codeBlock.svg +1 -0
  166. package/src/sass/icons/uEA75-expand.svg +3 -0
  167. package/src/sass/icons/uEA76-unExpand.svg +3 -0
  168. package/src/sass/icons/uEA77-swap-vert.svg +1 -0
  169. package/src/sass/icons/uEA78-swap.svg +1 -0
  170. package/src/sass/icons/uEA79-keyboard.svg +1 -0
  171. package/src/sass/icons/uEA7A-command.svg +1 -0
  172. package/src/sass/icons/uEA7B-search.svg +1 -0
  173. package/src/sass/index.scss +3 -0
  174. package/src/sass/markdown.scss +668 -0
  175. package/src/sass/markdown_pure.scss +9 -0
  176. package/src/sass/prettyprint/prettyprint.scss +118 -0
  177. package/src/sass/previewer.scss +179 -0
  178. package/src/sass/print.scss +13 -0
  179. package/src/sass/prism/coy.scss +220 -0
  180. package/src/sass/prism/dark.scss +132 -0
  181. package/src/sass/prism/default.scss +143 -0
  182. package/src/sass/prism/funky.scss +133 -0
  183. package/src/sass/prism/okaidia.scss +126 -0
  184. package/src/sass/prism/one-dark.scss +440 -0
  185. package/src/sass/prism/one-light.scss +428 -0
  186. package/src/sass/prism/solarized-light.scss +153 -0
  187. package/src/sass/prism/tomorrow-night.scss +125 -0
  188. package/src/sass/prism/twilight.scss +202 -0
  189. package/src/sass/prism/vs-dark.scss +275 -0
  190. package/src/sass/prism/vs-light.scss +168 -0
  191. package/src/sass/themes/blue.scss +411 -0
  192. package/src/sass/themes/dark.scss +517 -0
  193. package/src/sass/themes/default.scss +255 -0
  194. package/src/sass/themes/green.scss +395 -0
  195. package/src/sass/themes/light.scss +368 -0
  196. package/src/sass/themes/red.scss +397 -0
  197. package/src/sass/themes/violet.scss +410 -0
  198. package/src/sass/variable.scss +84 -0
  199. package/src/toolbars/Bubble.js +234 -0
  200. package/src/toolbars/BubbleFormula.js +298 -0
  201. package/src/toolbars/BubbleTable.js +147 -0
  202. package/src/toolbars/FloatMenu.js +131 -0
  203. package/src/toolbars/HiddenToolbar.js +36 -0
  204. package/src/toolbars/HookCenter.js +234 -0
  205. package/src/toolbars/MenuBase.js +569 -0
  206. package/src/toolbars/PreviewerBubble.js +608 -0
  207. package/src/toolbars/ShortcutKeyConfigPanel.js +345 -0
  208. package/src/toolbars/Sidebar.js +36 -0
  209. package/src/toolbars/Toc.js +242 -0
  210. package/src/toolbars/Toolbar.js +449 -0
  211. package/src/toolbars/ToolbarRight.js +37 -0
  212. package/src/toolbars/hooks/Audio.js +79 -0
  213. package/src/toolbars/hooks/BarTable.js +41 -0
  214. package/src/toolbars/hooks/Bold.js +73 -0
  215. package/src/toolbars/hooks/Br.js +34 -0
  216. package/src/toolbars/hooks/ChangeLocale.js +62 -0
  217. package/src/toolbars/hooks/ChatGpt.js +182 -0
  218. package/src/toolbars/hooks/CheckList.js +41 -0
  219. package/src/toolbars/hooks/Code.js +49 -0
  220. package/src/toolbars/hooks/CodeTheme.js +66 -0
  221. package/src/toolbars/hooks/Color.js +298 -0
  222. package/src/toolbars/hooks/Copy.js +141 -0
  223. package/src/toolbars/hooks/Detail.js +69 -0
  224. package/src/toolbars/hooks/DrawIo.js +57 -0
  225. package/src/toolbars/hooks/Export.js +49 -0
  226. package/src/toolbars/hooks/File.js +79 -0
  227. package/src/toolbars/hooks/Formula.js +69 -0
  228. package/src/toolbars/hooks/FullScreen.js +50 -0
  229. package/src/toolbars/hooks/Graph.js +263 -0
  230. package/src/toolbars/hooks/H1.js +71 -0
  231. package/src/toolbars/hooks/H2.js +71 -0
  232. package/src/toolbars/hooks/H3.js +71 -0
  233. package/src/toolbars/hooks/Header.js +118 -0
  234. package/src/toolbars/hooks/Hr.js +35 -0
  235. package/src/toolbars/hooks/Image.js +91 -0
  236. package/src/toolbars/hooks/InlineCode.js +53 -0
  237. package/src/toolbars/hooks/Insert.js +193 -0
  238. package/src/toolbars/hooks/Italic.js +72 -0
  239. package/src/toolbars/hooks/Justify.js +49 -0
  240. package/src/toolbars/hooks/LineTable.js +41 -0
  241. package/src/toolbars/hooks/Link.js +49 -0
  242. package/src/toolbars/hooks/List.js +55 -0
  243. package/src/toolbars/hooks/MobilePreview.js +44 -0
  244. package/src/toolbars/hooks/Ol.js +41 -0
  245. package/src/toolbars/hooks/Panel.js +140 -0
  246. package/src/toolbars/hooks/Pdf.js +78 -0
  247. package/src/toolbars/hooks/Publish.js +123 -0
  248. package/src/toolbars/hooks/QuickTable.js +43 -0
  249. package/src/toolbars/hooks/Quote.js +45 -0
  250. package/src/toolbars/hooks/Redo.js +33 -0
  251. package/src/toolbars/hooks/Ruby.js +59 -0
  252. package/src/toolbars/hooks/Search.js +53 -0
  253. package/src/toolbars/hooks/Settings.js +220 -0
  254. package/src/toolbars/hooks/ShortcutKey.js +62 -0
  255. package/src/toolbars/hooks/Size.js +118 -0
  256. package/src/toolbars/hooks/Split.js +37 -0
  257. package/src/toolbars/hooks/Strikethrough.js +71 -0
  258. package/src/toolbars/hooks/Sub.js +58 -0
  259. package/src/toolbars/hooks/Sup.js +58 -0
  260. package/src/toolbars/hooks/SwitchModel.js +56 -0
  261. package/src/toolbars/hooks/Table.js +56 -0
  262. package/src/toolbars/hooks/Theme.js +62 -0
  263. package/src/toolbars/hooks/Toc.js +35 -0
  264. package/src/toolbars/hooks/TogglePreview.js +91 -0
  265. package/src/toolbars/hooks/Ul.js +41 -0
  266. package/src/toolbars/hooks/Underline.js +68 -0
  267. package/src/toolbars/hooks/Undo.js +30 -0
  268. package/src/toolbars/hooks/Video.js +79 -0
  269. package/src/toolbars/hooks/Word.js +78 -0
  270. package/src/toolbars/hooks/WordCount.js +106 -0
  271. package/src/utils/autoindent.js +58 -0
  272. package/src/utils/cm-search-replace.js +794 -0
  273. package/src/utils/code-preview-language-setting.js +180 -0
  274. package/src/utils/codeBlockContentHandler.js +400 -0
  275. package/src/utils/config.js +174 -0
  276. package/src/utils/copy.js +55 -0
  277. package/src/utils/dialog.js +214 -0
  278. package/src/utils/dom.js +163 -0
  279. package/src/utils/downloadUtil.js +23 -0
  280. package/src/utils/env.js +22 -0
  281. package/src/utils/error.js +61 -0
  282. package/src/utils/event.js +38 -0
  283. package/src/utils/export.js +166 -0
  284. package/src/utils/file.js +164 -0
  285. package/src/utils/formulaUtilsHandler.js +232 -0
  286. package/src/utils/htmlparser.js +976 -0
  287. package/src/utils/image.js +99 -0
  288. package/src/utils/imgSizeHandler.js +279 -0
  289. package/src/utils/lazyLoadImg.js +327 -0
  290. package/src/utils/lineFeed.js +49 -0
  291. package/src/utils/listContentHandler.js +227 -0
  292. package/src/utils/lookbehind-replace.js +81 -0
  293. package/src/utils/mathjax.js +89 -0
  294. package/src/utils/myersDiff.js +211 -0
  295. package/src/utils/pasteHelper.js +253 -0
  296. package/src/utils/platformTransform.js +71 -0
  297. package/src/utils/recount-pos.js +59 -0
  298. package/src/utils/regexp.js +295 -0
  299. package/src/utils/sanitize.js +477 -0
  300. package/src/utils/selection.js +50 -0
  301. package/src/utils/shortcutKey.js +291 -0
  302. package/src/utils/svgUtils.js +96 -0
  303. package/src/utils/tableContentHandler.js +876 -0
  304. package/test/core/CommonMark.spec.ts +62 -0
  305. package/test/core/hooks/AutoLink.spec.ts +28 -0
  306. package/test/core/hooks/List.spec.ts +79 -0
  307. package/test/core/hooks/__snapshots__/List.spec.ts.snap +11 -0
  308. package/test/example.md +778 -0
  309. package/test/node.js +10 -0
  310. package/test/suites/commonmark.spec.json +5218 -0
  311. package/test/tsconfig.test.json +6 -0
  312. package/test/utils/regexp.spec.ts +28 -0
  313. package/types/cherry.d.ts +675 -0
  314. package/types/codemirror.d.ts +22 -0
  315. package/types/editor.d.ts +72 -0
  316. package/types/global.d.ts +16 -0
  317. package/types/menus.d.ts +24 -0
  318. package/types/previewer.d.ts +53 -0
  319. package/types/syntax.d.ts +52 -0
@@ -0,0 +1,332 @@
1
+ /**
2
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import SyntaxBase, { HOOKS_TYPE_LIST } from './SyntaxBase';
17
+ import { prependLineFeedForParagraph } from '@/utils/lineFeed';
18
+ import { getIsClassicBrFromLocal, testKeyInLocal } from '@/utils/config';
19
+ import { blockNames } from '@/utils/sanitize';
20
+
21
+ let cacheCounter = 0;
22
+ // ~~C${cacheCounter}I${cacheIndex}$
23
+ // let cacheMap = {};
24
+
25
+ export default class ParagraphBase extends SyntaxBase {
26
+ static HOOK_TYPE = HOOKS_TYPE_LIST.PAR;
27
+ // 不需要排他的sign前缀,如~~C0I${IN_PARAGRAPH_CACHE_KEY_PREFIX}sign$
28
+ static IN_PARAGRAPH_CACHE_KEY_PREFIX = '!';
29
+ static IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX = '\\!';
30
+
31
+ constructor({ needCache, defaultCache = {} } = { needCache: false }) {
32
+ super({});
33
+ this.needCache = !!needCache;
34
+ this.sign = '';
35
+ if (needCache) {
36
+ this.cache = defaultCache || {};
37
+ this.cacheKey = `~~C${cacheCounter}`;
38
+ cacheCounter += 1;
39
+ }
40
+ }
41
+
42
+ initBrReg(classicBr = false) {
43
+ // 是否启用经典换行逻辑
44
+ // true:一个换行会被忽略,两个以上连续换行会分割成段落,
45
+ // false: 一个换行会转成<br>,两个连续换行会分割成段落,三个以上连续换行会转成<br>并分割段落
46
+ this.classicBr = testKeyInLocal('classicBr') ? getIsClassicBrFromLocal() : classicBr;
47
+ this.removeBrAfterBlock = null;
48
+ this.removeBrBeforeBlock = null;
49
+ this.removeNewlinesBetweenTags = null;
50
+ }
51
+
52
+ /**
53
+ * 处理经典换行问题
54
+ * @param {string} str markdown源码
55
+ * @returns markdown源码
56
+ */
57
+ $cleanParagraph(str) {
58
+ // remove leading and trailing newlines
59
+ const trimedPar = str.replace(/^\n+/, '').replace(/\n+$/, '');
60
+ if (this.classicBr) {
61
+ return trimedPar;
62
+ }
63
+ const minifiedPar = this.joinRawHtml(trimedPar);
64
+ return minifiedPar.replace(/\n/g, '<br>').replace(/\r/g, '\n'); // recover \n from \r
65
+ }
66
+
67
+ /**
68
+ * remove all newlines in html text
69
+ *
70
+ * @param {string} textContainsHtml
71
+ */
72
+ joinRawHtml(textContainsHtml) {
73
+ if (!this.removeBrAfterBlock) {
74
+ // preprocess custom white list
75
+ let customTagWhiteList = this.$engine.htmlWhiteListAppend?.split('|') ?? [];
76
+ customTagWhiteList = customTagWhiteList
77
+ .map((tag) => {
78
+ if (/[a-z-]+/gi.test(tag)) {
79
+ return tag;
80
+ }
81
+ return null;
82
+ })
83
+ .filter((tag) => tag !== null);
84
+ // concat all white list
85
+ const allBlockNames = customTagWhiteList.concat(blockNames).join('|');
86
+ // 段落标签自然换行,所以去掉段落标签两边的换行符
87
+ /**
88
+ * remove newlines after start tag, and remove whitespaces before newline
89
+ * e.g.
90
+ * <p> \n text</p> => <p> text</p>
91
+ * ^^
92
+ * $1$2
93
+ */
94
+ this.removeBrAfterBlock = new RegExp(`<(${allBlockNames})(>| [^>]*?>)[^\\S\\n]*?\\n`, 'ig');
95
+ /**
96
+ * remove newlines before end tag, and whitespaces before end tag will be preserved
97
+ * e.g.
98
+ * <p> text\n </p> => <p> text </p>
99
+ * ^
100
+ * $1
101
+ */
102
+ this.removeBrBeforeBlock = new RegExp(`\\n[^\\S\\n]*?<\\/(${allBlockNames})>[^\\S\\n]*?\\n`, 'ig');
103
+ /**
104
+ * remove newlines between end tag & start tag
105
+ * e.g.
106
+ * </p> \n <p foo="bar"> => </p>\r <p foo="bar">
107
+ * ^ ^^ ^ ^^^^^^^^^^^^
108
+ * $1 $2 $3 $4
109
+ */
110
+ this.removeNewlinesBetweenTags = new RegExp(
111
+ `<\\/(${allBlockNames})>[^\\S\\n]*?\\n([^\\S\\n]*?)<(${allBlockNames})(>| [^>]*?>)`,
112
+ 'ig',
113
+ );
114
+ }
115
+ return textContainsHtml
116
+ .replace(this.removeBrAfterBlock, '<$1$2')
117
+ .replace(this.removeBrBeforeBlock, '</$1>')
118
+ .replace(this.removeNewlinesBetweenTags, '</$1>\r$2<$3$4'); // replace \n to \r
119
+ }
120
+
121
+ toHtml(str, sentenceMakeFunc) {
122
+ return str;
123
+ }
124
+
125
+ makeHtml(str, sentenceMakeFunc) {
126
+ return sentenceMakeFunc(str).html;
127
+ }
128
+
129
+ afterMakeHtml(html) {
130
+ return this.restoreCache(html);
131
+ }
132
+
133
+ isContainsCache(str, fullMatch) {
134
+ if (fullMatch) {
135
+ // 如果是全匹配:不能包含CherryINPRAGRAPH
136
+ const containsParagraphCache = /^(\s*~~C\d+I\w+\$\s*)+$/g.test(str);
137
+ const containsInParagraphCache = new RegExp(
138
+ `~~C\\d+I${ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX}\\w+\\$`,
139
+ 'g',
140
+ ).test(str);
141
+ return containsParagraphCache && !containsInParagraphCache;
142
+ }
143
+ // 如果是局部匹配: 不能只包含CherryINPRAGRAPH
144
+ // const containsParagraphCache = /~~C\d+I\w+\$/g.test(str);
145
+ // const containsInParagraphCache = new RegExp(
146
+ // `~~C\\d+I${ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX}\\w+\\$`, 'g').test(str);
147
+ const containsNonInParagraphCache = new RegExp(
148
+ `~~C\\d+I(?!${ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX})\\w+\\$`,
149
+ 'g',
150
+ ).test(str);
151
+ return containsNonInParagraphCache;
152
+
153
+ // return fullMatch ?
154
+ // /^(\s*~~C\d+I\w+\$\s*)+$/g.test(str) && !/^(\s*~~C\d+ICherryINPRAGRAPH\w+\$\s*)+$/g.test(str) :
155
+ // /~~C\d+I\w+\$/g.test(str) && !(/~~C\d+ICherryINPRAGRAPH\w+\$/g.test(str)
156
+ // && !/~~C\d+I(?!CherryINPRAGRAPH)\w+\$/g.test(str));
157
+ }
158
+
159
+ /**
160
+ *
161
+ * @param {string} html
162
+ * @return
163
+ */
164
+ $splitHtmlByCache(html) {
165
+ // ~~C0I(?!prefix)sign$
166
+ const regex = new RegExp(`\\n*~~C\\d+I(?!${ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX})\\w+\\$\\n?`, 'g');
167
+ return {
168
+ caches: html.match(regex),
169
+ contents: html.split(regex),
170
+ };
171
+ }
172
+
173
+ makeExcludingCached(content, processor) {
174
+ const { caches, contents } = this.$splitHtmlByCache(content);
175
+ const paragraphs = contents.map(processor);
176
+ let ret = '';
177
+ for (let i = 0; i < paragraphs.length; i++) {
178
+ ret += paragraphs[i];
179
+ if (caches && caches[i]) {
180
+ ret += caches[i].trim();
181
+ }
182
+ }
183
+ return ret;
184
+ }
185
+
186
+ /**
187
+ * 获取非捕获匹配丢掉的换行,适用于能被【嵌套】的段落语法
188
+ *
189
+ * @param {string} cache 需要返回的cache
190
+ * @param {string} md 原始的md字符串
191
+ * @param {boolean} alwaysAlone 是否能被【嵌套】,true:不能被嵌套,如标题、注释等;false:能被嵌套,如代码块、有序列表等
192
+ * @return {string} str
193
+ */
194
+ getCacheWithSpace(cache, md, alwaysAlone = false) {
195
+ const preSpace = md.match(/^\n+/)?.[0] ?? '';
196
+ const afterSpace = md.match(/\n+$/)?.[0] ?? '';
197
+ if (alwaysAlone) {
198
+ return prependLineFeedForParagraph(md, cache);
199
+ }
200
+ return `${preSpace}${cache}${afterSpace}`;
201
+ }
202
+
203
+ /**
204
+ * 获取行号,只负责向上计算\n
205
+ * 会计算cache的行号
206
+ *
207
+ * @param {string} md md内容
208
+ * @param {string} preSpace 前置换行
209
+ * @return {number} 行数
210
+ */
211
+ getLineCount(md, preSpace = '') {
212
+ let content = md;
213
+ /**
214
+ * 前置换行个数,【注意】:前置换行个数不包括上文的最后一个\n
215
+ * 例:
216
+ * - aa\n
217
+ * - bb\n
218
+ * \n
219
+ * cc\n
220
+ *
221
+ * cc的前置换行个数为 1,bb后的\n不计算在内
222
+ * cc的正则为:/(?:^|\n)(\n*)xxxxxx/
223
+ */
224
+ let preLineCount = preSpace.match(/^\n+/g)?.[0]?.length ?? 0;
225
+ preLineCount = preLineCount === 1 ? 1 : 0; // 前置换行超过2个就交给BR进行渲染
226
+ content = content.replace(/^\n+/g, '');
227
+
228
+ const regex = new RegExp(
229
+ `\n*~~C\\d+I(?:${ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX})?\\w+?_L(\\d+)\\$`,
230
+ 'g',
231
+ );
232
+ let cacheLineCount = 0;
233
+ content = content.replace(regex, (match, lineCount) => {
234
+ cacheLineCount += parseInt(lineCount, 10);
235
+ return match.replace(/^\n+/g, '');
236
+ });
237
+ return preLineCount + cacheLineCount + (content.match(/\n/g) || []).length + 1; // 实际内容所占行数,至少为1行
238
+ }
239
+
240
+ /**
241
+ *
242
+ * @param {string} str 渲染后的内容
243
+ * @param {string} sign 签名
244
+ * @param {number} lineCount md原文的行数
245
+ * @return {string} cacheKey ~~C0I0_L1$
246
+ */
247
+ pushCache(str, sign = '', lineCount = 0) {
248
+ if (!this.needCache) {
249
+ return;
250
+ }
251
+ const $sign = sign || this.$engine.hash(str);
252
+ const key = `${this.cacheKey}I${$sign}_L${lineCount}$`;
253
+ this.cache[$sign] = {
254
+ content: str,
255
+ key,
256
+ };
257
+ return key;
258
+ }
259
+
260
+ popCache(sign) {
261
+ if (!this.needCache) {
262
+ return;
263
+ }
264
+ return this.cache[sign].content || '';
265
+ }
266
+
267
+ testHasCache(sign) {
268
+ if (!this.needCache || !this.cache[sign]) {
269
+ return false;
270
+ }
271
+ return this.cache[sign].key;
272
+ }
273
+
274
+ // 当缓存全部被消费后,调用此方法清理多大的缓存
275
+ resetCache() {
276
+ if (!this.needCache) {
277
+ return;
278
+ }
279
+ // 当缓存队列比较大时,随机抛弃500个缓存
280
+ if (Object.keys(this.cache).length > 3000) {
281
+ let limit = 0;
282
+ for (const key of Object.keys(this.cache)) {
283
+ limit += 1;
284
+ if (limit > 500) {
285
+ return;
286
+ }
287
+ delete this.cache[key];
288
+ }
289
+ }
290
+ }
291
+
292
+ restoreCache(html) {
293
+ // restore cached content
294
+ if (!this.needCache) {
295
+ return html;
296
+ }
297
+ const regex = new RegExp(
298
+ `${this.cacheKey}I((?:${ParagraphBase.IN_PARAGRAPH_CACHE_KEY_PREFIX_REGEX})?\\w+)\\$`,
299
+ 'g',
300
+ );
301
+ const $html = html.replace(regex, (match, cacheSign) => this.popCache(cacheSign.replace(/_L\d+$/, '')));
302
+ if (this.timer) {
303
+ clearTimeout(this.timer);
304
+ this.timer = null;
305
+ }
306
+ this.timer = setTimeout(() => {
307
+ this.resetCache();
308
+ }, 1000);
309
+ return $html;
310
+ }
311
+
312
+ /**
313
+ *
314
+ * @param {string} wholeMatch whole match
315
+ */
316
+ checkCache(wholeMatch, sentenceMakeFunc, lineCount = 0) {
317
+ this.sign = this.$engine.hash(wholeMatch);
318
+ // miss cache
319
+ if (!this.cache[this.sign]) {
320
+ return this.toHtml(wholeMatch, sentenceMakeFunc);
321
+ }
322
+ return `${this.cacheKey}I${this.sign}_L${lineCount}$`;
323
+ }
324
+
325
+ mounted() {
326
+ // console.log('base mounted');
327
+ }
328
+
329
+ signWithCache(html) {
330
+ return false;
331
+ }
332
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ export default class HookBase {
17
+ getType() {
18
+ const typeList = {
19
+ 1: 'sentence',
20
+ 2: 'paragraph',
21
+ 3: 'page',
22
+ };
23
+ return typeList[this.HOOKTYPE] || 'sentence';
24
+ }
25
+
26
+ getName() {
27
+ return this.HOOKNAME;
28
+ }
29
+
30
+ constructor() {
31
+ this.HOOKNAME = '';
32
+ this.HOOKTYPE = 1;
33
+ }
34
+
35
+ // makeHtml(str) {
36
+ // return str;
37
+ // }
38
+ getMakeHtml() {
39
+ return this.makeHtml || false;
40
+ }
41
+
42
+ // onKeyDown(e, str) {
43
+ // return false;
44
+ // }
45
+ getOnKeyDown() {
46
+ return this.onKeyDown || false;
47
+ }
48
+
49
+ // test(str) {
50
+ // let rule = this.getRule();
51
+ // let reg = new RegExp(rule.begin+rule.content+rule.end, 'g');
52
+ // return reg.test(str)
53
+ // }
54
+
55
+ // rule() {
56
+ // return {begin:'#+', end:'\n', content:'[^\#\n]+'};
57
+ // }
58
+ getRule() {
59
+ return this.rule || false;
60
+ }
61
+
62
+ // toolbar() {
63
+ // return new ToolBar();
64
+ // }
65
+ }
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * @typedef {import('~types/syntax').HookType} HookType
19
+ * @typedef {import('~types/syntax').HookTypesList} HookTypesList
20
+ * @typedef {import('~types/syntax').EditorConfig} EditorConfig
21
+ * @typedef {import('~types/syntax').HookRegexpRule} HookRegexpRule
22
+ */
23
+
24
+ /** @type {boolean} */
25
+ let isMathjaxConfig = false;
26
+
27
+ /**
28
+ * @type {HookTypesList}
29
+ */
30
+ export const HOOKS_TYPE_LIST = {
31
+ SEN: 'sentence',
32
+ PAR: 'paragraph',
33
+ DEFAULT: 'sentence',
34
+ };
35
+
36
+ export default class SyntaxBase {
37
+ /**
38
+ * @static
39
+ * @type {string}
40
+ */
41
+ static HOOK_NAME = 'default';
42
+ /**
43
+ * @static
44
+ * @type {HookType}
45
+ */
46
+ static HOOK_TYPE = HOOKS_TYPE_LIST.DEFAULT;
47
+ /**
48
+ * @protected
49
+ * @type {import('../Engine').default}
50
+ */
51
+ $engine;
52
+ $locale;
53
+
54
+ /**
55
+ * @constructor
56
+ * @param {Partial<EditorConfig>} editorConfig
57
+ */
58
+ constructor(editorConfig) {
59
+ // editorConfig.pageHooks: 已实例化的页面级hook
60
+ // editorConfig.syntaxOptions: 当前Hook的用户配置
61
+ // editorConfig.externals: 第三方库
62
+ this.RULE = this.rule(editorConfig);
63
+ }
64
+
65
+ getType() {
66
+ return /** @type {typeof SyntaxBase} */ (this.constructor).HOOK_TYPE || HOOKS_TYPE_LIST.DEFAULT;
67
+ }
68
+
69
+ getName() {
70
+ return /** @type {typeof SyntaxBase} */ (this.constructor).HOOK_NAME;
71
+ }
72
+
73
+ afterInit(callback) {
74
+ if (typeof callback === 'function') {
75
+ callback();
76
+ }
77
+ }
78
+
79
+ setLocale(locale) {
80
+ this.$locale = locale;
81
+ }
82
+
83
+ /**
84
+ * 生命周期函数
85
+ * @param {string} str 待处理的markdown文本
86
+ * @returns {string} 处理后的文本,一般为html
87
+ */
88
+ beforeMakeHtml(str) {
89
+ return str;
90
+ }
91
+
92
+ /**
93
+ * 生命周期函数
94
+ * @param {string} str 待处理的markdown文本
95
+ * @returns {string} 处理后的文本,一般为html
96
+ */
97
+ makeHtml(str) {
98
+ return str;
99
+ }
100
+
101
+ /**
102
+ * 生命周期函数
103
+ * @param {string} str 待处理的markdown文本
104
+ * @returns {string} 处理后的文本,一般为html
105
+ */
106
+ afterMakeHtml(str) {
107
+ return str;
108
+ }
109
+
110
+ // getMakeHtml() {
111
+ // return this.makeHtml || false;
112
+ // }
113
+
114
+ /**
115
+ *
116
+ * @param {KeyboardEvent} e 触发事件
117
+ * @param {*} str
118
+ */
119
+ onKeyDown(e, str) {}
120
+
121
+ getOnKeyDown() {
122
+ return this.onKeyDown || false;
123
+ }
124
+
125
+ getAttributesTest() {
126
+ return /^(color|fontSize|font-size|id|title|class|target|underline|line-through|overline|sub|super)$/;
127
+ }
128
+
129
+ /**
130
+ *
131
+ * @param {string} attr
132
+ * @param {() => {}} func 回调函数
133
+ */
134
+ $testAttributes(attr, func) {
135
+ if (this.getAttributesTest().test(attr)) {
136
+ func();
137
+ }
138
+ }
139
+
140
+ /**
141
+ * 提取属性
142
+ * @param {string} str 待提取字符串
143
+ * @returns {{attrs: Record<string,any>; str: string}}
144
+ */
145
+ getAttributes(str) {
146
+ const ret = { attrs: {}, str };
147
+ // if(/(?<=[^\\]){([a-zA-Z-]+=[0-9a-z-]+(?=;|\||}))+}$/.test(str)) {
148
+ // str.match(/(?<=[^\\]){[^\n]+?}$/)[0]
149
+ // .match(/([a-zA-Z-]+=[0-9a-z-]+(?=;|\||}))+/g)
150
+ // .foreach((one) => {
151
+ // one = one.split('=');
152
+ // this._testAttributes(one[0], ()=>{
153
+ // ret.attrs[one[0]] = one[1];
154
+ // });
155
+ // });
156
+ // ret.str = str.replace(/(?<=[^\\]){[^\n]+?}$/, '');
157
+ // }
158
+ return ret;
159
+ }
160
+
161
+ static getMathJaxConfig() {
162
+ return isMathjaxConfig;
163
+ }
164
+
165
+ /**
166
+ *
167
+ * @param {boolean} version 指定mathJax是否使用MathJax
168
+ */
169
+ static setMathJaxConfig(version) {
170
+ isMathjaxConfig = version;
171
+ }
172
+
173
+ /**
174
+ * 测试输入的字符串是否匹配当前Hook规则
175
+ * @param {string} str 待匹配文本
176
+ * @returns {boolean}
177
+ */
178
+ test(str) {
179
+ return this.RULE.reg ? this.RULE.reg.test(str) : false;
180
+ }
181
+
182
+ /**
183
+ *
184
+ * @param {Partial<EditorConfig>} editorConfig
185
+ * @returns {HookRegexpRule}
186
+ */
187
+ rule(editorConfig) {
188
+ return { begin: '', end: '', content: '', reg: new RegExp('') };
189
+ }
190
+
191
+ mounted() {
192
+ // console.log('base mounted');
193
+ }
194
+ }