科研技能库/幻灯片精修
图表可视化
未发现用户侧风险

幻灯片精修

对学术演讲幻灯片进行逐页 Codex 审查,并应用针对性的 python-pptx / Beamer 修复。在 /paper-slides(或任何外部生成的 PPTX/Beamer)之后使用,当幻灯片看起来“基本没问题”但用户希望进行最终调整时:对齐视觉权重与参考,放大 PPTX 字体至演讲可读大小,消除斜体样式泄漏,修复文本框溢出,并捕获每页的布局偏移。触发短语:“polish slides”、“slides 排版不对”、“PPTX 字体太小”、“和 Beamer 比一下”、“per-page review”、“和 codex 一页一页过”。

文件预览

1 个文件
SKILL.md
27.7 KB · 可预览
---
name: slides-polish
description: "Per-page Codex review + targeted python-pptx / Beamer fixes for academic talk slides. Use AFTER /paper-slides (or any externally generated PPTX/Beamer) when the deck looks 'mostly OK' but the user wants a final pass that aligns visual weight with a reference, bumps PPTX fonts to projector-readable size, kills italic style leaks, fixes text-frame overflow, and catches per-slide layout drift. Trigger phrases: \"polish slides\", \"slides 排版不对\", \"PPTX 字体太小\", \"和 Beamer 比一下\", \"per-page review\", \"和 codex 一页一页过\"."
argument-hint: "[slides-dir-or-pptx] — reference: <ref-pdf> [— style: generic | why-rf | neurips | icml | iclr | cvpr] [— effort: lite | balanced | max | beast] [— interactive]"
allowed-tools: Bash(*), Read, Write, Edit, Grep, Glob, mcp__codex__codex
---

# Slides Polish: Per-Page Codex Review + Targeted Layout Fixes

Polish a generated slide deck — Beamer (`.tex` + `.pdf`) and/or PPTX — by
running **per-page Codex review** against a reference visual and applying
surgical fixes (font scaling, text-frame resize, callout-box style, em-dash
spacing, anonymity placeholders, Chinese-font hints, italic style leaks)
until each slide reads at the same visual weight as the reference.

Polish: **$ARGUMENTS**

## What This Skill Is — and Is NOT

**This skill polishes layout and typography only.** It is the post-generation
visual pass for an existing deck.

**Hard scope rules** (load-bearing — see Hard Invariants):

- It **does not** rewrite content, claims, numbers, citations, URLs, author
  names, affiliations, or experiment results.
- It **does not** add, remove, or reorder slides unless the user explicitly
  asks (e.g., `— add-slide` / `— drop-slide` flags).
- It **does not** generate outlines, speaker scripts, or new Beamer/PPTX from
  paper source. That is `/paper-slides`'s job.
- It **does not** change figures or equations content.

If you do not yet have a deck, run `/paper-slides` first. If you want to
change content, go back to `/paper-slides` Phases 1-2 (or rewrite the outline
manually) — do not run `/slides-polish` for that.

## Constants

- **REVIEWER_MODEL = `gpt-5.5`** — Codex MCP model for per-page review. xhigh reasoning is non-negotiable (see `../shared-references/effort-contract.md`). `gpt-5.4` is acceptable when the user has no `gpt-5.5` access; `gpt-5.5` is preferred for visual nuance.
- **REVIEWER_REASONING = `xhigh`** — Hard invariant; the effort knob does **not** change this.
- **CONTEXT_POLICY = `fresh`** — Each per-page review uses a **fresh** Codex thread (`mcp__codex__codex`, never `codex-reply`). See `../shared-references/reviewer-independence.md`. This prevents the reviewer from anchoring on prior fixes.
- **REFERENCE_VISUAL** — Path to a PDF the user wants the polished deck to **align with** in visual weight (typography proportion, color discipline, callout density). Required input. If polishing PPTX only, the **Beamer compile of the same talk** is the ideal reference. If no reference exists yet, ask the user; do not silently default to "Why-RF" or any preset.
- **STYLE_PRESET = `generic`** — Default style anchor. Other options: `why-rf` (academic-minimalist, derived from a 2025 academic talk), `neurips`, `icml`, `iclr`, `cvpr`. Presets influence color discipline + element library; the **reference PDF is the visual ground truth**, not the preset.
- **PPTX_SCALE_HINT = `1.6×`** — Heuristic multiplier from Beamer point sizes to PPTX point sizes for matched visual weight on 13.33"×7.5" PowerPoint at 16:9. Range 1.5-1.8×. The actual scale is **always** validated by visual review, never blindly applied.
- **INTERACTIVE = false** — When false, applies the recommended fix automatically and continues to the next slide. When true (`— interactive`), pauses for user confirmation before each fix.
- **OUTPUT_VERSIONING = on** — Output is a versioned file named `<input-stem>_polished.<ext>` (or `_polished_v2`, `_v3`, …). Snapshot of the input is preserved as `<input-stem>_pre_polish.<ext>`. **The original is never overwritten.** All edit operations target the `_polished` working copy.

> 💡 Override examples
>
> - `/slides-polish talk_pptx/talk.pptx — reference: talk_beamer/main.pdf — style: why-rf`
> - `/slides-polish talk_beamer/ — reference: ./reference_talk.pdf — style: generic — effort: max`
> - `/slides-polish talk.pptx — reference: ./why_rf_2025.pdf — interactive`

## Prerequisites

The skill discovers and reports missing prerequisites at Phase 0; it does not
auto-install. Required:

- **Python**: `python3` with `python-pptx>=0.6` (`pip install python-pptx`).
- **PDF inspection**: `pdfinfo` and either `pdftoppm` (poppler, preferred) or `mutool draw` (mupdf) for rendering slides to PNG. Required so the per-page Codex call sees actual slide pixels, not text extraction alone. Render command: `pdftoppm -r 150 -png <pdf> <out-stem>` (or `mutool draw -o <out-stem>-%d.png -r 150 <pdf>`).
- **PPTX → PDF rendering**: `soffice` (LibreOffice headless) preferred; otherwise the user must export PDF manually from PowerPoint/Keynote.
- **LaTeX** (Beamer side only): `xelatex` (CJK) or `pdflatex`, plus `latexmk` for clean recompiles. The Beamer fix patterns in Phase 2 may require these LaTeX packages: `microtype` (letter-spacing in section labels), `array` (raggedright p-columns), `tcolorbox` (banners and callouts), `ctex` or `xeCJK` (CJK), `tikz` + `tikz-cd` (diagrams).
- **Codex MCP**: `mcp__codex__codex` must be available (the user must be signed in to Codex MCP). The skill aborts at Phase 0 if Codex MCP cannot be reached.

Fallback rules:

- If `pdftoppm`/`mutool` missing → ask user to install, do not proceed (visual review without rendered pages produces low-confidence Codex feedback).
- If `soffice` missing and PPTX is the input → ask user to export PDF from their slide tool; resume after.

## Inputs

Discovered automatically from `$ARGUMENTS` and the project directory:

