# Bilingual Paper Translator

> Create bilingual versions of research papers as interleaved HTML and paginated PDF, translating the original text into a selected target language with one whole-paper model context while preserving formulas, figures, tables, references, and links. Use when the user provides an arXiv title, ID, or URL; a DOI or official paper page; a direct PDF URL; a local PDF; or local HTML. Prefer arXiv HTML, then arXiv TeX, then the official PDF; convert other PDFs to HTML with Docling. The target language defaults to Simplified Chinese.

- Skill: `yelloworz/bilingual-paper-translator` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add yelloworz/bilingual-paper-translator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yelloworz/bilingual-paper-translator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: YellowOrz (https://skillmd.com/u/yelloworz)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/yelloworz/bilingual-paper-translator

---


# Create a bilingual research paper

Produce both `bilingual.html` and a conventionally paginated `bilingual.pdf`. Preserve the original language and insert each target-language block immediately after its source block. Use the host agent's current model for translation; do not call sentence-level translation services.

## Runtime

Use the shared Python environment in [`references/python-environment.md`](references/python-environment.md). In the commands below, `PYTHON` means that environment's interpreter command, not an environment variable. The renderer additionally needs Node.js, Playwright/Chromium, and Poppler. Install missing dependencies only with user approval.

## Workflow

1. Create one temporary job directory outside this skill directory. Keep every acquisition, translation, rendering, and intermediate file for this paper in that directory.

2. Acquire and normalize exactly one paper:

   ```text
   PYTHON scripts/paper_pipeline.py acquire INPUT -o JOB_DIR
   ```

   `INPUT` may be an existing local PDF or HTML file, an arXiv title/ID/URL, a DOI, an official paper page, or a direct PDF URL. A path-like input that does not exist is an error. Other URL schemes and unsupported local formats are errors.

   Explicit PDFs are processed directly and never replaced by a guessed arXiv source. DOI and official-page inputs follow redirects and use only one unambiguous PDF link; do not automate a browser, execute page JavaScript, guess private endpoints, or bypass login, consent, CAPTCHA, or paywalls. A downloaded PDF must have a `%PDF-` header. Other PDFs are converted to HTML with Docling; do not add a second OCR fallback.

   A plain title searches only the official arXiv API. The arXiv route has a strict priority: official HTML; otherwise downloadable TeX source, safe merge, and Docling; otherwise the official PDF only when TeX is absent. Never use a third-party mirror. If downloaded TeX cannot be merged or converted, stop instead of hiding the failure with a PDF fallback.

   Local HTML is copied to `JOB_DIR/source.html`. Local relative resources must remain inside the input HTML directory tree; path traversal, missing files, and empty files are fatal. Remote static resources are localized. Scripts are not executed. External hyperlinks remain external.

   Acquisition creates `metadata.json` and a redacted `pipeline.log`, records the actual source route and quality metrics, and rejects invalid/near-empty normalized HTML. Review any quality warnings before translation.

   Immediately rename the acquired job directory and use the printed path as `JOB_DIR` for every later step:

   ```text
   PYTHON scripts/paper_pipeline.py organize JOB_DIR [--short-name SHORT_NAME]
   ```

   Pass `--short-name` when the paper has a known abbreviation or short title; prefer it to the full title. Otherwise the command uses an explicit abbreviation in the detected title, then the full detected title. It replaces characters forbidden by common filesystems (including Windows `:`, `<`, `>`, `"`, `/`, `\`, `|`, `?`, and `*`), avoids Windows reserved device names and trailing dots/spaces, and limits the UTF-8 name length. If no reliable title is detected, stop and ask the user for `SHORT_NAME`. Do not continue translation in the temporary directory.

3. Extract the translation manifest:

   ```text
   PYTHON scripts/paper_pipeline.py prepare JOB_DIR/source.html -o JOB_DIR
   ```

   Add `--target-language LANGUAGE` when needed; the default is `Simplified Chinese`. A user-supplied source-language statement is translation guidance, but no source language is assumed. If the source already appears to be the target language, ask the user to confirm.

   Optional switches are `--translate-figures`, `--translate-tables`, `--translate-equations`, and `--translate-references`; all default to off. Captions are always included. Disabled content must be absent from `segments.json`, not sent to the model for unchanged output. These switches affect exposed HTML text only; never OCR, overwrite, or redraw text inside bitmap images. Protected markup appears as `⟦KEEP_nnnn⟧`.

4. Read all of `JOB_DIR/segments.json` before translating. Translate every `source` naturally into the recorded target language in one whole-paper model context. Preserve every `id` and every protected token exactly once in the proper semantic position. Return plain text, never HTML, in UTF-8 `JOB_DIR/translations.json`:

   ```json
   {
     "translations": [
       {"id": "t00001", "translation": "Translation in the target language"}
     ]
   }
   ```

   JSON string values must not contain unescaped ASCII double quotes `"` (U+0022). Use Unicode curly quotes `"` (U+201C) / `"` (U+201D) for quoted terms in the translation text, or escape as `\"` when an ASCII double quote is genuinely needed.

   Do not silently split a paper into independent translation calls. If the complete manifest exceeds the current model context, stop and explain that this run cannot satisfy the whole-paper-context requirement.

5. Build the interleaved HTML:

   ```text
   PYTHON scripts/paper_pipeline.py build JOB_DIR/segments.json JOB_DIR/translations.json -o JOB_DIR/bilingual.html
   ```

   The builder rejects missing or extra IDs, changed protected tokens, and model-generated HTML. Original blocks remain untouched and skipped content remains once in its original location.

6. Render the paginated PDF:

   ```text
   node scripts/render_continuous_pdf.cjs JOB_DIR/bilingual.html JOB_DIR/bilingual.pdf
   ```

   The renderer defaults to A4 and 10pt text and creates bookmarks from `h1`–`h6`. It accepts `--paper-size Letter`, `--margin-mm N`, and `--font-size N`.

7. Verify both deliverables. Use `pdfinfo`, render representative first/middle/last pages with `pdftoppm`, and inspect pages containing formulas, figures, and tables. Confirm resources exist and are nonempty, same-paper anchors resolve, every translation ID is present, captions are bilingual, target-language fonts render, and PDF page size, pagination, and bookmarks are correct.

Deliver both `bilingual.html` and `bilingual.pdf` from the paper-named `JOB_DIR`. Keep all acquisition, translation, rendering, and intermediate files together there unless the user asks to remove them.

