# @brett\_lamy/docstream-editor 中文文档

规范地址：https://npmcn.com/package/%40brett_lamy/docstream-editor/

版本：1\.35\.0
npm 元数据更新时间：2026-11-04T03:30:21.954Z
中文译文更新时间：2026-11-08T14:46:30.403Z
软件包许可：未声明

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

原始 npm 页面：https://www.npmjs.com/package/%40brett_lamy/docstream-editor
原文对照：https://npmcn.com/package/%40brett_lamy/docstream-editor/?lang=original
项目主页：https://github.com/BLamy/docstream-editor#readme
源码仓库：https://github.com/BLamy/docstream-editor

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

- 包体积（解压后）：731 kB，84 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：4 个
- peer 依赖：react \>=18，react-dom \>=18，@tiptap/pm ^3\.26\.1，@tiptap/core ^3\.26\.1，@tiptap/react ^3\.26\.1，@tiptap/suggestion ^3\.26\.1，@tiptap/starter-kit ^3\.26\.1，@tiptap/extension-code ^3\.26\.1，@tiptap/extension-list ^3\.26\.1，@tiptap/extension-table ^3\.26\.1，@tiptap/extension-code-block ^3\.26\.1，@tiptap/extension-placeholder ^3\.26\.1
- 首次发布：2026-06-15T18:20:03.455Z
- 最新版本发布：2026-11-04T03:30:21.782Z
- 近 30 天下载量：5758（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：77（近 12 个月 77 个）

## 中文简介

Docstream GitBook 风格标记下文档的 TipTap 编辑器 .

## 安装

```sh
npm install @brett_lamy/docstream-editor
```

也可以使用：`pnpm add @brett_lamy/docstream-editor`、`yarn add @brett_lamy/docstream-editor`、`bun add @brett_lamy/docstream-editor`

## README

# @brett lamy/多流编辑器

用于 Docstream GitBook 风格标记下文档的 TipTap 编辑器组件 .

`@brett_lamy/docstream-editor` 提供同一文档模型的可编辑层 `@brett_lamy/docstream`。它用于需要丰富编辑的docs应用,同时保留了GitBook-flavorred 标记下块,用于预览、存储和AI流渲染.

## 特征

-   为 GitBook 风格的 Markdown 所控制的反应编辑器组件 .
-   常见写流的 TipTap 扩展名 .
-   Docstream AST和TipTap JSON之间的转换助手.
-   插入所支持块的斜线菜单 .
-   代码块语法突出显示通过 [`gpu-lexer`](https://gpu-lexer.vercel.app/) (语言不可知,WebGPU;没有WebGPU的纯文本).
-   表格、任务列表、标题、引文和内置格式支持.
-   在转换回标记下时保留 Docstream/GitBook 块语义.
-   复制一个docspage(docstream的"Copy page")并粘贴在:编辑器显示同一页和 将它序列化回为字节的字节——用其内置文件演示,安装命令框,标题 选项卡集和全部。 内置代码可能与链接、粗体、斜体和击打结合 (单位:千美元)``[`@brett_lamy/ui`](url)``, (中文(简体) ), ``**bold `x` text**``); 编辑的 `GbCode` 标记允许它.
-   无损失:任何Markdown页面都会通过编辑器返回字节. docstream 的布局字段 (横线,栅栏,列表标记,标记线,生HTML,.) 骑在每一个节点上 `md` 属性 (单位:千美元)`GbMarkdownLayout`; 链接细节和链接/代码标记上的代码宽回接; 逃脱 `mdEscaped` 标记; 嵌入式为 `more` 标记; 参考定义和未知 `{% tags %}` 作为 `gbDefinition` 编号 : `gbRaw` 块; 芯片和内置图像带有强调和链接标记.
-   保存挂载的源文件/导出出地,并且可以通过Vite将编辑写入真实文件.

## 安装

```sh
pnpm add @brett_lamy/docstream-editor @tiptap/core @tiptap/extension-code @tiptap/extension-code-block \
  @tiptap/extension-list @tiptap/extension-placeholder @tiptap/extension-table @tiptap/pm \
  @tiptap/react @tiptap/starter-kit @tiptap/suggestion react react-dom
```