1. **Slides source**:
   - A directory containing `*.pptx`, or `talk_beamer/main.tex` + `main.pdf`, or both.
   - A specific file path (`talk.pptx` or `main.tex`).
2. **Reference PDF** (`— reference: <path>`, REQUIRED). If not supplied, the skill prompts the user. Do not silently substitute.
3. **Style preset** (`— style: <preset>`, default `generic`). Influences color hex codes and element library; see Style Presets below.
4. **Effort** (`— effort: lite | balanced | max | beast`, default `balanced`). See Effort Levels.
5. **Interactive flag** (`— interactive`). Pauses after each per-slide fix.

## Output Layout

```
<deck-dir>/
├── <stem>.pptx                       # original (untouched)
├── <stem>_pre_polish.pptx            # snapshot before any edit
├── <stem>_polished.pptx              # versioned working output
├── <stem>_polished.pdf               # rendered (when conversion available)
└── ... (Beamer files mirrored)

.aris/slides-polish/<deck-stem>/
├── POLISH_STATE.json                 # phase + per-slide status + version pointer
├── INSPECT_<stem>.json               # pre-polish shape inventory
├── TRIAGE.md                         # Phase-1 verdict matrix (per-slide PASS/NEEDS-WORK/BLOCKER)
├── POLISH_CHANGELOG.md               # per-slide fix log (auditable)
└── traces/                           # codex traces (per-slide review JSON, see review-tracing.md)
    ├── slide_01.json
    ├── slide_02.json
    └── ...
```

The skill keeps a self-contained cache under
`.aris/slides-polish/<deck-stem>/`. Per-call Codex traces also follow the
shared convention `.aris/traces/slides-polish/<date>_runNN/` per
`../shared-references/review-tracing.md`. Resumable across sessions if
`POLISH_STATE.json` exists with `"status": "in_progress"` and is < 24h old.

Note: existing skills like `/paper-slides` may use a co-located state file
(e.g., `slides/SLIDES_STATE.json`). `/slides-polish` keeps its state
in `.aris/` to keep the deck directory free of polish-specific cruft.

## Workflow

### Phase 0: Inventory, Inspect, Triage

1. **Discover inputs**: parse `$ARGUMENTS`; locate slides files; check prerequisites; emit a brief inventory report.
2. **Confirm reference PDF**: validate the file exists and has the same slide count (or at least ≥ slide count) as the input. If a mismatch, ask user.
3. **Inspect shapes**: run the inspector (Phase 0 sub-step below) to produce `INSPECT_<stem>.json` listing every text-frame and shape on every slide with: shape id, type, text content (escaped), font sizes per run, bbox in inches, fill/line color, image dimensions for pictures, presence of speaker notes. This file is the ground truth for "find shape by text" downstream.
4. **Snapshot original**: `cp <stem>.pptx <stem>_pre_polish.pptx` (and `.tex` if Beamer present). All subsequent edits target `_polished` copy.
5. **Render PPTX → PDF if needed** (`soffice --headless --convert-to pdf`). If unavailable, prompt user to export.
6. **Render PDF → PNG**: `pdftoppm -r 150 <pdf> .aris/slides-polish/<stem>/png/page` produces one PNG per slide; passed to Codex during per-page review.
7. **Triage pass**: a single fresh Codex call sweeps all N slides comparing PPTX-PDF (or Beamer PDF) against the reference. Output: per-slide verdict matrix.

#### Inspector contract

The skill ships a contract for `inspect_pptx.py` rather than a fixed
implementation. **On first run, if the script is absent under
`.aris/slides-polish/<deck-stem>/inspect_pptx.py`, create it from this
contract.** Implementations may evolve; the contract is what downstream
phases depend on.

CLI:

```
python3 inspect_pptx.py --pptx <input.pptx> --out <state-dir>/INSPECT_<stem>.json
# exit 0 on success, 2 on missing python-pptx, 3 on parse failure
```

Recurse through groups; surface table cells and placeholders. Convert all
geometry from EMU to inches via `EMU_PER_INCH = 914400`. Compute
`notes_text_hash` as `sha256(notes_text)` for byte-level integrity check
in Phase 4. Schema:

```json
{
  "slide_count": 22,
  "slide_size_in": [13.33, 7.5],
  "slides": [
    {
      "index": 0,
      "page_number_text": "1 / 22",
      "has_notes": true,
      "notes_text_hash": "sha256:…",
      "shapes": [
        {
          "id": "13",
          "name": "TextBox 3",
          "shape_path": ["13"],
          "parent_group_ids": [],
          "type": "TEXT_FRAME",
          "placeholder_type": null,
          "table_cell": null,
          "text": "ARIS",
          "runs": [
            {"text": "ARIS", "font_pt": 80.0, "bold": false,
             "italic": false, "color_rgb": "1F1F1F"}
          ],
          "bbox_in": {"left": 0.5, "top": 1.6, "width": 12.33, "height": 0.95},
          "fill_rgb": null,
          "line_rgb": null,
          "image_size_px": null
        }
      ]
    }
  ]
}
```

Schema notes:

- `shape_path`: list of shape IDs from outermost group to leaf shape.
- `parent_group_ids`: empty if shape is at the slide root.
- `type`: one of `TEXT_FRAME | PICTURE | AUTO_SHAPE | GROUP | TABLE | CONNECTOR | PLACEHOLDER`.
- `placeholder_type`: e.g., `TITLE | BODY | OBJECT | NONE`.
- `table_cell`: `{row, col}` if shape is a table cell, else null.
- All hex colors are 6-char uppercase, no leading `#`.
- All geometry in inches, rounded to 4 decimals.

#### Triage Codex prompt

```
mcp__codex__codex:
  model: gpt-5.5
  config: {"model_reasoning_effort": "xhigh"}
  sandbox: read-only
  prompt: |
    Triage pass. For each of N slides in <pptx-pdf-path>, compared against
    <reference-pdf-path>, give one line:

      Slide K | PASS | NEEDS-WORK | BLOCKER — <one-sentence reason>

    Focus on: visual-weight match, text-frame overflow, page-number overlap,
    awkward title wraps, italic style leaks, Chinese tofu/missing-glyph
    boxes, callout-box color discipline, anonymity leaks (e.g., real titles
    appearing where placeholders should be).

    Do NOT rewrite content. Do NOT propose font scaling for slides that
    already read fine. Do NOT comment on speaker notes.

    End with a one-line summary: "K BLOCKERS, K NEEDS-WORK, K PASS."
```

Save matrix to `TRIAGE.md`. Present to user before deep work begins.

### Phase 1: Per-Page Review + Fix Loop

For each slide flagged `NEEDS-WORK` or `BLOCKER`, run a focused fresh-thread
Codex call. Apply the returned fix immediately (subject to `INTERACTIVE`),
recompile or save, move to next slide.

**Per-page loop, not batch.** Empirically: per-page Codex calls converge in
1-2 polish rounds where single-pass batch review never converges.

#### Per-page Codex prompt template

