ProseMirror input rules: turn a typed prefix into document structure

Register inputRules({ rules }) to transform a pattern as an author types it. Use schema-aware helpers such as wrappingInputRule() for structural changes, and bind undoInputRule so the author can immediately reverse an unwanted conversion. Input rules act on matching text before the cursor; they do not parse an imported Markdown document. Input rules reference

In an incident-note editor, typing > at the start of a paragraph should create a blockquote for a witness statement. Typing > inside an ordinary sentence should leave that sentence alone. A developer needs to define that boundary before adding shortcuts to every punctuation pattern.

Match the intended paragraph boundary

The existing ProseMirror schema must already contain a suitable blockquote node. Add this plugin to the current editor state without replacing the application's other plugins:

import {
  inputRules,
  wrappingInputRule
} from 'prosemirror-inputrules';

function witnessInputRules(schema) {
  const quote = schema.nodes.blockquote;
  if (!quote) {
    throw new Error('This editor needs a blockquote node.');
  }

  return inputRules({
    rules: [wrappingInputRule(/^>\s$/, quote)]
  });
}

The leading ^ restricts this rule to the start of the textblock, and $ anchors it at the cursor-side end of the match. The expression requires a whitespace character after the greater-than sign. For a deliberate keyboard test, type > followed by a space in an empty paragraph.

The helper wraps the textblock in the supplied node type and removes the triggering prefix. It uses the schema's allowed structure; adding a rule cannot make an unsupported blockquote valid. Inspect the resulting document model as well as its appearance.

Provide an immediate way to recover the literal prefix

Add a keymap ahead of a more general Backspace handler:

import { keymap } from 'prosemirror-keymap';
import { undoInputRule } from 'prosemirror-inputrules';

const reverseTypedConversion = keymap({
  Backspace: undoInputRule
});

Keep the application's ordinary editing keymaps after that plugin. undoInputRule handles the key when an input-rule conversion was the last action and can be reversed. When it does not handle the command, later keymaps still need the opportunity to perform normal deletion.

This immediate reversal is separate from a general Undo history. The ProseMirror history guide covers grouping normal edits into undoable events. Do not assume that adding a history plugin automatically exposes the input-rule-specific Backspace behavior.

For the incident note, type the prefix, then press Backspace immediately. Confirm the literal prefix returns in an ordinary paragraph. Type it again and continue the witness statement to test the intended transformed route.

Keep prose transformations away from technical tokens

A custom InputRule can replace text or return a transaction. Its regular expression should end with $, because the rule inspects text immediately before the cursor. The handler receives model positions for the matched range; those positions are not exported-HTML indices.

The current reference distinguishes code nodes from inline code marks. Rules skip code nodes by default. Inline code marks have a separate inCodeMark option, whose documented default allows matching. A prose substitution that must leave inline code untouched therefore needs an explicit choice:

import { InputRule } from 'prosemirror-inputrules';

const copyrightNoticeRule = new InputRule(
  /\(c\)$/,
  '©',
  { inCode: false, inCodeMark: false }
);

This is an optional independent rule, not required for the blockquote example. Add it to the same rules array only if authors want the substitution. Check the installed package version against the current reference before using options in an older integration.

Test typing separately from importing a document

Use a short development checklist: type > at a paragraph start; type a greater-than sign in the middle of a sentence; immediately undo the conversion; then repeat in the editor's supported code contexts. Inspect both the visible result and the document structure.

Pasting a whole Markdown file is a separate conversion boundary. The Markdown import guide illustrates that distinction using a parser, sanitization policy, and editor import step. It does not establish that a typed input rule runs on paste.

Finally, save and reopen an incident note containing a real blockquote and an ordinary comparison sentence. Read both as the recipient will: the quotation should remain a quotation, while the comparison keeps the literal punctuation the author chose.

Keep reading