# @itshixun/qckeditor-plugin-math

CKEditor 5 插件：LaTeX 数学公式编辑。在编辑器中插入和编辑数学公式，使用 KaTeX 进行渲染，支持行内公式和块级公式。

## 安装

```bash
npm install @itshixun/qckeditor-plugin-math
# 或
pnpm add @itshixun/qckeditor-plugin-math
```

依赖：
- `ckeditor5`（peerDependencies，需自行安装）
- `katex`（插件内部依赖，会自动安装）

## 基本使用

### 1. 引入样式

```ts
// 插件样式
import '@itshixun/qckeditor-plugin-math/dist/index.css';
// KaTeX 渲染样式（必须引入，否则公式无法正确显示）
import 'katex/dist/katex.min.css';
```

### 2. 注册插件

```ts
import { ClassicEditor } from 'ckeditor5';
import { QstMath } from '@itshixun/qckeditor-plugin-math';

const editor = await ClassicEditor.create(element, {
  plugins: [
    // ... 其他插件
    QstMath,
  ],
  toolbar: [
    // ... 其他按钮
    'insertMath',  // 工具栏按钮名称：插入公式
  ],
  qstMath: {
    katex: {
      throwOnError: false,
      trust: false,
      output: 'html',
    },
    defaultType: 'inline', // 弹窗默认公式类型：'inline' 或 'display'
    autoformat: true,      // 是否启用 Autoformat，默认 true
  },
});
```

### 3. Vue 中使用

```vue
<script setup lang="ts">
import { ClassicEditor } from 'ckeditor5';
import { QstMath } from '@itshixun/qckeditor-plugin-math';

const config = {
  editor: ClassicEditor,
  plugins: [/* ... */, QstMath],
  toolbar: ['bold', 'italic', 'insertMath'],
  qstMath: {
    defaultType: 'inline',
    autoformat: true,
  },
};
</script>

<template>
  <ckeditor :editor="config.editor" :config="config" />
</template>
```

## 配置项

| 属性 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `katex.throwOnError` | `boolean` | 否 | KaTeX 解析错误时是否抛出异常，默认 `false` |
| `katex.trust` | `boolean` | 否 | 是否信任输入内容，默认 `false`（安全） |
| `katex.output` | `'html' \| 'mathml'` | 否 | KaTeX 输出格式，默认 `'html'` |
| `defaultType` | `'inline' \| 'display'` | 否 | 弹窗默认公式类型，默认 `'inline'` |
| `autoformat` | `boolean` | 否 | 是否启用 Autoformat 自动转换，默认 `true` |

## 命令说明

### `insertMath` — 插入/更新公式

插入新公式或更新选中的公式：

```ts
// 插入行内公式
editor.execute('insertMath', {
  latex: 'E = mc^2',
  display: false, // false = 行内，true = 块级
});

// 插入块级公式
editor.execute('insertMath', {
  latex: '\\sum_{i=1}^{n} x_i = x_1 + x_2 + \\cdots + x_n',
  display: true,
});
```

如果当前选中了公式元素，执行 `insertMath` 会**更新**该公式；否则会**插入**新公式。

## Widget 工具栏

选中公式后，会显示 Widget 上下文工具栏，包含以下按钮：

| 按钮名称 | 功能 |
|----------|------|
| `mathEdit` | 编辑公式（打开弹窗修改 LaTeX） |
| `mathToggleType` | 切换行内/块级公式类型 |
| `mathDelete` | 删除公式 |

```ts
const editor = await ClassicEditor.create(element, {
  plugins: [QstMath],
  toolbar: ['insertMath'],
  // Widget 工具栏按钮会自动显示，无需额外配置
});
```

## Autoformat 自动转换

插件支持 Autoformat 功能，在编辑器中输入特定模式时自动转换为公式：

| 输入模式 | 公式类型 | 示例 |
|----------|---------|------|
| `$$...$$` | 块级公式 | `$$E = mc^2$$` |
| `\(...\)` | 行内公式 | `\(a^2 + b^2 = c^2\)` |
| `\[...\]` | 块级公式 | `\[\int_a^b f(x)dx\]` |

**注意：** Autoformat 只在用户手动输入时触发，不会拦截粘贴或 `setData` 操作。

如需禁用 Autoformat：

```ts
const editor = await ClassicEditor.create(element, {
  plugins: [QstMath],
  qstMath: {
    autoformat: false,
  },
});
```

## 输出 HTML

### 保存态（Data Downcast）

保存时输出标准 LaTeX 分隔符格式，方便在其他系统中渲染：

```html
<!-- 行内公式 -->
<span class="math-tex">\(E = mc^2\)</span>

<!-- 块级公式 -->
<span class="math-tex">\[\sum_{i=1}^{n} x_i\]</span>
```

### 编辑态（Editing Downcast）

编辑态使用 KaTeX 实时渲染，显示为 Widget：

```html
<span class="ck-qst-math" data-latex="E = mc^2" data-display="false" contenteditable="false">
  <!-- KaTeX 渲染的 HTML -->
  <span class="katex-render">...</span>
</span>
```

块级公式会额外添加 `ck-qst-math--display` 类：

```html
<span class="ck-qst-math ck-qst-math--display" data-latex="..." data-display="true" contenteditable="false">
  <span class="katex-render">...</span>
</span>
```

## 类型支持

导入插件后，`EditorConfig` 类型自动扩展，TypeScript 可直接识别 `qstMath` 配置：

```ts
const config: EditorConfig = {
  // 无类型错误，qstMath 已声明
  qstMath: {
    katex: { throwOnError: false },
    defaultType: 'display',
    autoformat: true,
  },
};
```

## 导出 API

```ts
import {
  QstMath,              // 主插件（Editing + UI + Autoformat + Toolbar）
  QstMathEditing,       // 编辑插件（Schema + Conversion + insertMath 命令）
  QstMathUI,            // UI 插件（工具栏按钮 + 弹窗）
  QstMathFormView,      // 公式编辑弹窗视图
  QstMathCommand,       // 插入/更新公式的命令
  QstMathAutoformat,    // Autoformat 插件（自动转换 LaTeX 分隔符）
  QstMathToolbar,       // Widget 上下文工具栏插件
  insertMath,           // 工具函数：插入公式元素
  isMathAllowed,        // 工具函数：检查是否允许插入公式
  renderKaTeX,          // 工具函数：使用 KaTeX 渲染 LaTeX
  type QstMathConfig,
  type MathCommandOptions,
  type MathAutoformatPattern,
} from '@itshixun/qckeditor-plugin-math';
```
