Skip to main content

首页 / Posts

[Zotero-pdf2zh] Quickly Translate PDFs While Preserving the Original Layout

A Zotero PDF translation guide based on zotero-pdf2zh and PDFMathTranslate Next, covering Python and Docker deployments, plugin configuration, formula and figure preservation, and bilingual reading.

Rosetears·
··2184 words·11 mins

Introduction
#

In academic research, reading foreign-language literature is normal, and a tool that preserves the original PDF layout during translation is extremely valuable. PDFMathTranslate Next, powered by BabelDOC, can provide accurate structure-preserving bilingual translation, making it a strong option for research papers.

The combination of Zotero + PDF2zh/PDF2zh_next has become an active and widely praised workflow. The Zotero-pdf2zh plugin has now moved to a simpler 3.x version. This guide walks through configuration and shows how to deploy the translation service with Python or Docker.

If you only want pdf2zh_next without the Zotero plugin, see PDF2zh 2.0: three deployment guides and Zotero plugin configuration. If Python deployment feels hard, jump to the Docker section. If even that feels troublesome, try Immersive Translate → common features → BabelDOC → log in → drag in the file → start translating.

Project links:

It is strongly recommended to watch the video together with this post: Zotero-pdf2zh PDF translation walkthrough


Environment requirements
#

  • Install Python 3.12 from python.org.
  • Zotero-pdf2zh currently supports Zotero 7 desktop; Zotero 8 adaptation is pending. Download Zotero from zotero.org.
  • Docker is optional and can be downloaded from Docker Desktop.
  • You need an OpenAI-compatible model service with API Key and Base URL.
  • Download the Zotero plugin .xpi from GitHub Releases, then drag it into Zotero under Tools → Plugins and restart if needed.

If network access is poor, the original post provides a Quark Netdisk mirror with extraction code 79Xd.


Part 1: Python deployment
#

Step 1: install uv
#

Install uv either through pip or the official install script. Check installation with uv --version. If it fails, the PATH probably has not taken effect; add uv’s install directory to PATH and restart the terminal.

Step 2: download and extract server files
#

Create a zotero-pdf2zh folder, download server.zip from the zotero-pdf2zh repository, extract it, and enter the server directory. The extracted directory contains server.py, requirements.txt, config/, translated/, doc/, and utils/.

Step 3: install dependencies and start the service
#

Before starting, confirm that Python, uv, or conda is available. If you are on a restricted network, test whether your mirror source is reachable.

You can start directly with python server.py, use the uv/conda warm-up scripts, or manually create virtual environments for pdf2zh_next 2.x and pdf2zh 1.x. Common parameters include disabling virtual-environment management, choosing conda, changing the port, disabling update checks, switching update sources, configuring mirrors, or using a Windows .exe path.

If you use a pdf2zh_next executable, start the service with --enable_winexe=True and pass the executable path.

Step 4: start translating
#

In Zotero, open Edit → Preferences → PDF2zh. Configure the translation engine, API Base URL, API Key, model name, concurrency, and QPS. Select a literature item in Zotero, right-click, and choose the relevant action.

Available actions include:

  • Translate PDF: generate translated PDF attachments.
  • Crop PDF: crop margins and split wide pages for smaller screens.
  • Compare PDF: create a side-by-side bilingual PDF.
  • Crop-Compare PDF: designed for two-column papers; crop into single columns first, then combine.

If the plugin cannot call the server, check that server.py is running, the port matches plugin settings, and firewall/security tools allow local access.


One-click startup scripts
#

First get the directory path containing server.py. Open a terminal in that folder and run a Python pathlib command to print the resolved parent path. Then choose the Windows .bat or macOS/Linux .sh template, replace PROJECT_PATH, save the script, and run it. On macOS/Linux, remember to give the .sh file execute permission with chmod +x.


Part 2: Docker deployment with Compose
#

If you want to use pdf2zh 1.x, jump to the optional switching section in the original workflow. Otherwise, use the default pdf2zh_next image.

  1. Verify Docker with docker version and docker compose version.
  2. Create a zotero-pdf2zh_docker directory, download docker.zip, extract it, and enter the docker subdirectory.
  3. Pull the core image first: awwaawwa/pdfmathtranslate-next:latest.
  4. Start with docker compose up -d --build.
  5. Use docker start, docker stop, docker logs -f, and docker compose down for daily management.

