docs: add file format support matrix (DOC-FULL-028)

- 9 MaterialType × 8 capabilities matrix
- MIME detection strategy (magic bytes → extension)
- Per-format details: Markdown/Text/PDF/EPUB/Image/Office
- PreviewMode mapping, search capabilities, limits

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wangdl 2026-06-18 14:38:00 +08:00
parent 8968858211
commit a7b941bd42

View File

@ -0,0 +1,162 @@
# 文件格式支持矩阵
## 1. 概述
Document Runtime 支持以下文件格式的解析、元数据提取、文本提取和搜索。
---
## 2. 能力矩阵
| 格式 | 枚举值 | MIME 检测 | 预览模式 | 文本提取 | 元数据 | 搜索 | 定位 | 锚点 |
|------|--------|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| Markdown | `Markdown` | 扩展名 `.md` / `.markdown` | NativeReader | ✅ Block 解析 | ✅ 行/词/字符统计 | ✅ | ✅ Block+Scroll | ✅ Block ID |
| 纯文本 | `Text` | 扩展名 `.txt` | NativeReader | ✅ 按行 | ✅ 行/词/字符统计 | ✅ | ✅ 行号+Scroll | ❌ |
| PDF | `Pdf` | 文件头 `%PDF-` | PlatformPreview | ✅ BT/ET 流式扫描 | ✅ 页数/标题/作者 | ✅ | ✅ 页码+Progress | ✅ 页码 |
| EPUB | `Epub` | 文件头 `PK` + mimetype | NativeReader | ✅ HTML strip | ✅ 标题/作者/章节数 | ✅ | ✅ 章节+Progress | ✅ 章节 ID |
| 图片 | `Image` | 文件头魔术字节 | NativeReader | ❌ | ✅ 宽/高/格式 | ❌ | ✅ Zoom+Offset | ❌ |
| Word | `Word` | 扩展名 `.docx` | PlatformPreview | ❌ | ❌ | ❌ | ❌ | ✅ 整体 |
| Excel | `Excel` | 扩展名 `.xlsx` | PlatformPreview | ❌ | ❌ | ❌ | ❌ | ✅ 整体 |
| PowerPoint | `PowerPoint` | 扩展名 `.pptx` | ExternalOpen | ❌ | ❌ | ❌ | ❌ | ✅ 整体 |
| 未知 | `Unknown` | — | Unsupported | ❌ | ❌ | ❌ | ❌ | ❌ |
---
## 3. MIME 检测
### 3.1 检测策略
```
1. 文件头魔术字节(前 8KB
├─ %PDF- → PDF
├─ PK + mimetype=application/epub+zip → EPUB
└─ PNG/JPG/GIF/WebP 头 → Image
2. 扩展名回退
├─ .md / .markdown → Markdown
├─ .txt → Text
├─ .epub → EPUB
└─ .pdf → PDF
```
### 3.2 代码路径
```rust
// material_type.rs
pub fn detect_material_type(file_path: &str) -> Result<MaterialType, DocumentError>
```
---
## 4. 各格式详情
### 4.1 Markdown
| 能力 | 说明 |
|------|------|
| 解析 | `parse_markdown()``Vec<DocumentBlock>`8 种块类型) |
| 块类型 | Heading / Paragraph / List / CodeBlock / Quote / Table / Image / HorizontalRule |
| 元数据 | YAML Front Matter 自动解析为 metadata |
| 搜索 | `search_blocks()` — 在每个块的文本内容中搜索 |
| 定位 | `ReadingPosition::Markdown(blockId, scrollProgress)` |
| 锚点 | `resolveNoteAnchors()``#heading-id` / `#paragraph-id` |
### 4.2 纯文本
| 能力 | 说明 |
|------|------|
| 解析 | 按换行符分割为行,不作为结构化块 |
| 元数据 | 行数、词数(`text_stats()`)、字符数 |
| 搜索 | `search_text()` — 按行搜索,返回行号 |
| 定位 | `ReadingPosition::Text(lineNumber, scrollProgress)` |
### 4.3 PDF
| 能力 | 说明 |
|------|------|
| 页数检测 | `/Type /Page` 对象计数 → `/Pages /Count` → 默认 1 |
| 文本提取 | 扫描 `BT..ET` 块,提取括号内文本(`extract_pdf_text()` |
| 元数据 | `/Title`, `/Author` 字段,仅支持 ASCII/PDFDocEncoding |
| 限制 | 最大扫描 8MB`MAX_SCAN_BYTES`);加密 PDF 不解析 |
| 搜索 | 依赖 `extract_pdf_text()` 输出 |
| 定位 | `ReadingPosition::Pdf(pageNumber, pageProgress, overallProgress)` |
### 4.4 EPUB
| 能力 | 说明 |
|------|------|
| TOC | NCXEPUB2→ NAVEPUB3回退 |
| 章节列表 | Spine 解析 → `read_epub_chapters()` |
| 文本提取 | `extract_epub_chapter_texts()` — HTML 标签移除 + 空白合并 |
| 元数据 | `dc:title`, `dc:creator` |
| 定位 | `ReadingPosition::Epub(chapterId, chapterProgress, overallProgress)` |
| 路径策略 | 含 `/``.xhtml`/`.html`→直接用;否则 `OEBPS/{id}.xhtml` |
### 4.5 图片
| 能力 | 说明 |
|------|------|
| 支持格式 | PNG / JPG / GIF / WebP |
| 元数据 | `read_image_meta()` → 宽度、高度、格式 |
| 搜索 | 不支持 |
| 定位 | `ReadingPosition::Image(zoomScale, offsetX, offsetY)` |
### 4.6 OfficeWord / Excel / PowerPoint
| 能力 | 说明 |
|------|------|
| 预览 | PlatformPreview / ExternalOpen不内置渲染 |
| 文本提取 | 不支持(依赖第三方预览组件) |
| 搜索 | 不支持 |
| 锚点 | 仅 Material 级别 |
---
## 5. PreviewMode 对照
| MaterialType | PreviewMode | 渲染方式 |
|-------------|-------------|----------|
| Markdown | NativeReader | Rust 解析 → SwiftUI 渲染 |
| Text | NativeReader | SwiftUI 文本视图 |
| Pdf | PlatformPreview | WKWebView / PDFKit |
| Image | NativeReader | SwiftUI Image |
| Epub | NativeReader | Rust HTML strip → SwiftUI |
| Word | PlatformPreview | WKWebView / Office URI |
| Excel | PlatformPreview | WKWebView / Office URI |
| PowerPoint | ExternalOpen | 系统分享 Sheet |
| Unknown | Unsupported | 错误提示 |
---
## 6. 搜索能力
| 格式 | 搜索方式 | 返回粒度 |
|------|----------|:--:|
| Markdown | `search_blocks()` | Block ID + 片段 |
| Text | `search_text()` | 行号 + 片段 |
| PDF | 预提取文本后搜索 | 页码 |
| EPUB | 预提取文本后搜索 | 章节 ID |
| Image | 不支持 | — |
| Office | 不支持 | — |
**验证函数**`validate_search_result()` — 校验搜索结果片段中的匹配位置是否正确。
---
## 7. 限制与边界
| 项 | 值 | 说明 |
|------|------|------|
| Markdown 文档大小 | 无硬限制 | 依赖内存 |
| PDF 扫描上限 | 8 MB | `MAX_SCAN_BYTES` |
| PDF 文本提取 | BT/ET 块扫描 | 不解析 CMap/Type0 字体 |
| EPUB 支持版本 | EPUB 2.0 / 3.0 | NCX + NAV 回退 |
| 图片元数据 | 仅基础 | 不含 EXIF GPS/时间 |
| Office 解析 | 不支持 | 仅预览模式判断 |
---
## 8. 相关文档
- [iOS FFI 调用指南](./ios-ffi-integration-guide.md)
- [UniFFI UDL 编写规范](./uniffi-udl-spec.md)