反应和 TipTap 软件包(包括 `@tiptap/extension-code`)是同伴的依赖关系. `@brett_lamy/docstream` 是运行时的依赖性(被绑定在和编辑器相同的版本上),因为编辑器使用相同的解析器,序列器,OpenAPI渲染和资产助手. 安装中没有任何东西运行一个构建脚本,编辑器从不引用 Docstream 的可选的近节点操场(`@agent-wasm/core`()——见 `liveRenderer` 在下面选择加入.

### 文档属性和任务状态(1.9)

YAML 前题是文档模型的一部分. 编辑器显示一个可编辑的压缩属性表 身体以上; `documentProperties={false}` 藏起来 `documentProperties={{ defaultOpen: true }}` 扩展它。 属性编辑使用正则 `onChange` 并撤销/重写历史。 主体编辑保存 原始 YAML, 并控制了 Markdown 更新属性和正文 。 自定义编辑器可以 使用情况 `GbDocumentProperties`, (中文(简体) ), `DocumentPropertiesEditor` 财务报告和审定财务报表 `editor.commands.setDocumentProperties()`。 。 。 .

任务复选框支持 `[ ]`, (中文(简体) ), `[~]`, (中文(简体) ), `[?]`, (中文(简体) ), `[b]`, (中文(简体) ), `[d]`, (中文(简体) ), `[!]`, (中文(简体) ), `[x]`,以及 `[-]` 共享文档流 图标和工具提示。 单击任何标记状态以清除它,然后再次点击以验证它. 右键单击或 Shift+F10 打开每个图标和标签的状态拾取器. 选择序列化到原始标记 并参与撤销/重写. `GbTaskItem` 财务报告和审定财务报表 `editor.commands.setTaskState(state)` 可供 自定义编辑器 `createGitbookExtensions`。 。 。 .

### 迁移到1.5

无中断更改 。 复制带有演示块的选中项时, 正在写入 docstream 剪贴板( 见 [编辑器之间的复制和粘贴演示](https://npmcn.com/package/%40brett_lamy/docstream-editor/#readme-copy-and-paste-demos-between-editors), (中文(简体) ), 粘贴一个会用文件恢复演示,演示块会获得拖动抓取. 新建道具 : `demoVFS`, (中文(简体) ), `onDemoFilesChange`, (中文(简体) ), `pastedDemoFiles`, (中文(简体) ), `demoClipboard`。 。 。 . `react-aria` 现在是一个 抚养(`useClipboard`) (中文(简体) ).

### 迁移到1.4

没有 API 更改 。 拟汇编的出口决心 `dist/*.js` + 键 `.d.ts` 改为 `src/*.ts(x)` (Docstream 1.4做同样的事情); 放弃任何 `optimizeDeps` 编号 : `transpilePackages` 条目或 类型检查设置.

### 迁移到1.3

-   `GitbookEditor` 不再运行 `live` jsx/tsx 代码块在近节点的自有. 过 `liveRenderer={almostNodeLiveRenderer}` (从) `@brett_lamy/docstream/playground`)以保留预览.
-   `ReactDemoEditor` 一样 `liveRenderer` 道具; 没有道具, 文件仍可编辑, a 替换预览.

## 基本设置

在您的应用程序入口附近导入两个软件包样式 :

```ts
import "@brett_lamy/docstream/styles.css"
import "@brett_lamy/docstream-editor/styles.css"
```

如果您的 TypeScript app 检查 CSS 的副作用导入, 请包括 Vite 的标准环境声明或等同的 CSS 模块声明 :

```ts
/// <reference types="vite/client" />
```

## 使用量

`GitbookEditor` 是受控组件。 将当前标记下传并接收更新标记下传 `onChange`。 。 。 .

```tsx
import { useState } from "react"
import { GitbookEditor } from "@brett_lamy/docstream-editor"
import "@brett_lamy/docstream/styles.css"
import "@brett_lamy/docstream-editor/styles.css"

const initialMarkdown = `# Getting started

{% hint style="info" %}
Type / to insert supported blocks.
{% endhint %}
`

export function EditorPage() {
  const [markdown, setMarkdown] = useState(initialMarkdown)

  return (
    <GitbookEditor
      markdown={markdown}
      onChange={setMarkdown}
    />
  )
}
```

## 道具

每个道具都是可选的.

```ts
export interface GitbookEditorProps {
  markdown?: string
  onChange?: (markdown: string) => void
  documentProperties?: boolean | { defaultOpen?: boolean } // default true
  toolbar?: boolean // default true
  slashMenu?: boolean | { items?: SlashItem[] } // default true
  references?: boolean | ReferenceSources // default true
  editable?: boolean // default true
  placeholder?: string // default "Write, or type / to insert a block…"
  className?: string
  autofocus?: boolean // default false
  disableHistory?: boolean // default false
  extensions?: AnyExtension[]
  onEditorReady?: (editor: Editor | null) => void
  onKeyDown?: (event: KeyboardEvent) => boolean
  onPaste?: (event: ClipboardEvent) => boolean
  imagePaste?: "inline" | "chip"
  attachments?: EditorAttachment[]
  onAttachmentAdd?: (attachment: EditorAttachment & { file: File }) => void
  onAttachmentRemove?: (ids: string[]) => void
  onAttachmentOpen?: (attachment: EditorAttachment) => void
  demoResolver?: DemoResolver
  demoRuntime?: InlineDemoRuntime
  liveRenderer?: LivePreviewRenderer
  demoDependencies?: Record<string, string>
  markdownPaste?: boolean
  demoVFS?: DemoVFS
  onDemoFilesChange?: (files: Readonly<Record<string, DemoFile[]>>, change: DemoVFSChange) => void
  pastedDemoFiles?: "inline" | "vfs"
  demoClipboard?: boolean
  sourceClient?: SourceReferenceClient
  sourcePreview?: boolean // default true
  sourceAutoSave?: boolean | number // default true (500ms)
  onSourceSaved?: (snapshot: SourceFileSnapshot) => void
  onSourceError?: (error: Error) => void
  resolveAsset?: AssetResolver
  pickFile?: FilePicker
  uploadFile?: FileUploader
  onDropEmbeds?: (data: DataTransfer) => Promise<readonly string[]> | readonly string[] | null
}
```

-   `markdown`:源码减值. 当给定时, 编辑器会被控制; 省略它, 用于无控制 开始为空的编辑器.
    
-   `onChange`: 每当 TipTap 内容改变时, 使用序列化标记调用 .
    
-   `documentProperties`, (中文(简体) ), `toolbar`, (中文(简体) ), `slashMenu`, (中文(简体) ), `references`, (中文(简体) ), `editable`, (中文(简体) ), `placeholder`, (中文(简体) ), `className`, (中文(简体) ), `autofocus`: 属性表、格式工具栏、 `/` 菜单中 `@` 编号 : `#` 编号 : `$` 拾取器(见 [提及、频道和密码库](https://npmcn.com/package/%40brett_lamy/docstream-editor/#readme-mentions-channels-and-codebases)),只读 模式、空文档占位符、包装类(`gb <className>`),专注于上山.
    
-   `disableHistory`, (中文(简体) ), `extensions`, (中文(简体) ), `onEditorReady`: Yjs 风格的集成——关闭 StarterKit 的 撤销/重做, 附加 TipTap 扩展, 接收 TipTap `Editor` (和 `null` 被撕毁.
    
-   `autofocus`, (中文(简体) ), `placeholder`, (中文(简体) ), `slashMenu`, (中文(简体) ), `references`, (中文(简体) ), `disableHistory` 财务报告和审定财务报表 `extensions` 为: 当创建了 TipTap 编辑器时读取; 后期更改没有效果, 因此重挂( 例如使用) (单位:千美元) `key`)切换. `editable` 随时随地跟着道具.
    
-   `onKeyDown` 编号 : `onPaste`: 在内置编辑器行为之前运行的可选主机钩; 返回时 `true` 当应用程序处理事件时.
    
-   `imagePaste`, (中文(简体) ), `attachments`, (中文(简体) ), `onAttachmentAdd`, (中文(简体) ), `onAttachmentRemove`, (中文(简体) ), `onAttachmentOpen`数字 : 如何处理粘贴/被放入的图像——见 [粘贴并丢弃图像](https://npmcn.com/package/%40brett_lamy/docstream-editor/#readme-pasted-and-dropped-images)。 。 。 .
    
-   `demoResolver`: 解决 `{% demo src %}` ids 所以演示块显示一个活的,只读 预览 — 见 [演示块](https://npmcn.com/package/%40brett_lamy/docstream-editor/#readme-demo-blocks)。 。 。 .
    
-   `demoRuntime` 编号 : `demoDependencies`: 运行将文件内含且无 后面的解析器——与 Docstream 相同的选项 `DocRenderOptions`。 。 。 .
    
-   `liveRenderer`: 使上面的预览 `live` jsx/tsx 代码块( 作为 Docstream 的) `liveRenderer`) (中文(简体) ). 编辑器从不导入 Docstream 的近节点操场本身; 要运行 密码,通过 `almostNodeLiveRenderer` 编号 : `createAlmostNodeDemoRuntime()` 从 `@brett_lamy/docstream/playground` (并安装) `@agent-wasm/core`) (中文(简体) ). 没有他们,就用活代码 块作为普通代码编辑,并打开其代码视图的内置演示.
    
-   `markdownPaste` (默认) `true`: 包含 块( 一个“ 复制页” 导出, ), `{% … %}` 标记、栅栏、列表、标题...) 编辑器块而不是粘贴为文字文本。 平面画像往常粘贴; HTML 剪贴板 保留TipTap自己的处理方式(VS代码除外,它被视为纯文本).
    
-   `demoVFS`, (中文(简体) ), `onDemoFilesChange`, (中文(简体) ), `pastedDemoFiles`, (中文(简体) ), `demoClipboard`: 演示副本/粘贴和 演示虚拟文件系统——见 [编辑器之间的复制和粘贴演示](https://npmcn.com/package/%40brett_lamy/docstream-editor/#readme-copy-and-paste-demos-between-editors)。 。 。 .
    
-   `sourceClient`, (中文(简体) ), `sourcePreview`, (中文(简体) ), `sourceAutoSave`, (中文(简体) ), `onSourceSaved`, (中文(简体) ), `onSourceError`编辑 后面的文件 `{% source-ref %}` 块-见 [编辑引用源文件](https://npmcn.com/package/%40brett_lamy/docstream-editor/#readme-edit-a-referenced-source-file)。 。 。 .
    
-   `resolveAsset`, (中文(简体) ), `pickFile`, (中文(简体) ), `uploadFile`, (中文(简体) ), `onDropEmbeds`: 见 [主机项目的文件](https://npmcn.com/package/%40brett_lamy/docstream-editor/#readme-files-from-the-hosts-project)。 。 。 .
    

编辑器跟踪它释放的上个标记下, 因此正常的控制更新不会持续重置 TipTap 文档 。 传递不同的外部 `markdown` 值替换编辑器内容.

## 支持的编辑表面

编辑器支持常见的ProseMirror/TipTap内容外加来自Docstream的GitBook-flavored块.

-   标题
-   段 次 页 次
-   粗体、斜体、打击、内线代码和链接(内部的链接强调, `**[x](url)**`,留下来 与联系中的重点不同, `[**x**](url)`(中文(简体) )
-   任务列表
-   块名
-   代码块
-   表格
-   提示
-   标签(包括 `{% tabs sync="key" %}` 同步组和标题集 `{% tabs title="Installation" level="3" %}` 作为带开关的一节 其行——单击标签条的标题图标以添加标题)
-   软件包管理命令框(`{% command %}npm install x{% endcommand %}`, (中文(简体) ), `/install command`(中文(简体) )
-   可扩展
-   阶梯
-   嵌入层
-   内容参考
-   组件和故事书来源参考
-   现场演示`{% demo %}`,解析器备份或内含其文件
-   列数
-   数字和图像
-   OpenAPI 操作占位符

一些块被故意作为结构化的节点,而不是完全的有声编辑控制. 它们通过剖析,编辑,并串行来保存,这样文档就可以继续以"GitBook-tyle-markdown"来进行回行.

## 提及、频道和密码库

键入 `@`, (中文(简体) ), `#`,或 `$` 打开拾取器并插入一个串行为 `@id`, (中文(简体) ), `#id`,或 `$id` (单位:千美元)`$org/repo` 工作也一样。 种子每个触发静态列表或 自动同步 `(query) => options` 函数; 选项可以带有 `label`, (中文(简体) ), `description`,以及 `group` (降为行头. `$` 仅在 `codebases` 已经设定,所以 普通散文中的美元符号从不打开菜单. 自由式入口总是提供.

```tsx
<GitbookEditor
  markdown={md}
  onChange={setMd}
  references={{
    mentions: [
      ...people.map((p) => ({ id: p.handle, label: p.name, description: p.email, group: "People" })),
      ...agents.map((a) => ({ id: a.handle, label: a.name, description: a.harness, group: "Agents" })),
    ],
    tags: async (query) => searchChannels(query), // [{ id: "general", description: "channel" }]
    codebases: async (query) => searchRepos(query), // [{ id: "reading-room" }]
  }}
/>
```

## 粘贴并丢弃图像

`imagePaste` 控制粘贴或丢弃的图像文件如何输入文档。 紧接着跑  `onPaste` (返回数) `true` 来接手吧 同时带平原的剪贴板数据 文本,例如 Word 或 Excel 选择,仍然粘贴为文本.

-   `"inline"` (默认) : 文件作为数据 URL 的图像块,其渲染方式 .
-   `"chip"`:一个紧凑的附着芯片在护身符上. 主机存储文件 。 芯片 序列化为 `![image.png](attachment:att-xyz)`缩略图和大小,预览 盘旋时完整图像,点击时打开.

```tsx
const [markdown, setMarkdown] = useState("")
const [attachments, setAttachments] = useState<EditorAttachment[]>([])

<GitbookEditor
  markdown={markdown}
  onChange={setMarkdown}
  imagePaste="chip"
  attachments={attachments}
  // once per image: { id, name, src (data URL), size, type, file }
  onAttachmentAdd={({ file, ...attachment }) => setAttachments((all) => [...all, attachment])}
  // chips deleted, cut or cleared by the user
  onAttachmentRemove={(ids) => setAttachments((all) => all.filter((a) => !ids.includes(a.id)))}
  // optional; omit it to use the built-in full-screen viewer
  onAttachmentOpen={(attachment) => openLightbox(attachment)}
/>
```

`EditorAttachment` 实值 `{ id, name, src?, size?, type? }`。芯片在 `attachments` 依编号,所以 `src` 可以是数据 URL 或上传 URL 。 删除芯片 从外部编辑,呼叫 `editor.commands.removeAttachment(id)` (获得实例) 从 `onEditorReady`) (中文(简体) ). 用一个标记下图像 `attachment:` URL总是作为芯片加载, 无论模式如何. `serializeEditorMarkdown(ast)` 是连载器,将它们写入 这个表格.

## 主机项目的文件

从文件夹中编辑 Markdown 的应用程序可以插入自己的文件. 四道道具皆可选取.

```tsx
<GitbookEditor
  markdown={markdown}
  onChange={setMarkdown}
  // "./case/part.stl" as written → a URL the browser can load (blob: of the local file).
  resolveAsset={(url) => (url.startsWith("./") ? blobUrlFor(url) : null)}
  // Adds "Choose file…" to embed blocks ("Choose image…" to figures).
  pickFile={({ kind }) => openMyFilePicker({ imagesOnly: kind === "image" })}
  // Drops you claim become embeds at the drop point: images as figures, anything else as an embed.
  onDropEmbeds={(data) =>
    data.types.includes("Files") ? copyIntoProject([...data.files]).then((paths) => paths.map((p) => `./${p}`)) : null
  }
  // Adds "Upload…" to embed and image blocks; dropped or pasted files that aren't images land here too.
  uploadFile={(file) => saveNextToDocument(file).then((path) => `./${path}`)}
/>
```

-   `resolveAsset` 包括数字、内含图像和 `.stl` 编号 : `.strudel` 编号 : `.rrweb` 以物配主. A 类 `.rrweb` 嵌入是rweb记录(一个JSON事件阵列)在docstream的回放播放器中播放.
-   `pickFile` 确定要写入的 URL , 或当用户取消时没有.
-   `onDropEmbeds` 同步决定:返回 `null` 而编辑器将像以前一样处理空投(图像) 内线,演示块). `embedBlockFor(url)` 是一个 URL 变成的块 .
-   缩略图图像( U)`![alt](src "thumbnail: 0:39.8")`, docstream 1.18 显示为 docstream 的缩略图 悬牌;起先走一步的走头,拇指坐在标题输入旁并活下来 复问.
-   `uploadFile(file, { kind })` 存储文件并解析到要写入的 URL,或者没有跳过它. 已丢弃或粘贴的不是图像的文件( E)`.rrweb` 录音, `.stl` 模型,(...) 上传和 嵌入它们降落的地方; 图像仍然像以前一样内入(或切入芯片),以及 `onDropEmbeds` 看见了 先放下药. 使用 docstream的维特插件, `POST /@docstream/source?mount=…&path=…` 文件为 尸体写到磁盘上.

## 编辑引用源文件

`GitbookEditor` 编辑 Markdown 组成,包括结构化 `source-ref` 节点. `SourceFileEditor` 编辑该节点后面的真实文件 :

```tsx
import { createViteSourceClient, type SourceRefNode } from "@brett_lamy/docstream"
import { SourceFileEditor } from "@brett_lamy/docstream-editor"

const client = createViteSourceClient()
const reference: SourceRefNode = {
  type: "source-ref",
  mount: "ui",
  path: "Button.stories.tsx",
  exportName: "Primary",
  kind: "story",
}

<SourceFileEditor reference={reference} client={client} />
```

保存调用 Docstream Vite 插件, 写入挂载文件, 返回其 出处,并刷新现场组件/故事预览 。 配置挂载 与 `docstreamSources()` 从 `@brett_lamy/docstream/vite` 显示于 (原始内容存档于2018-09-26). Docstream README.

## 演示块

`{% demo src="<page>/<example>" %}` 变成一个 `gbDemo` 原子节点。 每个标签 属性 - `src`, (中文(简体) ), `title`, (中文(简体) ), `description`, (中文(简体) ), `height`, (中文(简体) ), `layout`, (中文(简体) ), `variants`, (中文(简体) ), `viewport`, (中文(简体) ), `entry` ——保存在节点上,而文件也是块表 带入(有标题的栅栏之间) `{% demo … %}` 财务报告和审定财务报表 `{% enddemo %}`,作为 `files: { path, content, language? }[]`),因此块序列化回原样是 写作。 Docstream的"Copy page"以这种方式写出每个演示.

节点显示可编辑的紧凑标题 `src` 财务报告和审定财务报表 `title` 输入(插入) 一个 `/demo`)和a 数据 **文件** 切换打开一个小文件编辑器:标签 每个文件(重新命名到位,标出条目,删除),一个代码区域,以及 `+` 以添加文件。 删除每个文件都会再次给出一行标记表单 .

在标题下, Docstream 只读 `DemoViewer` 制作演示: `demoResolver` 当它知道 `src`,否则来自内置文件——所以 粘贴的多克页面看起来像多克页面。 预览中运行的内置文件 结束 `demoRuntime` (例如:. `createAlmostNodeDemoRuntime()` 从 `@brett_lamy/docstream/playground`与 `demoDependencies`; 没有运行时间 观众显示他们的代码.

```tsx
import { createGlobDemoResolver } from "@brett_lamy/docstream/demo"
import { GitbookEditor } from "@brett_lamy/docstream-editor"

const demoResolver = createGlobDemoResolver({ /* see the Docstream README */ })

<GitbookEditor markdown={markdown} onChange={setMarkdown} demoResolver={demoResolver} />
```

## 编辑器之间的复制和粘贴演示

复制( 或剪切) 包含演示块的选中项—— 一个选中的 演示,或者在其中带有演示的出品——通过反应-aria写出一个剪贴板项目 `useClipboard`数字 :

| 类型 | 内容 |
| --- | --- |
| `text/plain`, (中文(简体) ), `text/markdown` | 可渲染的 Markdown : 每个演示都带入其文件 。 (`src`\- 只能演示获得解析器的文件和 `meta.json`),所以它使任何地方 |
| `application/x-docstream+json` | `{ kind: "docstream", version: 1, markdown, files: { [src]: DemoFile[] }, meta: { [src]: DemoMeta } }` 精确的Markdown 加上每个演示文件 |

任何其他选择保留了ProseMiror的普通副本. 文档流 `DemoViewer` **复制演示** 按钮( 在编辑器内和已渲染的页面上) 写同样内容 用于演示的项目。 解析器文件被提前获取( N)`prefetchDemoSources`),作为a 复制事件不能等待他们.

粘贴更喜欢 JSON 有效载荷, 倒回Markdown 与内置文件 演示`text/plain` 编号 : `text/markdown` 页:1 粘贴的演示块保持内线 文件,每个演示文件都在编辑器中注册 **演示 VFS** - 一个 记忆 `{ [src]: { files, meta } }` 以便他们造化:

1.  与主机连接 `demoResolver` 当它知道 `src`· ;
2.  其它来自块的内置文件或VFS文件,运行于 `demoRuntime` (单位:千美元)`createAlmostNodeDemoRuntime()` 从 `@brett_lamy/docstream/playground`,安装时);
3.  否则,在代码视图中用"需要运行时间"注释.

`pastedDemoFiles` 决定粘贴地点 `src`\- 仅演示文件 `"inline"` (默认) —— 输入 VFS 并在块中内置( 除非主机解析器列表) `src`因此,拯救的马克德是自成一体的; `"vfs"` ——只有VFS,块 保留其精确的复制结构; 坚持文件本身.

```tsx
import { GitbookEditor, useDemoVFS, useDemoVFSFiles } from "@brett_lamy/docstream-editor"

const vfs = useDemoVFS()            // one VFS shared by both editors
const files = useDemoVFSFiles(vfs)  // { [src]: DemoFile[] } — or use onDemoFilesChange

<GitbookEditor markdown={a} onChange={setA} demoResolver={demoResolver} demoVFS={vfs} />
<GitbookEditor markdown={b} onChange={setB} demoVFS={vfs} demoRuntime={demoRuntime}
  pastedDemoFiles="vfs" onDemoFilesChange={(files) => save(files)} />
```

无 `demoVFS` 每个编辑都有自己的. `demoClipboard={false}` 转动 演示复制/ 粘贴处理关闭 。 将相同的 VFS 传递到一个渲染器(`demoVFS` 打开 文档流 `MarkdownContent` 编号 : `DocsRenderer`)使保存的Markdown与 粘贴的文件.

**拖绳.** 每个演示块都有抓住: 拖入另一个 docstream 编辑器 复制演示(相同的有效载荷,包括文件),或在其编辑器内移动 这个 拖放使用本地 HTML5 用多流有效载荷拖放, 而不是 反应 `useDrag` 编号 : `useDrop`数字 : `useDrag` 坚持 `useDrop` 目标,哪些 坐在ProseMirror 自己的滴水处理之上 键盘/ 屏幕阅读器拖曳 未来的工作(复制/粘贴封面).

用于自定义编辑器的下层部件导出 : `selectionClipboard(editor, { resolver, vfs })`, (中文(简体) ), `payloadContent(payload, { resolver, vfs, mode })`, (中文(简体) ), `registerPayloadFiles`, (中文(简体) ), `clipboardForDoc`, (中文(简体) ), `useEditorClipboard`,加上 Docstream 语句 `createDemoVFS`, (中文(简体) ), `readDocstreamClipboard` 财务报告和审定财务报表 `DOCSTREAM_CLIPBOARD_TYPE`。 。 。 .

## 命令框

`{% command %}npm install @brett_lamy/ui{% endcommand %}` (或区块形式,用于 数行)成为 a `gbCommand` 由 Docstream 自己制造的原子节点 命令框:终端 glyph, pnpm / npm / 纱线 / bun 开关(全页), 复制按钮。 当可编辑时, npm 命令和每个管理者覆盖 (单位:千美元)`pnpm="…"`, (中文(简体) ), `yarn="…"`, (中文(简体) ), `bun="…"`; 占位符显示产生的命令) 在框下编辑. `sync` 被保存下来。 插入一个 `/install command`。 。 。 .

## 斜线菜单

编辑器包括用于插入所支持的块结构的斜线菜单扩展名. 类型 `/` 地点 开始行或打开块插入选项的空格后;按标题输入过滤 关键词 过 `slashMenu={{ items }}` (默认列表 : `SLASH_ITEMS`用于自己的物品,或 `slashMenu={false}` 把它关掉.

## 转换辅助工具

需要直接检查或转换编辑器状态时使用转换辅助器.

```ts
import { astToTiptap, serializeEditorMarkdown, tiptapToAst } from "@brett_lamy/docstream-editor"
import { parseMarkdown } from "@brett_lamy/docstream"

const ast = parseMarkdown(markdown)
const tiptapJson = astToTiptap(ast)
const back = tiptapToAst(tiptapJson)
// TipTap JSON has no place for footnote definitions; carry them across as GitbookEditor does.
if (ast.citations?.length) back.citations = ast.citations
const markdownAgain = serializeEditorMarkdown(back) // === markdown
```

输出 :

-   `GitbookEditor`, (中文(简体) ), `GitbookEditorProps`, (中文(简体) ), `embedBlockFor`,以及道具类型 `EditorAttachment`, (中文(简体) ), `FilePicker`, (中文(简体) ), `FilePickKind`, (中文(简体) ), `FileUploader`, (中文(简体) ), `AssetResolver`
-   `astToTiptap`, (中文(简体) ), `tiptapToAst`, (中文(简体) ), `PMNode`, (中文(简体) ), `serializeEditorMarkdown`, (中文(简体) ), `markdownPasteContent` (单位:千美元) 标记后方的平板解析器 `markdownPaste`(中文(简体) )
-   `SourceFileEditor`, (中文(简体) ), `SourceFileEditorProps`, (中文(简体) ), `ReactDemoEditor`, (中文(简体) ), `ReactDemoEditorProps`
-   `GbDocumentProperties`, (中文(简体) ), `DocumentPropertiesEditor`, (中文(简体) ), `GbTaskItem`,加上 Docstream 语句 `TaskCheckbox`, (中文(简体) ), `TASK_STATE_ICONS`, (中文(简体) ), `TASK_STATES`, (中文(简体) ), `TaskState`, (中文(简体) ), `DocumentPropertiesNode`
-   自定义编辑器的组件 : `createGitbookExtensions`, (中文(简体) ), `GitbookExtensionOptions`, (中文(简体) ), `ReferenceSources`, (中文(简体) ), `getGitbookSchema`, (中文(简体) ), `GbCode`, (中文(简体) ), `GbTable`, (中文(简体) ), `GbLinkInner`, (中文(简体) ), `GbMarkSpelling`, (中文(简体) ), `gitbookNodes`, (中文(简体) ), `GbCodeBlock`, (中文(简体) ), `GbCommand`, (中文(简体) ), `GbDemo`, (中文(简体) ), `GbReference`, (中文(简体) ), `GbAttachment`, (中文(简体) ), `formatBytes`, (中文(简体) ), `SlashMenu`, (中文(简体) ), `createSlashMenu`, (中文(简体) ), `SLASH_ITEMS`, (中文(简体) ), `SlashItem`, (中文(简体) ), `createReferenceSuggestion`, (中文(简体) ), `resolveReferenceOptions`, (中文(简体) ), `ReferenceOption`, (中文(简体) ), `ReferenceSource`, (中文(简体) ), `ReferenceSuggestionOptions`, (中文(简体) ), `ReferenceTrigger`, (中文(简体) ), `SuggestionMenuView`, (中文(简体) ), `createSuggestionRender`, (中文(简体) ), `SuggestionMenuItem`
-   演示剪贴板和 VFS : `clipboardForDoc`, (中文(简体) ), `lookupDemoSource`, (中文(简体) ), `payloadContent`, (中文(简体) ), `registerPayloadFiles`, (中文(简体) ), `selectionClipboard`, (中文(简体) ), `useEditorClipboard`, (中文(简体) ), `ClipboardBridge`, (中文(简体) ), `DemoSources`, (中文(简体) ), `PastedDemoFiles`,加上 Docstream 语句 `DOCSTREAM_CLIPBOARD_TYPE`, (中文(简体) ), `createDemoVFS`, (中文(简体) ), `readDocstreamClipboard`, (中文(简体) ), `useDemoVFS`, (中文(简体) ), `useDemoVFSFiles`, (中文(简体) ), `DemoVFS`, (中文(简体) ), `DemoVFSChange`, (中文(简体) ), `DemoVFSEntry`, (中文(简体) ), `DocstreamClipboardPayload`

两个狭窄的入站点也被公布. `./editor` 仅出口 `GitbookEditor`, (中文(简体) ), `embedBlockFor` 及其类型 —— 它仍然加载每个节点视图( 包括 : `{% source-ref %}` 块),但不是 `ReactDemoEditor` 或建筑块再出口. `./convert` 输出转换函数(+) `pmToDemo`, (中文(简体) ), `pmDemoFiles`, (中文(简体) ), `pmToCommand`),仅取决于 打开 `@brett_lamy/docstream/gitbook` -没有反应,没有TipTap:

```tsx
import { GitbookEditor } from "@brett_lamy/docstream-editor/editor"
import { astToTiptap } from "@brett_lamy/docstream-editor/convert"
```

## 造型和赛明

编辑CSS的设计是坐在旁边 `@brett_lamy/docstream/styles.css` 并继承相同的应用程序主题符号。 在阴影风格的应用中, 定义您的全球主题变量并导入 CSS 两个切入点一次 .

编辑器将符号读取为完整的颜色(`var(--card, #ffffff)`以颜色定义它们 而不是像 shadcn v3 HSL 频道的三进制像 `0 0% 100%`,将生成无效值:

```css
:root {
  --card: #ffffff;
  --background: #ffffff;
  --foreground: #0f172a;
  --border: #e2e8f0;
  --muted: #f1f5f9;
  --muted-foreground: #64748b;
  --accent: #f1f5f9;
  --accent-foreground: #0f172a;
  --primary: #2563eb;
}
```

编辑器专用符号( E)`--gb-radius`, (中文(简体) ), `--gb-code-bg`,则 `--gb-info` 编号 : `--gb-success` 编号 : `--gb-warning` 编号 : `--gb-danger` 提示调色板, ...) 被声明在 `.gb`,所以控制他们在那里。 这个 斜线/ 参考菜单和附件悬浮卡渲染成 `document.body` 阅读 主机符号( 加) `--popover` 编号 : `--popover-foreground`从 `:root`。 。 。 .

编辑会揭露诸如 `gb`, (中文(简体) ), `gb-toolbar`, (中文(简体) ), `gb-tool`, (中文(简体) ), `gb-tool-active`,以及 `gb-content` 用于主机应用程序覆盖 .

## 邦德勒笔记

自1.4起,货包船编集了ES模块(ES2022, `react-jsx`有类型 声明和声明地图——每个源模块一个文件 `dist/`提普塔普,你觉得呢, Docstream 和 剩下的所有其他依赖性作为进口:

```json
{
  "exports": {
    ".": {
      "source": "./src/index.ts",
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "default": "./dist/index.js"
    },
    "./editor": {
      "source": "./src/editor/Editor.tsx",
      "types": "./dist/editor/Editor.d.ts",
      "import": "./dist/editor/Editor.js",
      "default": "./dist/editor/Editor.js"
    },
    "./convert": {
      "source": "./src/editor/convert.ts",
      "types": "./dist/editor/convert.d.ts",
      "import": "./dist/editor/convert.js",
      "default": "./dist/editor/convert.js"
    },
    "./styles.css": "./dist/styles.css"
  }
}
```

不需要捆绑器配置: Vite 预捆绑编辑器( 和 TipTap 的普通JS) 依赖性,例如 `use-sync-external-store`像任何其他依赖,所以没有 `optimizeDeps` 条目; Next.js 和 Webpack 将其消耗为简单的无害环境管理;您的类型检查 读取 `.d.ts` 文件而不是编辑器的来源。 类型脚本来源是 也发表在a后面 `source` 导出条件,用于从源头编译的单重机.

## 渲染器对等

对于只读预览或AI 流输出,将本包配对 `@brett_lamy/docstream`数字 :

```tsx
import { GitbookStreamdown } from "@brett_lamy/docstream"

<GitbookStreamdown markdown={markdown} isStreaming={false} />
```

嵌入节点保存 Docstream 介质属性(`title`, (中文(简体) ), `poster`, (中文(简体) ), `autoplay`, (中文(简体) ), `loop`, (中文(简体) ), `muted`,以及 `controls`) 当转换到 可编辑 TipTap 文档和 GitBook 标记下调 。 这很短,很沉默, 自动播放剪辑通过编辑器进行回转而不丢失播放 合同.

### 活图块

`xstate` 财务报告和审定财务报表 `tscircuit` 栅栏使用"人鱼"等源出和预告卡. 直接编辑源;短暂停后共享 Docstream预览更新. 类型 `/` 选择 **X 状态图** 或者说 **tsturn 实例** 插入一个起点。 XState 读取 JSON 或静态类型Script `createMachine({...})` 配置不执行行动或守卫。 被隔离的被托管的 tswead 运行时间需要网络连接. 两种栅栏语言在保存Markdown时都会被保存.

## 常见问题

### @brett\_lamy/docstream-editor 是什么？

Docstream GitBook 风格标记下文档的 TipTap 编辑器 \.

### 如何安装 @brett\_lamy/docstream-editor？

在项目目录运行 npm install @brett\_lamy/docstream-editor，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（\>=18）、react-dom（\>=18）、@tiptap/pm（^3\.26\.1）、@tiptap/core（^3\.26\.1）、@tiptap/react（^3\.26\.1）、@tiptap/suggestion（^3\.26\.1）、@tiptap/starter-kit（^3\.26\.1）、@tiptap/extension-code（^3\.26\.1）、@tiptap/extension-list（^3\.26\.1）、@tiptap/extension-table（^3\.26\.1）、@tiptap/extension-code-block（^3\.26\.1）、@tiptap/extension-placeholder（^3\.26\.1）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @brett\_lamy/docstream-editor 支持 TypeScript 吗？

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

### @brett\_lamy/docstream-editor 支持 ESM 还是 CommonJS？

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

### @brett\_lamy/docstream-editor 可以商用吗？

@brett\_lamy/docstream-editor 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @brett\_lamy/docstream-editor 的下载量有多少？

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

### @brett\_lamy/docstream-editor 还在维护吗？

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