To switch to pdf2zh 1.x, change the image variable to byaidu/pdf2zh:1.9.6, replace the wrapper command from pdf2zh_next to pdf2zh, update docker-compose.yaml, rebuild, and select pdf2zh in the Zotero plugin.

If GitHub downloads are slow during image builds, either add a proxy prefix such as https://ghproxy.net/ or replace the server ZIP URL with a jsDelivr CDN URL, then rebuild without cache.


Part 3: connect Zotero
#

Whichever deployment you use, the final step is Zotero configuration:

  1. Open Edit → Preferences → PDF2zh.
  2. Make sure the service address matches the backend, usually http://localhost:8890 or the configured local address.
  3. Configure the translation engine, provider Base URL, API Key, and model.
  4. Return to the Zotero main interface, select one or more items, right-click, and start translation.

FAQ
#

Q1: The first translation stays at translate 10/100 for a long time.

Enable proxy/mirror acceleration for first-time resource downloads, or download a Windows release with bundled assets and trigger resource extraction through the Web UI.

Q2: Windows reports DLL initialization failure or missing runtime.

Install Microsoft Visual C++ 2015–2022 (x64).

Q3: Zotero shows no progress bar and tasks do not start.

Check Zotero-to-local-service connectivity, loopback address, proxy settings, and whether the plugin service address matches the backend port.

Q4: The server returns 401, 403, 404, 429, or endpoint unavailable.

Check Base URL, API Key, model name, rate limits, QPS, and concurrency.

Q5: How should I estimate threads or rate?

Use the provider’s RPM/TPM limits. A conservative starting point is QPS = floor(RPM / 60).

Q6: Which model service is recommended?

Free or trial services are good for entry-level use; Volcano Engine collaboration quotas, non-reasoning models, and cost-effective models such as deepseek-v3 or qwen-plus-latest are commonly useful. Machine-translation services are not recommended for BabelDOC workflows.

Q7: What if I cannot handle deployment at all?

Use Immersive Translate → common features → BabelDOC, log in, drag the file in, and start translating.

More help
#

Read the detailed FAQ, search or open GitHub Issues, or join the user QQ group 971960014 with verification github. When asking questions, include terminal error logs as text, Zotero plugin settings screenshots, error pop-up screenshots, and the problematic PDF when appropriate.

If this post helped, you can support Rosetears on Afdian. Thanks, and enjoy the workflow.

Preserved command, configuration, and prompt blocks
#

1
2
链接:https://pan.quark.cn/s/4242e66baf05?pwd=79Xd
提取码:79Xd
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 方法一(可选):用 pip 安装 uv
pip install uv

# 使用中科大镜像源
pip install -i https://mirrors.ustc.edu.cn/pypi/simple uv

# 方法二(推荐):使用官方独立安装脚本
# macOS / Linux(任选其一)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 或
wget -qO- https://astral.sh/uv/install.sh | sh

# Windows(PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
1
uv --version
1
2
3
4
5
# Windows PowerShell
$env:Path = "$env:USERPROFILE\.local\bin;$env:Path"

# macOS / Linux
export PATH="$HOME/.local/bin:$PATH"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 1. 创建并进入zotero-pdf2zh文件夹
mkdir zotero-pdf2zh && cd zotero-pdf2zh

# 2. 下载并解压server文件夹
# 如果server.zip下载失败, 可以直接访问: https://raw.githubusercontent.com/guaguastandup/zotero-pdf2zh/main/server.zip 手动下载
curl -L -o server.zip https://raw.githubusercontent.com/guaguastandup/zotero-pdf2zh/main/server.zip
REM 解压(任选一种;如命令行解压失败,可在资源管理器中右键解压到当前目录)
powershell -Command "Expand-Archive -Path '.\server.zip' -DestinationPath '.' -Force"
REM 或者(如果 tar 可用)
REM tar -xf server.zip

