# 插件

> 把 textlane 的 Markdown 与 HTML 插件加入每个页面构建所经的流水线。

每个页面都由 [textlane](https://textlane.dev) 构建，这是一条用 Rust 编写的 Markdown 与 HTML 流水线。`htmlpress.yaml` 的 `plugins` 键把 textlane 自带的插件加入其中，分两个挂载点：

- `md` 作用于 Markdown 页面的语法树（mdast）
- `html` 作用于每个页面的语法树（hast），HTML 与 Markdown 页面皆然

**htmlpress.yaml**

```yaml
plugins:
  md:
    - name: md.shiftHeading
      options: { shift: 1 }
  html:
    - name: html.externalLinks
      options: { target: _blank }
```

## 插件可以是什么

每个挂载点是一个列表，其条目与 textlane 的 `use` 接受的形式相同：

- **一个名称**：textlane 自带的插件之一，如 `html.externalLinks` 或 `md.toc`，使用其默认选项。
- **带选项的名称**：`{ name, options }`，选项按 textlane 对该插件的说明填写。

htmlpress 是单个二进制文件，所以挂载点只接受内置的插件，不像 Livemark 那样接受 JavaScript 插件。如需自己的标记，请改用 [项目组件](/zh/customization/overriding-escaping/)：一个 `:::name` 指令或 `<htmlpress-name>` 标签，由你的 `components/<name>/` 文件填充。

## 各挂载点在哪里运行

```text
Markdown 页面：解析 → frontmatter、GFM、定义列表、数学公式、指令
  → md 插件 → 标题 id、组件 → HTML
每个页面：     解析 → 表情、链接、数学公式 → KaTeX → html 插件
  → 标题 slug → 路径重写 → 语法高亮
```

- `md` 插件在 htmlpress 把指令渲染为组件**之前**运行，因此能看到所有指令。
- `html` 插件在生成标题 slug **之前**运行，因此插件添加的标题会获得锚点，并出现在“本页内容”目录中。它们也在语法高亮之前运行，因此代码块仍是纯文本。

## htmlpress 已运行的插件

指定一个流水线中已有的插件，如 `md.gfm` 或 `html.slug`，会重新配置它，而不是运行两次：你的选项会与 htmlpress 的选项合并，正如 textlane 的 `use` 合并再次使用的插件。若 htmlpress 设置了同一选项，则以它的值为准，因为它的插件在你的之后加入。

**htmlpress.yaml**

```yaml
plugins:
  html:
    - name: html.slug
      options: { prefix: doc- }
```

这里每个自动生成的标题 id 都带上 `doc-` 前缀，且每个标题仍只获得一次 id。

## 错误与重建

未知的名称或错误的选项会使构建失败，并报出 `plugins.md` 或 `plugins.html` 错误；语法树与挂载点不符的插件（如放在 `html` 下的 `md.toHtml`）同样如此。在 `htmlpress start` 运行时编辑 `htmlpress.yaml` 会用新插件重建所有页面。

## 另请参阅

- [配置](/zh/customization/configuration-file/)：其余所有配置键。
- [textlane](https://textlane.dev)：插件及其选项。
