Introduction¶
The philosophy of DSH is “everything is a plugin.” In agent development scenarios, document processing is a common requirement. The traditional approach is to copy PDF content, translate it, and then reformat it, which loses the layout details of the original document.
The mariomly/dsh-pdf-translate plugin solves this problem through a sidebar panel: after an English PDF is dropped in, it automatically generates a Chinese PDF and Markdown file while preserving the original layout. It is not simple OCR recognition, but parses the PDF structure, first measures the original parameters, and then reflows the content according to those parameters.
Core Features¶
- Sidebar “Translation” panel: Adds an entry below “Schedule” in the left sidebar, supporting drag-and-drop or click-to-select files.
- Layout preservation: Output files preserve the original margins, font sizes, line spacing, paragraph spacing, emphasis colors, and headers/footers.
- Multi-format output: Generates both a Chinese PDF and a Markdown file.
- Model tool integration: Registers the
pdf_translatemodel tool, allowing translation requests to be sent to the Agent directly in the conversation. - KaTeX formula rendering: Automatically restores mathematical formulas in PDFs to LaTeX and renders them with KaTeX.
- Object stream support: Supports parsing complex PDF structures such as object streams (
/ObjStm) and cross-reference streams.
Installation and Activation¶
To install this plugin, run the following command. The plugin automatically registers the service and panel entry, taking effect after restarting the desktop app or refreshing the page.
dsh plugin --profile web add <本目录>
After installation, a “Translation” entry appears in the left sidebar. The default output directory is D:\Translation. This path can be temporarily changed in the panel, or the default value can be changed directly in the defaultOutDir() function in lib/index.js.
Typical Usage¶
- Open the DSH panel and find the “Translation” entry in the left sidebar.
- Drag an English electronic PDF into the panel (or click to select a file).
- Wait for parsing, translation, and reflow (the duration depends on the file size and model speed).
- The results are saved under the
D:\Translationdirectory, with file names formatted as<原名>_中文版.pdfand<原名>_中文版.md. - In the conversation, you can also directly use the model tool
pdf_translatewith the Agent to translate the PDF in the current context.
Technical Implementation and Limitations¶
The plugin implements layout preservation through a five-step process: parse, measure layout, translate, reflow, and print.
| Stage | What it does |
|---|---|
| ① Parse | Uses a zero-dependency PDF parser to extract the text layer, positions, font sizes, and colors, and supports object streams and complex fonts. |
| ② Measure layout | Measures margins, font sizes at each level, line spacing, paragraph spacing, emphasis colors, and headers/footers, then splits the content into blocks such as headings, body text, and formulas. |
| ③ Translate | Restores formulas to LaTeX (they are often fragmented in PDFs), sends them to the model in batches for translation, and handles failure retries and follow-up questions for missing blocks. |
| ④ Reflow | Generates HTML using the measured parameters, renders formulas with KaTeX (for example, right-aligned \tag{}), and tries to match the page count of the original. |
| ⑤ Print | Generates the PDF through Edge’s CDP Page.printToPDF, follows @page rules, and uses the same paper as the original. |
Important limitations:
* Only electronic PDFs are supported: It only processes electronic PDFs with a text layer and does not support scanned PDFs (no OCR).
* English-to-Chinese only: Currently, it only supports translating English to Chinese and does not support specifying language pairs.
* Skin compatibility: The panel root node must set position: relative and must not add z-index; otherwise, under certain skins (such as maid-atelier), it may be obscured by the character art layer.
* Token dependency: It does not depend on --dsw-alias-* tokens, which do not exist during local testing.
Development and Self-Check¶
The plugin includes a verification script verify.mjs, covering 88 offline assertions to ensure consistent host/client contracts, correct client artifacts, and expected engine behavior. During development, you can run the following commands for a self-check:
pnpm install
pnpm run typecheck # tsc --noEmit
pnpm run build # tsdown 构建客户端 + 包成 ModuleLoader 工厂
node verify.mjs # 执行断言检查
The verification script automatically checks whether formulas are rendered correctly, whether the page count can be read from object-stream PDFs, and whether model stalls are interrupted by timeouts, among other things. In addition, tools/engine-render.mjs can run the entire process completely independently of DSH, allowing the layout to be validated in isolation.
The KaTeX library is bundled as an offline dependency in the lib/vendor/katex/ directory. The package.json in that directory declares commonjs, and the "type": "module" setting in the plugin root directory ensures that Node does not treat UMD as ESM when loading, preventing this from being undefined and causing formula rendering to fail.
Conclusion¶
This plugin provides an efficient document translation solution for the DSH ecosystem, suitable for developers who frequently process English documents and need to preserve the original layout. The source code and details are available at GitHub.