# 3. 进入server文件夹
cd server
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 1. 创建并进入zotero-pdf2zh文件夹
mkdir zotero-pdf2zh && cd zotero-pdf2zh

# 2. 下载并解压server文件夹
# 如果server.zip下载失败, 可以直接访问: https://raw.githubusercontent.com/guaguastandup/zotero-pdf2zh/main/server.zip 手动下载
curl -L -o server.zip https://raw.githubusercontent.com/guaguastandup/zotero-pdf2zh/main/server.zip
# 解压(任选其一)
unzip server.zip
# 或(若系统支持 bsdtar 解压 zip)
# tar -xf server.zip

# 3. 进入server文件夹
cd server
1
2
3
4
5
6
server.py
requirements.txt
config/
translated/
doc/
utils/
1
pip index versions pip -i https://mirrors.ustc.edu.cn/pypi/simple
1
2
3
pip install -r requirements.txt
# 若网络受限,可临时使用镜像(示例为中科大源):
# pip install -r requirements.txt -i https://mirrors.ustc.edu.cn/pypi/simple
1
python server.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 关闭虚拟环境管理
python server.py --enable_venv=False
# 切换虚拟环境管理工具为 conda
python server.py --env_tool=conda
# 切换端口
python server.py --port={Your Port Num}
# 关闭自动检查更新
python server.py --check_update=False
# 切换自动更新源为 gitee
python server.py --update_source="gitee"
# 关闭包安装时启用镜像(默认为中科大镜像源)
python server.py --enable_mirror=False
# 自定义镜像源(示例为清华源)
python server.py --mirror_source="https://pypi.tuna.tsinghua.edu.cn/simple/"
# 开启 Windows exe 安装模式;将 pdf2zh_next 可执行文件路径传入
#(例如 .\pdf2zh-v2.6.3-BabelDOC-v0.5.7-win64\pdf2zh\pdf2zh.exe)
python server.py --enable_winexe=True --winexe_path="xxxxxxx"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 1. 利用uv预热(首次安装)
# Windows用户:
.\install-with-uv.bat --warmup
# MacOS/Linux用户:
./install-with-uv.sh --warmup

# 预热后,您需要检查命令行中是否提示安装成功,如果安装失败,请不要进行下一步

# 2. 首次执行脚本
python server.py --skip_install=True

# install-with-uv.sh有三个选项:
# --warmup 对babeldoc的资源文件进行预热(需要一些时间)
# --upgrade 对当前包进行升级
# --no-mirror 不使用国内镜像源

# 3.以后执行版本
python server.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 1. 利用conda预热(首次安装)
# Windows用户:
.\install-with-conda.bat --warmup
# MacOS/Linux用户:
./install-with-conda.sh  --warmup

# 预热后,您需要检查命令行中是否提示安装成功,如果安装失败,请不要进行下一步

# 2. 首次执行脚本
python server.py --env_tool=conda --skip_install=True

# install-with-conda.sh有三个选项:
# --warmup 对babeldoc的资源文件进行预热(需要一些时间)
# --upgrade 对当前包进行升级
# --no-mirror 不使用国内镜像源