```
mcp__codex__codex:
  model: gpt-5.5
  config: {"model_reasoning_effort": "xhigh"}
  sandbox: read-only
  prompt: |
    SLIDE K review. Compare PPTX page K against reference page K.

    Files:
    - PPTX page rendering: <png-path>/page-K.png
    - Reference page rendering: <ref-png-path>/page-K.png
    - Source: <pptx-file-path> (slide index K-1) and/or <main-tex-path>
    - Inspector inventory for slide K: <inspect-json-slide-K-snippet>

    Slide K title (from inventory): "<title>".

    Style anchor: <style-preset> + reference PDF.

    Give:
    1. Status: PASS / NEEDS-WORK / BROKEN
    2. What's working (1-2 specifics)
    3. What's drifting vs reference (1-3 specifics)
    4. Concrete python-pptx (or .tex) fixes:
       - Identify shapes by their text content (NOT by index — index drifts).
       - Use unique-prefix substring matching; if duplicate matches, abort
         and request human disambiguation rather than touching the first.
       - Give before/after snippets.
    5. If a fix would change CONTENT (claims, numbers, anonymity placeholder
       text, etc.), STOP and report it instead of suggesting it.

    End: VERDICT: PASS | NEEDS-WORK | BROKEN. Under 500 words.
```

#### Fix application

After Codex returns, call `apply_fix(slide_index, fix_block)` which:

1. Loads the `_polished` working copy.
2. Locates each target shape by `text_frame.text` substring; **asserts unique match** or aborts.
3. Applies edits (font size, position, color, italic, line spacing).
4. Saves atomically (write to tmp + rename).
5. Logs the change to `POLISH_CHANGELOG.md` (one line: `Slide K | <change> | reason`).

After every 3 slides, write a checkpoint snapshot
`<stem>_polished_checkpoint_KK.pptx`.

#### Robust shape selection

```python
def find_shape(slide, contains: str, *, kind: str | None = None):
    """Return the unique shape whose text_frame.text contains `contains`.
    Aborts if duplicate matches (caller must disambiguate by bbox or kind).
    """
    matches = []
    for sh in slide.shapes:
        if not sh.has_text_frame:
            continue
        if kind is not None and sh.shape_type != kind:
            continue
        if contains in sh.text_frame.text:
            matches.append(sh)
    if len(matches) == 0:
        raise LookupError(f"no shape contains {contains!r} on slide")
    if len(matches) > 1:
        raise AmbiguousMatch(f"{len(matches)} shapes contain {contains!r}; "
                             f"need disambiguator (kind, bbox, or longer needle)")
    return matches[0]
```

For grouped shapes, recurse into `shape.shapes` if `shape_type == GROUP`.

### Phase 2: Beamer-Side Polish (if Beamer source present)

Same per-page review pattern, but on `main.tex` source + compiled PDF. Fixes
are direct `Edit` tool operations on a `main_polished.tex` working copy
followed by `xelatex` recompile and PNG re-render. The original `main.tex`
is preserved.

#### Common Beamer fix patterns (inline catalog — no external file required)

These are encoded directly in this SKILL.md so the skill has zero external
dependencies:

- **Frame title size + thin underline rule**: use `beamercolorbox` template
  with `\hrule height 0.55pt` AFTER the title text, NOT a bare `\rule{}`
  outside the beamercolorbox (which renders top-right, not under title).
- **`\sectionlabel` macro for small caps blue mini-headers**:
  ```latex
  \newcommand{\sectionlabel}[1]{%
    {\sffamily\fontsize{8}{10}\selectfont
     \textcolor{<accent>}{\textls[200]{\MakeUppercase{#1}}}}}
  ```
  Requires `microtype` for `\textls`.
- **`array` package for `>{\raggedright\arraybackslash}p{Xcm}` in cards**.
  Without it, tabular cells justify and create rivers / mid-word hyphenation
  in narrow columns.
- **Banner = real `tcolorbox`**, not `\begin{center}\color{...}` (which
  renders as plain centered text, not a banner).
- **Em-dash spacing**: prefer `\textemdash{}` (with explicit braces) or
  `\,---\,` over a bare `—`. A bare em-dash often renders with collapsed
  surrounding whitespace.
- **Color-leak inside `\sectionlabel`**: `\sectionlabel{... \textcolor{red}{...}}`
  BREAKS because `\MakeUppercase` uppercases color name → undefined-color
  error. Put `\textcolor` outside or define a colored `\sectionlabel*` variant.
- **CJK + math**: with `xelatex`, use `\usepackage[fontset=fandol]{ctex}` or
  set EA fonts explicitly. Mixed Chinese-English in titles needs the EA font
  hint or characters fall back to Latin.

### Phase 3: PPTX-Side Polish

Apply font scaling **first** (Phase 3a), then layout fix loop (Phase 3b).
Bumping fonts without resizing frames creates overflow.

#### Phase 3a: Font scaling (heuristic table)

Compute target sizes from Beamer reference using `PPTX_SCALE_HINT`. Reference
mapping:

| Beamer pt | PPTX target | Role |
|---|---|---|
| 8 / 8.5 | 14-18 small caps | section labels |
| 10 italic | 14 italic | gray italic cue / hints |
| 11 body | 22-24 | bullets, paragraphs |
| 12 page number | 16 | "N / total" gray bottom-right (cap at 16) |
| 14 emphasis body | 22-24 | bigger sub-headers |
| 16 callout content | 24-28 | eqbox / yellowstrip body |
| 17-22 big number | 28-36 | hero stats (e.g., "8.1k+", funnel "8/6/2/1") |
| 22 frame title | 40-44 | every page title |
| 28 emphasis hero | 36-44 | hero text |
| 42 cover wordmark | 80-100 plain BLACK | cover (Why-RF discipline: not colored) |

**Page-number rule**: never bump page numbers above 16pt. They stay small.

After scaling, **always** revisit Phase 1 triage — the 1.6× hint is a
starting point; some slides need 1.5×, some 1.8×.

#### Phase 3b: Text-frame layout fix loop

Two recurring failure modes after font bump:

1. **Title overlaps subtitle/body**: a title at 100pt sits in a 0.95"-tall
   frame but the glyph is ~1.4" tall, so it bleeds down. Fix: increase the
   text frame height AND reposition the next-element top.
2. **Body bullets wrap mid-sentence**: a long-noun-phrase bullet wraps
   with the final noun alone on the next line because the frame width is
   sized for the old (smaller) font. Fix: widen the frame AND narrow the
   adjacent column.

Each per-page Codex call returns specific shape resize commands; apply via
the inspector's bbox primitives.

#### Phase 3c: Common PPTX pitfalls (inline catalog)

- **Image aspect ratio**: bumping `width` without `height` stretches embedded
  PNGs. Always compute `height = width × (image_height_px / image_width_px)`.
- **Banner = real filled rectangle**: use `tcolorbox`-equivalent (in PPTX,
  a separate `MSO_SHAPE.RECTANGLE` behind the text frame), not just colored
  text.
