Files
claude/skills/pdf-translate/SKILL.md
T

7.4 KiB

name, description
name description
pdf-translate Use when translating a PDF (especially OCR or image-based) to another language and producing faithful HTML output. Handles image extraction, layout preservation, contextual translation, and style-matched reconstruction. Triggers on "translate this PDF", "PDF en francais", "convert PDF to HTML translated", "traduire ce document".

PDF Translate

Translate a PDF into another language and produce an HTML document that preserves the original layout, images, and visual style. Optimized for OCR/image-based PDFs where the text layer is unreliable.

Pipeline

digraph pipeline {
  rankdir=LR;
  PDF [shape=folder];
  Images [shape=box, label="Page PNGs\n+ embedded images"];
  Analysis [shape=box, label="Claude Vision\nread + translate\n+ layout map"];
  HTML [shape=box, label="Faithful HTML\n/design-html"];
  QA [shape=diamond, label="Visual QA\nPDF vs HTML"];

  PDF -> Images [label="STEP 1"];
  Images -> Analysis [label="STEP 2-3"];
  Analysis -> HTML [label="STEP 4"];
  HTML -> QA [label="STEP 5"];
  QA -> Analysis [label="fix", style=dashed];
}

STEP 0: Dependencies

Check before starting. Install what's missing.

# Option A: poppler (lighter)
command -v pdftoppm && echo "OK" || echo "INSTALL: sudo apt install poppler-utils"

# Option B: PyMuPDF (more powerful — extracts embedded images with coordinates)
python3 -c "import fitz; print('OK')" 2>/dev/null || echo "INSTALL: pip install pymupdf"

Prefer PyMuPDF if both available — it extracts embedded images + gives page dimensions.

STEP 1: PDF → Page Images + Embedded Assets

# Create working directory
mkdir -p pdf-translate-work/{pages,assets}

# Convert pages to high-res PNGs
pdftoppm -png -r 300 input.pdf pdf-translate-work/pages/page
# OR with PyMuPDF:
python3 -c "
import fitz
doc = fitz.open('input.pdf')
for i, page in enumerate(doc):
    pix = page.get_pixmap(dpi=300)
    pix.save(f'pdf-translate-work/pages/page-{i+1:03d}.png')
    for img_idx, img in enumerate(page.get_images(full=True)):
        xref = img[0]
        base = doc.extract_image(xref)
        with open(f'pdf-translate-work/assets/img-p{i+1}-{img_idx+1}.{base[\"ext\"]}', 'wb') as f:
            f.write(base['image'])
"

STEP 2: First Pass — Style Analysis

Read page 1 (and optionally 2-3 more) with Claude Vision. Extract:

  • Typography: font style (serif/sans), heading sizes, body size, weight
  • Colors: background, text, accent, header colors
  • Layout: single/multi column, margins, header/footer pattern
  • Spacing: line height, paragraph gaps, section gaps
  • Special elements: callout boxes, sidebars, tables, captions, footnotes

Output a style brief — this feeds into STEP 4.

STEP 3: Page-by-Page Read + Translate

For each page image, use Claude Vision (Read tool on PNG):

  1. Read the text content from the image (ignore OCR text layer)
  2. Map layout: identify text blocks, headings, images, tables, their relative positions
  3. Translate to target language preserving:
    • Register and tone (formal/informal/technical)
    • Technical terms (keep original in parentheses on first occurrence if ambiguous)
    • Sentence structure adapted to target language (not word-for-word)
  4. Note image references: what each image shows, where it sits relative to text

Cross-page context

Maintain a running glossary of translated terms across pages. If page 1 translates "stakeholder" as "partie prenante", every subsequent page must use the same term.

Output per page:

## Page N

### Layout
[column structure, image positions]

### Content (translated)
[translated text with markdown structure]

### Images
- img-pN-1.png: [description], position: [top-right / inline / full-width]

STEP 4: HTML Reconstruction

Invoke /design-html (or /frontend-design) with:

  1. The style brief from STEP 2
  2. All translated page content from STEP 3
  3. Extracted images from pdf-translate-work/assets/

Requirements for the HTML:

  • Single self-contained HTML file (inline CSS, base64 images or relative paths)
  • Match original typography feel (use closest web-safe or Google Font)
  • Preserve column layout, spacing, color scheme
  • Images at original positions with proper sizing
  • Print-friendly: @media print styles, page breaks where original had them
  • Responsive: readable on screen, faithful on print

STEP 5: Visual QA

Compare original PDF and translated HTML side by side:

  1. Read a few pages of the original PDF (Read tool, pages parameter)
  2. Take screenshot of the HTML (if /browse available)
  3. Check: layout match, no missing content, images present, style fidelity
  4. Fix discrepancies → iterate STEP 4

Failure modes

Trigger First move If still stuck
STEP 0: neither poppler nor PyMuPDF present, install fails (no sudo / no pip) Print BOTH install commands, ask the user to run one STOP. No degraded no-image path — the pipeline is image-based by design
STEP 1: PDF > 30 pages (check pdfinfo input.pdf | grep Pages first) Ask before converting: batch by section, or draft pass at -r 150 User declines both → STOP, oversized one-shot runs produce GB of PNGs and stall Vision
STEP 1: extraction yields 0 page PNGs or 0-byte files Retry with the other tool (poppler ↔ PyMuPDF) STOP and report the PDF as unreadable (encrypted/corrupt) — never translate from the text layer as a silent fallback
STEP 3: region unreadable (blur, handwriting, tiny footnote) Mark [illisible: <best guess>?] inline + add to an UNCERTAIN list per page Leave the marker in the HTML; STEP 5 QA re-reads every UNCERTAIN item at higher zoom. Never invent clean text
STEP 4: /design-html and /frontend-design unavailable Write the HTML directly from the STEP 2 style brief + STEP 3 content (same requirements list) —
STEP 5: no /browse / screenshot tool QA on structure instead: compare HTML section order + image refs against STEP 3 layout maps Report "visual QA skipped — structural QA only" in the final summary
STEP 5: QA still finds discrepancies after 2 fix iterations Stop iterating; list residual differences for the user User decides: accept, or target specific pages for a 3rd pass
pdf-translate-work/ already exists Ask: resume (keep PNGs, redo STEP ≥3) or clean restart —

Decision: OCR vs Native PDF

digraph ocr_check {
  Check [shape=diamond, label="Does PDF have\nreliable text layer?"];
  Native [shape=box, label="Can use marker\n+ Claude translate"];
  OCR [shape=box, label="Use Vision pipeline\n(this skill)"];
  Test [shape=box, label="Copy text from PDF.\nGarbled or missing?"];

  Check -> Test [label="unsure"];
  Test -> OCR [label="yes"];
  Test -> Native [label="no, text is clean"];
  Check -> Native [label="native PDF"];
  Check -> OCR [label="scanned/OCR"];
}

If the PDF has a clean text layer, marker (pip install marker-pdf) is faster. This skill's Vision pipeline is for when the text layer is unreliable.

Common Mistakes

Mistake Fix
Using OCR text layer from scanned PDF Read page images with Vision instead
Translating page-by-page without glossary Maintain cross-page term consistency
Generic HTML that doesn't match original style Extract style brief first (STEP 2)
Word-for-word translation Adapt sentence structure to target language
Forgetting prefers-reduced-motion or print styles Include in HTML output
Images as decoration only Preserve original placement and sizing