# 3.以后执行脚本
# 指定虚拟环境工具为conda
python server.py --env_tool=conda
1
2
3
4
5
6
:: 进入 server 目录
cd server
:: 1) 创建虚拟环境
uv venv zotero-pdf2zh-next-venv --python 3.12
:: 2) 安装依赖(使用镜像)
uv pip install --python .\zotero-pdf2zh-next-venv\Scripts\python.exe --index-url https://mirrors.ustc.edu.cn/pypi/simple pdf2zh_next pypdf PyMuPDF flask toml
1
2
3
4
# cmd
zotero-pdf2zh-next-venv\Scripts\activate
# powershell
.\zotero-pdf2zh-next-venv\Scripts\Activate.ps1
1
2
3
4
5
6
# 进入 server 目录
cd server
# 1) 创建虚拟环境
uv venv zotero-pdf2zh-next-venv --python 3.12
# 2) 安装依赖(使用镜像)
uv pip install --python ./zotero-pdf2zh-next-venv/bin/python --index-url https://mirrors.ustc.edu.cn/pypi/simple pdf2zh_next pypdf PyMuPDF flask toml
1
source ./zotero-pdf2zh-next-venv/bin/activate
1
2
3
4
5
6
# 进入 server 目录
cd server
# 1) 创建环境
conda create -n zotero-pdf2zh-next-venv python=3.12 -y
# 2) 安装依赖(使用镜像)
conda run -n zotero-pdf2zh-next-venv pip install --index-url https://mirrors.ustc.edu.cn/pypi/simple pdf2zh_next pypdf PyMuPDF flask toml
1
conda activate zotero-pdf2zh-next-venv
1
2
3
4
5
6
:: 进入 server 目录
cd server
:: 1) 创建虚拟环境(Python 3.12)
uv venv zotero-pdf2zh-venv --python 3.12
:: 2) 安装依赖(使用科大镜像)
uv pip install --python .\zotero-pdf2zh-venv\Scripts\python.exe --index-url https://mirrors.ustc.edu.cn/pypi/simple pdf2zh==1.9.11 pypdf PyMuPDF flask numpy==2.2.0 toml pdfminer.six==20250416
1
2
3
4
# cmd
zotero-pdf2zh-venv\Scripts\activate
# powershell
.\zotero-pdf2zh-venv\Scripts\Activate.ps1
1
2
3
4
5
6
7
# 进入 server 目录
# 进入 server 目录
cd server
# 1) 创建虚拟环境(Python 3.12)
uv venv zotero-pdf2zh-venv --python 3.12
# 2) 安装依赖(使用科大镜像)
uv pip install --python ./zotero-pdf2zh-venv/bin/python --index-url https://mirrors.ustc.edu.cn/pypi/simple pdf2zh==1.9.11 pypdf PyMuPDF flask numpy==2.2.0 toml pdfminer.six==20250416
1
source ./zotero-pdf2zh-venv/bin/activate
1
2
3
4
5
6
7
# 进入 server 目录
# 进入 server 目录
cd server
# 1) 创建环境
conda create -n zotero-pdf2zh-venv python=3.12 -y
# 2) 安装依赖(使用科大镜像)
conda run -n zotero-pdf2zh-venv pip install --index-url https://mirrors.ustc.edu.cn/pypi/simple pdf2zh==1.9.11 pypdf PyMuPDF flask numpy==2.2.0 toml pdfminer.six==20250416
1
conda activate zotero-pdf2zh-venv
1
python server.py --enable_winexe=True --winexe_path="Your\path\to\pdf2zh\pdf2zh.exe"
1
   python -c "import pathlib; print(pathlib.Path('server.py').resolve().parent)"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
     py -3 -c "import pathlib; print(pathlib.Path('server.py').resolve().parent)"
     ```

```bat
@echo off
chcp 65001 >nul
set PYTHONUTF8=1
rem  只需要修改下面这一行
set "PROJECT_PATH=这里替换成你的路径"
python "%PROJECT_PATH%\server.py"
pause
1
2
3
4
5
6
7
8
#!/usr/bin/env bash
set -euo pipefail
export PYTHONUTF8=1
# ← 只需要修改下面这一行
PROJECT_PATH="这里替换成你的路径"
cd "$PROJECT_PATH"
python3 server.py
read -rp $'完成。按 Enter 退出…' _
> @echo off
> chcp 65001 >nul
> set PYTHONUTF8=1
> rem ← 只需要修改下面这一行
> set "PROJECT_PATH=这里替换成你的路径"
> python "%PROJECT_PATH%\server.py"
> pause
> ```

```bash
docker version
docker compose version
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
mkdir zotero-pdf2zh_docker
cd zotero-pdf2zh_docker

REM 下载
curl -L -o docker.zip https://raw.githubusercontent.com/guaguastandup/zotero-pdf2zh/main/docker.zip

REM 解压(任选一种;如命令行解压失败,可在资源管理器中右键解压到当前目录)
powershell -Command "Expand-Archive -Path '.\docker.zip' -DestinationPath '.' -Force"
REM 或者(如果 tar 可用)
REM tar -xf docker.zip

REM 进入 docker 子目录(里面有 Dockerfile 和 docker-compose.yaml)
cd docker
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
mkdir -p zotero-pdf2zh_docker
cd zotero-pdf2zh_docker