- **Curved arrows**: python-pptx has no curved-arrow primitive. Approximate
  with two straight `MSO_CONNECTOR_TYPE.STRAIGHT` connectors (vertical +
  horizontal) or use an `add_freeform` Bezier. Document the approximation.
- **Italic style leak**: `\itshape` in the source without braces causes all
  following runs in the same paragraph to inherit italic. Wrap as
  `{\itshape ...}` or scope to a single run.
- **Chinese rendering**: PowerPoint needs the East Asian font hint
  (`<a:ea typeface="PingFang SC"/>` for macOS, `Microsoft YaHei` for
  Windows). Without it, characters fall back to a Latin font and render
  as tofu boxes.
- **Em-dash spacing**: bare `—` in titles often renders with collapsed
  spaces. Insert literal spaces (`" — "`) or use figure-space.
- **Cycle-arrow / feedback-loop labels**: ensure label bbox stays inside
  slide bounds (`L > 0.4in`, `T > 0.4in`). PPTX silently clips off-slide
  content, and curved labels positioned near the left/top edge are the
  most common offenders.
- **Anonymity placeholder discipline**: ALL placeholders for under-review
  work must use generic phrasing (e.g., "Withheld for anonymous review",
  "[anonymized]"). NEVER infer or fill in real titles, counts, or URLs.
  See `../shared-references/experiment-integrity.md`.

### Phase 4: Verification + Re-Triage

1. **Re-render PPTX → PDF** (LibreOffice or user-export).
2. **Re-render PDF → PNG** for visual.
3. **Re-triage**: rerun Phase 0.7 prompt. Goal: 0 BLOCKERS, ≤2 NEEDS-WORK.
   If > 2 NEEDS-WORK remain, loop back to Phase 1 for those slides.
4. **Speaker-notes integrity check**: assert every slide's `notes_slide` is
   present and unchanged from `_pre_polish.pptx` (a polish round must never
   touch notes content).
5. **Anonymity scan**: grep the final PPTX for known sensitive strings (real
   author names absent from the original, real URLs added by the LLM, real
   submission counts). If found, fail closed and report.
6. **Final emit**: `<stem>_polished.pptx` (and `.pdf` if rendered).

### Phase 5: Changelog

Write `POLISH_CHANGELOG.md`:

```
Slide  1 cover  | bumped wordmark 80→86; subtitle 36→40; line spacing 0.9        | Codex per-page review
Slide  2 hook   | left body L=0.45 W=8.30; right cards 28→19pt; yellow strip 22→19 | wrap fix
Slide  3 …      | …                                                              | …
```

This makes every polish round auditable and reversible (each line maps to
a `_polished_v{i}` checkpoint).

## Style Presets

Presets influence default colors and the element library only — the
**reference PDF is always the visual ground truth**, not the preset.

### `generic` (default)

Black + one accent (default `#2563EB`). No callout-box fills beyond a single
neutral background where load-bearing.

### `why-rf` (academic-minimalist, example preset)

Anchor: a 2025 academic talk on rectified flow with the following discipline.

| Element | Beamer | PPTX (1.6× hint) | Notes |
|---|---|---|---|
| Frame title | `\fontsize{22}{26}` | 40-44pt sans bold | + thin 0.55pt accent underline rule full-width |
| Body text | 11pt | 22-26pt | Calibri / Helvetica Neue equivalent |
| Card title (chorebox) | 11pt bold | 20-26pt bold | Within `chorebox` callout |
| Section label | 8pt small caps | 16-18pt small caps wide-tracked | Color = primary accent |
| Italic gray cue | `\scriptsize\itshape` | 12-14pt italic | Color = pagegray |
| Page number | `\footnotesize` | 14-16pt | Bottom-right gray |
| Cover title | 44pt plain BLACK | 80-100pt plain BLACK | Title is **not** colored |

**Color palette** (load-bearing only, sparingly):

- Primary accent (e.g., `#2E75B6`)
- Darker accent (chip backgrounds, big numbers, e.g., `#1F4E79`)
- Light callout bg (e.g., `#DEEBF7`)
- Honest-disclosure yellow (e.g., `#FFF4CC`)
- Audit-bug red (safety disclaimers only, e.g., `#C00000`)
- Page gray (e.g., `#808080`)
- Text dark (e.g., `#1F1F1F`)

**Element library** (used sparingly):

- `chorebox`: white bg + thin top accent rule + section-label + bold title + body
- `eqbox`: light-accent full-width banner; load-bearing assumption / conclusion only
- `yellowstrip`: honest-yellow + 3pt left-edge orange rule; honest disclosures only
- `redbox`: light red + red border; **safety disclaimers only**
- `banner`: light-accent full-width strip; brief banner caption

**Discipline**: fewer color boxes than typical "designerly" templates. Cosmetic
cards become plain bullets; marketing flourishes are removed.

### `neurips` / `icml` / `iclr` / `cvpr`

Inherit color schemes from `/paper-slides`. Polish-loop and font-scaling rules
unchanged.

## Effort Levels

See `../shared-references/effort-contract.md` for the full contract.

| `effort` | Behavior |
|---|---|
| `lite` | Triage pass + fix BLOCKERS only. Skip per-page review for NEEDS-WORK slides. ~30% of full token cost. |
| `balanced` (default) | Triage + per-page review for all NEEDS-WORK and BLOCKER slides. PASS slides untouched. |
| `max` | Per-page review on **every** slide (including PASS). ~2.5× tokens. |
| `beast` | `max` + a second polish round after Phase-4 re-triage; chase remaining ≤2pt overfull / minor wraps. ~5× tokens. |

`reasoning_effort: xhigh` is non-negotiable across all levels.

## Hard Invariants

These are non-negotiable:

1. **Reference is required.** The skill never polishes without an explicit visual anchor. If no reference PDF, ask the user. A style preset is **not** a substitute.
2. **Original is never overwritten.** All edits target `<stem>_polished.<ext>`; the snapshot at `<stem>_pre_polish.<ext>` is the rollback target.
3. **Speaker notes are preserved verbatim.** Every PPTX edit must preserve `slide.notes_slide` content. Phase 4.4 verifies this byte-for-byte against the snapshot.
4. **No content edits.** No new claims, numbers, citations, URLs, author names, affiliations, or experiment results. No equation or figure-content changes. No paraphrasing of body text — only style/typography/box edits. If a Codex fix proposal would change content, the skill stops and reports it.
5. **No slide reordering, addition, or deletion** unless the user passes an explicit flag (`— add-slide-K-after-J`, `— drop-slide-K`).
6. **Cross-model independence**: per-page Codex calls are fresh threads, not `codex-reply`. Reviewer never sees prior fix lists. See `reviewer-independence.md`.
7. **Anonymity placeholders fail closed.** If a Codex fix proposes filling in a real title, count, or URL where a placeholder was, the skill rejects it and surfaces the proposal for human review. See `experiment-integrity.md`.
8. **Page numbers stay ≤ 16pt.** Why-RF discipline; never bump them.
9. **`reasoning_effort: xhigh`** is invariant across all `effort` levels.
10. **Robust shape selection**: edits use unique-prefix `text_frame.text` matching with assert-unique semantics. If duplicate matches, abort and request disambiguation.

