x-star-editor 0.0.2
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/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/XStarEditor/index.d.ts +12 -0
- package/dist/XStarEditor/index.js +114 -0
- package/dist/XStarEditor/index.module.css +19 -0
- package/dist/XStarMdEditor/index.d.ts +31 -0
- package/dist/XStarMdEditor/index.js +263 -0
- package/dist/XStarMdEditor/index.module.css +13 -0
- package/dist/XStarMdViewer/index.d.ts +18 -0
- package/dist/XStarMdViewer/index.js +33 -0
- package/dist/XStarMdViewer/index.module.css +10 -0
- package/dist/components/FileInput.d.ts +15 -0
- package/dist/components/FileInput.js +107 -0
- package/dist/components/FileInput.module.css +81 -0
- package/dist/components/Toolbar.d.ts +22 -0
- package/dist/components/Toolbar.js +294 -0
- package/dist/components/Toolbar.module.css +116 -0
- package/dist/components/icons/bold.svg +1 -0
- package/dist/components/icons/code-library.svg +1 -0
- package/dist/components/icons/code.svg +1 -0
- package/dist/components/icons/image.svg +1 -0
- package/dist/components/icons/italic.svg +1 -0
- package/dist/components/icons/link.svg +1 -0
- package/dist/components/icons/strikethrough.svg +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +5 -0
- package/dist/styles/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dist/styles/katex.css +1120 -0
- package/dist/styles/markdown.css +129 -0
- package/dist/styles/prism.css +182 -0
- package/dist/utils/container.d.ts +45 -0
- package/dist/utils/container.js +366 -0
- package/dist/utils/handler.d.ts +44 -0
- package/dist/utils/handler.js +227 -0
- package/dist/utils/history.d.ts +59 -0
- package/dist/utils/history.js +305 -0
- package/dist/utils/jsx-runtime.d.ts +7 -0
- package/dist/utils/markdown.d.ts +38 -0
- package/dist/utils/markdown.js +292 -0
- package/dist/utils/module-css.d.ts +3 -0
- package/package.json +88 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
var _defaultSchema$tagNam, _defaultSchema$attrib, _defaultSchema$attrib2, _defaultSchema$attrib3, _defaultSchema$attrib4, _defaultSchema$attrib5, _defaultSchema$attrib6, _defaultSchema$attrib7, _defaultSchema$attrib8;
|
|
2
|
+
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
3
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
4
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
5
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
6
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
7
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
8
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
9
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
10
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
11
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
12
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
|
13
|
+
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
14
|
+
import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
|
|
15
|
+
import { Fragment, jsx, jsxs } from 'react/jsx-runtime';
|
|
16
|
+
import rehypeKatex from 'rehype-katex';
|
|
17
|
+
import rehypePrism from 'rehype-prism-plus';
|
|
18
|
+
import rehypeRaw from 'rehype-raw';
|
|
19
|
+
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
|
|
20
|
+
import remarkBreaks from 'remark-breaks';
|
|
21
|
+
import remarkGfm from 'remark-gfm';
|
|
22
|
+
import remarkMath from 'remark-math';
|
|
23
|
+
import remarkParse from 'remark-parse';
|
|
24
|
+
import remarkRehype from 'remark-rehype';
|
|
25
|
+
import { unified } from 'unified';
|
|
26
|
+
var schema = _objectSpread(_objectSpread({}, defaultSchema), {}, {
|
|
27
|
+
tagNames: [].concat(_toConsumableArray((_defaultSchema$tagNam = defaultSchema.tagNames) !== null && _defaultSchema$tagNam !== void 0 ? _defaultSchema$tagNam : []), ['video', 'custom']),
|
|
28
|
+
attributes: _objectSpread(_objectSpread({}, defaultSchema.attributes), {}, {
|
|
29
|
+
pre: [].concat(_toConsumableArray((_defaultSchema$attrib = (_defaultSchema$attrib2 = defaultSchema.attributes) === null || _defaultSchema$attrib2 === void 0 ? void 0 : _defaultSchema$attrib2.pre) !== null && _defaultSchema$attrib !== void 0 ? _defaultSchema$attrib : []), ['className', 'style']),
|
|
30
|
+
code: [].concat(_toConsumableArray((_defaultSchema$attrib3 = (_defaultSchema$attrib4 = defaultSchema.attributes) === null || _defaultSchema$attrib4 === void 0 ? void 0 : _defaultSchema$attrib4.code) !== null && _defaultSchema$attrib3 !== void 0 ? _defaultSchema$attrib3 : []), ['className', 'style']),
|
|
31
|
+
div: [].concat(_toConsumableArray((_defaultSchema$attrib5 = (_defaultSchema$attrib6 = defaultSchema.attributes) === null || _defaultSchema$attrib6 === void 0 ? void 0 : _defaultSchema$attrib6.div) !== null && _defaultSchema$attrib5 !== void 0 ? _defaultSchema$attrib5 : []), ['className', 'style']),
|
|
32
|
+
span: [].concat(_toConsumableArray((_defaultSchema$attrib7 = (_defaultSchema$attrib8 = defaultSchema.attributes) === null || _defaultSchema$attrib8 === void 0 ? void 0 : _defaultSchema$attrib8.span) !== null && _defaultSchema$attrib7 !== void 0 ? _defaultSchema$attrib7 : []), ['className', 'style', 'line']),
|
|
33
|
+
video: ['src'],
|
|
34
|
+
custom: ['meta', 'value']
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 将 Markdown 文本解析为 Mdast 树并转换为 Hast 树的处理器
|
|
40
|
+
*/
|
|
41
|
+
var processor = unified().use(remarkParse).use(remarkBreaks).use(remarkGfm).use(remarkMath).use(remarkRehype, {
|
|
42
|
+
allowDangerousHtml: true,
|
|
43
|
+
handlers: {
|
|
44
|
+
math: function math(h, node) {
|
|
45
|
+
return (
|
|
46
|
+
// 如果 Math 节点的 `meta` 属性不为空,则视为自定义块
|
|
47
|
+
node.meta ? h(node.position, 'custom', {
|
|
48
|
+
meta: node.meta,
|
|
49
|
+
value: node.value
|
|
50
|
+
}) : h(node, 'div')
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}).use(rehypePrism, {
|
|
55
|
+
ignoreMissing: true
|
|
56
|
+
}).use(rehypeKatex).use(rehypeRaw).use(rehypeSanitize, schema).freeze();
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Mdast 节点
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 将 Markdown 文本映射到 DOM 树,第一层为 `<div>` 块元素,第二层为 `<div>` 行元素,之后均为 `<span>` 元素
|
|
64
|
+
*
|
|
65
|
+
* @param sourceCode Markdown 文本
|
|
66
|
+
* @returns DOM 树
|
|
67
|
+
*/
|
|
68
|
+
export var editorRender = function editorRender(sourceCode) {
|
|
69
|
+
/**
|
|
70
|
+
* CSS 类名前缀
|
|
71
|
+
*/
|
|
72
|
+
var classNamePrefix = 'x-star-md-editor-';
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 扫描偏移量,表示已经添加到 DOM 树的文本
|
|
76
|
+
*/
|
|
77
|
+
var scanOffset = 0;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 遍历 Mdast 树时的栈,保存 Mdast 节点、对应的 DOM 元素、是否为 Mdast 节点的第一个子元素
|
|
81
|
+
*/
|
|
82
|
+
var stack = [];
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 块级元素
|
|
86
|
+
*/
|
|
87
|
+
var block = document.createElement('div');
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* DOM 树根元素
|
|
91
|
+
*/
|
|
92
|
+
var el = document.createElement('div');
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* 判断一个 Mdast 节点的子节点是否为流内容
|
|
96
|
+
*
|
|
97
|
+
* @param node Mdast 节点
|
|
98
|
+
* @returns 子节点是否为流内容
|
|
99
|
+
*/
|
|
100
|
+
var isFlowContent = function isFlowContent(node) {
|
|
101
|
+
return node.type === 'blockquote' || node.type === 'listItem' || node.type === 'footnoteDefinition';
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 将栈中指定索引的 DOM 元素推到对应的父元素中
|
|
106
|
+
*
|
|
107
|
+
* @param index 索引
|
|
108
|
+
* @param last 是否为 Mdast 节点的最后一个子元素,默认为 `false`
|
|
109
|
+
*/
|
|
110
|
+
var pushElement = function pushElement(index) {
|
|
111
|
+
var last = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
112
|
+
var _stack$index = stack[index],
|
|
113
|
+
node = _stack$index.node,
|
|
114
|
+
first = _stack$index.first;
|
|
115
|
+
|
|
116
|
+
// 如果节点为流内容,则将样式添加到该行的 `<div>` 元素上,否则添加到该节点的元素上
|
|
117
|
+
var styleElement = stack[index && !isFlowContent(stack[index - 1].node) ? index : 0].el;
|
|
118
|
+
styleElement.classList.add("".concat(classNamePrefix).concat(node.type));
|
|
119
|
+
if (node.type === 'heading') {
|
|
120
|
+
styleElement.classList.add("".concat(classNamePrefix, "heading").concat(node.depth));
|
|
121
|
+
} else if (node.type === 'html' || node.type === 'code' || node.type === 'math') {
|
|
122
|
+
if (first) {
|
|
123
|
+
styleElement.classList.add("".concat(classNamePrefix, "first"));
|
|
124
|
+
}
|
|
125
|
+
if (last) {
|
|
126
|
+
styleElement.classList.add("".concat(classNamePrefix, "last"));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// 如果索引为 0,则父节点为块级元素,否则为前一个索引的 DOM 元素
|
|
131
|
+
var parentElement = index ? stack[index - 1].el : block;
|
|
132
|
+
parentElement.append(stack[index].el);
|
|
133
|
+
stack[index].el = document.createElement(index ? 'span' : 'div');
|
|
134
|
+
stack[index].first = false;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* 将块级元素推到 DOM 树根元素中
|
|
139
|
+
*/
|
|
140
|
+
var pushBlock = function pushBlock() {
|
|
141
|
+
block.classList.add("".concat(classNamePrefix, "block"));
|
|
142
|
+
el.append(block);
|
|
143
|
+
block = document.createElement('div');
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* 创建分隔文本元素
|
|
148
|
+
*
|
|
149
|
+
* @param text 文本
|
|
150
|
+
* @returns `<span>` 元素
|
|
151
|
+
*/
|
|
152
|
+
var createDelimiter = function createDelimiter(text) {
|
|
153
|
+
var temp = document.createElement('span');
|
|
154
|
+
temp.append(text);
|
|
155
|
+
temp.classList.add("".concat(classNamePrefix, "delimiter"));
|
|
156
|
+
return temp;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 创建行元素
|
|
161
|
+
*
|
|
162
|
+
* @param text 文本
|
|
163
|
+
* @returns `<div>` 元素
|
|
164
|
+
*/
|
|
165
|
+
var createLine = function createLine(text) {
|
|
166
|
+
var temp = document.createElement('div');
|
|
167
|
+
temp.append("".concat(text, "\u200B"));
|
|
168
|
+
return temp;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* 添加文本到 DOM 树
|
|
173
|
+
*
|
|
174
|
+
* @param text 文本
|
|
175
|
+
* @param delimiter 是否为分隔文本,默认为 `false`
|
|
176
|
+
*/
|
|
177
|
+
var addText = function addText(text) {
|
|
178
|
+
var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
179
|
+
// 每行文本放在不同 `<div>` 元素中
|
|
180
|
+
var lines = text.split('\n');
|
|
181
|
+
if (stack.length) {
|
|
182
|
+
// 如果栈不为空,说明为块级元素内的文本,每一行都应推到块级元素中
|
|
183
|
+
if (lines[0]) {
|
|
184
|
+
stack[stack.length - 1].el.append(delimiter ? createDelimiter(lines[0]) : lines[0]);
|
|
185
|
+
}
|
|
186
|
+
for (var i = 1; i < lines.length; i++) {
|
|
187
|
+
for (var j = stack.length - 1; j; j--) {
|
|
188
|
+
pushElement(j);
|
|
189
|
+
}
|
|
190
|
+
stack[0].el.append("\u200B");
|
|
191
|
+
pushElement(0);
|
|
192
|
+
if (lines[i]) {
|
|
193
|
+
stack[stack.length - 1].el.append(delimiter ? createDelimiter(lines[i]) : lines[i]);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
scanOffset += text.length;
|
|
197
|
+
} else {
|
|
198
|
+
// 如果栈为空,说明为块级元素间的文本,最后一行应视为下一块级元素内的文本
|
|
199
|
+
for (var _i = 0; _i < lines.length - 1; _i++) {
|
|
200
|
+
block.append(createLine(lines[_i]));
|
|
201
|
+
pushBlock();
|
|
202
|
+
scanOffset += lines[_i].length + 1;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* 根据 Mdast 节点生成对应的 DOM 子元素
|
|
209
|
+
*
|
|
210
|
+
* @param nodes Mdast 节点
|
|
211
|
+
* @param parentEndOffset 父节点终点偏移量
|
|
212
|
+
*/
|
|
213
|
+
var getChildren = function getChildren(nodes, parentEndOffset) {
|
|
214
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
215
|
+
var _node$position, _node$position2;
|
|
216
|
+
var node = nodes[i];
|
|
217
|
+
var startOffset = (_node$position = node.position) === null || _node$position === void 0 ? void 0 : _node$position.start.offset;
|
|
218
|
+
var endOffset = (_node$position2 = node.position) === null || _node$position2 === void 0 ? void 0 : _node$position2.end.offset;
|
|
219
|
+
if (startOffset === undefined || endOffset === undefined) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
// 由于 unified 的问题,起点偏移量可能小于扫描偏移量,应修正
|
|
223
|
+
if (startOffset < scanOffset) {
|
|
224
|
+
startOffset = scanOffset;
|
|
225
|
+
}
|
|
226
|
+
// 如果起点偏移量大于等于终点偏移量,则不用添加任何文本
|
|
227
|
+
if (startOffset >= endOffset) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// 添加扫描偏移量与起点偏移量间的分隔文本
|
|
232
|
+
addText(sourceCode.slice(scanOffset, startOffset), true);
|
|
233
|
+
|
|
234
|
+
// 为 Mdast 节点创建 DOM 元素
|
|
235
|
+
stack.push({
|
|
236
|
+
node: node,
|
|
237
|
+
el: document.createElement(stack.length ? 'span' : 'div'),
|
|
238
|
+
first: true
|
|
239
|
+
});
|
|
240
|
+
if ('children' in node) {
|
|
241
|
+
getChildren(node.children, endOffset);
|
|
242
|
+
} else {
|
|
243
|
+
addText(sourceCode.slice(scanOffset, endOffset));
|
|
244
|
+
}
|
|
245
|
+
if (stack.length > 1) {
|
|
246
|
+
pushElement(stack.length - 1, true);
|
|
247
|
+
} else {
|
|
248
|
+
// 如果栈大小为 1,说明为块级元素终点
|
|
249
|
+
stack[0].el.append("\u200B");
|
|
250
|
+
pushElement(0, true);
|
|
251
|
+
block.setAttribute('index', "".concat(i));
|
|
252
|
+
pushBlock();
|
|
253
|
+
scanOffset++;
|
|
254
|
+
}
|
|
255
|
+
stack.pop();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// 添加扫描偏移量与父节点终点偏移量间的分隔文本
|
|
259
|
+
addText(sourceCode.slice(scanOffset, parentEndOffset), true);
|
|
260
|
+
};
|
|
261
|
+
getChildren(processor.parse(sourceCode).children, sourceCode.length);
|
|
262
|
+
if (scanOffset <= sourceCode.length) {
|
|
263
|
+
// 添加最后一行文本
|
|
264
|
+
block.append(createLine(sourceCode.slice(scanOffset)));
|
|
265
|
+
pushBlock();
|
|
266
|
+
}
|
|
267
|
+
return el;
|
|
268
|
+
};
|
|
269
|
+
/**
|
|
270
|
+
* 将 Markdown 文本映射到 React 虚拟 DOM 树
|
|
271
|
+
*
|
|
272
|
+
* @param sourceCode Markdown 文本
|
|
273
|
+
* @param options 配置项
|
|
274
|
+
* @returns React 虚拟 DOM 树
|
|
275
|
+
*/
|
|
276
|
+
export var viewerRender = function viewerRender(sourceCode, options) {
|
|
277
|
+
return toJsxRuntime(processor.runSync(processor.parse(sourceCode)), {
|
|
278
|
+
Fragment: Fragment,
|
|
279
|
+
jsx: jsx,
|
|
280
|
+
jsxs: jsxs,
|
|
281
|
+
components: _objectSpread(_objectSpread({}, options.customHTMLElements), {}, {
|
|
282
|
+
custom: function custom(_ref) {
|
|
283
|
+
var _options$customBlocks;
|
|
284
|
+
var meta = _ref.meta,
|
|
285
|
+
value = _ref.value;
|
|
286
|
+
return jsx((_options$customBlocks = options.customBlocks[meta]) !== null && _options$customBlocks !== void 0 ? _options$customBlocks : 'div', {
|
|
287
|
+
children: value
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
})
|
|
291
|
+
});
|
|
292
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "x-star-editor",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "An editor developed by turingstar",
|
|
5
|
+
"module": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "npm run dev",
|
|
9
|
+
"dev": "dumi dev",
|
|
10
|
+
"build": "father build",
|
|
11
|
+
"build:watch": "father dev",
|
|
12
|
+
"docs:build": "dumi build",
|
|
13
|
+
"prepare": "husky install && dumi setup",
|
|
14
|
+
"doctor": "father doctor",
|
|
15
|
+
"lint": "npm run lint:es && npm run lint:css",
|
|
16
|
+
"lint:css": "stylelint \"{src,test}/**/*.{css,less}\"",
|
|
17
|
+
"lint:es": "eslint \"{src,test}/**/*.{js,jsx,ts,tsx}\"",
|
|
18
|
+
"prepublishOnly": "father doctor && npm run build"
|
|
19
|
+
},
|
|
20
|
+
"authors": [
|
|
21
|
+
"XYD Tech Team tech@xinyoudui.com"
|
|
22
|
+
],
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"commitlint": {
|
|
28
|
+
"extends": [
|
|
29
|
+
"@commitlint/config-conventional"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"lint-staged": {
|
|
33
|
+
"*.{md,json}": [
|
|
34
|
+
"prettier --write --no-error-on-unmatched-pattern"
|
|
35
|
+
],
|
|
36
|
+
"*.{css,less}": [
|
|
37
|
+
"stylelint --fix",
|
|
38
|
+
"prettier --write"
|
|
39
|
+
],
|
|
40
|
+
"*.{js,jsx}": [
|
|
41
|
+
"eslint --fix",
|
|
42
|
+
"prettier --write"
|
|
43
|
+
],
|
|
44
|
+
"*.{ts,tsx}": [
|
|
45
|
+
"eslint --fix",
|
|
46
|
+
"prettier --parser=typescript --write"
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"react": ">=16.9.0",
|
|
54
|
+
"react-dom": ">=16.9.0"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@commitlint/cli": "^17.1.2",
|
|
58
|
+
"@commitlint/config-conventional": "^17.1.0",
|
|
59
|
+
"@types/react": "^18.0.0",
|
|
60
|
+
"@types/react-dom": "^18.0.0",
|
|
61
|
+
"@umijs/lint": "^4.0.0",
|
|
62
|
+
"dumi": "^2.2.0",
|
|
63
|
+
"eslint": "^8.23.0",
|
|
64
|
+
"father": "^4.1.0",
|
|
65
|
+
"husky": "^8.0.1",
|
|
66
|
+
"lint-staged": "^13.0.3",
|
|
67
|
+
"prettier": "^2.7.1",
|
|
68
|
+
"prettier-plugin-organize-imports": "^3.0.0",
|
|
69
|
+
"prettier-plugin-packagejson": "^2.2.18",
|
|
70
|
+
"react": "^18.0.0",
|
|
71
|
+
"react-dom": "^18.0.0",
|
|
72
|
+
"stylelint": "^14.9.1"
|
|
73
|
+
},
|
|
74
|
+
"dependencies": {
|
|
75
|
+
"classnames": "^2.3.2",
|
|
76
|
+
"hast-util-to-jsx-runtime": "^1.2.0",
|
|
77
|
+
"rehype-katex": "^6.0.3",
|
|
78
|
+
"rehype-prism-plus": "^1.6.1",
|
|
79
|
+
"rehype-raw": "^6.1.1",
|
|
80
|
+
"rehype-sanitize": "^5.0.1",
|
|
81
|
+
"remark-breaks": "^3.0.3",
|
|
82
|
+
"remark-gfm": "^3.0.1",
|
|
83
|
+
"remark-math": "^5.1.1",
|
|
84
|
+
"remark-parse": "^10.0.2",
|
|
85
|
+
"remark-rehype": "^10.1.0",
|
|
86
|
+
"unified": "^10.1.2"
|
|
87
|
+
}
|
|
88
|
+
}
|