@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.
- package/package.json +149 -0
- package/src/Cherry.config.js +625 -0
- package/src/Cherry.js +1104 -0
- package/src/CherryStatic.js +70 -0
- package/src/Editor.js +748 -0
- package/src/Engine.js +381 -0
- package/src/Event.js +140 -0
- package/src/Factory.js +180 -0
- package/src/Logger.js +31 -0
- package/src/Previewer.js +1183 -0
- package/src/Sanitizer.js +4 -0
- package/src/Sanitizer.node.js +7 -0
- package/src/UrlCache.js +98 -0
- package/src/addons/advance/cherry-table-echarts-plugin.js +170 -0
- package/src/addons/cherry-code-block-mermaid-plugin.js +158 -0
- package/src/addons/cherry-code-block-plantuml-plugin.js +106 -0
- package/src/core/HookCenter.js +297 -0
- package/src/core/HooksConfig.js +100 -0
- package/src/core/ParagraphBase.js +332 -0
- package/src/core/SentenceBase.js +65 -0
- package/src/core/SyntaxBase.js +194 -0
- package/src/core/hooks/AutoLink.js +232 -0
- package/src/core/hooks/BackgroundColor.js +46 -0
- package/src/core/hooks/Blockquote.js +70 -0
- package/src/core/hooks/Br.js +85 -0
- package/src/core/hooks/CodeBlock.js +446 -0
- package/src/core/hooks/Color.js +46 -0
- package/src/core/hooks/CommentReference.js +96 -0
- package/src/core/hooks/Detail.js +108 -0
- package/src/core/hooks/Emoji.config.js +1825 -0
- package/src/core/hooks/Emoji.js +119 -0
- package/src/core/hooks/Emphasis.js +113 -0
- package/src/core/hooks/Footnote.js +125 -0
- package/src/core/hooks/FrontMatter.js +51 -0
- package/src/core/hooks/Header.js +234 -0
- package/src/core/hooks/HighLight.js +37 -0
- package/src/core/hooks/Hr.js +52 -0
- package/src/core/hooks/HtmlBlock.js +184 -0
- package/src/core/hooks/Image.js +174 -0
- package/src/core/hooks/InlineCode.js +48 -0
- package/src/core/hooks/InlineMath.js +107 -0
- package/src/core/hooks/Link.js +160 -0
- package/src/core/hooks/List.js +264 -0
- package/src/core/hooks/MathBlock.js +103 -0
- package/src/core/hooks/Panel.js +145 -0
- package/src/core/hooks/Paragraph.js +84 -0
- package/src/core/hooks/Ruby.js +34 -0
- package/src/core/hooks/Size.js +51 -0
- package/src/core/hooks/Strikethrough.js +54 -0
- package/src/core/hooks/Sub.js +47 -0
- package/src/core/hooks/SuggestList.js +333 -0
- package/src/core/hooks/Suggester.js +707 -0
- package/src/core/hooks/Sup.js +47 -0
- package/src/core/hooks/Table.js +275 -0
- package/src/core/hooks/Toc.js +292 -0
- package/src/core/hooks/Transfer.js +47 -0
- package/src/core/hooks/Underline.js +37 -0
- package/src/index.core.js +29 -0
- package/src/index.engine.core.js +68 -0
- package/src/index.engine.js +28 -0
- package/src/index.js +32 -0
- package/src/libs/mermaidAPI.8.4.8.js +1 -0
- package/src/libs/mermaidAPI.8.5.2.js +42 -0
- package/src/libs/rawdeflate.js +1663 -0
- package/src/locales/en_US.js +139 -0
- package/src/locales/index.js +25 -0
- package/src/locales/ru_RU.js +139 -0
- package/src/locales/zh_CN.js +142 -0
- package/src/sass/base.scss +26 -0
- package/src/sass/bubble_formula.scss +166 -0
- package/src/sass/ch-icon.scss +118 -0
- package/src/sass/cherry.scss +1116 -0
- package/src/sass/components/bubble.scss +173 -0
- package/src/sass/components/shortcut_key_config.scss +108 -0
- package/src/sass/formula_utils_bubble.scss +82 -0
- package/src/sass/icon_template.scss +24 -0
- package/src/sass/icons/uEA03-list.svg +19 -0
- package/src/sass/icons/uEA04-check.svg +14 -0
- package/src/sass/icons/uEA09-square.svg +10 -0
- package/src/sass/icons/uEA0A-bold.svg +20 -0
- package/src/sass/icons/uEA0B-code.svg +18 -0
- package/src/sass/icons/uEA0C-color.svg +13 -0
- package/src/sass/icons/uEA0D-header.svg +8 -0
- package/src/sass/icons/uEA0E-image.svg +15 -0
- package/src/sass/icons/uEA0F-italic.svg +8 -0
- package/src/sass/icons/uEA10-link.svg +16 -0
- package/src/sass/icons/uEA11-ol.svg +21 -0
- package/src/sass/icons/uEA12-size.svg +11 -0
- package/src/sass/icons/uEA13-strike.svg +16 -0
- package/src/sass/icons/uEA14-table.svg +12 -0
- package/src/sass/icons/uEA15-ul.svg +17 -0
- package/src/sass/icons/uEA16-underline.svg +13 -0
- package/src/sass/icons/uEA17-word.svg +16 -0
- package/src/sass/icons/uEA18-blockquote.svg +11 -0
- package/src/sass/icons/uEA19-font.svg +10 -0
- package/src/sass/icons/uEA1F-insertClass.svg +39 -0
- package/src/sass/icons/uEA20-insertFlow.svg +8 -0
- package/src/sass/icons/uEA21-insertFormula.svg +23 -0
- package/src/sass/icons/uEA22-insertGantt.svg +13 -0
- package/src/sass/icons/uEA23-insertGraph.svg +13 -0
- package/src/sass/icons/uEA24-insertPie.svg +19 -0
- package/src/sass/icons/uEA25-insertSeq.svg +20 -0
- package/src/sass/icons/uEA26-insertState.svg +35 -0
- package/src/sass/icons/uEA27-line.svg +11 -0
- package/src/sass/icons/uEA28-preview.svg +18 -0
- package/src/sass/icons/uEA29-previewClose.svg +24 -0
- package/src/sass/icons/uEA2A-toc.svg +24 -0
- package/src/sass/icons/uEA2D-sub.svg +15 -0
- package/src/sass/icons/uEA2E-sup.svg +15 -0
- package/src/sass/icons/uEA2F-h1.svg +16 -0
- package/src/sass/icons/uEA30-h2.svg +20 -0
- package/src/sass/icons/uEA31-h3.svg +23 -0
- package/src/sass/icons/uEA32-h4.svg +16 -0
- package/src/sass/icons/uEA33-h5.svg +20 -0
- package/src/sass/icons/uEA34-h6.svg +17 -0
- package/src/sass/icons/uEA35-video.svg +20 -0
- package/src/sass/icons/uEA36-insert.svg +25 -0
- package/src/sass/icons/uEA37-little_table.svg +30 -0
- package/src/sass/icons/uEA38-pdf.svg +27 -0
- package/src/sass/icons/uEA39-checklist.svg +22 -0
- package/src/sass/icons/uEA40-close.svg +12 -0
- package/src/sass/icons/uEA41-fullscreen.svg +81 -0
- package/src/sass/icons/uEA42-minscreen.svg +77 -0
- package/src/sass/icons/uEA43-insertChart.svg +23 -0
- package/src/sass/icons/uEA44-question.svg +25 -0
- package/src/sass/icons/uEA45-settings.svg +32 -0
- package/src/sass/icons/uEA46-ok.svg +7 -0
- package/src/sass/icons/uEA47-br.svg +22 -0
- package/src/sass/icons/uEA48-normal.svg +15 -0
- package/src/sass/icons/uEA49-undo.svg +19 -0
- package/src/sass/icons/uEA50-redo.svg +21 -0
- package/src/sass/icons/uEA51-copy.svg +6 -0
- package/src/sass/icons/uEA52-phone.svg +5 -0
- package/src/sass/icons/uEA53-cherry-table-delete.svg +17 -0
- package/src/sass/icons/uEA54-cherry-table-insert-bottom.svg +16 -0
- package/src/sass/icons/uEA55-cherry-table-insert-left.svg +15 -0
- package/src/sass/icons/uEA56-cherry-table-insert-right.svg +16 -0
- package/src/sass/icons/uEA57-cherry-table-insert-top.svg +16 -0
- package/src/sass/icons/uEA58-sort-s.svg +13 -0
- package/src/sass/icons/uEA59-pinyin.svg +1 -0
- package/src/sass/icons/uEA5A-create.svg +24 -0
- package/src/sass/icons/uEA5B-download.svg +34 -0
- package/src/sass/icons/uEA5C-edit.svg +3 -0
- package/src/sass/icons/uEA5D-export.svg +53 -0
- package/src/sass/icons/uEA5E-folder-open.svg +3 -0
- package/src/sass/icons/uEA5F-folder.svg +3 -0
- package/src/sass/icons/uEA60-help.svg +5 -0
- package/src/sass/icons/uEA61-pen-fill.svg +13 -0
- package/src/sass/icons/uEA62-pen.svg +3 -0
- package/src/sass/icons/uEA64-tips.svg +5 -0
- package/src/sass/icons/uEA65-warn.svg +5 -0
- package/src/sass/icons/uEA66-mistake.svg +4 -0
- package/src/sass/icons/uEA67-success.svg +4 -0
- package/src/sass/icons/uEA68-danger.svg +4 -0
- package/src/sass/icons/uEA69-info.svg +5 -0
- package/src/sass/icons/uEA6A-primary.svg +5 -0
- package/src/sass/icons/uEA6B-warning.svg +5 -0
- package/src/sass/icons/uEA6C-justify.svg +19 -0
- package/src/sass/icons/uEA6D-justifyCenter.svg +19 -0
- package/src/sass/icons/uEA6E-justifyLeft.svg +19 -0
- package/src/sass/icons/uEA6F-justifyRight.svg +19 -0
- package/src/sass/icons/uEA70-chevronsLeft.svg +1 -0
- package/src/sass/icons/uEA71-chevronsRight.svg +1 -0
- package/src/sass/icons/uEA72-trendingUp.svg +1 -0
- package/src/sass/icons/uEA74-codeBlock.svg +1 -0
- package/src/sass/icons/uEA75-expand.svg +3 -0
- package/src/sass/icons/uEA76-unExpand.svg +3 -0
- package/src/sass/icons/uEA77-swap-vert.svg +1 -0
- package/src/sass/icons/uEA78-swap.svg +1 -0
- package/src/sass/icons/uEA79-keyboard.svg +1 -0
- package/src/sass/icons/uEA7A-command.svg +1 -0
- package/src/sass/icons/uEA7B-search.svg +1 -0
- package/src/sass/index.scss +3 -0
- package/src/sass/markdown.scss +668 -0
- package/src/sass/markdown_pure.scss +9 -0
- package/src/sass/prettyprint/prettyprint.scss +118 -0
- package/src/sass/previewer.scss +179 -0
- package/src/sass/print.scss +13 -0
- package/src/sass/prism/coy.scss +220 -0
- package/src/sass/prism/dark.scss +132 -0
- package/src/sass/prism/default.scss +143 -0
- package/src/sass/prism/funky.scss +133 -0
- package/src/sass/prism/okaidia.scss +126 -0
- package/src/sass/prism/one-dark.scss +440 -0
- package/src/sass/prism/one-light.scss +428 -0
- package/src/sass/prism/solarized-light.scss +153 -0
- package/src/sass/prism/tomorrow-night.scss +125 -0
- package/src/sass/prism/twilight.scss +202 -0
- package/src/sass/prism/vs-dark.scss +275 -0
- package/src/sass/prism/vs-light.scss +168 -0
- package/src/sass/themes/blue.scss +411 -0
- package/src/sass/themes/dark.scss +517 -0
- package/src/sass/themes/default.scss +255 -0
- package/src/sass/themes/green.scss +395 -0
- package/src/sass/themes/light.scss +368 -0
- package/src/sass/themes/red.scss +397 -0
- package/src/sass/themes/violet.scss +410 -0
- package/src/sass/variable.scss +84 -0
- package/src/toolbars/Bubble.js +234 -0
- package/src/toolbars/BubbleFormula.js +298 -0
- package/src/toolbars/BubbleTable.js +147 -0
- package/src/toolbars/FloatMenu.js +131 -0
- package/src/toolbars/HiddenToolbar.js +36 -0
- package/src/toolbars/HookCenter.js +234 -0
- package/src/toolbars/MenuBase.js +569 -0
- package/src/toolbars/PreviewerBubble.js +608 -0
- package/src/toolbars/ShortcutKeyConfigPanel.js +345 -0
- package/src/toolbars/Sidebar.js +36 -0
- package/src/toolbars/Toc.js +242 -0
- package/src/toolbars/Toolbar.js +449 -0
- package/src/toolbars/ToolbarRight.js +37 -0
- package/src/toolbars/hooks/Audio.js +79 -0
- package/src/toolbars/hooks/BarTable.js +41 -0
- package/src/toolbars/hooks/Bold.js +73 -0
- package/src/toolbars/hooks/Br.js +34 -0
- package/src/toolbars/hooks/ChangeLocale.js +62 -0
- package/src/toolbars/hooks/ChatGpt.js +182 -0
- package/src/toolbars/hooks/CheckList.js +41 -0
- package/src/toolbars/hooks/Code.js +49 -0
- package/src/toolbars/hooks/CodeTheme.js +66 -0
- package/src/toolbars/hooks/Color.js +298 -0
- package/src/toolbars/hooks/Copy.js +141 -0
- package/src/toolbars/hooks/Detail.js +69 -0
- package/src/toolbars/hooks/DrawIo.js +57 -0
- package/src/toolbars/hooks/Export.js +49 -0
- package/src/toolbars/hooks/File.js +79 -0
- package/src/toolbars/hooks/Formula.js +69 -0
- package/src/toolbars/hooks/FullScreen.js +50 -0
- package/src/toolbars/hooks/Graph.js +263 -0
- package/src/toolbars/hooks/H1.js +71 -0
- package/src/toolbars/hooks/H2.js +71 -0
- package/src/toolbars/hooks/H3.js +71 -0
- package/src/toolbars/hooks/Header.js +118 -0
- package/src/toolbars/hooks/Hr.js +35 -0
- package/src/toolbars/hooks/Image.js +91 -0
- package/src/toolbars/hooks/InlineCode.js +53 -0
- package/src/toolbars/hooks/Insert.js +193 -0
- package/src/toolbars/hooks/Italic.js +72 -0
- package/src/toolbars/hooks/Justify.js +49 -0
- package/src/toolbars/hooks/LineTable.js +41 -0
- package/src/toolbars/hooks/Link.js +49 -0
- package/src/toolbars/hooks/List.js +55 -0
- package/src/toolbars/hooks/MobilePreview.js +44 -0
- package/src/toolbars/hooks/Ol.js +41 -0
- package/src/toolbars/hooks/Panel.js +140 -0
- package/src/toolbars/hooks/Pdf.js +78 -0
- package/src/toolbars/hooks/Publish.js +123 -0
- package/src/toolbars/hooks/QuickTable.js +43 -0
- package/src/toolbars/hooks/Quote.js +45 -0
- package/src/toolbars/hooks/Redo.js +33 -0
- package/src/toolbars/hooks/Ruby.js +59 -0
- package/src/toolbars/hooks/Search.js +53 -0
- package/src/toolbars/hooks/Settings.js +220 -0
- package/src/toolbars/hooks/ShortcutKey.js +62 -0
- package/src/toolbars/hooks/Size.js +118 -0
- package/src/toolbars/hooks/Split.js +37 -0
- package/src/toolbars/hooks/Strikethrough.js +71 -0
- package/src/toolbars/hooks/Sub.js +58 -0
- package/src/toolbars/hooks/Sup.js +58 -0
- package/src/toolbars/hooks/SwitchModel.js +56 -0
- package/src/toolbars/hooks/Table.js +56 -0
- package/src/toolbars/hooks/Theme.js +62 -0
- package/src/toolbars/hooks/Toc.js +35 -0
- package/src/toolbars/hooks/TogglePreview.js +91 -0
- package/src/toolbars/hooks/Ul.js +41 -0
- package/src/toolbars/hooks/Underline.js +68 -0
- package/src/toolbars/hooks/Undo.js +30 -0
- package/src/toolbars/hooks/Video.js +79 -0
- package/src/toolbars/hooks/Word.js +78 -0
- package/src/toolbars/hooks/WordCount.js +106 -0
- package/src/utils/autoindent.js +58 -0
- package/src/utils/cm-search-replace.js +794 -0
- package/src/utils/code-preview-language-setting.js +180 -0
- package/src/utils/codeBlockContentHandler.js +400 -0
- package/src/utils/config.js +174 -0
- package/src/utils/copy.js +55 -0
- package/src/utils/dialog.js +214 -0
- package/src/utils/dom.js +163 -0
- package/src/utils/downloadUtil.js +23 -0
- package/src/utils/env.js +22 -0
- package/src/utils/error.js +61 -0
- package/src/utils/event.js +38 -0
- package/src/utils/export.js +166 -0
- package/src/utils/file.js +164 -0
- package/src/utils/formulaUtilsHandler.js +232 -0
- package/src/utils/htmlparser.js +976 -0
- package/src/utils/image.js +99 -0
- package/src/utils/imgSizeHandler.js +279 -0
- package/src/utils/lazyLoadImg.js +327 -0
- package/src/utils/lineFeed.js +49 -0
- package/src/utils/listContentHandler.js +227 -0
- package/src/utils/lookbehind-replace.js +81 -0
- package/src/utils/mathjax.js +89 -0
- package/src/utils/myersDiff.js +211 -0
- package/src/utils/pasteHelper.js +253 -0
- package/src/utils/platformTransform.js +71 -0
- package/src/utils/recount-pos.js +59 -0
- package/src/utils/regexp.js +295 -0
- package/src/utils/sanitize.js +477 -0
- package/src/utils/selection.js +50 -0
- package/src/utils/shortcutKey.js +291 -0
- package/src/utils/svgUtils.js +96 -0
- package/src/utils/tableContentHandler.js +876 -0
- package/test/core/CommonMark.spec.ts +62 -0
- package/test/core/hooks/AutoLink.spec.ts +28 -0
- package/test/core/hooks/List.spec.ts +79 -0
- package/test/core/hooks/__snapshots__/List.spec.ts.snap +11 -0
- package/test/example.md +778 -0
- package/test/node.js +10 -0
- package/test/suites/commonmark.spec.json +5218 -0
- package/test/tsconfig.test.json +6 -0
- package/test/utils/regexp.spec.ts +28 -0
- package/types/cherry.d.ts +675 -0
- package/types/codemirror.d.ts +22 -0
- package/types/editor.d.ts +72 -0
- package/types/global.d.ts +16 -0
- package/types/menus.d.ts +24 -0
- package/types/previewer.d.ts +53 -0
- package/types/syntax.d.ts +52 -0
|
@@ -0,0 +1,47 @@
|
|
|
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 from '@/core/SyntaxBase';
|
|
17
|
+
import { isLookbehindSupported } from '@/utils/regexp';
|
|
18
|
+
import { replaceLookbehind } from '@/utils/lookbehind-replace';
|
|
19
|
+
|
|
20
|
+
export default class Sup extends SyntaxBase {
|
|
21
|
+
static HOOK_NAME = 'sup';
|
|
22
|
+
|
|
23
|
+
// constructor() {
|
|
24
|
+
// super();
|
|
25
|
+
// }
|
|
26
|
+
|
|
27
|
+
toHtml(whole, leadingChar, m1) {
|
|
28
|
+
return `${leadingChar}<sup>${m1}</sup>`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
makeHtml(str) {
|
|
32
|
+
if (isLookbehindSupported()) {
|
|
33
|
+
return str.replace(this.RULE.reg, this.toHtml);
|
|
34
|
+
}
|
|
35
|
+
return replaceLookbehind(str, this.RULE.reg, this.toHtml, true, 1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
rule() {
|
|
39
|
+
const ret = {
|
|
40
|
+
begin: isLookbehindSupported() ? '((?<!\\\\))\\^' : '(^|[^\\\\])\\^',
|
|
41
|
+
end: '\\^',
|
|
42
|
+
content: '([\\w\\W]+?)',
|
|
43
|
+
};
|
|
44
|
+
ret.reg = new RegExp(ret.begin + ret.content + ret.end, 'g');
|
|
45
|
+
return ret;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,275 @@
|
|
|
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 ParagraphBase from '@/core/ParagraphBase';
|
|
17
|
+
import { getTableRule } from '@/utils/regexp';
|
|
18
|
+
|
|
19
|
+
const TABLE_LOOSE = 'loose';
|
|
20
|
+
const TABLE_STRICT = 'strict';
|
|
21
|
+
|
|
22
|
+
export default class Table extends ParagraphBase {
|
|
23
|
+
static HOOK_NAME = 'table';
|
|
24
|
+
|
|
25
|
+
constructor({ externals, config }) {
|
|
26
|
+
super({ needCache: true });
|
|
27
|
+
const {
|
|
28
|
+
enableChart,
|
|
29
|
+
selfClosing,
|
|
30
|
+
chartRenderEngine: ChartRenderEngine,
|
|
31
|
+
externals: requiredPackages,
|
|
32
|
+
chartEngineOptions = {},
|
|
33
|
+
} = config;
|
|
34
|
+
this.chartRenderEngine = null;
|
|
35
|
+
this.selfClosing = selfClosing;
|
|
36
|
+
if (enableChart === true) {
|
|
37
|
+
try {
|
|
38
|
+
this.chartRenderEngine = new ChartRenderEngine({
|
|
39
|
+
// 注入需要的第三方包
|
|
40
|
+
...(externals &&
|
|
41
|
+
requiredPackages instanceof Array &&
|
|
42
|
+
requiredPackages.reduce((acc, pkg) => {
|
|
43
|
+
delete chartEngineOptions[pkg]; // 过滤第三方包选项
|
|
44
|
+
return { ...acc, [pkg]: externals[pkg] };
|
|
45
|
+
}, {})),
|
|
46
|
+
renderer: 'svg',
|
|
47
|
+
width: 500,
|
|
48
|
+
height: 300,
|
|
49
|
+
...chartEngineOptions,
|
|
50
|
+
});
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.warn(error);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 保持每列长度一致
|
|
58
|
+
$extendColumns(row, colCount) {
|
|
59
|
+
const delta = colCount - row.length;
|
|
60
|
+
if (delta < 1) {
|
|
61
|
+
return row;
|
|
62
|
+
}
|
|
63
|
+
return row.concat(' |'.repeat(delta).split('|', delta));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
$parseChartOptions(cell) {
|
|
67
|
+
// 初始化失败
|
|
68
|
+
if (!this.chartRenderEngine) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const CHART_REGEX = /^[ ]*:(\w+):(?:[ ]*{(.*?)}[ ]*)?$/;
|
|
72
|
+
if (!CHART_REGEX.test(cell)) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const match = cell.match(CHART_REGEX);
|
|
76
|
+
const [, chartType, axisOptions] = match;
|
|
77
|
+
const DEFAULT_AXIS_OPTIONS = ['x', 'y'];
|
|
78
|
+
return {
|
|
79
|
+
type: chartType,
|
|
80
|
+
options: axisOptions ? axisOptions.split(/\s*,\s*/) : DEFAULT_AXIS_OPTIONS,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
$parseColumnAlignRules(row) {
|
|
85
|
+
const COLUMN_ALIGN_MAP = { L: 'left', R: 'right', C: 'center' };
|
|
86
|
+
const COLUMN_ALIGN_CACHE_SIGN = ['U', 'L', 'R', 'C']; // U for undefined
|
|
87
|
+
const textAlignRules = row.map((rule) => {
|
|
88
|
+
const $rule = rule.trim();
|
|
89
|
+
let index = 0;
|
|
90
|
+
if (/^:/.test($rule)) {
|
|
91
|
+
index += 1;
|
|
92
|
+
}
|
|
93
|
+
if (/:$/.test($rule)) {
|
|
94
|
+
index += 2;
|
|
95
|
+
}
|
|
96
|
+
return COLUMN_ALIGN_CACHE_SIGN[index];
|
|
97
|
+
});
|
|
98
|
+
return { textAlignRules, COLUMN_ALIGN_MAP };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
$parseTable(lines, sentenceMakeFunc, dataLines) {
|
|
102
|
+
let maxCol = 0;
|
|
103
|
+
const rows = lines.map((line, index) => {
|
|
104
|
+
const cols = line.replace(/\\\|/g, '~CS').split('|');
|
|
105
|
+
if (cols[0] === '') {
|
|
106
|
+
cols.shift();
|
|
107
|
+
}
|
|
108
|
+
if (cols[cols.length - 1] === '') {
|
|
109
|
+
cols.pop();
|
|
110
|
+
}
|
|
111
|
+
// 文本对齐相关列,不作为最多列数的参考依据
|
|
112
|
+
index !== 1 && (maxCol = Math.max(maxCol, cols.length));
|
|
113
|
+
return cols;
|
|
114
|
+
});
|
|
115
|
+
const { textAlignRules, COLUMN_ALIGN_MAP } = this.$parseColumnAlignRules(rows[1]);
|
|
116
|
+
const tableObject = {
|
|
117
|
+
header: [],
|
|
118
|
+
rows: [],
|
|
119
|
+
colLength: maxCol,
|
|
120
|
+
rowLength: rows.length - 2, // 去除表头和控制行
|
|
121
|
+
};
|
|
122
|
+
const chartOptions = this.$parseChartOptions(rows[0][0]);
|
|
123
|
+
const chartOptionsSign = this.$engine.hash(rows[0][0]);
|
|
124
|
+
// 如果需要生成图表,
|
|
125
|
+
if (chartOptions) {
|
|
126
|
+
rows[0][0] = '';
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* ~CTHD: <thead>
|
|
130
|
+
* ~CTHD$: </thead>
|
|
131
|
+
* ~CTBD: <tbody>
|
|
132
|
+
* ~CTBD$: </tbody>
|
|
133
|
+
* ~CTR: <tr>
|
|
134
|
+
* ~CTR$: </tr>
|
|
135
|
+
* ~CTH(L|R|C|U): <th>
|
|
136
|
+
* ~CTH$: </th>
|
|
137
|
+
* ~CTD(L|R|C|U): <td>
|
|
138
|
+
* ~CTD$: </td>
|
|
139
|
+
*/
|
|
140
|
+
const tableHeader = this.$extendColumns(rows[0], maxCol)
|
|
141
|
+
.map((cell, col) => {
|
|
142
|
+
tableObject.header.push(cell.replace(/~CS/g, '\\|'));
|
|
143
|
+
const { html: cellHtml } = sentenceMakeFunc(cell.replace(/~CS/g, '\\|').trim());
|
|
144
|
+
// 前后补一个空格,否则自动链接会将缓存的内容全部收入链接内部
|
|
145
|
+
return `~CTH${textAlignRules[col] || 'U'} ${cellHtml} ~CTH$`;
|
|
146
|
+
})
|
|
147
|
+
.join('');
|
|
148
|
+
const tableRows = rows
|
|
149
|
+
.reduce((table, row, line) => {
|
|
150
|
+
if (line <= 1) {
|
|
151
|
+
return table;
|
|
152
|
+
}
|
|
153
|
+
const currentRowCountWithoutHeader = line - 2;
|
|
154
|
+
tableObject.rows[currentRowCountWithoutHeader] = [];
|
|
155
|
+
const $extendedColumns = this.$extendColumns(row, maxCol).map((cell, col) => {
|
|
156
|
+
tableObject.rows[currentRowCountWithoutHeader].push(cell.replace(/~CS/g, '\\|'));
|
|
157
|
+
const { html: cellHtml } = sentenceMakeFunc(cell.replace(/~CS/g, '\\|').trim());
|
|
158
|
+
// 前后补一个空格,否则自动链接会将缓存的内容全部收入链接内部
|
|
159
|
+
return `~CTD${textAlignRules[col] || 'U'} ${cellHtml} ~CTD$`;
|
|
160
|
+
});
|
|
161
|
+
table.push(`~CTR${$extendedColumns.join('')}~CTR$`);
|
|
162
|
+
return table;
|
|
163
|
+
}, [])
|
|
164
|
+
.join('');
|
|
165
|
+
// console.log('obj', tableObject);
|
|
166
|
+
const tableResult = this.$renderTable(COLUMN_ALIGN_MAP, tableHeader, tableRows, dataLines);
|
|
167
|
+
if (!chartOptions) {
|
|
168
|
+
return tableResult;
|
|
169
|
+
}
|
|
170
|
+
const chart = this.chartRenderEngine.render(chartOptions.type, chartOptions.options, tableObject);
|
|
171
|
+
const chartHtml = `<figure class="cherry-table-figure">${chart}</figure>`;
|
|
172
|
+
const newSign = `${tableResult.sign}${chartOptionsSign}`;
|
|
173
|
+
return {
|
|
174
|
+
html: tableResult.html
|
|
175
|
+
.replace(/(^<div .*?>)/, `$1${chartHtml}`)
|
|
176
|
+
.replace(/(^<div .*? data-sign=")[^"]+?"/, `$1${newSign}"`),
|
|
177
|
+
sign: newSign,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* 如果table.head是空的,就不渲染<thead>了
|
|
183
|
+
* @param {String} str
|
|
184
|
+
* @returns {Boolean}
|
|
185
|
+
*/
|
|
186
|
+
$testHeadEmpty(str) {
|
|
187
|
+
const test = str
|
|
188
|
+
.replace(/ /g, '')
|
|
189
|
+
.replace(/\s/g, '')
|
|
190
|
+
.replace(/(~CTH\$|~CTHU|~CTHL|~CTHR|~CTHC)/g, '');
|
|
191
|
+
return test?.length > 0;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
$renderTable(COLUMN_ALIGN_MAP, tableHeader, tableRows, dataLines) {
|
|
195
|
+
const cacheSrc = this.$testHeadEmpty(tableHeader)
|
|
196
|
+
? `~CTHD${tableHeader}~CTHD$~CTBD${tableRows}~CTBD$`
|
|
197
|
+
: `~CTBD${tableRows}~CTBD$`;
|
|
198
|
+
const html = cacheSrc;
|
|
199
|
+
const sign = this.$engine.hash(html);
|
|
200
|
+
const renderHtml = html
|
|
201
|
+
.replace(/~CTHD\$/g, '</thead>')
|
|
202
|
+
.replace(/~CTHD/g, '<thead>')
|
|
203
|
+
.replace(/~CTBD\$/g, '</tbody>')
|
|
204
|
+
.replace(/~CTBD/g, '</tbody>')
|
|
205
|
+
.replace(/~CTR\$/g, '</tr>')
|
|
206
|
+
.replace(/~CTR/g, '<tr>')
|
|
207
|
+
.replace(/[ ]?~CTH\$/g, '</th>')
|
|
208
|
+
.replace(/[ ]?~CTD\$/g, '</td>') // 在这里将加上的空格还原回来
|
|
209
|
+
.replace(/~CT(D|H)(L|R|C|U)[ ]?/g, (match, type, align) => {
|
|
210
|
+
let tag = `<t${type}`;
|
|
211
|
+
if (align === 'U') {
|
|
212
|
+
tag += '>';
|
|
213
|
+
} else {
|
|
214
|
+
tag += ` align="${COLUMN_ALIGN_MAP[align]}">`;
|
|
215
|
+
}
|
|
216
|
+
return tag;
|
|
217
|
+
})
|
|
218
|
+
.replace(/\\\|/g, '|'); // escape \|
|
|
219
|
+
return {
|
|
220
|
+
html: `<div class="cherry-table-container" data-sign="${sign}${dataLines}" data-lines="${dataLines}">
|
|
221
|
+
<table class="cherry-table">${renderHtml}</table></div>`,
|
|
222
|
+
sign,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
makeHtml(str, sentenceMakeFunc) {
|
|
227
|
+
let $str = str;
|
|
228
|
+
if (this.$engine.$cherry.options.engine.global.flowSessionContext || this.selfClosing) {
|
|
229
|
+
if (/(^|^[^|][^\n]*\n|\n\n|\n[^|][^\n]*\n)\s*\|[^\n]+\n{0,1}[|:-\s]*\n*$/.test($str)) {
|
|
230
|
+
$str = `${$str.replace(/\n[|:-\s]*\n*$/, '')}\n|-|`;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// strict fenced mode
|
|
234
|
+
if (this.test($str, TABLE_STRICT)) {
|
|
235
|
+
$str = $str.replace(this.RULE[TABLE_STRICT].reg, (match, leading) => {
|
|
236
|
+
const dataLines = this.getLineCount(match, leading);
|
|
237
|
+
// 必须先trim,否则分割出来的结果不对
|
|
238
|
+
// 将fenced mode转换为loose mode
|
|
239
|
+
const lines = match
|
|
240
|
+
.trim()
|
|
241
|
+
.split(/\n/)
|
|
242
|
+
.map((line) => String(line).trim());
|
|
243
|
+
const { html: table, sign } = this.$parseTable(lines, sentenceMakeFunc, dataLines);
|
|
244
|
+
return this.getCacheWithSpace(this.pushCache(table, sign, dataLines), match);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
// loose mode
|
|
248
|
+
if (this.test($str, TABLE_LOOSE)) {
|
|
249
|
+
// console.log(TABLE_LOOSE);
|
|
250
|
+
$str = $str.replace(this.RULE[TABLE_LOOSE].reg, (match, leading) => {
|
|
251
|
+
const dataLines = this.getLineCount(match, leading);
|
|
252
|
+
// 必须先trim,否则分割出来的结果不对
|
|
253
|
+
const lines = match
|
|
254
|
+
.trim()
|
|
255
|
+
.split(/\n/)
|
|
256
|
+
.map((line) => String(line).trim());
|
|
257
|
+
const { html: table, sign } = this.$parseTable(lines, sentenceMakeFunc, dataLines);
|
|
258
|
+
return this.getCacheWithSpace(this.pushCache(table, sign, dataLines), match);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
return $str;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
test(str, flavor) {
|
|
265
|
+
return this.RULE[flavor].reg && this.RULE[flavor].reg.test(str);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* TODO: fix type errors
|
|
270
|
+
* @returns
|
|
271
|
+
*/
|
|
272
|
+
rule() {
|
|
273
|
+
return /** @type {any} */ (getTableRule());
|
|
274
|
+
}
|
|
275
|
+
}
|
|
@@ -0,0 +1,292 @@
|
|
|
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 ParagraphBase from '@/core/ParagraphBase';
|
|
17
|
+
import { prependLineFeedForParagraph, calculateLinesOfParagraph } from '@/utils/lineFeed';
|
|
18
|
+
|
|
19
|
+
function defaultLinkProcessor(link) {
|
|
20
|
+
return link;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const defaultOptions = {
|
|
24
|
+
tocStyle: 'plain', // plain or nested
|
|
25
|
+
tocNodeClass: 'toc-li',
|
|
26
|
+
tocContainerClass: 'toc',
|
|
27
|
+
tocTitleClass: 'toc-title',
|
|
28
|
+
linkProcessor: defaultLinkProcessor,
|
|
29
|
+
showAutoNumber: false,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const emptyLinePlaceholder = '<p data-sign="empty-toc" data-lines="1"> </p>';
|
|
33
|
+
|
|
34
|
+
export default class Toc extends ParagraphBase {
|
|
35
|
+
static HOOK_NAME = 'toc';
|
|
36
|
+
|
|
37
|
+
tocStyle = 'nested'; // plain or nested
|
|
38
|
+
tocNodeClass = 'toc-li';
|
|
39
|
+
tocContainerClass = 'toc';
|
|
40
|
+
tocTitleClass = 'toc-title';
|
|
41
|
+
linkProcessor = defaultLinkProcessor;
|
|
42
|
+
baseLevel = 1;
|
|
43
|
+
/** 标记当前是否处于第一个toc,且仅渲染一个toc */
|
|
44
|
+
isFirstTocToken = true;
|
|
45
|
+
/** 允许渲染多个TOC */
|
|
46
|
+
allowMultiToc = false;
|
|
47
|
+
/** 是否显示自增序号 */
|
|
48
|
+
showAutoNumber = false;
|
|
49
|
+
|
|
50
|
+
constructor({ externals, config }) {
|
|
51
|
+
super({ needCache: true });
|
|
52
|
+
Object.keys(defaultOptions).forEach((key) => {
|
|
53
|
+
this[key] = config[key] || defaultOptions[key];
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
beforeMakeHtml(str) {
|
|
58
|
+
let $str = str;
|
|
59
|
+
if (this.test($str, 'extend')) {
|
|
60
|
+
// TODO: fix this error
|
|
61
|
+
// @ts-expect-error
|
|
62
|
+
$str = $str.replace(this.RULE.extend.reg, (match, lines, toc) => {
|
|
63
|
+
if (!this.allowMultiToc && !this.isFirstTocToken) {
|
|
64
|
+
// 需要补齐非捕获的\n,以及第一个分组中的\n
|
|
65
|
+
return `\n${lines}${emptyLinePlaceholder}`;
|
|
66
|
+
}
|
|
67
|
+
const placeHolder = this.pushCache(match);
|
|
68
|
+
this.isFirstTocToken = false;
|
|
69
|
+
return prependLineFeedForParagraph(match, placeHolder);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (this.test($str, 'standard')) {
|
|
73
|
+
// TODO: fix this error
|
|
74
|
+
// @ts-expect-error
|
|
75
|
+
$str = $str.replace(this.RULE.standard.reg, (match, lines, toc) => {
|
|
76
|
+
if (!this.allowMultiToc && !this.isFirstTocToken) {
|
|
77
|
+
// 需要补齐非捕获的\n,以及第一个分组中的\n
|
|
78
|
+
return `\n${lines}${emptyLinePlaceholder}`;
|
|
79
|
+
}
|
|
80
|
+
this.isFirstTocToken = false;
|
|
81
|
+
const placeHolder = this.pushCache(match);
|
|
82
|
+
return prependLineFeedForParagraph(match, placeHolder);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return $str;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
makeHtml(str) {
|
|
89
|
+
return str;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
$makeLevel(num) {
|
|
93
|
+
let ret = '';
|
|
94
|
+
for (let i = this.baseLevel; i < num; i++) {
|
|
95
|
+
ret += ' ';
|
|
96
|
+
}
|
|
97
|
+
return ret;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 生成TOC节点HTML
|
|
102
|
+
* @param {{ level: number; id: string; text: string }} node Toc节点对象
|
|
103
|
+
* @param {boolean} prependWhitespaceIndent 是否在文本前插入缩进空格
|
|
104
|
+
* @param {boolean} [closeTag=true] 是否闭合标签
|
|
105
|
+
* @returns {string}
|
|
106
|
+
*/
|
|
107
|
+
$makeTocItem(node, prependWhitespaceIndent, closeTag = true) {
|
|
108
|
+
let nodePrefix = '';
|
|
109
|
+
if (prependWhitespaceIndent) {
|
|
110
|
+
nodePrefix = this.$makeLevel(node.level);
|
|
111
|
+
}
|
|
112
|
+
const tocLink = this.linkProcessor(`#${node.id}`.replace(/safe_/g, '')); // transform header id to avoid being sanitized
|
|
113
|
+
return `<li class="${this.tocNodeClass}${this.showAutoNumber ? ` toc-li-${node.level}` : ''}">
|
|
114
|
+
${nodePrefix}<a href="${tocLink}" class="level-${node.level}" target="_self">${node.text}</a>${
|
|
115
|
+
closeTag ? '</li>' : ''
|
|
116
|
+
}`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
$makePlainToc(tocNodeList) {
|
|
120
|
+
// this.baseLevel = Math.min(...tocNodeList.map((node) => node.level));
|
|
121
|
+
const items = tocNodeList.map((node) => this.$makeTocItem(node, true));
|
|
122
|
+
return items.join('');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 生成嵌套的TOC列表,算法思路参考flexmark
|
|
127
|
+
* @see https://github.com/vsch/flexmark-java/blob/master/flexmark-ext-toc/
|
|
128
|
+
* src/main/java/com/vladsch/flexmark/ext/toc/TocUtils.java#L140-L227
|
|
129
|
+
*
|
|
130
|
+
* @param {{ level:number; id:string; text:string }[]} nodeList 节点列表
|
|
131
|
+
* @returns {string}
|
|
132
|
+
*/
|
|
133
|
+
$makeNestedToc(nodeList) {
|
|
134
|
+
let lastLevel = 0;
|
|
135
|
+
const unclosedItem = new Array(7).fill(false);
|
|
136
|
+
const unclosedList = new Array(7).fill(false);
|
|
137
|
+
// lists nodes for debug
|
|
138
|
+
// const lists = [];
|
|
139
|
+
// const nodes = [];
|
|
140
|
+
let html = '';
|
|
141
|
+
nodeList.forEach((node) => {
|
|
142
|
+
const { level: nodeLevel } = node;
|
|
143
|
+
if (lastLevel === 0) {
|
|
144
|
+
for (let i = nodeLevel; i >= this.baseLevel; i--) {
|
|
145
|
+
html += '<ul>';
|
|
146
|
+
// lists.push('ul');
|
|
147
|
+
// nodes.push(null);
|
|
148
|
+
unclosedList[i] = true;
|
|
149
|
+
}
|
|
150
|
+
html += this.$makeTocItem(node, false, false);
|
|
151
|
+
// lists.push('li');
|
|
152
|
+
// nodes.push(node);
|
|
153
|
+
unclosedItem[nodeLevel] = true;
|
|
154
|
+
lastLevel = nodeLevel;
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (nodeLevel < lastLevel) {
|
|
158
|
+
// 减少层级
|
|
159
|
+
for (let i = lastLevel; i >= nodeLevel; i--) {
|
|
160
|
+
if (unclosedItem[i]) {
|
|
161
|
+
html += '</li>';
|
|
162
|
+
// lists.push('/li');
|
|
163
|
+
// nodes.push(null);
|
|
164
|
+
unclosedItem[i] = false;
|
|
165
|
+
}
|
|
166
|
+
// 减少层级时,不闭合当前层级的列表,只闭合同层级的列表项
|
|
167
|
+
if (unclosedList[i] && i > nodeLevel) {
|
|
168
|
+
html += '</ul>';
|
|
169
|
+
// lists.push('/ul');
|
|
170
|
+
// nodes.push(null);
|
|
171
|
+
unclosedList[i] = false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
unclosedItem[nodeLevel] = true;
|
|
175
|
+
html += this.$makeTocItem(node, false, false);
|
|
176
|
+
// lists.push('li');
|
|
177
|
+
// nodes.push(node);
|
|
178
|
+
lastLevel = nodeLevel;
|
|
179
|
+
} else if (nodeLevel === lastLevel) {
|
|
180
|
+
if (unclosedItem[lastLevel]) {
|
|
181
|
+
html += '</li>';
|
|
182
|
+
// lists.push('/li');
|
|
183
|
+
// nodes.push(null);
|
|
184
|
+
}
|
|
185
|
+
html += this.$makeTocItem(node, false, false);
|
|
186
|
+
// lists.push('li');
|
|
187
|
+
// nodes.push(node);
|
|
188
|
+
unclosedItem[nodeLevel] = true;
|
|
189
|
+
unclosedList[nodeLevel] = true;
|
|
190
|
+
} else {
|
|
191
|
+
// 增加层级
|
|
192
|
+
for (let i = lastLevel + 1; i <= nodeLevel; i++) {
|
|
193
|
+
html += '<ul>';
|
|
194
|
+
// lists.push('ul');
|
|
195
|
+
// nodes.push(null);
|
|
196
|
+
unclosedList[i] = true;
|
|
197
|
+
}
|
|
198
|
+
unclosedItem[nodeLevel] = true;
|
|
199
|
+
html += this.$makeTocItem(node, false, false);
|
|
200
|
+
// lists.push('li');
|
|
201
|
+
// nodes.push(node);
|
|
202
|
+
lastLevel = nodeLevel;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
for (let i = lastLevel; i >= this.baseLevel; i--) {
|
|
206
|
+
if (unclosedItem[i]) {
|
|
207
|
+
html += '</li>';
|
|
208
|
+
// lists.push('/li');
|
|
209
|
+
// nodes.push(null);
|
|
210
|
+
unclosedItem[i] = false;
|
|
211
|
+
}
|
|
212
|
+
if (unclosedList[i]) {
|
|
213
|
+
html += '</ul>';
|
|
214
|
+
// lists.push('/ul');
|
|
215
|
+
// nodes.push(null);
|
|
216
|
+
unclosedList[i] = false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// console.log(lists, nodes);
|
|
220
|
+
// console.log(html);
|
|
221
|
+
return html;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
$makeToc(arr, dataSign, preLinesMatch) {
|
|
225
|
+
const lines = calculateLinesOfParagraph(preLinesMatch, 1);
|
|
226
|
+
let ret = `<div class="${this.tocContainerClass}${this.showAutoNumber ? ' auto-num-toc' : ''}"
|
|
227
|
+
data-sign="${dataSign}-${lines}" data-lines="${lines}">`;
|
|
228
|
+
ret += `<p class="${this.tocTitleClass}">${this.$locale?.toc ?? '目录'}</p>`;
|
|
229
|
+
if (arr.length <= 0) {
|
|
230
|
+
return '';
|
|
231
|
+
}
|
|
232
|
+
this.baseLevel = Math.min(...arr.map((node) => node.level));
|
|
233
|
+
if (this.tocStyle === 'nested') {
|
|
234
|
+
ret += this.$makeNestedToc(arr);
|
|
235
|
+
} else {
|
|
236
|
+
ret += this.$makePlainToc(arr);
|
|
237
|
+
}
|
|
238
|
+
ret += '</div>';
|
|
239
|
+
return ret;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
afterMakeHtml(str) {
|
|
243
|
+
let $str = super.afterMakeHtml(str);
|
|
244
|
+
const headerList = [];
|
|
245
|
+
const headerRegex = /<h([1-6])[^>]*? id="([^"]+?)"[^>]*?>(?:<a[^/]+?\/a>|)(.+?)<\/h\1>/g;
|
|
246
|
+
let str2Hash = '';
|
|
247
|
+
$str.replace(headerRegex, (match, level, id, text) => {
|
|
248
|
+
const $text = text.replace(/~fn#[0-9]+#/g, '');
|
|
249
|
+
headerList.push({ level: +level, id, text: $text });
|
|
250
|
+
str2Hash += `${level}${id}`;
|
|
251
|
+
});
|
|
252
|
+
str2Hash = this.$engine.hash(str2Hash);
|
|
253
|
+
$str = $str.replace(/(?:^|\n)(\[\[|\[|【【)(toc|TOC)(\]\]|\]|】】)([<~])/, (match) =>
|
|
254
|
+
match.replace(/(\]\]|\]|】】)([<~])/, '$1\n$2'),
|
|
255
|
+
);
|
|
256
|
+
// 首先识别扩展语法
|
|
257
|
+
// TODO: fix this error
|
|
258
|
+
// @ts-expect-error
|
|
259
|
+
$str = $str.replace(this.RULE.extend.reg, (match, preLinesMatch) =>
|
|
260
|
+
this.$makeToc(headerList, str2Hash, preLinesMatch),
|
|
261
|
+
);
|
|
262
|
+
// 处理标准语法
|
|
263
|
+
// TODO: fix this error
|
|
264
|
+
// @ts-expect-error
|
|
265
|
+
$str = $str.replace(this.RULE.standard.reg, (match, preLinesMatch) =>
|
|
266
|
+
this.$makeToc(headerList, str2Hash, preLinesMatch),
|
|
267
|
+
);
|
|
268
|
+
// 重置toc状态
|
|
269
|
+
this.isFirstTocToken = true;
|
|
270
|
+
return $str;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
test(str, flavor) {
|
|
274
|
+
return this.RULE[flavor].reg ? this.RULE[flavor].reg.test(str) : false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* TODO: fix type errors, prefer use `rules` for multiple spec instead
|
|
279
|
+
* @returns
|
|
280
|
+
*/
|
|
281
|
+
rule() {
|
|
282
|
+
const extend = {
|
|
283
|
+
begin: '(?:^|\\n)(\\n*)',
|
|
284
|
+
end: '(?=$|\\n)',
|
|
285
|
+
content: '[ ]*((?:【【|\\[\\[)(?:toc|TOC)(?:\\]\\]|】】))[ ]*',
|
|
286
|
+
};
|
|
287
|
+
extend.reg = new RegExp(extend.begin + extend.content + extend.end, 'g');
|
|
288
|
+
const standard = { begin: '(?:^|\\n)(\\n*)', end: '(?=$|\\n)', content: '[ ]*(\\[(?:toc|TOC)\\])[ ]*' };
|
|
289
|
+
standard.reg = new RegExp(standard.begin + standard.content + standard.end, 'g');
|
|
290
|
+
return /** @type {any} */ ({ extend, standard });
|
|
291
|
+
}
|
|
292
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
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 from '../SyntaxBase.js';
|
|
17
|
+
|
|
18
|
+
export default class Transfer extends SyntaxBase {
|
|
19
|
+
static HOOK_NAME = 'transfer';
|
|
20
|
+
|
|
21
|
+
// constructor() {
|
|
22
|
+
// super();
|
|
23
|
+
// }
|
|
24
|
+
|
|
25
|
+
rule() {
|
|
26
|
+
return {
|
|
27
|
+
begin: '',
|
|
28
|
+
content: '',
|
|
29
|
+
end: '',
|
|
30
|
+
reg: new RegExp(''),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
beforeMakeHtml(str) {
|
|
35
|
+
return str.replace(/\\\n/g, '\\ \n');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
afterMakeHtml(str) {
|
|
39
|
+
let $str = str.replace(/~Q/g, '~');
|
|
40
|
+
$str = $str.replace(/~X/g, '`');
|
|
41
|
+
$str = $str.replace(/~Y/g, '!');
|
|
42
|
+
$str = $str.replace(/~Z/g, '#');
|
|
43
|
+
$str = $str.replace(/~&/g, '&');
|
|
44
|
+
$str = $str.replace(/~K/g, '/');
|
|
45
|
+
return $str;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
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 from '@/core/SyntaxBase';
|
|
17
|
+
|
|
18
|
+
export default class Underline extends SyntaxBase {
|
|
19
|
+
static HOOK_NAME = 'underline';
|
|
20
|
+
|
|
21
|
+
// constructor() {
|
|
22
|
+
// super();
|
|
23
|
+
// }
|
|
24
|
+
|
|
25
|
+
makeHtml(str) {
|
|
26
|
+
if (!this.test(str)) {
|
|
27
|
+
return str;
|
|
28
|
+
}
|
|
29
|
+
return str.replace(this.RULE.reg, '$1<span style="text-decoration: underline;">$2</span>$3');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
rule() {
|
|
33
|
+
const ret = { begin: '(^| )\\/', end: '\\/( |$)', content: '([^\\n]+?)' };
|
|
34
|
+
ret.reg = new RegExp(ret.begin + ret.content + ret.end, 'g');
|
|
35
|
+
return ret;
|
|
36
|
+
}
|
|
37
|
+
}
|