Files
outline/shared/editor/marks/Code.ts

88 lines
2.0 KiB
TypeScript

import { toggleMark } from "prosemirror-commands";
import {
MarkSpec,
MarkType,
Node as ProsemirrorNode,
Mark as ProsemirrorMark,
} from "prosemirror-model";
import moveLeft from "../commands/moveLeft";
import moveRight from "../commands/moveRight";
import markInputRule from "../lib/markInputRule";
import { MarkdownSerializerState } from "../lib/markdown/serializer";
import Mark from "./Mark";
function backticksFor(node: ProsemirrorNode, side: -1 | 1) {
const ticks = /`+/g;
let match: RegExpMatchArray | null;
let len = 0;
if (node.isText) {
while ((match = ticks.exec(node.text || ""))) {
len = Math.max(len, match[0].length);
}
}
let result = len > 0 && side > 0 ? " `" : "`";
for (let i = 0; i < len; i++) {
result += "`";
}
if (len > 0 && side < 0) {
result += " ";
}
return result;
}
export default class Code extends Mark {
get name() {
return "code_inline";
}
get schema(): MarkSpec {
return {
excludes: "_",
parseDOM: [{ tag: "code.inline", preserveWhitespace: true }],
toDOM: () => ["code", { class: "inline", spellCheck: "false" }],
};
}
inputRules({ type }: { type: MarkType }) {
return [markInputRule(/(?:^|[^`])(`([^`]+)`)$/, type)];
}
keys({ type }: { type: MarkType }) {
// Note: This key binding only works on non-Mac platforms
// https://github.com/ProseMirror/prosemirror/issues/515
return {
"Mod`": toggleMark(type),
ArrowLeft: moveLeft(),
ArrowRight: moveRight(),
};
}
toMarkdown() {
return {
open(
_state: MarkdownSerializerState,
_mark: ProsemirrorMark,
parent: ProsemirrorNode,
index: number
) {
return backticksFor(parent.child(index), -1);
},
close(
_state: MarkdownSerializerState,
_mark: ProsemirrorMark,
parent: ProsemirrorNode,
index: number
) {
return backticksFor(parent.child(index - 1), 1);
},
escape: false,
};
}
parseMarkdown() {
return { mark: "code_inline" };
}
}