# gesp技能 **Repository Path**: hyx-work/gesp ## Basic Information - **Project Name**: gesp技能 - **Description**: gesp技能,目前只有pdf->md->html功能,详情参考readme文件,欢迎gesp老师共建 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-09-29 - **Last Updated**: 2026-10-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # gesp — GESP C++ 真题一体化处理 > 把 CCF GESP C++ 真题 PDF **结构化**,再**离线复盘**。一条链出「可编辑的源文件包」, > 另一条链出「双击即用的答题页」。全程本地,不联网发布。 > 版本 1.2.0 · 入口 `/gesp md` 与 `/gesp review` · 适用 C++ 一 ~ 八级 ## 1. 它能做什么 | 入口 | 输入 | 终点产物 | 面向 | |---|---|---|---| | `/gesp md` | 真题 PDF(关键字自动下载 / 本地路径 / 直链) | `GESPCPP-{YYYYMM}-md/` + `.zip`:每级「真题 / 解析 / 答案 .md + .json」+ 图片 | 老师 / 内容侧:可编辑、可入库 | | `/gesp review` | 上一步的 `*.json` | `GESPCPP-{YYYYMM}-site/` + `.zip`:每级一个自包含单文件答题页 + 导航页 | 学生:双击打开、无需联网 | 两条链只读同一个**工作过程目录** `GESPCPP-{YYYYMM}/*.json`(**json 是唯一数据源**,三份 md 全部由 `derive_md.py` 派生、禁止手写),互不依赖。 ## 2. 快速开始 ```bash /gesp md 2026年9月GESP C++ 一级到八级真题 # PDF → GESPCPP-202609-pdf/ 过程 → GESPCPP-202609/(每级 4 件套) # 最终产物 → GESPCPP-202609-md/ + GESPCPP-202609-md.zip ★ /gesp review GESPCPP-202609 # 过程 → GESPCPP-202609/2026年09月GESP-C++{级别}复盘.html # 最终产物 → GESPCPP-202609-site/ + GESPCPP-202609-site.zip ★ ``` ### 目录铁律(一级前缀 `GESPCPP-{YYYYMM}`) | 目录 | 角色 | 说明 | |---|---|---| | `GESPCPP-{YYYYMM}-pdf/` | PDF 源 | 下载/本地识别的试卷 PDF 一律归入,**只读** | | `GESPCPP-{YYYYMM}/` | 工作过程目录 | txt / 页图 / json / 三份 md / 配图 / 复盘页 —— 两条链的过程产物 | | `GESPCPP-{YYYYMM}-md/` | 最终产物(md) | 每级 4 件套 + 图片,平铺;同名 `.zip` | | `GESPCPP-{YYYYMM}-site/` | 最终产物(复盘站) | 导航页 + 各级答题页;同名 `.zip` | 带后缀的目录(`-pdf`/`-md`/`-site`)**永不参与扫描**;目录名的唯一来源是 `scripts/paths.py`。旧布局 `GESP-{YYYYMM}/` 仍可读取,但新产出一律用 `GESPCPP-`。 单级也行:`/gesp md 2026年9月三级真题`,或直接给 PDF 路径 / 下载直链。 ## 3. 环境 - **Python 3**:`pip install -r requirements.txt`(唯一第三方依赖 **PyMuPDF**);不用 poppler(`pdftotext`/`pdftoppm` 一律不使)。 - **node**(可选):`verify_pages.py` 真语法校验、`render_check.js` 渲染兜底门。 - **urlgo**(可选,仅官网结构变化、curl 抓不到直链时兜底):路径自动探测,可用环境变量 `URLGO_PY` / `URLGO_BIN` 覆盖。 - 本机 Bash 残缺(缺 `head`/`ls`/`find`)时,命令前先 `export PATH="/usr/bin:/bin:$PATH"`。 ## 4. 目录结构 ``` gesp/ ├── SKILL.md # 模型执行契约:字段定义 + 19 条硬约束 + 路由(改前必读) ├── README.md CONTRIBUTING.md CHANGELOG.md LICENSE requirements.txt ├── steps/md/ # /gesp md 五步:01-detect → 02-download → 03-extract → 04-create → 05-pack ├── steps/review/ # /gesp review 三步:01-precheck → 02-generate → 03-verify ├── scripts/ # 18 个工具(17 py + 1 js,见 §5) │ └── paths.py # 目录规范唯一来源(GESPCPP-{YYYYMM}[-pdf|-md|-site]),改目录只动它 ├── assets/template.html # 复盘页骨架(改样式只动这里) └── references/ # gesp-syllabus.md(考纲,syllabus 取值唯一来源)、gesp-color-system.md(分级配色) ``` ## 5. 脚本参考(参数见各脚本 `--help`) | 阶段 | 脚本 | 作用 | |---|---|---| | md · 抽取 | `dl_pdf.py` / `pdf_extract.py` / `extract_figure.py` | 下载或拷贝 PDF(**自动落 `…-pdf/`**)/ 抽全文+渲染页图 / 导出配图(**整幅导出,禁子窗口裁切**) | | 通用 | `paths.py` | 目录名唯一来源:`GESPCPP-{YYYYMM}` 工作过程、`-pdf` 源、`-md`/`-site` 最终产物 | | md · 答案 | `dump_answers.py` / `check_answers.py` | **起草前**抠官方答案序列 / **产出后**与官方 PDF 逐题核对 | | md · 规范 | `normalize_math.py` / `normalize_prog.py` / `derive_md.py` | 印刷体数学统一成 **LaTeX `$...$`**(代码与 caret 原样保留)/ 编程题页头三行 + 样例命名围栏 / 由 json 派生三份 md | | md · 审计打包 | `audit_pack.py` / `build_md_pack.py` | **一键审计**(28 项结构 + 内联答案复核;PDF 会自动到 `…-pdf/` 找)/ 打 `GESPCPP-{YYYYMM}-md` 包(目录 + zip) | | review · 生成 | `gen_review.py` | 生成离线复盘页(json 内嵌、单文件自包含) | | review · 校验 | `verify_pages.py` / `render_check.js` / `smoke_390.py` / `pc_check.py` | 静态门 / **无浏览器渲染兜底门** / 390px 真视口全流程 / PC 吸顶与代码块 | | review · 装配 | `build_site.py` | 导航站 + 离线版 zip(**index 恒 8 个可点链接,缺级自动补占位页,点开不 404**) | | 维护 | `normalize_eol.py` | 工作区行尾统一为 LF(幂等、内容零变更;不属两条链) | ## 6. 校验链 ```bash # /gesp md python scripts/audit_pack.py --root . --year 2026 --month 9 # 28 项结构 + 答案审计,退出码 0 才过 # /gesp review(由弱到强) python scripts/verify_pages.py --root . # ① 静态门(命名契约/样例围栏/页头三行) node scripts/render_check.js <复盘页.html> # ② 渲染兜底门:无浏览器也能验 python scripts/smoke_390.py --file <复盘页.html> --out-dir out --port 9022 # ③ 390px 真视口全流程 python scripts/pc_check.py --file <复盘页.html> --out-dir out # ④ PC 吸顶 / 代码块 ``` > CDP 调试浏览器偶发抽风(端口起不来 / 截图超时)时,用 ② 即可判定渲染层是否正常。 ## 7. 产物契约(两个包,两套顶层约定) ```bash / ├── GESPCPP-{YYYYMM}-pdf/ # PDF 源(下载 / 本地试卷归入),只读 ├── GESPCPP-{YYYYMM}/ # 工作过程目录:txt + 页图 + 每级 4 件套 + 配图 + 复盘页(过程产物) ├── GESPCPP-{YYYYMM}-md/ # ★ 内容侧最终产物:每级 4 件套 + 图片 ├── GESPCPP-{YYYYMM}-md.zip # 顶层一个总目录,内部平铺 ├── GESPCPP-{YYYYMM}-site/ # ★ 学生用最终产物:导航站(恒 8 个可点链接)+ 各级答题页(缺级为占位页) └── GESPCPP-{YYYYMM}-site.zip # 根目录平铺,解压即用 ``` - **两套 zip 顶层约定不同,别搞混**:site 包**平铺**(学生直接找到 html);md 包**带一个总目录**(35 个文件不撒满桌面)。md 内图片是相对同目录引用,故图片与 md 平铺同级。 - **目录命名唯一来源 `scripts/paths.py`**:一级前缀 `GESPCPP-{YYYYMM}`,`-pdf` 源 / 无后缀工作过程 / `-md`·`-site` 最终产物。带后缀目录永不参与 json、md、复盘页扫描。 - json 字段契约(`question_type` 三类 / 判断题答案恒 `T`/`F` / 编程题 `correct_answer` 为完整官方参考程序 / `content` 页头三行 + ` ```inputNN `/` ```outputNN ` 命名围栏…)**详见 `SKILL.md`**。 ## 8. 关键铁律(完整版见 `SKILL.md` 硬约束 19 条) 1. **无在线发布**,产物全是本地文件。 2. **目录铁律**:一切以 `GESPCPP-{YYYYMM}` 起头 —— `-pdf` 存 PDF 源、无后缀是工作过程目录、`-md`/`-site` 是最终产物;脚本只从 `scripts/paths.py` 取目录名,禁止自造。 4. **json 是唯一数据源**:md 一律由 `derive_md.py` 派生,禁止手写。 5. **答案/解析唯一来源是官方 PDF**:起草前 `dump_answers.py`、产出后 `check_answers.py` / `audit_pack.py`,退出码 0 才算完成;PDF 未提供时自行分析并**标注「非官方」**。 6. **判断题答案 json 恒 `T`/`F`**(✅/❌ 只在 md 视图层);**数学式子规范源是 LaTeX `$...$`**(`normalize_math.py` 产出;md 可留 Unicode 上下标兜底);**caret `^` 绝不转**——C++ 里是异或。 7. **文本层不可尽信**:`.txt` 常丢数字/公式/样例框,一律以渲染页图为准。 8. **配图**:整幅导出、禁子窗口裁切;落盘保持高清,显示尺寸由页面层收(不靠裁小图/降 dpi)。 9. **只改模板不改产物**(改 `assets/template.html` → 重跑 `gen_review.py`);**改完 json 必须重建**(页面内嵌数据,不自动跟随)。 10. **代码细节**:`re.sub` 注入 JSON 必须用 lambda;`META` 必须先于首次使用(否则整页 TDZ 崩);代码块浅色 `#fafbff` 不得回退深色。 11. **AVOID**:json `content` 里写答案/解析/参考程序;md 写 front matter / 题内分值标注;跳过 `01-precheck` 直接生成;用 `pdftotext`/`pdftoppm`;`syllabus` 写自造标签(必须取自 `references/gesp-syllabus.md`)。 ## 9. 排障速查 | 症状 | 根因 / 处理 | |---|---| | `check_answers` / `audit_pack` 报「PDF 不存在」 | PDF 与 json 分目录了 → 把试卷放(或重新下载)到 `GESPCPP-{YYYYMM}-pdf/`,文件名与 json 同名(脚本会自动去找) | | `gen_review --check` / `build_*` 说找不到 json | json 得在**无后缀的工作过程目录** `GESPCPP-{YYYYMM}/`;`-md`/`-site`/`-pdf` 目录不参与扫描 | | 外部命令 `command not found` | 本机 Bash 残缺 → 先 `export PATH="/usr/bin:/bin:$PATH"` | | 点「开始考试」无反应 / 页面 `NaN`、`undefined` | `META` TDZ 或 `re.sub` 未用 lambda → 回 `steps/review/02-generate.md` | | 页面上题面/选项还是旧的 | json 改了没重建 → 重跑 `gen_review.py` + `build_site.py` | | 样例卡片翻倍(8 列) | 配对时两个占位符各插一张卡片 → 只有首个承载 HTML、其余置空 | | 配图被切偏 / 空白太多 / 显示过大 | 子窗口裁切 → `extract_figure.py` 整幅导出(方格纸底 `--thr 128 --pad 22`);尺寸由页面层收,别裁小图 | | 冒烟截图超时 / `smoke_390.py` 挂起 | 调试浏览器抽风 → 用 `render_check.js` 兜底;脚本已有 45s 超时 + 自动 accept | | git:`add` 一直提示 CRLF / `status` 报 ` M` 而 `diff` 为空 / 推送后 `[gone]` | `normalize_eol.py --apply` + `git add --renormalize -A`;`[gone]` 手工写 `refs/remotes` 或自己终端跑一次 `git fetch` | ## 10. 维护与致谢 - **改样式** → `assets/template.html` 后重建;**改配色** → `gen_review.py` 的 `_LEVEL_RAW`;**改考纲** → `references/gesp-syllabus.md`;**批量多级** → 每级一个子代理,汇总后自己跑 `audit_pack.py` 复核,不采信自述;**提交前**顺手 `normalize_eol.py --apply`。改动流程详见 [CONTRIBUTING.md](CONTRIBUTING.md)。 > 本技能受 **冯老师([fslong520](https://github.com/fslong520))** 的开源项目 **[aiSkill](https://github.com/fslong520/aiSkill)** 启发良多,特此致敬——`mdgesp`(PDF → 结构化真题,「每级 4 件套、json 唯一数据源」的数据契约与它同源)、`urlgo`(CDP 浏览器,390px 真视口冒烟依赖它)以及技能目录组织方式均来自该合集。若与 `aiSkill` 中相关技能存在重叠或可合并之处,欢迎指出。 > 仓库许可证 [MIT](LICENSE);真题数据(CCF 版权)不随仓库分发。 --- _两条链、一个数据源、零联网。改前先读 `SKILL.md` 的「硬约束」与「AVOID」。_