# Grammar Highlighter
利用 spaCy 与 benepar 的句法信息,为英文文本提供可视化的语法高亮,帮助学习者或编辑快速看懂句子结构。项目暴露 FastAPI 接口,可单独调用 `/analyze`,也内置一个网页代理 `/proxy` 用来抓取文章后直接高亮,并带有可选的流式 TTS 朗读控件。
## 功能特性
- **句法角色高亮**:识别主语、谓语、宾语、补语、同位语、状语、固定搭配等多种结构,同时对括号说明、绝对结构、固定短语等给予特殊样式。
- **benepar Constituency 支持**:在成功加载 benepar 时会标注状语从句、名词性从句、非限定结构、关系从句等;若模型缺失自动回退到依存句法并给出警告。
- **句子分析摘要**:每个句子带中文提示(可在 `style_config.py` 中通过 `SENTENCE_HELPER_ENABLED` 开关控制),说明句型、主谓宾、从句功能、连接词等。
- **网页代理模式**:`/proxy` 路由用 httpx 拉取远程页面,提取正文、列表、代码块与图片占位符,随后复用同一高亮流程,可按需重新注入图片或代码片段。
- **TTS 朗读**:UI 中的“朗读高亮文本/朗读选中文本”按钮会将文本发送到 `TTS_ENDPOINT`(默认 `http://141.140.15.30:8028/generate`),逐段播放流式音频。
- **健壮的降级策略**:自动补全 spaCy 句子切分、禁用 benepar 时继续运行;`/health` 接口会暴露 benepar 状态与任何加载警告。
## 环境要求
- Python 3.10+(建议使用虚拟环境)
- 依赖见 `requirements.txt`:FastAPI、httpx、pydantic、spaCy、benepar、uvicorn。
- 首次运行时需要下载 `en_core_web_sm` 和 `benepar_en3` 模型。代码会尝试自动下载;若机器无法联网,可手动执行:
```bash
python -m spacy download en_core_web_sm
python -m benepar.download benepar_en3
```
## 快速开始
1. 安装依赖:
```bash
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
```
2. 启动 API:
```bash
uvicorn mainspacy:app --host 0.0.0.0 --port 12012 --reload
```
生产环境可直接使用仓库中的 `./start.sh`(禁用了 access log,端口 12012)。
3. 打开 即可看到最简 UI;或调用下方 API。
## API 说明
### `POST /analyze`
- 请求体:`{"text": "Your English paragraph..."}`(UTF‑8 JSON)。
- 响应:`{"highlighted_html": "
...
"}`。
- 示例:
```bash
curl -X POST http://localhost:12012/analyze \
-H 'Content-Type: application/json' \
-d '{"text": "The book that you lent me is inspiring."}'
```
- `STYLE_BLOCK` 从 `style_config.py` 生成,可在该文件启用/关闭样式或句子说明。
### `GET /proxy`
- 参数:
- `url`:想要抓取的完整 URL。
- `show_images`(可选,`1` 为显示图片,否则用占位符提升速度)。
- 返回一个带输入表单、TTS 控件以及高亮结果的 HTML 页面。
- 抓取逻辑:使用 httpx 获取 HTML → `SimpleHTMLStripper` 提取正文、列表信息、图片与代码块 → 调用 `highlight_text_with_spacy` → 按需注入图片/代码 → 输出。
- 若目标站点返回 403/404,会给出友好的错误消息。
### `GET /health`
- 返回 `{"status": "ok", "benepar_attached": true}` 等诊断信息。
- 当 spaCy/benepar 未成功加载时 `status` 为 `failed`,并附带 `detail` 或 `warning` 字段。
### `GET /`
- 轻量级前端,支持输入文本、查看高亮、清空结果和触发 TTS。
## 自定义与扩展
- **样式**:在 `style_config.py` 中增删 `StyleRule` 或调节 `SENTENCE_HELPER_ENABLED`,运行时 `STYLE_BLOCK` 会随之变化。
- **NLP 行为**:修改 `mainspacy.py` 中 `_load_spacy_pipeline` 的 `model_name` / `benepar_model` 参数可切换 spaCy 或 benepar 模型。
- **代理白名单**:`ALLOWED_URL_SCHEMES`, `MAX_REMOTE_HTML_BYTES`, `REMOTE_FETCH_HEADERS` 等常量定义了抓取限制,可根据部署环境调整。
- **TTS**:如果有自己的语音服务,可替换两处前端脚本里的 `TTS_ENDPOINT`。
## 常见问题
- **Benepar 下载失败**:检查网络代理或单独运行 `python -m benepar.download benepar_en3`。服务仍会运行,只是退回依存句法并在 `/health` 提示 warning。
- **句子未拆分**:确保 spaCy 管线中有 `parser`/`senter`。代码会尝试自动添加 `sentencizer`。
- **代理抓取 403**:很多站点禁止程序化访问,可手动复制文章文本直接使用 `/analyze`。
- **TTS 没有声音**:确认可访问 `TTS_ENDPOINT`,或替换为在你网络内可用的服务。