# 输入与粘贴规则

显式转换新输入，保持组合输入、范围边界和撤销的一致性。

## 何时需要规则

解析插件只解释源码。输入规则会改变用户刚输入的文本，例如将 `::ok ` 换成 `[[done]] `；粘贴规则可以将外部系统的 `[STATUS:DONE]` 换成自己的状态语法。转换应是应用明确启用的行为，并能撤销。

以下完整模块可与 [状态节点](/extensions/custom-node) 一起安装；不安装状态节点时，转换后的文本仍是普通源码。

### recipes/rules.ts

```ts
import { Extension, InputRule, PasteRule } from "@quirekit/msfe-core";
/** Explicit opt-in text normalization, separate from syntax-only rendering plugins. */
export const SourceRules = Extension.create({ name: "exampleRules",
  /** @returns A suffix rule triggered by the final space after ::ok. */
  addInputRules() { return [new InputRule({ find: /::ok $/u,
    /** @returns Exact canonical replacement. */ handler() { return "[[done]] "; },
  })]; },
  /** @returns A clipboard-only legacy status migration. */
  addPasteRules() { return [new PasteRule({ find: /\[STATUS:DONE\]/u,
    /** @returns Exact canonical status syntax. */ handler() { return "[[done]]"; },
  })]; },
});

```

## handler 的坐标和结果

`find` 是正则；`handler({ match, range, document })` 取得原生输入已经进入文本后的匹配结果和 UTF-16 范围。返回字符串替换这一段，返回 `null` 保留输入。不要在 handler 内提交命令、发请求或改变 DOM。

`document` 可用于必要的有界上下文判断。例子有意定义为全局字面转换，也会转换代码中的匹配字面值；业务若要求代码区域保留原样，需要增加准确的语法上下文约束并覆盖输入尚未解析完成的情况。不能只靠正则声称完成 Markdown 语义判断。

## 内置工作边界

- 输入规则只检查当前行末尾最多 512 个逻辑单元，且匹配必须结束于输入位置。第一条适用转换生效。
- 粘贴规则只扫描本次插入的文本，不扫描原文。超过 65,536 单元的单次插入保留原样。
- 重叠粘贴匹配不会重复应用；结果按源码位置排序。
- 多选区、只读和原生组合输入不会进入普通规则转换路径。程序化命令也不能当作键盘输入规则触发器。

这些是当前实现的有界策略；不要依赖超长输入自动改写。处理大型导入应走独立、可预览的导入命令。

## 验证转换没有越界

测试转换后的精确源码和一次撤销结果，同时覆盖：不匹配、空匹配、两个规则竞争、多个粘贴匹配、原文中存在同样字符串、长剪贴板、中文输入法及只读。返回与原匹配相同的字符串不会增加额外替换。

签名见 [扩展 API](/api/extensions)。只需改变显示时，选择 [Markdown 插件](/extensions/markdown-plugins)，不要用输入规则重写已有文件。
