@type-editor/inputrules
v0.0.3
Published
This is a refactored version of the ProseMirror's 'inputrules' module. Original: https://github.com/ProseMirror/prosemirror-inputrules
Maintainers
Readme
@type-editor/inputrules
A refactored version of ProseMirror's prosemirror-inputrules module, providing a plugin for defining input rules that react to or transform text typed by the user.
Installation
npm install @type-editor/inputrulesOverview
This module defines a plugin for attaching input rules to an editor. Input rules are regular expressions describing text patterns that, when typed, trigger automatic transformations. This enables features like:
- Converting
--into an em dash (—) - Transforming
...into an ellipsis (…) - Smart quote substitution
- Wrapping paragraphs starting with
>into blockquotes - Converting lines starting with
#into headings
Core API
InputRule Class
The InputRule class represents a single input rule that matches a regex pattern and applies a transformation.
import { InputRule } from '@type-editor/inputrules';
const myRule = new InputRule(
/pattern$/, // RegExp - must end with $
'replacement', // string or handler function
{ undoable: true } // optional configuration
);Constructor Parameters
| Parameter | Type | Description |
|-----------|------------------------------|---------------------------------------------------------|
| match | RegExp | Pattern to match against typed text. Must end with $. |
| handler | string \| InputRuleHandler | Replacement string or handler function. |
| options | InputRuleOptions | Optional configuration object. |
InputRuleOptions
| Option | Type | Default | Description |
|--------------|---------------------|---------|--------------------------------------------------------------------------------------------------------------------|
| undoable | boolean | true | When false, the undoInputRule command won't work on this rule. |
| inCode | boolean \| 'only' | false | Controls behavior in code nodes. false: won't apply; true: applies everywhere; 'only': only applies in code. |
| inCodeMark | boolean | true | Controls whether the rule applies inside code marks. |
InputRuleHandler
A handler function receives the editor state and match information:
type InputRuleHandler = (
state: EditorState,
match: RegExpMatchArray,
start: number,
end: number
) => Transaction | null;inputRulesPlugin
Creates a plugin that enables input rule matching and application.
import { inputRulesPlugin } from '@type-editor/inputrules';
const plugin = inputRulesPlugin({
rules: [rule1, rule2, rule3]
});Also exported as inputRules for compatibility.
Built-in Rules
Text Replacement Rules
| Rule | Pattern | Replacement | Description |
|------------|---------|-------------|-------------------------------------------------|
| emDash | -- | — | Converts two dashes into an em dash. |
| ellipsis | ... | … | Converts three dots into an ellipsis character. |
Smart Quote Rules
| Rule | Description |
|--------------------|-------------------------------------------------------|
| openDoubleQuote | Inserts " (left double quote) in opening contexts. |
| closeDoubleQuote | Inserts " (right double quote) in closing contexts. |
| openSingleQuote | Inserts ' (left single quote) in opening contexts. |
| closeSingleQuote | Inserts ' (right single quote) in closing contexts. |
| smartQuotes | Array containing all four smart quote rules. |
Smart quote rules detect context automatically—they insert opening quotes after whitespace or opening punctuation, and closing quotes elsewhere.
Utility Functions
wrappingInputRule
Creates an input rule that wraps a textblock in a given node type.
import { wrappingInputRule } from '@type-editor/inputrules';
// Wrap lines starting with "> " in a blockquote
const blockQuoteRule = wrappingInputRule(
/^>\s$/,
schema.nodes.blockquote
);
// With computed attributes
const listRule = wrappingInputRule(
/^(\d+)\.\s$/,
schema.nodes.ordered_list,
(match) => ({ order: +match[1] })
);
// With join predicate
const bulletRule = wrappingInputRule(
/^\s*([-+*])\s$/,
schema.nodes.bullet_list,
null,
(match, node) => node.childCount > 0
);Parameters
| Parameter | Type | Description |
|-----------------|-------------------------------|---------------------------------------------------------|
| regexp | RegExp | Pattern to match (typically starts with ^). |
| nodeType | NodeType | The node type to wrap in. |
| getAttrs | Attrs \| ((match) => Attrs) | Attributes for the wrapper node. |
| joinPredicate | (match, node) => boolean | Whether to join with an adjacent node of the same type. |
textblockTypeInputRule
Creates an input rule that changes the type of a textblock.
import { textblockTypeInputRule } from '@type-editor/inputrules';
// Convert lines starting with "# " to h1
const headingRule = textblockTypeInputRule(
/^#\s$/,
schema.nodes.heading,
{ level: 1 }
);
// With computed attributes for multiple heading levels
const headingRules = [1, 2, 3, 4, 5, 6].map((level) =>
textblockTypeInputRule(
new RegExp(`^#{${level}}\\s$`),
schema.nodes.heading,
{ level }
)
);Parameters
| Parameter | Type | Description |
|------------|-------------------------------|-----------------------------------------------|
| regexp | RegExp | Pattern to match (typically starts with ^). |
| nodeType | NodeType | The new node type for the textblock. |
| getAttrs | Attrs \| ((match) => Attrs) | Attributes for the new node. |
Commands
undoInputRule
A command that undoes the last input rule application, if any.
import { undoInputRule } from '@type-editor/inputrules';
// Use in a keymap
const keymap = {
'Backspace': undoInputRule
};This allows users to press Backspace immediately after an input rule fires to revert the transformation.
Usage Example
import {
inputRulesPlugin,
emDash,
ellipsis,
smartQuotes,
wrappingInputRule,
textblockTypeInputRule
} from '@type-editor/inputrules';
import { schema } from './my-schema';
// Create custom rules for your schema
const blockquoteRule = wrappingInputRule(/^>\s$/, schema.nodes.blockquote);
const codeBlockRule = textblockTypeInputRule(/^```$/, schema.nodes.code_block);
const headingRule = textblockTypeInputRule(
/^(#{1,6})\s$/,
schema.nodes.heading,
(match) => ({ level: match[1].length })
);
// Combine all rules into a plugin
const plugin = inputRulesPlugin({
rules: [
emDash,
ellipsis,
...smartQuotes,
blockquoteRule,
codeBlockRule,
headingRule
]
});
// Add the plugin to your editor stateExported Types
| Type | Description |
|------------------------|----------------------------------------------------|
| InputRuleHandler | Function signature for custom input rule handlers. |
| InputRuleOptions | Configuration options for InputRule constructor. |
| InputRulesPluginSpec | Plugin specification interface. |
| PluginState | Internal plugin state type. |
License
MIT
