# @automerge/prosemirror 中文文档

规范地址：https://npmcn.com/package/%40automerge/prosemirror/

版本：0\.2\.0
npm 元数据更新时间：2026-04-13T19:45:15.140Z
中文译文更新时间：2026-11-07T06:58:20.127Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40automerge/prosemirror
原文对照：https://npmcn.com/package/%40automerge/prosemirror/?lang=original

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：201 kB，41 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：10 个
- 首次发布：2024-03-15T17:22:34.153Z
- 最新版本发布：2026-02-25T09:43:46.337Z
- 近 30 天下载量：32178（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：18（近 12 个月 1 个）

## 中文简介

合作编写紧随 [丰富的文本计划](https://automerge.org/docs/reference/under-the-hood/rich-text-schema/) 使用ProseMirror. (英语).

## 安装

```sh
npm install @automerge/prosemirror
```

也可以使用：`pnpm add @automerge/prosemirror`、`yarn add @automerge/prosemirror`、`bun add @automerge/prosemirror`

## README

# 自动缩放 prosemiror 绑定

合作编写紧随 [丰富的文本计划](https://automerge.org/docs/reference/under-the-hood/rich-text-schema/) 使用ProseMirror. (英语).

## 状态

这个插件是β质量软件. API可能会在稳定放出之前稍有改变,并且存在bugs,但也有合理的效果.

## 怎样玩

此寄存器中有一个功能完备的编辑器, 您可以通过运行来播放 `npm run playground` 然后访问 `http://localhost:5173`。 。 。 .

## 示例

这个库提供了一个插件,用于映射Autommerge文档和ProseMirror文档之间. 这个插件依赖于两件事:第一,你使用的图案是ProseMiror schema的一个非常具体的子集,它被映射到Automerce丰富的文本图案(更多关于这个)上;第二,你从Automerce文档中初始化了ProseMiror文档. 因此,我们提供一个简单的切入点,为你们做所有这些事情:

```javascript
import { init } from "@automerge/prosemirror"

// Obtain a DocHandle somehow
const handle = repo.find("some-doc-url")
// wait for the handle to be ready before continuing
await handle.whenReady()

// This is the important part, we initialize the plugin with the handle and the path to the text field in the document
// and we get back a schema, a ProseMirror document, and a plugin
const { schema, pmDoc, plugin } = init(handle, ["text"])

// Create your prosemirror state with the schema, plugin, and document
let editorConfig = {
  schema,
  plugins: [
    keymap({
      ...baseKeymap,
      "Mod-b": toggleBold,
      "Mod-i": toggleItalic,
      "Mod-z": undo,
      "Mod-y": redo,
      "Mod-Shift-z": redo,
    }),
    plugin,
  ],
  doc: pmDoc
}

let state = EditorState.create(editorConfig)

const view = new EditorView(<whatever DOM element you are rendering to>, {
  state
})
```

见 `playground/src/Editor.tsx` 用于完整显示的示例.

## Schema 绘图

ProseMirror 文档有一个计划,它决定文档中允许的节点和标记的种类. 要在自动化文档和ProseMirror文档中的块标记和标记之间映射,您必须创建 `SchemaAdapter`。对 `SchemaAdapter` 和那个一样 `{nodes, marks}` 对象,用于创建 `ProseMirror` 计划,但是 `nodes` 财务报告和审定财务报表 `marks` 对象有一个额外的可选密钥,名为 `automerge`,它配置自动化文档如何映射到ProseMirror文档.

举例来说,这里有一个片段,它描绘了 `paragraph` 节点到 `paragraph` 块类型 :

```typescript
import {SchemaAdapter} from "@automerge/prosemirror"
const adapter = new SchemaAdapter({
    nodes: {
        ... // other nodes
        /// A plain paragraph textblock. Represented in the DOM
        /// as a `<p>` element.
        paragraph: {
          // ---------------------------------------
          //    This is the automerge configuration
          // ---------------------------------------
          automerge: {
            block: "paragraph",
          },
          // ---------------------------------------
          content: "inline*",
          group: "block",
          parseDOM: [{ tag: "p" }],
          toDOM() {
            return pDOM
          },
        } as NodeSpec,
    }
})
```

此策略适配器可以传递给 `init` 作为一种选项:

```typescript
const { pmDoc, schema, plugin } = init(handle, ["text"], {
  schemaAdapter: adapter,
})
```

表格中有许多键可用 `automerge` 测绘. 要了解它们都意味着什么 你需要了解计划绘图的目标:

-   在自动合并块和ProseMirror节点之间转换
-   在自动合并标记和ProseMiror标记之间转换
-   在ProseMirror 文档中代表未知的块和标记,这样编辑一个带有未知标记或块的文档不会导致它们丢失

### 将块转换为节点

#### 简单块 <- > 节点映射

将块转换为节点的简单案例是当从块类型到节点类型的一对一映射,而节点没有任何额外的属性. 与上段标记的情况一样,这通常看起来像:

```typescript
nodes: {
    <node name>: {
        // rest of the node spec
        automerge: {
            block: <block name>
        }
    }
}
```

#### 依靠父母绘制地图

一个更复杂的案例是当块的类型取决于周围的内容. 例如,a `<li>` proseMirror中的节点可以是 `ordered-list-item` 或一个 `unordered-list-item` 在丰富的文本中, 在这种情况下,你可以使用 `within` 键 :

```typescript
nodes: {
    list_item: {
        // rest of the node spec
        automerge: {
            // Here the keys of the map are other nodes in the schema
            within: {
                ordered_list: "ordered-list-item",
                bullet_list: "unordered-list-item"
            }
        }
    }
}
```

#### 具有额外属性的映射

许多节点和块标记比仅仅一种类型名称更为复杂. 它们也带有属性. 在这种情况下,你使用 `attrParsers` 会 议 日 程 和 议 程 `automerge` 键。 例如 `heading` 块标记 `level` 属性,用于确定标题的级别。 这就是你如何将它映射到ProseMirror节点:

```typescript
nodes: {
    heading {
    // rest of the node spec
      automerge: {
        block: "heading",
        attrParsers: {
          fromAutomerge: block => ({ level: block.attrs.level }),
          fromProsemirror: node => ({ level: node.attrs.level }),
        },
      },
    }
}
```

这个 `fromAutomerge` 函数将会被传递到块标记,并且应该返回一组节点属性,同时 `fromProsemirror` 函数将传递一个节点,并返回块属性地图.

#### 嵌入区块

一些块类型并不代表分级内容,而是代表嵌入内容,这些内容不会改变文本继而起的结构作用。 例如,一个图像块标记只是表示一个图像应该出现在块标记的位置上. 对于这些街区,你可以设置 `isEmbed` 键到 `true`数字 :

```typescript
nodes: {
  image: {
    // the rest of the node spec
    automerge: {
      block: "image",
      isEmbed: true,
      attrParsers: { .. },
    }
  }
}
```

### 将标记转换为标记

标记比块简单一点 这个 `automerge` 在标记 spec上键可以包含 `markName` 键,该键指定自动合并文档中的标记与ProseMirror文档中的标记相对应.

例如,a `strong` 标记可能是这样绘制的:

```typescript
marks: {
    strong: {
      // rest of the mark spec
      automerge: {
        markName: "strong",
      },
    },
}
```

与块一样,一些标记也具有需要转换的属性。 这事是用 `attrParsers` 键。 与块标记不同的是,块标记不能将复杂内容存储在自动化的标记值上,因此在解析器中,我们通常会转换成或从JSON编码的字符串,比如:

```typescript
marks: {
    link: {
      automerge: {
        markName: "link",
        parsers: {
          fromAutomerge: (mark: am.MarkValue) => {
            if (typeof mark === "string") {
              try {
                const value = JSON.parse(mark)
                return {
                  href: value.href || "",
                  title: value.title || "",
                }
              } catch (e) {
                console.warn("failed to parse link mark as JSON")
              }
            }
            return {
              href: "",
              title: "",
            }
          },
          fromProsemirror: (mark: Mark) =>
            JSON.stringify({
              href: mark.attrs.href,
              title: mark.attrs.title,
            }),
        },
      },
  }
}
```

#### 未知块

每个变相器都必须提供某种方式来代表未知的块. 这使得应用程序可以使用不同的方案在同一个文本文档上合作. 未知块将代表我的 `node` 拥有 `automerge.unknownBlock` 键集为正则,其中可以包含计划中的任何其他节点.

一个简单的方法是:

```typescript
nodes: {
  unknownBlock: {
    automerge: {
      unknownBlock: true,
    },
    group: "block",
    content: "block+", // Allow any block content
    parseDOM: [{ tag: "div", attrs: { "data-unknown-block": "true" } }],
    toDOM() {
      return ["div", { "data-unknown-block": "true" }, 0]
    },
  },
}
```

## API 密码

### `SchemaAdapter`

A 类 `SchemaAdapter` 提供ProseMirror Schema和您在自动合并文档中使用的块标记之间的映射。 这个API要理解的部分是您传递给 `SchemaAdapter` 建筑师.

一个schema适配器规格是ProseMiror schema的延伸. 它代表着一个物体 `nodes` 键和 a `marks` 键,每个键都类似于它们在 ProseMirror schema 中的等同键,但带有几个额外的键.

这个 `nodes` 值必须是ProseMirror `NodeSpec` 附加对象 `automerge` 键,类型如下:

```typescript
type AutomergeNodeSpec = {
  unknownBlock?: boolean
  block?: BlockMappingSpec
  isEmbed?: boolean
  attrParsers?: {
    fromProsemirror: (node: Node) => { [key: string]: am.MaterializeValue }
    fromAutomerge: (block: BlockMarker) => Attrs
  }
}

type BlockMappingSpec = string | { within: { [key: string]: string } }

type BlockMarker = {
  type: automerge.ImmutableString
  parents: automerge.ImmutableString[]
  attrs: { [key: string]: any }
  isEmbed?: boolean
}
```

这个 `marks` 值必须是ProseMirror `MarkSpec` 附加对象 `automerge` 键,类型如下:

```typescript
automerge?: {
    markName: string
    parsers?: {
      fromAutomerge: (value: automerge.MarkValue) => Attrs
      fromProsemirror: (mark: Mark) => automerge.MarkValue
    }
  }

```

## 常见问题

### @automerge/prosemirror 是什么？

合作编写紧随 丰富的文本计划 使用ProseMirror\. \(英语\)\.

### 如何安装 @automerge/prosemirror？

在项目目录运行 npm install @automerge/prosemirror，或使用 pnpm add / yarn add / bun add。

### @automerge/prosemirror 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @automerge/prosemirror 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @automerge/prosemirror 可以商用吗？

@automerge/prosemirror 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @automerge/prosemirror 的下载量有多少？

根据 npm 官方下载统计，@automerge/prosemirror 在 2026/10/07 – 2026/11/05 这 30 天内被下载 32,178 次，日均约 1,073 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @automerge/prosemirror 还在维护吗？

最新版本 0\.2\.0 发布于 2026/02/25（8 个月前）；至今共发布 18 个版本，其中过去 12 个月发布了 1 个；首次发布于 2024/03/16。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

