x-star-editor 0.0.7 → 0.0.9

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.
@@ -7,8 +7,8 @@ type HandlerContext = ReturnType<typeof useHistory>;
7
7
  /**
8
8
  * 处理函数
9
9
  */
10
- export interface Handler {
11
- (ctx: HandlerContext): void;
10
+ export interface Handler<T = void> {
11
+ (ctx: HandlerContext): T;
12
12
  }
13
13
  export declare const insertHandler: (payload: InsertAction['payload']) => Handler;
14
14
  export declare const deleteHandler: (payload: DeleteAction['payload']) => Handler;
@@ -23,7 +23,7 @@ export declare const selectHandler: (selection: SelectAction['selection']) => Ha
23
23
  * 接收一个处理函数,获取上下文后执行它
24
24
  */
25
25
  export interface Executor {
26
- (handler: Handler): void;
26
+ <T>(handler: Handler<T>): T;
27
27
  }
28
28
  /**
29
29
  * 键盘事件处理函数
@@ -28,7 +28,10 @@ export interface ToggleAction {
28
28
  type: 'heading';
29
29
  depth: 1 | 2 | 3 | 4 | 5 | 6;
30
30
  } | {
31
- type: 'thematicBreak' | 'blockquote' | 'code' | 'emphasis' | 'strong' | 'inlineCode' | 'delete' | 'math' | 'inlineMath';
31
+ type: 'code';
32
+ language: string;
33
+ } | {
34
+ type: 'thematicBreak' | 'blockquote' | 'emphasis' | 'strong' | 'inlineCode' | 'delete' | 'math' | 'inlineMath';
32
35
  } | {
33
36
  type: 'link' | 'image';
34
37
  url: string;
@@ -112,6 +112,14 @@ var stateReducer = function stateReducer(_ref, action) {
112
112
  selection: createSelection(lineStartOffset + _text.length)
113
113
  };
114
114
  }
115
+ case 'code':
116
+ {
117
+ var language = action.payload.language;
118
+ return {
119
+ sourceCode: "".concat(sourceCode.slice(0, lineEndOffset), "\n```").concat(language, " showLineNumbers\n\n```\n").concat(lineAfter),
120
+ selection: createSelection(lineEndOffset + language.length + 21)
121
+ };
122
+ }
115
123
  case 'thematicBreak':
116
124
  {
117
125
  return {
@@ -143,14 +151,11 @@ var stateReducer = function stateReducer(_ref, action) {
143
151
  selection: createSelection(lineStartOffset + _text2.length)
144
152
  };
145
153
  }
146
- case 'code':
147
154
  case 'math':
148
155
  {
149
- var type = action.payload.type;
150
- var delimiter = type === 'code' ? '```' : '$$';
151
156
  return {
152
- sourceCode: "".concat(sourceCode.slice(0, lineEndOffset), "\n").concat(delimiter, "\n\n").concat(delimiter, "\n").concat(lineAfter),
153
- selection: createSelection(lineEndOffset + delimiter.length + 2)
157
+ sourceCode: "".concat(sourceCode.slice(0, lineEndOffset), "\n$$\n\n$$\n").concat(lineAfter),
158
+ selection: createSelection(lineEndOffset + 4)
154
159
  };
155
160
  }
156
161
  case 'emphasis':
@@ -159,8 +164,8 @@ var stateReducer = function stateReducer(_ref, action) {
159
164
  case 'delete':
160
165
  case 'inlineMath':
161
166
  {
162
- var _type = action.payload.type;
163
- var delimiters = _type === 'emphasis' ? ['*', '_'] : _type === 'strong' ? ['**', '__'] : _type === 'inlineCode' ? ['`'] : _type === 'delete' ? ['~~'] : ['$'];
167
+ var type = action.payload.type;
168
+ var delimiters = type === 'emphasis' ? ['*', '_'] : type === 'strong' ? ['**', '__'] : type === 'inlineCode' ? ['`'] : type === 'delete' ? ['~~'] : ['$'];
164
169
  var _text3 = sourceCode.slice(startOffset, endOffset);
165
170
  for (var _i4 = 0, _delimiters = delimiters; _i4 < _delimiters.length; _i4++) {
166
171
  var _delimiter = _delimiters[_i4];
@@ -172,23 +177,23 @@ var stateReducer = function stateReducer(_ref, action) {
172
177
  };
173
178
  }
174
179
  }
175
- var _delimiter2 = delimiters[0];
180
+ var delimiter = delimiters[0];
176
181
  // 插入分隔文本
177
182
  return {
178
- sourceCode: "".concat(before).concat(_delimiter2).concat(_text3).concat(_delimiter2).concat(after),
179
- selection: createSelection(anchorOffset + _delimiter2.length, focusOffset + _delimiter2.length)
183
+ sourceCode: "".concat(before).concat(delimiter).concat(_text3).concat(delimiter).concat(after),
184
+ selection: createSelection(anchorOffset + delimiter.length, focusOffset + delimiter.length)
180
185
  };
181
186
  }
182
187
  case 'link':
183
188
  case 'image':
184
189
  {
185
190
  var _action$payload2 = action.payload,
186
- _type2 = _action$payload2.type,
191
+ _type = _action$payload2.type,
187
192
  url = _action$payload2.url,
188
193
  description = _action$payload2.description;
189
194
  return {
190
- sourceCode: "".concat(before).concat(_type2 === 'link' ? '' : '!', "[").concat(description, "](").concat(url, ")").concat(after),
191
- selection: createSelection(startOffset + url.length + description.length + 4 + (_type2 === 'link' ? 0 : 1))
195
+ sourceCode: "".concat(before).concat(_type === 'link' ? '' : '!', "[").concat(description, "](").concat(url, ")").concat(after),
196
+ selection: createSelection(startOffset + url.length + description.length + 4 + (_type === 'link' ? 0 : 1))
192
197
  };
193
198
  }
194
199
  default:
@@ -42,4 +42,18 @@ export interface ViewerOptions {
42
42
  * @returns React 虚拟 DOM 树
43
43
  */
44
44
  export declare const viewerRender: (sourceCode: string, options: ViewerOptions) => JSX.Element;
45
+ /**
46
+ * 将 Markdown 文本转成 HTML 文本
47
+ *
48
+ * @param sourceCode Markdown 文本
49
+ * @returns HTML 文本
50
+ */
51
+ export declare const toHTML: (sourceCode: string) => string;
52
+ /**
53
+ * 将带有 HTML 的 Markdown 文本转成 Markdown 文本
54
+ *
55
+ * @param sourceCode 带有 HTML 的 Markdown 文本
56
+ * @returns Markdown 文本
57
+ */
58
+ export declare const toMarkdown: (sourceCode: string) => string;
45
59
  export {};
@@ -16,25 +16,31 @@ import { Fragment, jsx, jsxs } from 'react/jsx-runtime';
16
16
  import rehypeKatex from 'rehype-katex';
17
17
  import rehypePrism from 'rehype-prism-plus';
18
18
  import rehypeRaw from 'rehype-raw';
19
+ import rehypeRemark from 'rehype-remark';
19
20
  import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
21
+ import rehypeStringify from 'rehype-stringify';
20
22
  import remarkBreaks from 'remark-breaks';
21
23
  import remarkGfm from 'remark-gfm';
22
24
  import remarkMath from 'remark-math';
23
25
  import remarkParse from 'remark-parse';
24
26
  import remarkRehype from 'remark-rehype';
27
+ import remarkStringify from 'remark-stringify';
25
28
  import { unified } from 'unified';
26
29
  import { prefix } from "./global";
27
30
  export var getDefaultSchema = function getDefaultSchema() {
28
- var _defaultSchema$tagNam, _defaultSchema$attrib, _defaultSchema$attrib2, _defaultSchema$attrib3, _defaultSchema$attrib4, _defaultSchema$attrib5, _defaultSchema$attrib6, _defaultSchema$attrib7, _defaultSchema$attrib8;
31
+ var _defaultSchema$attrib, _defaultSchema$attrib2, _defaultSchema$attrib3, _defaultSchema$attrib4, _defaultSchema$attrib5, _defaultSchema$attrib6, _defaultSchema$attrib7, _defaultSchema$attrib8, _defaultSchema$protoc, _defaultSchema$protoc2, _defaultSchema$tagNam;
29
32
  return _objectSpread(_objectSpread({}, defaultSchema), {}, {
30
- tagNames: [].concat(_toConsumableArray((_defaultSchema$tagNam = defaultSchema.tagNames) !== null && _defaultSchema$tagNam !== void 0 ? _defaultSchema$tagNam : []), ['custom']),
31
33
  attributes: _objectSpread(_objectSpread({}, defaultSchema.attributes), {}, {
32
34
  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']),
33
35
  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']),
34
36
  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']),
35
37
  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']),
36
38
  custom: ['meta', 'value']
37
- })
39
+ }),
40
+ protocols: _objectSpread(_objectSpread({}, defaultSchema.protocols), {}, {
41
+ src: [].concat(_toConsumableArray((_defaultSchema$protoc = (_defaultSchema$protoc2 = defaultSchema.protocols) === null || _defaultSchema$protoc2 === void 0 ? void 0 : _defaultSchema$protoc2.src) !== null && _defaultSchema$protoc !== void 0 ? _defaultSchema$protoc : []), ['data'])
42
+ }),
43
+ tagNames: [].concat(_toConsumableArray((_defaultSchema$tagNam = defaultSchema.tagNames) !== null && _defaultSchema$tagNam !== void 0 ? _defaultSchema$tagNam : []), ['custom'])
38
44
  });
