mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
104 lines
2.6 KiB
TypeScript
104 lines
2.6 KiB
TypeScript
import {
|
|
mathBackspaceCmd,
|
|
insertMathCmd,
|
|
mathSchemaSpec,
|
|
} from "@benrbray/prosemirror-math";
|
|
import type { PluginSimple } from "markdown-it";
|
|
import type {
|
|
NodeSpec,
|
|
NodeType,
|
|
Schema,
|
|
Node as ProsemirrorNode,
|
|
} from "prosemirror-model";
|
|
import type { Command, Plugin } from "prosemirror-state";
|
|
import MathPlugin from "../extensions/Math";
|
|
import type { MarkdownSerializerState } from "../lib/markdown/serializer";
|
|
import mathRule, { REGEX_INLINE_MATH_DOLLARS } from "../rules/math";
|
|
import Node from "./Node";
|
|
import { InputRule } from "prosemirror-inputrules";
|
|
import { isInCode } from "../queries/isInCode";
|
|
|
|
export default class Math extends Node {
|
|
get name() {
|
|
return "math_inline";
|
|
}
|
|
|
|
get schema(): NodeSpec {
|
|
return mathSchemaSpec.nodes.math_inline;
|
|
}
|
|
|
|
commands({ type }: { type: NodeType }) {
|
|
return (): Command => (state, dispatch) => {
|
|
dispatch?.(state.tr.replaceSelectionWith(type.create()).scrollIntoView());
|
|
return true;
|
|
};
|
|
}
|
|
|
|
inputRules({ schema }: { schema: Schema }) {
|
|
return [
|
|
new InputRule(REGEX_INLINE_MATH_DOLLARS, (state, match, start, end) => {
|
|
if (isInCode(state)) {
|
|
return null;
|
|
}
|
|
|
|
let $start = state.doc.resolve(start);
|
|
let index = $start.index();
|
|
let $end = state.doc.resolve(end);
|
|
// check if replacement valid
|
|
if (
|
|
!$start.parent.canReplaceWith(
|
|
index,
|
|
$end.index(),
|
|
schema.nodes.math_inline
|
|
)
|
|
) {
|
|
return null;
|
|
}
|
|
// perform replacement
|
|
return state.tr.replaceRangeWith(
|
|
start,
|
|
end,
|
|
schema.nodes.math_inline.create(
|
|
undefined,
|
|
schema.nodes.math_inline.schema.text(match[1])
|
|
)
|
|
);
|
|
}),
|
|
];
|
|
}
|
|
|
|
keys({ type }: { type: NodeType }) {
|
|
return {
|
|
"Mod-Space": insertMathCmd(type),
|
|
Backspace: mathBackspaceCmd,
|
|
};
|
|
}
|
|
|
|
get plugins(): Plugin[] {
|
|
return [MathPlugin];
|
|
}
|
|
|
|
get rulePlugins(): PluginSimple[] {
|
|
return [mathRule];
|
|
}
|
|
|
|
toMarkdown(state: MarkdownSerializerState, node: ProsemirrorNode) {
|
|
state.write("$");
|
|
// Pipes inside math would otherwise be mistaken for cell delimiters when
|
|
// the math appears within a table, so escape them here.
|
|
const content = state.inTable
|
|
? node.textContent.replace(/\|/g, "\\$&")
|
|
: node.textContent;
|
|
state.text(content, false);
|
|
state.write("$");
|
|
}
|
|
|
|
parseMarkdown() {
|
|
return {
|
|
node: "math_inline",
|
|
block: "math_inline",
|
|
noCloseToken: true,
|
|
};
|
|
}
|
|
}
|