## Review Tracing

After each per-page Codex call, save the trace following
`../shared-references/review-tracing.md`. Per-call file under
`.aris/slides-polish/<stem>/traces/slide_KK.json` with:

- Codex `threadId`
- prompt (verbatim)
- response (verbatim)
- applied diff summary (list of shape edits with before/after sizes/bboxes)
- validation status (post-fix re-render PASS/FAIL)

Both the triage pass and the per-slide passes are traced.

## Prior Skill Relationship

- Runs **after** `/paper-slides` (or any externally generated deck).
- Compatible with `/paper-poster` workflow (same color discipline) but
  different output cadence.
- Uses the same `mcp__codex__codex` MCP infrastructure as
  `/auto-paper-improvement-loop`, `/research-review`, etc.
- Does **not** call or compose with `/paper-slides` content phases — strict
  separation.

## When NOT to Use

- Slides are still in **content drafting** phase — go back to `/paper-slides`
  Phases 1-2.
- Complete redesign needed (different colors / template / aspect ratio) —
  re-run `/paper-slides`, not polish.
- Deck has fewer than 5 slides — per-page review overhead is not worth it;
  hand-edit.
- The user explicitly says "no Codex" — this skill is Codex-driven by design.

## Empirical Origin

This skill was extracted from a polish run on a Chinese-spoken academic
conference talk (May 2026). The convergent observation: **once content
is locked, the remaining cost is per-page visual fidelity** — and per-page
Codex review with concrete python-pptx / `.tex` fix snippets converges in
1-2 rounds where single-pass batch review never converges. The fix-pattern
catalogs in Phases 2-3 (Beamer template gotchas, PPTX font scaling, layout
fix loop, Chinese-font hints) are the durable artifact.

## Parameter Pass-Through

When invoked via `/research-pipeline` or another orchestrator, parameters
flow as:

- `— effort` → see Effort Levels.
- `— reference` → `REFERENCE_VISUAL`.
- `— style` → `STYLE_PRESET`.
- `— interactive` → `INTERACTIVE = true`.

Other args (e.g., `— venue`) are ignored by this skill and not propagated.

SKILL.md

元数据
nameslides-polish
description对学术演讲幻灯片进行逐页 Codex 审查,并应用针对性的 python-pptx / Beamer 修复。在 /paper-slides(或任何外部生成的 PPTX/Beamer)之后使用,当幻灯片看起来“基本没问题”但用户希望进行最终调整时:对齐视觉权重与参考,放大 PPTX 字体至演讲可读大小,消除斜体样式泄漏,修复文本框溢出,并捕获每页的布局偏移。触发短语:“polish slides”、“slides 排版不对”、“PPTX 字体太小”、“和 Beamer 比一下”、“per-page review”、“和 codex 一页一页过”。
argument-hint[slides-dir-or-pptx] — reference: <ref-pdf> [— style: generic | why-rf | neurips | icml | iclr | cvpr] [— effort: lite | balanced | max | beast] [— interactive]
allowed-toolsBash(*), Read, Write, Edit, Grep, Glob, mcp__codex__codex

幻灯片精修:逐页 Codex 审查 + 针对性布局修复

对已生成的幻灯片组——Beamer(.tex + .pdf)和/或 PPTX——进行逐页 Codex 审查,参照一份视觉参考,并应用精确修复(字体缩放、文本框调整、标注框样式、破折号间距、匿名占位符、中文字体提示、斜体样式泄漏),直到每页的视觉权重与参考一致。

精修对象:$ARGUMENTS

本技能是什么——不是什么

本技能仅润色布局和排版。 这是对已有幻灯片组进行生成后的视觉遍历。

硬性范围规则(承重墙——见硬性不变项):

  • 不修改内容、观点、数字、引用、URL、作者姓名、所属机构或实验结果。
  • 不添加、删除或重新排列幻灯片,除非用户明确要求(例如,— add-slide / — drop-slide 标志)。
  • 不从论文源生成大纲、演讲者文稿或新的 Beamer/PPTX。那是 /paper-slides 的工作。
  • 不更改图表或公式内容。

如果你还没有幻灯片组,请先运行 /paper-slides。如果你想修改内容,请返回 /paper-slides 的阶段 1-2(或手动重写大纲)——不要为此运行 /slides-polish。

常量

  • REVIEWER_MODEL = gpt-5.5 — 用于逐页审查的 Codex MCP 模型。xhigh 推理是硬性要求(见 ../shared-references/effort-contract.md)。当用户没有 gpt-5.5 访问权限时,可使用 gpt-5.4;但 gpt-5.5 是处理视觉细微差别的首选。
  • REVIEWER_REASONING = xhigh — 硬性不变项;精细程度旋钮不改变此值。
  • CONTEXT_POLICY = fresh — 每页审查使用全新 Codex 线程(mcp__codex__codex,绝不用 codex-reply)。参见 ../shared-references/reviewer-independence.md。这防止审查员受先前修复影响。
  • REFERENCEVISUAL∗∗REFERENCE_VISUAL** — 用户希望精修后幻灯片在视觉权重(字形比例、颜色使用纪律、标注框密度)上对齐的 PDF 文件路径。必须输入。如果仅精修 PPTX,则同一演讲的 Beamer 编译稿**是理想参考。若尚无参考,询问用户;不要默认为“Why-RF”或任何预设。
  • STYLE_PRESET = generic — 默认风格锚点。其他选项:why-rf(学术极简,源自 2025 学术演讲),neurips,icml,iclr,cvpr。预设影响颜色纪律和元素库;参考 PDF 仍是视觉真相,而非预设。
  • PPTX_SCALE_HINT = 1.6× — 从 Beamer 磅值到 PPTX 磅值的启发式乘数,用于在 16:9 的 13.33"×7.5" PowerPoint 上实现匹配的视觉权重。范围 1.5-1.8×。实际比例始终通过视觉审查验证,绝不盲用。
  • INTERACTIVE = false — 为 false 时,自动应用建议的修复并继续下一张幻灯片。为 true(— interactive)时,每次修复前暂停以征求用户确认。
  • **OUTPUTVERSIONING=on∗∗OUTPUT_VERSIONING = on** — 输出为带版本号的文件:<输入词干>_polished.<ext>(或 _polished_v2、_v3、…)。输入的快照保存为 <输入词干>_pre_polish.<ext>。原始文件永不被覆盖。所有编辑操作均针对 _polished 工作副本。

💡 覆盖示例

  • /slides-polish talk_pptx/talk.pptx — reference: talk_beamer/main.pdf — style: why-rf
  • /slides-polish talk_beamer/ — reference: ./reference_talk.pdf — style: generic — effort: max
  • /slides-polish talk.pptx — reference: ./why_rf_2025.pdf — interactive

先决条件

