59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
import type { NodeType, Schema } from 'prosemirror-model';
|
|
import {
|
|
inputRules,
|
|
wrappingInputRule,
|
|
smartQuotes,
|
|
emDash,
|
|
ellipsis,
|
|
InputRule,
|
|
} from 'prosemirror-inputrules';
|
|
|
|
const blockQuoteRule = (nodeType: NodeType) => wrappingInputRule(/^\s*>\s$/, nodeType);
|
|
|
|
const orderedListRule = (nodeType: NodeType) =>
|
|
wrappingInputRule(
|
|
/^(\d+)\.\s$/,
|
|
nodeType,
|
|
(match) => ({ order: +match[1] }),
|
|
(match, node) => node.childCount + node.attrs.order === +match[1],
|
|
);
|
|
|
|
const bulletListRule = (nodeType: NodeType) => wrappingInputRule(/^\s*([-+*])\s$/, nodeType);
|
|
|
|
const codeRule = () => {
|
|
const inputRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))$/;
|
|
|
|
return new InputRule(inputRegex, (state, match, start, end) => {
|
|
const { schema } = state;
|
|
|
|
const tr = state.tr.insertText(`${match[2]} `, start, end);
|
|
const mark = schema.marks.code.create();
|
|
|
|
return tr.addMark(start, start + match[2].length, mark);
|
|
});
|
|
};
|
|
|
|
const linkRule = () => {
|
|
const urlRegEx = /(?:https?:\/\/)?[\w-]+(?:\.[\w-]+)+\.?(?:\d+)?(?:\/\S*)?$/;
|
|
|
|
return new InputRule(urlRegEx, (state, match, start, end) => {
|
|
const { schema } = state;
|
|
|
|
const tr = state.tr.insertText(match[0], start, end);
|
|
const mark = schema.marks.link.create({ href: match[0], title: match[0] });
|
|
|
|
return tr.addMark(start, start + match[0].length, mark);
|
|
});
|
|
};
|
|
|
|
export const buildInputRules = (schema: Schema) => {
|
|
const rules = [...smartQuotes, ellipsis, emDash];
|
|
rules.push(blockQuoteRule(schema.nodes.blockquote));
|
|
rules.push(orderedListRule(schema.nodes.ordered_list));
|
|
rules.push(bulletListRule(schema.nodes.bullet_list));
|
|
rules.push(codeRule());
|
|
rules.push(linkRule());
|
|
|
|
return inputRules({ rules });
|
|
};
|