39
45
  };
40
46
 
@@ -56,25 +62,7 @@ var processor = unified().use(remarkParse).use(remarkBreaks).use(remarkGfm).use(
56
62
  }
57
63
  }).use(rehypePrism, {
58
64
  ignoreMissing: true
59
- }).use(rehypeKatex).use(rehypeRaw).use(function () {
60
- return function (root) {
61
- var _iterator = _createForOfIteratorHelper(root.children),
62
- _step;
63
- try {
64
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
65
- var node = _step.value;
66
- if ('properties' in node && node.properties) {
67
- var _node$position;
68
- node.properties.line = (_node$position = node.position) === null || _node$position === void 0 ? void 0 : _node$position.start.line;
69
- }
70
- }
71
- } catch (err) {
72
- _iterator.e(err);
73
- } finally {
74
- _iterator.f();
75
- }
76
- };
77
- }).freeze();
65
+ }).use(rehypeKatex).use(rehypeRaw).freeze();
78
66
 
79
67
  /**
80
68
  * Mdast 节点
@@ -232,14 +220,14 @@ export var editorRender = function editorRender(sourceCode) {
232
220
  * @param parentEndOffset 父节点终点偏移量
233
221
  */
234
222
  var getChildren = function getChildren(nodes, parentEndOffset) {
235
- var _iterator2 = _createForOfIteratorHelper(nodes),
236
- _step2;
223
+ var _iterator = _createForOfIteratorHelper(nodes),
224
+ _step;
237
225
  try {
238
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
239
- var _node$position2, _node$position3;
240
- var node = _step2.value;
241
- var startOffset = (_node$position2 = node.position) === null || _node$position2 === void 0 ? void 0 : _node$position2.start.offset;
242
- var endOffset = (_node$position3 = node.position) === null || _node$position3 === void 0 ? void 0 : _node$position3.end.offset;
226
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
227
+ var _node$position, _node$position2;
228
+ var node = _step.value;
229
+ var startOffset = (_node$position = node.position) === null || _node$position === void 0 ? void 0 : _node$position.start.offset;
230
+ var endOffset = (_node$position2 = node.position) === null || _node$position2 === void 0 ? void 0 : _node$position2.end.offset;
243
231
  if (startOffset === undefined || endOffset === undefined) {
244
232
  continue;
245
233
  }
@@ -269,11 +257,11 @@ export var editorRender = function editorRender(sourceCode) {
269
257
  if (stack.length > 1) {
270
258
  pushElement(stack.length - 1, true);
271
259
  } else {
272
- var _node$position4;
260
+ var _node$position3;
273
261
  // 如果栈大小为 1,说明为块级元素终点
274
262
  stack[0].el.append("\u200B");
275
263
  pushElement(0, true);
276
- block.setAttribute('line', "".concat((_node$position4 = node.position) === null || _node$position4 === void 0 ? void 0 : _node$position4.start.line));
264
+ block.setAttribute('line', "".concat((_node$position3 = node.position) === null || _node$position3 === void 0 ? void 0 : _node$position3.start.line));
277
265
  pushBlock();
278
266
  scanOffset++;
279
267
  }
@@ -282,9 +270,9 @@ export var editorRender = function editorRender(sourceCode) {
282
270
 
283
271
  // 添加扫描偏移量与父节点终点偏移量间的分隔文本
284
272
  } catch (err) {
285
- _iterator2.e(err);
273
+ _iterator.e(err);
286
274
  } finally {
287
- _iterator2.f();
275
+ _iterator.f();
288
276
  }
289
277
  addText(sourceCode.slice(scanOffset, parentEndOffset), true);
290
278
  };
@@ -304,7 +292,25 @@ export var editorRender = function editorRender(sourceCode) {
304
292
  * @returns React 虚拟 DOM 树
305
293
  */
306
294
  export var viewerRender = function viewerRender(sourceCode, options) {
307
- return toJsxRuntime(processor().use(rehypeSanitize, options.customSchema).runSync(processor.parse(sourceCode)), {
295
+ return toJsxRuntime(processor().use(rehypeSanitize, options.customSchema).use(function () {
296
+ return function (root) {
297
+ var _iterator2 = _createForOfIteratorHelper(root.children),
298
+ _step2;
299
+ try {
300
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
301
+ var node = _step2.value;
302
+ if ('properties' in node && node.properties) {
303
+ var _node$position4;
304
+ node.properties.line = (_node$position4 = node.position) === null || _node$position4 === void 0 ? void 0 : _node$position4.start.line;
305
+ }
306
+ }
307
+ } catch (err) {
308
+ _iterator2.e(err);
309
+ } finally {
310
+ _iterator2.f();
311
+ }
312
+ };
313
+ }).runSync(processor.parse(sourceCode)), {
308
314
  Fragment: Fragment,
309
315
  jsx: jsx,
310
316
  jsxs: jsxs,
@@ -319,4 +325,29 @@ export var viewerRender = function viewerRender(sourceCode, options) {
319
325
  }
320
326
  })
321
327
  });
328
+ };
329
+ var toHastProcessor = unified().use(remarkParse).use(remarkBreaks).use(remarkGfm).use(remarkRehype, {
330
+ allowDangerousHtml: true
331
+ }).use(rehypeRaw).freeze();
332
+ var toHTMLProcessor = unified().use(rehypeStringify).freeze();
333
+
334
+ /**
335
+ * 将 Markdown 文本转成 HTML 文本
336
+ *
337
+ * @param sourceCode Markdown 文本
338
+ * @returns HTML 文本
339
+ */
340
+ export var toHTML = function toHTML(sourceCode) {
341
+ return toHTMLProcessor.stringify(toHastProcessor.runSync(toHastProcessor.parse(sourceCode)));
342
+ };
343
+ var toMarkdownProcessor = unified().use(rehypeRemark).use(remarkGfm).use(remarkBreaks).use(remarkStringify).freeze();
344
+
345
+ /**
346
+ * 将带有 HTML 的 Markdown 文本转成 Markdown 文本
347
+ *
348
+ * @param sourceCode 带有 HTML 的 Markdown 文本
349
+ * @returns Markdown 文本
350
+ */
351
+ export var toMarkdown = function toMarkdown(sourceCode) {
352
+ return toMarkdownProcessor.stringify(toMarkdownProcessor.runSync(toHastProcessor.runSync(toHastProcessor.parse(sourceCode))));
322
353
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x-star-editor",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "An editor developed by turingstar",
5
5
  "license": "MIT",
6
6
  "module": "dist/index.js",
@@ -9,7 +9,7 @@
9
9
  "dist"
10
10
  ],
11
11
  "scripts": {
12
- "build": "father build && sass src/styles/index.scss dist/styles/index.css --style=compressed --no-source-map",
12
+ "build": "father build && sass src/styles/index.scss dist/styles/index.css --no-source-map",
13
13
  "build:watch": "father dev",
14
14
  "dev": "dumi dev",
15
15
  "docs:build": "dumi build",
@@ -49,12 +49,15 @@
49
49
  "rehype-katex": "^6.0.3",
50
50
  "rehype-prism-plus": "^1.6.1",
51
51
  "rehype-raw": "^6.1.1",
52
+ "rehype-remark": "^9.1.2",
52
53
  "rehype-sanitize": "^5.0.1",
54
+ "rehype-stringify": "^9.0.4",
53
55
  "remark-breaks": "^3.0.3",
54
56
  "remark-gfm": "^3.0.1",
55
57
  "remark-math": "^5.1.1",
56
58
  "remark-parse": "^10.0.2",
57
59
  "remark-rehype": "^10.1.0",
60
+ "remark-stringify": "^10.0.3",
58
61
  "unified": "^10.1.2"
59
62
  },
60
63
  "devDependencies": {