技能在阶段 0 发现并报告缺失的先决条件;不自动安装。需要:

  • Python:python3 且 python-pptx>=0.6 (pip install python-pptx)。
  • PDF 检测:pdfinfo 以及 pdftoppm(poppler,首选)或 mutool draw(mupdf),用于将幻灯片渲染为 PNG。必须提供,以便逐页 Codex 调用看到实际幻灯片像素,而非仅文本提取。渲染命令:pdftoppm -r 150 -png <pdf> <out-stem>(或 mutool draw -o <out-stem>-%d.png -r 150 <pdf>)。
  • PPTX → PDF 渲染:soffice(LibreOffice 无头模式)首选;否则用户须从 PowerPoint/Keynote 手动导出 PDF。
  • LaTeX(仅 Beamer 侧):xelatex(CJK)或 pdflatex,以及用于干净重编译的 latexmk。阶段 2 中的 Beamer 修复模式可能需要以下 LaTeX 宏包:microtype(节标题中的字母间距)、array(raggedright p-列)、tcolorbox(横幅和标注框)、ctex 或 xeCJK(CJK)、tikz + tikz-cd(示意图)。
  • Codex MCP:mcp__codex__codex 必须可用(用户必须登录 Codex MCP)。若阶段 0 无法连接 Codex MCP,技能终止。

回退规则:

  • 若 pdftoppm/mutool 缺失 → 要求用户安装,不得继续(无渲染页面的视觉审查会产生低置信度 Codex 反馈)。
  • 若 soffice 缺失且输入为 PPTX → 要求用户从其幻灯片工具导出 PDF;之后继续。

输入

从 $ARGUMENTS 和项目目录自动发现:

  1. 幻灯片源:
    • 包含 *.pptx 的目录,或 talk_beamer/main.tex + main.pdf,或两者。
    • 具体文件路径(talk.pptx 或 main.tex)。
  2. 参考 PDF(— reference: <path>,必选)。若未提供,技能提示用户。不得静默替换。
  3. 风格预设(— style: <preset>,默认 generic)。影响颜色十六进制代码和元素库;见下方风格预设。
  4. 精细程度(— effort: lite | balanced | max | beast,默认 balanced)。见精细程度级别。
  5. 交互标志(— interactive)。每页修复后暂停。

输出布局

text
<deck-dir>/
├── <stem>.pptx                       # 原始(未改动)
├── <stem>_pre_polish.pptx            # 编辑前快照
├── <stem>_polished.pptx              # 带版本的工作输出
├── <stem>_polished.pdf               # 渲染版(若转换可用)
└── ... (Beamer 文件镜像)

.aris/slides-polish/<deck-stem>/
├── POLISH_STATE.json                 # 阶段 + 每页状态 + 版本指针
├── INSPECT_<stem>.json               # 精修前形状清单
├── TRIAGE.md                         # 阶段 1 裁决矩阵(每页 PASS/NEEDS-WORK/BLOCKER)
├── POLISH_CHANGELOG.md               # 每页修复日志(可审计)
└── traces/                           # codex 轨迹(每页审查 JSON,参见 review-tracing.md)
    ├── slide_01.json
    ├── slide_02.json
    └── ...

技能在 .aris/slides-polish/<deck-stem>/ 下维护自包含缓存。每次调用的 Codex 轨迹也遵循共享约定 .aris/traces/slides-polish/<date>_runNN/,依 ../shared-references/review-tracing.md。若 POLISH_STATE.json 存在且 "status": "in_progress" 且距今 < 24h,则可跨会话恢复。

注意:现有技能如 /paper-slides 可能使用同级的状态文件(例如 slides/SLIDES_STATE.json)。/slides-polish 将其状态保存在 .aris/ 中,以保持幻灯片目录不含精修相关杂物。

工作流

阶段 0:盘点、检查、分诊

  1. 发现输入:解析 $ARGUMENTS;定位幻灯片文件;检查先决条件;输出简要盘点报告。
  2. 确认参考 PDF:验证文件存在且与输入幻灯片数相同(或至少 ≥ 幻灯片数)。若数目不匹配,询问用户。
  3. 检查形状:运行检查器(阶段 0 子步骤)生成 INSPECT_<stem>.json,列出每页每个文本框和形状的:形状 id、类型、文本内容(转义)、各文本运行的字体大小、英寸尺寸的边界框、填充/线条颜色、图片尺寸、是否有演讲者备注。此文件是下游“按文本查找形状”的真实数据源。
  4. 快照原始文件:cp <stem>.pptx <stem>_pre_polish.pptx(若 Beamer 存在且含 .tex)。所有后续编辑针对 _polished 副本。
  5. 按需渲染 PPTX → PDF(soffice --headless --convert-to pdf)。若不可用,提示用户导出。
  6. 渲染 PDF → PNG:pdftoppm -r 150 <pdf> .aris/slides-polish/<stem>/png/page 为每页生成一个 PNG;在逐页审查时传递给 Codex。
  7. 分诊遍历:一次全新的 Codex 调用扫描所有 N 页,比较 PPTX-PDF(或 Beamer PDF)与参考。输出:每页裁决矩阵。

检查器合约

技能附带 inspect_pptx.py 的合约,而非固定实现。首次运行时,若 .aris/slides-polish/<deck-stem>/inspect_pptx.py 不存在,则根据此合约创建它。 实现可能演化;下游阶段依赖的是合约。

CLI:

text
python3 inspect_pptx.py --pptx <input.pptx> --out <state-dir>/INSPECT_<stem>.json
# 成功时退出码 0;缺失 python-pptx 时退出码 2;解析失败时退出码 3

递归遍历组;暴露表格单元格和占位符。通过 EMU_PER_INCH = 914400 将所有几何量从 EMU 转换为英寸。使用 sha256(notes_text) 计算 notes_text_hash,用于阶段 4 的字节级完整性检查。模式:

json
{
  "slide_count": 22,
  "slide_size_in": [13.33, 7.5],
  "slides": [
    {
      "index": 0,
      "page_number_text": "1 / 22",
      "has_notes": true,
      "notes_text_hash": "sha256:…",
      "shapes": [
        {
          "id": "13",
          "name": "TextBox 3",
          "shape_path": ["13"],
          "parent_group_ids": [],
          "type": "TEXT_FRAME",
          "placeholder_type": null,
          "table_cell": null,
          "text": "ARIS",
          "runs": [
            {"text": "ARIS", "font_pt": 80.0, "bold": false,
             "italic": false, "color_rgb": "1F1F1F"}
          ],
          "bbox_in": {"left": 0.5, "top": 1.6, "width": 12.33, "height": 0.95},
          "fill_rgb": null,
          "line_rgb": null,
          "image_size_px": null
        }
      ]
    }
  ]
}

模式说明:

  • shape_path:从最外层组到叶形状的形状 ID 列表。
  • parent_group_ids:若形状在幻灯片根层级,则为空。
  • type:TEXT_FRAME | PICTURE | AUTO_SHAPE | GROUP | TABLE | CONNECTOR | PLACEHOLDER 之一。
  • placeholder_type:例如 TITLE | BODY | OBJECT | NONE。
  • table_cell:若形状是表格单元格则为 {row, col},否则 null。
  • 所有十六进制颜色为 6 字符大写,无前导 #。
  • 所有几何量以英寸为单位,四舍五入至 4 位小数。

