



























Render git-latexdiff between
any two commits of any LaTeX project, and browse the result — on pull requests,
via on-demand requests, and as a published, browsable web viewer. All the TeX
tooling ships in a prebuilt Docker image; you provide only your build instructions
(often none — it auto-detects).
Live demo: https://alpaylan.github.io/latex-diff-viewer-demo/ — pick two commits, view the rendered diff (added text blue + underlined, removed red + struck through), and click a changed page to jump straight to it. The demo repo is a tiny paper with a curated commit history (text edits, a table/float change, a section add).
Get PR diffs, on-demand diffs, and a browsable viewer — all in one file.
examples/consumer.yml to
.github/workflows/latex-diff.yml.difftool.toml. Skip it if your project is a single document
built with latexmk — the tool auto-detects the main .tex (the file with
\documentclass + \begin{document}). Otherwise:
main = "paper.tex" build_command = "make" # only if you don't use latexmk
latexdiff-store branch, set
Settings → Pages → Deploy from a branch → latexdiff-store / (root).That's it. Now:
| You do… | You get… |
|---|---|
| Open a PR | the base→head diff rendered in the viewer, linked from a PR comment |
Push to main |
recent commits' diffs + a current-draft full render, seeded into the viewer |
Open an issue latexdiff <base>..<head> |
that diff built on demand, with a viewer link |
The viewer (the latexdiff-store branch, served by Pages) shows all of them in one
place, with a clickable changed-pages index — automatically, no config.
PR comment (the diff renders in the viewer; the artifact is just a fork-PR fallback):
📄 LaTeX diff
✅ Built
a1b2c3d..e4f5a6b— 2 changed page(s).View the diff ↗ · or download the latex-diff artifact from the run.
Issue request — a single comment that transitions in place:
🔧 Building diff
v1..HEAD… Follow along in the workflow run ▸.
…then, when it's done (and the issue auto-closes):
📄 Built
v1..HEAD— 2 changed page(s). View it here:https://you.github.io/repo/?diff=v1..HEAD
Viewer on mobile — full-screen PDF (rendered with PDF.js so it works on iOS), with slide-in drawers:
┌──────────────────────────┐
│ ☰ Diffs Changes(2) │
├──────────────────────────┤
│ │
│ diff PDF (canvas) │
│ pinch · scroll │
│ │
│ [−][⤢][+] │
└──────────────────────────┘
☰ Diffs → picker + diffs/renders drawer
Changes(2) → drawer; tap a page to jump
PR ──────────┐ push ─────────┐ issue "latexdiff a..b" ──┐
▼ ▼ ▼
pr-diff.yml store-seed.yml issue-diff.yml
└──────── store-add / store-seed ──────────────┘
│ (append, idempotent, one concurrency group)
▼
latexdiff-store branch = manifest.json + PDFs + viewer
│ (served by GitHub Pages, branch source)
▼
browsable viewer · ?diff=a..b deep links
Everything appends to one store branch via the same idempotent store-add, so PR,
push, and on-demand diffs coexist in a single viewer. The changed-pages index is
float-aware: each change's page is recorded at shipout (via zref-abspage),
so a changed table or figure points to the page it actually lands on — not the
source line. (GitHub artifacts can't power a static viewer — they need auth and
expire — which is why the store lives in a branch.)
difftool.toml)All keys optional; a JSON difftool.json with the same keys also works.
| key | default | meaning |
|---|---|---|
main |
auto-detected, else main.tex |
Main LaTeX file. |
build_command |
latexmk -pdf -f -interaction=nonstopmode {main} |
Your full build. {main}/{build_dir}/{jobname} are substituted. |
build_dir |
(unset) | latexmk out_dir — set only if your latexmkrc writes the PDF into a subdir. |
output_pdf |
{build_dir}/{jobname}.pdf |
Where build_command leaves the PDF (auto-discovered if it differs). |
latexdiff_options |
[] |
Extra flags for git latexdiff (e.g. --add-to-config=VERBATIMLINEENV=code). |
untracked_assets |
[] |
Globs of gitignored files to mirror into checkouts (e.g. generated figures). |
pages_recent |
10 |
How many recent commits store-seed pre-builds on push. |
pages_pairs |
[] |
Pin specific base..compare diffs (overrides pages_recent). |
Point it at any repo — nothing to copy in:
git clone https://github.com/alpaylan/latex-diff-viewer && cd latex-diff-viewer PYTHONPATH=src python3 -m latexdiff_viewer.server --repo /path/to/your/paper # -> http://127.0.0.1:8765 (pick Base/Compare, Generate diff)
Or from the Docker image, against the current directory:
docker run --rm -it -p 8765:8765 -v "$PWD:/repo" -w /repo \
ghcr.io/alpaylan/latex-diff-viewer:v1 serve --host 0.0.0.0Needs python3, git-latexdiff, latexmk, and a LaTeX engine on PATH — or just
use the Docker image, which has them.
- uses: alpaylan/latex-diff-viewer@v1 with: { config: difftool.toml }
config, main/build_command/build_dir/latexdiff_options/assets
(overrides), base/head, full, comment, artifact_name, image.
Outputs: diff_pdf, full_pdf, changed_pages.pages.yml deploys a fresh
site via actions/deploy-pages (Pages source: GitHub Actions). Simpler, but no
on-demand requests, and it can't coexist with the store viewer (one Pages source
per repo).The Docker image's entrypoint (also python3 -m latexdiff_viewer.cli):
latex-diff-viewer build-diff --old A --new B -o out/diff.pdf # JSON + changed pages latex-diff-viewer build-full --commit HEAD -o out/full.pdf latex-diff-viewer store-add --old A --new B --store site # append a diff to a store latex-diff-viewer store-seed --store site # append recent diffs + a full render latex-diff-viewer serve --port 8765 # local interactive UI
docker build -t ldv:test .selftest.yml builds the image and exercises the CLI against a two-commit sample in
tests/sample-project/; docker-publish.yml pushes the image to GHCR on a v* tag.
This project's own code is MIT. The Docker image bundles git-latexdiff
(permissive/BSD), latexdiff and latexmk (GPL), and TeX Live (mixed), each under
its own license, unmodified — see THIRD-PARTY-NOTICES.md.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。