# HTML 与 Markdown 转换

选择浏览器或服务端转换入口，理解 Schema、格式规则与数据损失。

HTML 与 Markdown 是内容的输入输出格式。转换不会安装扩展，也不会生成 Classic 的分页界面。先确定产品采用的 Schema，再为需要交换的内容提供格式规则。

## 浏览器：读取当前编辑器

已挂载的 Editor 可以调用 `getJSON()`、`getHTML()`、`getMarkdown()`。HTML 使用节点和标记的 `renderHTML()`；JSON 是规范正文；Markdown 使用已安装扩展的 Markdown 规则。JSON 恢复与严格校验见[内容读取与替换](/guide/content)。

只做 HTML 转换而不创建编辑器时，使用 `@quirekit/html` 的 `generateJSON(html, extensions)` 和 `generateHTML(json, extensions)`。浏览器入口需要 DOM，不能直接放到 Node 服务端执行。

## 服务端：使用独立入口

```sh [安装 HTML 工具]
pnpm add @quirekit/html @quirekit/core @quirekit/starter-kit
```

Node 使用 `@quirekit/html/server`。工具接收解析后的扩展列表，像 StarterKit 这样的组合扩展先通过 `resolveExtensions()` 展开。以下函数不挂载 View，不依赖客户端编辑器，也不在请求之间共享一个 DOM 文档：

### core/formats/server.ts

```ts
import { generateHTML, generateJSON } from "@quirekit/html/server";
import { resolveExtensions } from "@quirekit/core";
import { StarterKit } from "@quirekit/starter-kit";

/**
 * Converts supported semantic HTML without mounting an editor or sharing a browser document.
 * @param html - Application-authorized HTML; this function is not a sanitizer.
 * @returns Normalized canonical JSON and its semantic HTML representation.
 */
export function normalizeArticleHTML(html: string) {
  const extensions = resolveExtensions([StarterKit.configure({})]);
  const document = generateJSON(html, extensions);
  return { document, html: generateHTML(document, extensions) };
}

```

客户端与服务端要安装相容的扩展及配置。比如服务端只认识段落，客户端的业务卡片就不能被正确恢复。`generateJSON()` 会按 Schema 归一化 HTML，可能丢弃未识别标签、属性或样式；成功返回不意味着原始 HTML 无损保留。

HTML 解析与安全过滤也是两件事。转换器不是通用 sanitizer；应用按自己的内容策略过滤不可信 HTML，再决定是否允许链接、图片或外部资源。

## Markdown：明确指定输入类型

字符串默认按 HTML 解析。使用 Markdown 时，创建选项或 `setContent()` 的选项必须包含 `contentType: 'markdown'`。

### core/formats/markdown.ts

```ts
import { Editor } from "@quirekit/core";
import { StarterKit } from "@quirekit/starter-kit";

/**
 * Converts supported Markdown in a headless editor, releasing its session afterwards.
 * @param markdown - Source using the installed extensions' Markdown syntax.
 * @returns Canonical JSON and normalized Markdown, not the original source spelling.
 */
export function normalizeArticleMarkdown(markdown: string) {
  const editor = new Editor({ extensions: [StarterKit.configure({})], content: markdown, contentType: "markdown" });
  try { return { document: editor.getJSON(), markdown: editor.getMarkdown() }; }
  finally { editor.destroy(); }
}

```

例程保留 StarterKit 支持的内容并输出归一化 Markdown，原始空格、分隔符写法和不支持的语法不保证保留。要继续编辑 JSON，恢复时仍安装相同模型；不要把再次解析 Markdown 当作无损 JSON 存储。

自定义 Node/Mark 的 HTML 规则不会自动成为 Markdown 规则。要支持自己的语法，还需声明 Markdown token 的解析和渲染合同；未实现前应明确禁止、降级或另存原文，不要声称格式已支持。输入 `==文字==` 的[输入规则](/guide/rules)也不会自动教会 Markdown 解析器这种语法。

## 怎么选择保存格式

| 目标 | 建议 |
| --- | --- |
| 精确恢复产品文档 | 保存版本化规范 JSON 及媒体资源 |
| 发布网页或交换语义 HTML | 使用 HTML 规则，测试链接、图片和业务节点 |
| 与 Markdown 工具互通 | 定义支持语法及损失策略，测试导入与导出 |
| 保存 Word 页面、样式和关系 | 使用 Word 模型与 DOCX 服务，查看转换诊断 |

至少用标题、混合标记、列表、链接和一个业务节点做往返测试，同时比较规范结构与重要属性。只比较 `textContent` 会漏掉结构与格式损失。