分诊 Codex 提示词

text
mcp__codex__codex:
  model: gpt-5.5
  config: {"model_reasoning_effort": "xhigh"}
  sandbox: read-only
  prompt: |
    分诊遍历。对于 <pptx-pdf-path> 中的 N 页幻灯片,与 <reference-pdf-path> 对比,为每页给出一行:

      第 K 页 | PASS | NEEDS-WORK | BLOCKER — <一句话原因>

    关注:视觉权重匹配、文本框溢出、页码重叠、别扭的标题换行、斜体样式泄漏、中文 tofu/缺失字形框、标注框颜色纪律、匿名泄露(例如,真实标题出现在应使用占位符的位置)。

    不要改写内容。不要对已读起来不错的幻灯片提出字体缩放建议。不要评论演讲者备注。

    以单行总结结束:“K 个 BLOCKER,K 个 NEEDS-WORK,K 个 PASS。”

将矩阵保存至 TRIAGE.md。深层工作开始前向用户展示。

阶段 1:逐页审查 + 修复循环

对每个标记为 NEEDS-WORK 或 BLOCKER 的幻灯片,运行一次聚焦的全新线程 Codex 调用。立即应用返回的修复(受 INTERACTIVE 影响),重编译或保存,移到下一张幻灯片。

逐页循环,而非批量。 经验表明:逐页 Codex 调用在 1-2 轮精修中收敛,而单次批量审查从不收敛。

逐页 Codex 提示词模板

text
mcp__codex__codex:
  model: gpt-5.5
  config: {"model_reasoning_effort": "xhigh"}
  sandbox: read-only
  prompt: |
    第 K 页审查。对比 PPTX 第 K 页与参考第 K 页。

    文件:
    - PPTX 页面渲染:<png-path>/page-K.png
    - 参考页面渲染:<ref-png-path>/page-K.png
    - 源文件:<pptx-file-path>(幻灯片索引 K-1)和/或 <main-tex-path>
    - 第 K 页检查器清单:<inspect-json-slide-K-snippet>

    第 K 页标题(来自清单):“<title>”。

    风格锚点:<style-preset> + 参考 PDF。

    给出:
    1. 状态:PASS / NEEDS-WORK / BROKEN
    2. 哪些有效(1-2 点具体内容)
    3. 哪些相较于参考有偏移(1-3 点具体内容)
    4. 具体的 python-pptx(或 .tex)修复:
       - 通过形状的文本内容(而非索引——索引会漂移)标识形状。
       - 使用唯一前缀子串匹配;若发现重复匹配,中止并要求人工消除歧义,而非触碰第一个匹配。
       - 给出修改前后代码片段。
    5. 若某项修复会改变内容(观点、数字、匿名占位符文本等),立即停止并报告,而非提议该修复。

    结束:VERDICT: PASS | NEEDS-WORK | BROKEN。不超过 500 字。

修复应用

Codex 返回后,调用 apply_fix(slide_index, fix_block),执行:

  1. 加载 _polished 工作副本。
  2. 通过 text_frame.text 子串定位每个目标形状;断言唯一匹配否则中止。
  3. 应用编辑(字体大小、位置、颜色、斜体、行距)。
  4. 原子保存(写入临时文件 + 重命名)。
  5. 将变更记录到 POLISH_CHANGELOG.md(每行:第 K 页 | <变更> | 原因)。

每完成 3 张幻灯片,写入一次检查点快照 <stem>_polished_checkpoint_KK.pptx。

稳健的形状选择

python
def find_shape(slide, contains: str, *, kind: str | None = None):
    """返回 text_frame.text 包含 `contains` 的唯一形状。
    若发现重复匹配则中止(调用者须通过 bbox 或 kind 消除歧义)。
    """
    matches = []
    for sh in slide.shapes:
        if not sh.has_text_frame:
            continue
        if kind is not None and sh.shape_type != kind:
            continue
        if contains in sh.text_frame.text:
            matches.append(sh)
    if len(matches) == 0:
        raise LookupError(f"幻灯片上未找到包含 {contains!r} 的形状")
    if len(matches) > 1:
        raise AmbiguousMatch(f"{len(matches)} 个形状包含 {contains!r};"
                             f"需要歧义消除器(kind、bbox 或更长的搜索词)")
    return matches[0]

对于组合形状,若 shape_type == GROUP 则递归进入 shape.shapes。

阶段 2:Beamer 侧精修(如存在 Beamer 源)

相同的逐页审查模式,但作用于 main.tex 源文件 + 编译 PDF。修复直接通过 Edit 工具操作 main_polished.tex 工作副本,随后用 xelatex 重编译并重渲染 PNG。原始 main.tex 被保留。

常见 Beamer 修复模式(内联目录——无需外部文件)

