Path: blob/master/src/packages/frontend/editors/slate/format/insert-text.ts
1698 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/* Automatic formatting67The idea is you type some markdown in a text cell, then space, and8if the markdown processor does something nontrivial given that text,9then the text gets replaced by the result.1011The actual implementation of this is **much deeper** than what is done12in the "shortcuts" slatejs demo here1314https://www.slatejs.org/examples/markdown-shortcuts1516in two ways:17181. This automatically supports everything the markdown-to-slate19implementation supports. Instead of having to reimplement bits20and pieces of markdown that we think of, we automatically get21absolutely everything the processor supports with 100% correct22results. If at any point we ever add a new plugin to markdown-it,23or change options, they just automatically work.24252. We use our slate-diff implementation to make the transformation26rather than coding it up for different special cases. This slate-diff27is itself deep, being based on diff-match-patch, and using numerous28heuristics.29*/3031import { Transforms, Range } from "slate";32import { markdownAutoformat } from "./auto-format";3334export const withInsertText = (editor) => {35const { insertText: insertText0 } = editor;3637const insertText = (text) => {38try {39if (editor.marks) {40// This case is to work around a strange bug that I don't know how to fix.41// If you type in a blank document:42// command+b then "foo"43// you will see "oof" in bold. This happens in many other situations, where44// initially when you insert a character in a blank paragraph with a mark, the45// cursor doesn't move. I don't know why. We thus check after inserting46// text that the focus moves, and if not, we move it.47const { selection } = editor;48insertText0(text);49if (50editor.selection != null &&51editor.selection.focus.offset == selection?.focus.offset52) {53Transforms.move(editor, { distance: 1 });54}55} else {56insertText0(text);57}58} catch (err) {59// I once saw trying to insert text when some state is invalid causing60// a crash in production to me. It's better for the text to not get61// inserted and get a console warning, than for everything to crash62// in your face, hence this.63console.warn(`WARNING -- problem inserting text "${text}" -- ${err}`);64}65};6667editor.insertText = (text, autoFormat?) => {68if (!text) return;69if (!autoFormat) {70insertText(text);71return;72}73const { selection } = editor;7475if (selection && Range.isCollapsed(selection)) {76if (text === " ") {77if (!markdownAutoformat(editor)) {78insertText(text);79}80return;81}82}8384insertText(text);85};8687return editor;88};899091