-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: nodeInputRule() support for group match #1574
Conversation
Fixes in nodeInputRule() - add support for "first group match, if any" similar to https://prosemirror.net/docs/ref/#inputrules - fix issue where rewriting includes extra unnecessary character from the match
Hey, sorry for that delay. Can you please show me a code example of what your PR is trying to fix? Thanks! |
@nokola This explains why you replaced I’m currently on a rewrite of inputrules and pasterules so things may change anytime soon. |
I ended up extending nodeInputRule() even further to support any text passed by user to replace in import type { NodeType } from 'prosemirror-model'
import { InputRule } from 'prosemirror-inputrules'
export type NodeMatchInfo = {
replaceText?: string,
attrs: Record<string, any>,
};
export default function (regexp: RegExp, type: NodeType, getMatchInfo?: ((match: RegExpExecArray) => NodeMatchInfo)): InputRule {
return new InputRule(regexp, (state, match, start, end) => {
const info: NodeMatchInfo | null = getMatchInfo == null ? null : getMatchInfo(match as RegExpExecArray);
const { tr } = state;
if (info?.replaceText) {
const offset = match[0].lastIndexOf(info.replaceText);
let matchStart = start + offset;
if (matchStart > end) {
matchStart = end;
}
else {
end = matchStart + info.replaceText.length;
}
// insert last typed character
const lastChar = match[0][match[0].length - 1];
tr.insertText(lastChar, start + match[0].length - 1);
// insert node from input rule
tr.replaceWith(matchStart, end, type.create(info?.attrs));
} else if (match[0]) {
tr.replaceWith(start, end, type.create(info?.attrs));
}
return tr;
})
} sample use: addInputRules() {
return [
nodeInputRule(/^\s*((?:DONE|CUT)?\s*(?:--))\s+$/, this.type as any, parseState),
];
},
enum TaskState {
TODO = "TODO",
DONE = "DONE",
CUT = "CUT"
}
function parseState(match: RegExpExecArray): NodeMatchInfo {
if (match[1].indexOf(TaskState.DONE) >= 0) {
return {
replaceText: match[1],
attrs: { state: TaskState.DONE },
};
}
if (match[1].indexOf(TaskState.CUT) >= 0) {
return {
replaceText: match[1],
attrs: { state: TaskState.CUT },
};
}
return {
replaceText: match[1],
attrs: { state: TaskState.TODO },
};
} Tasks look like:
|
Image input rule leaves erroneous text behind due to my previous change to add group matching in ueberdosis#1574. This change adds a `( ... )` regex group around the image input rule to have it work with the new code.
Fixes in nodeInputRule()