# 下载
curl -L -o docker.zip https://raw.githubusercontent.com/guaguastandup/zotero-pdf2zh/main/docker.zip

# 解压(任选其一)
unzip docker.zip
# 或
# tar -xf docker.zip

# 进入 docker 子目录(里面有官方 Dockerfile 和 docker-compose.yaml)
cd docker
1
2
3
4
Dockerfile
docker-compose.yaml
config/         (空文件夹,用于挂载配置)
translated/     (空文件夹,用于挂载输出)
1
docker pull awwaawwa/pdfmathtranslate-next:latest
1
2
3
4
5
{

  "registry-mirrors": ["https://<your-mirror-endpoint>"]

}
1
docker compose up -d --build
1
2
* Running on http://[redacted-ip]:8890
* Running on http://[redacted-ip]:8890
1
2
3
4
docker start zotero-pdf2zh      # 启动已存在的容器
docker stop zotero-pdf2zh       # 停止容器
docker logs -f zotero-pdf2zh    # 查看实时日志,用于排查问题
docker compose down             # 停止并移除容器
1
docker pull byaidu/pdf2zh:1.9.6
1
ZOTERO_PDF2ZH_FROM_IMAGE=awwaawwa/pdfmathtranslate-next:latest
1
ZOTERO_PDF2ZH_FROM_IMAGE=byaidu/pdf2zh:1.9.6
1
2
3
4
5
6
7
RUN printf '%s\n' \
  '#!/usr/bin/env bash' \
  'set -euo pipefail' \
  'img="${ZOTERO_PDF2ZH_FROM_IMAGE:-awwaawwa/pdfmathtranslate-next:latest}"' \
  'cid="$(cat /etc/hostname)"' \
  'exec docker run --rm --volumes-from "${cid}" -e TZ -e http_proxy -e https_proxy -e HF_ENDPOINT "$img" pdf2zh_next "$@"' \
  > /usr/local/bin/pdf2zh_next && chmod +x /usr/local/bin/pdf2zh_next
1
2
3
4
5
6
7
RUN printf '%s\n' \
  '#!/usr/bin/env bash' \
  'set -euo pipefail' \
  'img="${ZOTERO_PDF2ZH_FROM_IMAGE:-byaidu/pdf2zh:1.9.6}"' \
  'cid="$(cat /etc/hostname)"' \
  'exec docker run --rm --volumes-from "${cid}" -e TZ -e http_proxy -e https_proxy -e HF_ENDPOINT "$img" pdf2zh "$@"' \
  > /usr/local/bin/pdf2zh && chmod +x /usr/local/bin/pdf2zh
1
ZOTERO_PDF2ZH_FROM_IMAGE: awwaawwa/pdfmathtranslate-next:latest
1
ZOTERO_PDF2ZH_FROM_IMAGE: byaidu/pdf2zh:1.9.6
1
2
3
4
5
volumes:
  - ./translated:/app/server/translated
  - ./config:/app/server/config
  - ./LXGWWenKai-Regular.ttf:/app/LXGWWenKai-Regular.ttf:ro   # 可选
  - /var/run/docker.sock:/var/run/docker.sock
1
2
docker compose down
docker compose up -d --build
1
2
3
4
docker start zotero-pdf2zh      # 启动已存在的容器
docker stop zotero-pdf2zh       # 停止容器
docker logs -f zotero-pdf2zh    # 查看实时日志,用于排查问题
docker compose down             # 停止并移除容器
1
2
3
4
5
   services:
     pdf2zh-server:
       build:
         args:
           GITHUB_PROXY_PREFIX: "https://ghproxy.net/"
1
2
   docker compose build --no-cache
   docker compose up -d
1
2
3
4
5
6
   services:
     pdf2zh-server:
       build:
         args:
           SERVER_ZIP_URL: "https://cdn.jsdelivr.net/gh/guaguastandup/zotero-pdf2zh@main/server.zip"
           # GITHUB_PROXY_PREFIX:  # 留空或注释
1
2
   docker compose build --no-cache
   docker compose up -d

Related tools

Related