这些直接编码在本 SKILL.md 中,因此技能零外部依赖:

  • 帧标题大小 + 细下划线:使用 beamercolorbox 模板,并在标题文本之后加上 \hrule height 0.55pt,而非在 beamercolorbox 外使用裸 \rule{}(那样会渲染在右上角,而非标题下方)。
  • \sectionlabel 宏用于小型大写字母蓝色迷你标题:
    latex
    \newcommand{\sectionlabel}[1]{%
      {\sffamily\fontsize{8}{10}\selectfont
       \textcolor{<accent>}{\textls[200]{\MakeUppercase{#1}}}}}
    需要 microtype 包提供 \textls。
  • 卡片中使用 array 包的 >{\raggedright\arraybackslash}p{Xcm}。 否则,表格单元会两端对齐,在窄列中产生河流和句中连字符。
  • 横幅应为真实的 tcolorbox 环境,而非 \begin{center}\color{...}(后者渲染为纯居中文本,而非横幅)。
  • 破折号间距:首选 \textemdash{}(带显式括号)或 \,---\,,而非裸 —。裸破折号常导致周围空白塌陷。
  • \sectionlabel 内的颜色泄漏:\sectionlabel{... \textcolor{red}{...}} 会出错,因为 \MakeUppercase 将颜色名大写 → 未定义颜色错误。将 \textcolor 放在外部或定义带颜色的 \sectionlabel* 变体。
  • CJK + 数学:使用 xelatex 时,通过 \usepackage[fontset=fandol]{ctex} 或显式设置 EA 字体。中英混排标题需要 EA 字体提示,否则字符回退到拉丁字体。

阶段 3:PPTX 侧精修

首先应用字体缩放(阶段 3a),然后布局修复循环(阶段 3b)。缩放字体但不调整文本框会导致溢出。

阶段 3a:字体缩放(启发式表格)

使用 PPTX_SCALE_HINT 从 Beamer 参考计算目标尺寸。参考映射:

Beamer 磅值PPTX 目标角色
8 / 8.514-18 小型大写字母节标题
10 斜体14 斜体灰色斜体提示 / 备注
11 正文22-24项目符号、段落
12 页码16右下角灰色“N / 总数”(上限 16)
14 强调正文22-24较大子标题
16 标注内容24-28等式框 / 黄条正文
17-22 大数字28-36英雄数据(例如 “8.1k+”,漏斗 “8/6/2/1”)
22 帧标题40-44每页标题
28 强调英雄36-44英雄文本
42 封面字标80-100 纯黑封面(Why-RF 守则:不用颜色)

页码规则:永远不要将页码提升至超过 16pt。保持较小。

缩放后,务必重访阶段 1 分诊——1.6× 提示是起点;部分幻灯片需 1.5×,部分需 1.8×。

阶段 3b:文本框布局修复循环

字体增大后两种频发失效模式:

  1. 标题与副标题/正文重叠:100pt 的标题位于 0.95" 高的文本框内,但字形实际高度约 1.4",因此向下溢出。修复:增加文本框高度并重新定位下一元素的顶部。
  2. 正文项目符号在句中换行:一个长名词短语的项目符号换行时,最后一个名词孤零零出现在下一行,因为文本框宽度是按旧(较小)字体尺寸设置的。修复:拓宽文本框并缩窄相邻列。

每次逐页 Codex 调用返回具体的形状调整命令;使用检查器的 bbox 原语应用。

阶段 3c:常见 PPTX 陷阱(内联目录)

  • 图像宽高比:仅增大 width 而不改变 height 会拉伸嵌入的 PNG。始终计算 height = width × (image_height_px / image_width_px)。
  • 横幅应为真实的填充矩形:使用 tcolorbox 等效物(在 PPTX 中,为文本框背后的独立 MSO_SHAPE.RECTANGLE),而非仅着色的文本。
  • 曲线箭头:python-pptx 没有曲线箭头原语。用两个直线 MSO_CONNECTOR_TYPE.STRAIGHT 连接符(垂直 + 水平)近似,或使用 add_freeform 贝塞尔曲线。记录近似方法。
  • 斜体样式泄漏:源中未用括号包裹的 \itshape 会导致同一段落中所有后续文本运行继承斜体。用 {\itshape ...} 包裹或作用域限制在单个运行内。
  • 中文渲染:PowerPoint 需要东亚字体提示(macOS 为 <a:ea typeface="PingFang SC"/>,Windows 为 Microsoft YaHei)。否则字符回退到拉丁字体,显示为豆腐块。
  • 破折号间距:标题中裸 — 常导致空格塌陷。插入字面空格(" — ")或使用等宽空格。
  • 循环箭头 / 反馈环标签:确保标签 bbox 留在幻灯片边界内(L > 0.4in,T > 0.4in)。PPTX 会静默裁剪幻灯片外的内容,靠近左/上边缘的曲线标签是最常见的违规者。
  • 匿名占位符守则:所有用于审查中工作的占位符必须使用通用措辞(例如 “Withheld for anonymous review”、“[anonymized]”)。绝不推断或填入真实标题、统计数字或 URL。参见 ../shared-references/experiment-integrity.md。

阶段 4:验证 + 重新分诊

  1. 重新渲染 PPTX → PDF(LibreOffice 或用户导出)。
  2. 重新渲染 PDF → PNG 以用于视觉检查。
  3. 重新分诊:重新运行阶段 0.7 提示词。目标:0 BLOCKER,≤2 NEEDS-WORK。若仍 > 2 NEEDS-WORK,则循环回阶段 1 处理这些幻灯片。
  4. 演讲者备注完整性检查:断言每张幻灯片的 notes_slide 均存在且与 _pre_polish.pptx 相比未变(一轮精修绝不应触碰备注内容)。
  5. 匿名扫描:在最终 PPTX 中搜索已知敏感字符串(原始文件中不存在的真实作者姓名、LLM 添加的真实 URL、真实提交数量)。若发现,关闭并报告失败。
  6. 最终输出:<stem>_polished.pptx(以及渲染的 .pdf,若已生成)。

阶段 5:变更日志

编写 POLISH_CHANGELOG.md:

text
第 1 页 封面  | 字标 80→86;副标题 36→40;行距 0.9        | Codex 逐页审查
第 2 页 引子  | 左侧正文 L=0.45 W=8.30;右侧卡片 28→19pt;黄条 22→19 | 换行修复
第 3 页 …    | …                                                           | …

这使得每轮精修都可审计且可逆(每行映射到一个 _polished_v{i} 检查点)。

风格预设

预设仅影响默认颜色和元素库——参考 PDF 仍是视觉真相,而非预设。

generic(默认)

黑色 + 一种强调色(默认 #2563EB)。除单个承重中性背景外,无标注框填充。

why-rf(学术极简,示例预设)

锚点:一个 2025 年关于矫正流的学术演讲,遵循以下纪律。

元素BeamerPPTX(1.6× 提示)备注
帧标题\fontsize{22}{26}40-44pt 无衬线不加粗+ 全宽 0.55pt 强调色细下划线
正文11pt22-26ptCalibri / Helvetica Neue 等价
卡片标题(chorebox)11pt 加粗20-26pt 加粗在 chorebox 标注内
节标题8pt 小型大写字母16-18pt 小型大写字母宽字距颜色 = 主强调色
斜体灰色提示\scriptsize\itshape12-14pt 斜体颜色 = pagegray
页码\footnotesize14-16pt右下角灰色
封面标题44pt 纯黑80-100pt 纯黑标题不着色

颜色调色板(仅承重用,适量使用):

  • 主强调色(例如 #2E75B6)
  • 较深强调色(芯片背景、大数字,例如 #1F4E79)
  • 浅标注背景(例如 #DEEBF7)
  • 诚实披露黄(例如 #FFF4CC)
  • 审计缺陷红(仅安全声明,例如 #C00000)
  • 页码灰(例如 #808080)
  • 文本深色(例如 #1F1F1F)

元素库(适量使用):

  • chorebox:白色背景 + 顶部细强调色线 + 节标题 + 加粗标题 + 正文
  • eqbox:浅强调色全宽横幅;仅用于承重假设或结论
  • yellowstrip:诚实黄色 + 3pt 左边橙色线;仅用于诚实披露
  • redbox:浅红 + 红色边框;仅用于安全声明
  • banner:浅强调色全宽条;简短横幅说明

纪律:比典型“设计感”模板更少的彩色框。装饰性卡片变为纯项目符号;营销性修饰被去除。

neurips / icml / iclr / cvpr

继承 /paper-slides 的颜色方案。精修循环和字体缩放规则不变。

精细程度级别

完整合约见 ../shared-references/effort-contract.md。

effort行为
lite分诊遍历 + 仅修复 BLOCKER。跳过 NEEDS-WORK 幻灯片的逐页审查。约 30% 的完整 token 成本。
balanced(默认)分诊 + 对所有 NEEDS-WORK 和 BLOCKER 幻灯片进行逐页审查。