$npx -y skills add OpenRaiser/PaperFit --skill template-migrator本技能专门处理 Category E:跨模板迁移缺陷,包括:
| 1 | # Template Migrator Skill |
| 2 | |
| 3 | ## 概述 |
| 4 | |
| 5 | 本技能专门处理 **Category E:跨模板迁移缺陷**,包括: |
| 6 | |
| 7 | - **E1**:单栏↔双栏图表尺寸失配 |
| 8 | - **E2**:页数预算不匹配(如 9 页→14 页的内容重分布) |
| 9 | - **E3**:模板特定宏兼容性 |
| 10 | |
| 11 | 该技能由 `code-surgeon-agent` 在 `/migrate-template` 命令触发时调用,负责将一篇论文从原模板平滑迁移至目标模板,并自动适配图表尺寸、页数预算和宏包兼容性。这是 PaperFit 最具差异化价值的能力,直接解决了科研工作者切换会议投稿时的真实痛点。 |
| 12 | |
| 13 | ## 适用场景 |
| 14 | |
| 15 | | 缺陷 ID | 描述 | 优先级 | 是否允许语义修改 | |
| 16 | |---------|------|--------|-----------------| |
| 17 | | E1 | 单栏↔双栏图表尺寸失配 | Critical | 否 | |
| 18 | | E2 | 页数预算不匹配 | Critical | 是(最后手段) | |
| 19 | | E3 | 模板特定宏兼容性 | Critical | 否 | |
| 20 | |
| 21 | ## 输入规范 |
| 22 | |
| 23 | | 输入项 | 来源 | 说明 | |
| 24 | |--------|------|------| |
| 25 | | 主 `.tex` 文件路径 | 项目上下文 | 需修改的源文件 | |
| 26 | | 目标模板名称 | 用户命令参数 | 如 `ECCV2024`、`ICLR2025` | |
| 27 | | 模板配置 | `config/templates.yaml` | 包含目标模板的栏数、默认字号、页宽、预期页数等 | |
| 28 | | 原模板信息 | 自动检测或用户指定 | 当前 `\documentclass` 及主要宏包 | |
| 29 | | 排版侦探报告 | `layout-detective-agent` | 迁移后首次编译的 E 类缺陷列表 | |
| 30 | |
| 31 | ## 输出规范 |
| 32 | |
| 33 | ```json |
| 34 | { |
| 35 | "skill": "template-migrator", |
| 36 | "status": "success | partial | failed", |
| 37 | "modified_files": ["main.tex", "figures/fig1.tex"], |
| 38 | "changes": [ |
| 39 | { |
| 40 | "defect_id": "E1", |
| 41 | "object": "Figure 1", |
| 42 | "action": "单栏图改为跨栏图", |
| 43 | "before": "\\begin{figure}\n\\includegraphics[width=\\linewidth]{fig1.pdf}\n\\end{figure}", |
| 44 | "after": "\\begin{figure*}\n\\includegraphics[width=\\textwidth]{fig1.pdf}\n\\end{figure*}" |
| 45 | } |
| 46 | ], |
| 47 | "macro_fixes": [ |
| 48 | { |
| 49 | "issue": "\\theoremstyle undefined in ECCV", |
| 50 | "fix": "改用 \\newtheorem 直接定义" |
| 51 | } |
| 52 | ], |
| 53 | "unresolved": [], |
| 54 | "page_budget_status": { |
| 55 | "current_pages": 9, |
| 56 | "target_pages": 14, |
| 57 | "gap": 5, |
| 58 | "action_taken": "触发 adjust-length 子流程" |
| 59 | } |
| 60 | } |
| 61 | ``` |
| 62 | |
| 63 | ## 迁移流程 |
| 64 | |
| 65 | ### 第一步:加载模板配置 |
| 66 | |
| 67 | 1. 从 `config/templates.yaml` 读取目标模板的完整配置。 |
| 68 | 2. 配置项包括: |
| 69 | - `documentclass`:如 `\documentclass[10pt,twocolumn]{article}` 或 `\documentclass{iclr2025}` |
| 70 | - `column_type`:`single` 或 `double` |
| 71 | - `default_figure_width`:`\linewidth` 或 `\textwidth` |
| 72 | - `expected_pages`:该会议/期刊的典型页数(如 ICLR 9 页,ECCV 14 页) |
| 73 | - `forbidden_packages`:与新模板冲突的宏包列表 |
| 74 | - `required_packages`:新模板必须加载的宏包 |
| 75 | |
| 76 | 示例配置(`config/templates.yaml` 片段): |
| 77 | |
| 78 | ```yaml |
| 79 | ECCV2024: |
| 80 | documentclass: "\documentclass[10pt,twocolumn]{article}" |
| 81 | column_type: double |
| 82 | default_figure_width: "\linewidth" |
| 83 | expected_pages: 14 |
| 84 | forbidden_packages: ["amsthm", "algorithm2e"] |
| 85 | required_packages: ["graphicx", "amsmath", "amssymb"] |
| 86 | float_behavior: "figures may use figure* for wide content" |
| 87 | ``` |
| 88 | |
| 89 | ### 第二步:分析原模板特征 |
| 90 | |
| 91 | 1. 读取当前主 `.tex` 文件的 `\documentclass` 声明。 |
| 92 | 2. 识别当前栏数(单栏/双栏)。 |
| 93 | 3. 列出当前加载的宏包列表(`\usepackage{...}`)。 |
| 94 | 4. 若用户未明确指定原模板,尝试根据 `\documentclass` 自动推断。 |
| 95 | |
| 96 | ### 第三步:执行模板替换 |
| 97 | |
| 98 | **写入约束(强制)**: |
| 99 | |
| 100 | 1. 所有模板迁移修改必须先在内存中完成整组 patch 组装,不得分步直接覆写源文件。 |
| 101 | 2. 真正写盘时必须通过 `scripts/transactional_patch.py` 的 `atomic_write_text(...)` 一次性提交。 |
| 102 | 3. 写入前必须保留迁移前备份;若后续编译验证失败,必须回滚到该备份。 |
| 103 | 4. 不允许一边迁移 `documentclass` / 宏包,一边把半成品状态暴露给后续 agent 或编译轮次。 |
| 104 | |
| 105 | #### 3.1 替换 `\documentclass` |
| 106 | |
| 107 | 将原 `\documentclass` 替换为目标模板的声明。 |
| 108 | |
| 109 | ```latex |
| 110 | % 修改前(ICLR 2025 单栏) |
| 111 | \documentclass{iclr2025} |
| 112 | |
| 113 | % 修改后(ECCV 2024 双栏) |
| 114 | \documentclass[10pt,twocolumn]{article} |
| 115 | ``` |
| 116 | |
| 117 | **注意**:若目标模板有多个可选参数(如 `review`、`final`),询问用户偏好或使用默认值。 |
| 118 | |
| 119 | #### 3.2 处理宏包冲突 |
| 120 | |
| 121 | 1. 对比原宏包列表与目标模板的 `forbidden_packages`。 |
| 122 | 2. 若存在冲突,执行以下操作之一: |
| 123 | - **移除**:直接注释或删除该 `\usepackage` 行。 |
| 124 | - **替换**:提供替代方案(如 `algorithm2e` → `algorithmic`)。 |
| 125 | - **条件编译**:使用 `\ifdefined` 等实现跨模板兼容。 |
| 126 | |
| 127 | ```latex |
| 128 | % 修改前(含 amsthm,与新模板冲突) |
| 129 | \usepackage{amsthm} |
| 130 | \newtheorem{theorem}{Theorem} |
| 131 | |
| 132 | % 修改后(改用 LaTeX 原生定义) |
| 133 | % \usepackage{amsthm} % removed for template compatibility |
| 134 | \newtheorem{theorem}{Theorem} |
| 135 | ``` |
| 136 | |
| 137 | #### 3.3 添加必需宏包 |
| 138 | |
| 139 | 若目标模板要求特定宏包(如 `graphicx`),确保导言区已加载。若缺失,添加之。 |
| 140 | |
| 141 | ```latex |
| 142 | % 确保必需宏包存在 |
| 143 | \usepackage{graphicx} |
| 144 | \usepackage{amsmath} |
| 145 | ``` |
| 146 | |
| 147 | ### 第四步:图表尺寸适配(E1 修复) |
| 148 | |
| 149 | 这是跨模板迁移中最关键、最易出错的环节。 |
| 150 | |
| 151 | #### 4.1 判断单栏/双栏切换方向 |
| 152 | |
| 153 | | 原模板 | 目标模板 | 处理策略 | |
| 154 | |--------|----------|----------| |
| 155 | | 单栏 | 双栏 | 所有图表默认改为单栏宽(`\columnwidth`),宽图改为跨栏(`figure*`) | |
| 156 | | 双栏 | 单栏 | 所有跨栏图(`figure*`)改为普通图(`figure`),宽度改为 `\linewidth` | |
| 157 | | 双栏 | 双栏 | 保持原策略,仅检查宽度是否适配新模板的栏宽 | |
| 158 | | 单栏 | 单栏 | 基本不变,仅检查页宽是否变化 | |
| 159 | |
| 160 | #### 4.2 智能判断哪些图应跨栏(单栏→双栏时) |
| 161 | |
| 162 | 对于原单栏中的全宽图,在双栏中若仍用单栏会显得过小。需根据图片**宽高比**智能决策: |
| 163 | |
| 164 | - 若图片宽度 > 高度 × 1.5(宽高比 > 1.5),建议改为跨栏 `figure*`。 |
| 165 | - 若图片宽度 ≤ 高度 × 1.5,保留单栏 `figure`,但宽度设为 `\columnwidth`。 |
| 166 | |
| 167 | ```latex |
| 168 | % 原单栏全宽图(宽度 = \linewidth) |
| 169 | \begin{figure} |
| 170 | \includegraphics[width=\linewidth]{wide_arch.pdf} |
| 171 | \end{figure} |
| 172 | |
| 173 | % 迁移后(宽高比大,改为跨栏) |
| 174 | \begin{figure*} |
| 175 | \includegraphics[width=\textwidth]{wide_arch.pdf} |
| 176 | \end{figure*} |
| 177 | ``` |
| 178 | |
| 179 | #### 4.3 处理表格宽度 |
| 180 | |
| 181 | - 单栏表格在双栏中:宽度改为 `\columnwidth`。 |
| 182 | - 若原表格为 `tabularx{\linewidth}`,改为 `tabularx{\columnwidth}`。 |
| 183 | - 若表格列数过多,考虑改为跨栏 `table*` 并使用 `\textwidth`。 |
| 184 | |
| 185 | ```latex |
| 186 | % 修改前(单栏宽表) |
| 187 | \begin{table} |
| 188 | \begin{tabularx}{\linewidth}{|l|X|X|} |
| 189 | ... |
| 190 | \end{tabularx} |
| 191 | \end{table} |
| 192 | |
| 193 | % 修改后(双栏单栏宽表) |
| 194 | \begin{table} |
| 195 | \begin{tabularx}{\columnwidth}{|l|X|X|} |
| 196 | ... |
| 197 | \end{tabularx} |
| 198 | \end{table} |
| 199 | ``` |
| 200 | |
| 201 | #### 4.4 特殊对象处理 |
| 202 | |
| 203 | - **长公式**:双栏中公式宽度受限,可能需将 `equation` 改为 `multline` 或 `align` 并手动断行。 |
| 204 | - **算法伪代码**:双栏中宽度减半,可能需要调整缩进或改为跨栏 `figure*`。 |
| 205 | |
| 206 | ### 第五步:编译并检测遗留问题 |
| 207 | |
| 208 | 1. 完成上述修改后,执行首次编译。 |
| 209 | 2. 若编译失败,解析日志中的 `Undefined control sequence` 等错误(E3),返回第三步修正宏包冲突。 |
| 210 | 3. 若编译成功,渲染页图,调用 `layout-detective-agent` 检测 E1/E2 缺陷。 |
| 211 | |
| 212 | ### 第六步:页数预算调整(E2 修复) |
| 213 | |
| 214 | 1. 获取当前 PDF 总页数。 |
| 215 | 2. 与目标模板的 `expected_pages` 对比,计算偏差。 |
| 216 | 3. 若偏差在 ±1 页以内,通常可接受;若偏差 ≥ 2 页,执行以下操作: |
| 217 | - **若超页**:按 A3 修复策略压缩(见 `space-util-fixer`)。 |
| 218 | - ** |