Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/editors/slate/format/insert-text.ts
1698 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
/* Automatic formatting
7
8
The idea is you type some markdown in a text cell, then space, and
9
if the markdown processor does something nontrivial given that text,
10
then the text gets replaced by the result.
11
12
The actual implementation of this is **much deeper** than what is done
13
in the "shortcuts" slatejs demo here
14
15
https://www.slatejs.org/examples/markdown-shortcuts
16
17
in two ways:
18
19
1. This automatically supports everything the markdown-to-slate
20
implementation supports. Instead of having to reimplement bits
21
and pieces of markdown that we think of, we automatically get
22
absolutely everything the processor supports with 100% correct
23
results. If at any point we ever add a new plugin to markdown-it,
24
or change options, they just automatically work.
25
26
2. We use our slate-diff implementation to make the transformation
27
rather than coding it up for different special cases. This slate-diff
28
is itself deep, being based on diff-match-patch, and using numerous
29
heuristics.
30
*/
31
32
import { Transforms, Range } from "slate";
33
import { markdownAutoformat } from "./auto-format";
34
35
export const withInsertText = (editor) => {
36
const { insertText: insertText0 } = editor;
37
38
const insertText = (text) => {
39
try {
40
if (editor.marks) {
41
// This case is to work around a strange bug that I don't know how to fix.
42
// If you type in a blank document:
43
// command+b then "foo"
44
// you will see "oof" in bold. This happens in many other situations, where
45
// initially when you insert a character in a blank paragraph with a mark, the
46
// cursor doesn't move. I don't know why. We thus check after inserting
47
// text that the focus moves, and if not, we move it.
48
const { selection } = editor;
49
insertText0(text);
50
if (
51
editor.selection != null &&
52
editor.selection.focus.offset == selection?.focus.offset
53
) {
54
Transforms.move(editor, { distance: 1 });
55
}
56
} else {
57
insertText0(text);
58
}
59
} catch (err) {
60
// I once saw trying to insert text when some state is invalid causing
61
// a crash in production to me. It's better for the text to not get
62
// inserted and get a console warning, than for everything to crash
63
// in your face, hence this.
64
console.warn(`WARNING -- problem inserting text "${text}" -- ${err}`);
65
}
66
};
67
68
editor.insertText = (text, autoFormat?) => {
69
if (!text) return;
70
if (!autoFormat) {
71
insertText(text);
72
return;
73
}
74
const { selection } = editor;
75
76
if (selection && Range.isCollapsed(selection)) {
77
if (text === " ") {
78
if (!markdownAutoformat(editor)) {
79
insertText(text);
80
}
81
return;
82
}
83
}
84
85
insertText(text);
86
};
87
88
return editor;
89
};
90
91