# lyxy-document 统一文档解析工具 - 将 DOC、DOCX、XLS、XLSX、PPT、PPTX、PDF、HTML/URL 转换为 Markdown ## 项目概述 面向 AI Skill 的统一文档解析工具,支持多种文档格式解析为 Markdown,提供全文输出、字数统计、标题提取、内容搜索等功能。 ## 开发环境 - 使用 uv 运行脚本和测试,禁用主机 Python - 依赖管理:使用 `uv run --with` 按需加载依赖 - 自启动机制:脚本自动检测依赖并用正确的 uv 命令执行 ## 项目架构 ``` scripts/ ├── lyxy_document_reader.py # CLI 入口(自启动) ├── bootstrap.py # 实际执行模块 ├── config.py # 配置(含 DEPENDENCIES 依赖配置) ├── core/ # 核心模块 │ ├── parser.py # 解析调度 │ ├── advice_generator.py # 依赖检测和配置生成 │ ├── markdown.py # Markdown 工具 │ └── exceptions.py # 异常定义 ├── readers/ # 格式阅读器 │ ├── base.py # Reader 基类 │ ├── doc/ # DOC 解析器(旧格式) │ ├── docx/ # DOCX 解析器 │ ├── xls/ # XLS 解析器(旧格式) │ ├── xlsx/ # XLSX 解析器 │ ├── ppt/ # PPT 解析器(旧格式) │ ├── pptx/ # PPTX 解析器 │ ├── pdf/ # PDF 解析器 │ └── html/ # HTML/URL 解析器 └── utils/ # 工具函数 ├── file_detection.py # 文件检测 └── encoding_detection.py # 编码检测 tests/ # 测试套件 ├── test_readers/ # Reader 测试 │ └── fixtures/ # 静态测试文件(Git LFS 管理) │ └── xls/ # XLS 旧格式测试文件 openspec/ # OpenSpec 规范文档 build.py # 构建脚本(混淆模式) publish.py # 发布脚本 publish.sh # 一键构建+发布 README.md # 本文档(开发者文档) SKILL.md # AI Skill 文档 ``` ## 测试 Fixtures 规范 ### 静态测试文件目录 `tests/test_readers/fixtures/` 目录用于存放**预先准备的静态测试文件**,特别是难以通过 Python 自动化创建的旧格式文件(.xls)。 ### 目录使用规则 1. **仅存放静态文件**:该目录下的文件必须是预先准备好的,禁止在测试运行时向该目录动态生成临时文件。 2. **临时文件使用 tmp_path**:测试中需要临时文件时,使用 pytest 的 `tmp_path` fixture 在其他位置创建。 3. **Git LFS 管理**:该目录下所有文件通过 Git LFS 管理,见 `.gitattributes` 配置。 ### Fixture 说明 `tests/test_readers/conftest.py` 提供以下静态文件 fixtures: - 目录路径:`xls_fixture_path` - 单个文件:`simple_xls_path` 等 文件不存在时会自动 `pytest.skip()`,保证 CI 稳定性。 ## 核心概念 ### Reader 机制 每种文档格式对应一个 Reader 包,包含多个解析实现。Reader 基类定义 `supports()` 和 `parse()` 方法,解析器按顺序尝试,第一个成功的结果返回。 ### 依赖配置 (config.DEPENDENCIES) 按文件类型和平台组织依赖配置: ```python DEPENDENCIES = { "pdf": { "default": { "python": None, "dependencies": ["docling", "unstructured[pdf]", ...] }, "Darwin-x86_64": { "python": "3.12", "dependencies": ["docling==2.40.0", ...] } }, ... } ``` ### 自启动机制 入口脚本根据文件扩展名识别类型,检测当前平台,从 `config.DEPENDENCIES` 读取对应配置,自动生成并执行正确的 `uv run --with` 命令。 ## 快速开始 ### 验证环境 首先验证项目可以正常运行: ```bash # 测试解析功能(自动检测依赖并执行) python scripts/lyxy_document_reader.py "https://example.com" ``` ### 运行基础测试 ```bash # 运行 CLI 测试(验证项目基本功能) uv run \ --with pytest \ pytest tests/test_cli/ -v ``` ## 开发指南 ### 测试前置依赖说明 由于 `HtmlReader` 模块在导入时会加载 `cleaner.py`,但 `cleaner.py` 中的第三方库已改为动态导入,因此无需额外依赖。 `beautifulsoup4` 和 `chardet` 仅在实际使用 HTML 功能时才需要,模块导入时不依赖。 ### 如何添加新的 Reader 1. 在 `scripts/readers/` 下创建新目录 2. 继承 `BaseReader` 实现 `supports()` 和 `parse()` 3. 在 `scripts/readers/__init__.py` 中注册 4. 在 `config.DEPENDENCIES` 中添加依赖配置 ### 如何测试 项目包含完整的测试套件,覆盖 CLI、核心模块、工具函数和所有 Reader 实现。根据测试类型使用对应的 `uv run --with` 命令。 #### 测试目录结构 - tests/test_cli/ - CLI 功能测试 - tests/test_core/ - 核心模块测试(markdown, parser, advice_generator) - tests/test_readers/ - 各格式 Reader 测试 - tests/test_utils/ - 工具函数测试(file_detection, encoding_detection) #### 运行所有测试 ```bash uv run \ --with pytest \ --with pytest-cov \ --with docling \ --with "unstructured[pdf]" \ --with "unstructured[docx]" \ --with "unstructured[xlsx]" \ --with "unstructured[pptx]" \ --with "markitdown[pdf]" \ --with "markitdown[docx]" \ --with "markitdown[xlsx]" \ --with "markitdown[pptx]" \ --with "markitdown[xls]" \ --with pypdf \ --with markdownify \ --with reportlab \ --with pypandoc-binary \ --with python-docx \ --with python-pptx \ --with pandas \ --with tabulate \ --with xlrd \ --with olefile \ --with trafilatura \ --with domscribe \ --with html2text \ --with beautifulsoup4 \ --with httpx \ --with chardet \ --with pyppeteer \ --with selenium \ pytest ``` 注:由于依赖较多,也可以按测试类别分别运行(见下文)。 #### 测试 DOCX reader ```bash uv run \ --with pytest \ --with docling \ --with "unstructured[docx]" \ --with "markitdown[docx]" \ --with pypandoc-binary \ --with python-docx \ --with markdownify \ pytest tests/test_readers/test_docx/ ``` #### 测试 XLSX reader ```bash uv run \ --with pytest \ --with docling \ --with "unstructured[xlsx]" \ --with "markitdown[xlsx]" \ --with pandas \ --with tabulate \ pytest tests/test_readers/test_xlsx/ ``` #### 测试 PPTX reader ```bash uv run \ --with pytest \ --with docling \ --with "unstructured[pptx]" \ --with "markitdown[pptx]" \ --with python-pptx \ --with markdownify \ pytest tests/test_readers/test_pptx/ ``` #### 测试 PDF reader ```bash # 默认命令(macOS ARM、Linux、Windows) uv run \ --with pytest \ --with docling \ --with "unstructured[pdf]" \ --with "markitdown[pdf]" \ --with pypdf \ --with markdownify \ --with reportlab \ pytest tests/test_readers/test_pdf/ # macOS x86_64 (Intel) 特殊命令 uv run \ --python 3.12 \ --with pytest \ --with "docling==2.40.0" \ --with "docling-parse==4.0.0" \ --with "numpy<2" \ --with "markitdown[pdf]" \ --with pypdf \ --with markdownify \ --with reportlab \ pytest tests/test_readers/test_pdf/ ``` #### 测试 HTML reader ```bash uv run \ --with pytest \ --with trafilatura \ --with domscribe \ --with markitdown \ --with html2text \ --with beautifulsoup4 \ --with httpx \ --with chardet \ pytest tests/test_readers/test_html/ ``` #### 测试 XLS reader(旧格式,使用静态文件) ```bash uv run \ --with pytest \ --with "unstructured[xlsx]" \ --with "markitdown[xls]" \ --with pandas \ --with tabulate \ --with xlrd \ pytest tests/test_readers/test_xls/ ``` #### 测试 Core 模块 ```bash # 测试核心模块(无需额外依赖) uv run \ --with pytest \ pytest tests/test_core/ ``` #### 测试 Utils 模块 ```bash # 测试工具函数(无需额外依赖) uv run \ --with pytest \ pytest tests/test_utils/ ``` #### 测试 HTML 下载器 ```bash # 测试 HTML 下载器 uv run \ --with pytest \ --with trafilatura \ --with domscribe \ --with markitdown \ --with html2text \ --with beautifulsoup4 \ --with httpx \ --with chardet \ --with pyppeteer \ --with selenium \ pytest tests/test_readers/test_html_downloader.py ``` #### 运行特定测试文件或方法 ```bash # 运行特定测试文件(CLI 测试无需额外依赖) uv run \ --with pytest \ pytest tests/test_cli/test_main.py # 运行特定测试类或方法 uv run \ --with pytest \ --with docling \ pytest tests/test_cli/test_main.py::TestCLIDefaultOutput::test_default_output_docx ``` #### 查看测试覆盖率 ```bash uv run \ --with pytest \ --with pytest-cov \ pytest --cov=scripts --cov-report=term-missing ``` ### 代码规范 - 语言:仅中文(交流、注释、文档、代码) - 模块文件:150-300 行 - 错误处理:自定义异常 + 清晰信息 + 位置上下文 - Git 提交:`类型: 简短描述`(feat/fix/refactor/docs/style/test/chore) ## 构建与发布 ### 构建脚本 项目提供 `build.py` 用于构建 Skill 包,使用 PyArmor 进行代码混淆: ```bash uv run --with pyarmor python build.py ``` 构建产物输出到 `build/` 目录,包含: - `SKILL.md`(动态注入 version 和 author) - `scripts/`(混淆后的代码) ### 发布脚本 提供 `publish.py` 用于自动发布到目标仓库: ```bash uv run python publish.py ``` 发布流程: 1. 在临时目录 clone `https://github.com/lanyuanxiaoyao/skills.git`(--depth 1) 2. 清空 `skills/lyxy-document-reader/` 目录 3. 复制 `build/` 内容到目标路径 4. Git 提交并推送 ### 一键发布 使用 `publish.sh` 一键完成构建+发布: ```bash ./publish.sh ``` ## 文档说明 - **README.md**(本文档):面向项目开发者 - **SKILL.md**:面向 AI 使用的 Skill 文档 - **openspec/**:OpenSpec 规范文档 ## 许可证 MIT License