Skip to content

[Feature] olcli diff --latexdiff and --pdf: marked-up revision output for review #55

Description

@Waynting

Follow-up to #45, which you closed with latexdiff support "deliberately left out of that PR and still open as follow-up work". Nothing is tracking it, so here is the issue for it, with the design questions I would rather settle here than in review of finished code.

I am happy to implement it.

What it is for

The use case from #45 that you said convinced you: a student revises a thesis locally and has to show an advisor what changed. olcli diff answers that for someone who reads unified diffs. It does not produce the artifact an advisor or a journal actually asks for, which is a marked-up PDF — deletions struck through, additions underlined.

latexdiff is the standard tool for that and it is already installed anywhere TeX Live is. What is missing is the two things a user cannot easily do by hand: getting the remote side of the comparison onto disk, and compiling the result without a local TeX installation.

Proposed surface

olcli diff --latexdiff          # write a marked-up .tex
olcli diff --latexdiff --pdf    # ...and compile it on Overleaf, download the PDF

Both reuse the existing diff machinery unchanged: same single-request project fetch, same ignore filtering on both sides, same "remote is fetched fresh" semantics. The old side of the latexdiff run is the remote as of that fetch, the new side is the working directory, so the markup reads in the same direction as the patch output does today — struck-through text is what a push would overwrite, underlined text is what it would upload.

Supporting flags: --main <path> for the root document, -o/--output <path>, --no-flatten.

The five decisions worth settling first

1. --pdf cannot compile without writing to the project. This is the one I would most like your call on. The compile endpoint takes rootResourcePath, a path that must already exist in the project — there is no "compile this blob" API. So a remote compile means uploading the marked-up file, compiling it, downloading output.pdf and deleting it again.

That is a mutation of the user's project for the duration of one compile: it appears in project history, and a collaborator watching the file tree sees it appear and vanish. Three options:

  • Temp file in the project, cleaned up in a finally. One extra request each way, all other assets (.cls, .bib, figures) are already there. Cost: the mutation above, plus a stray file if the process is killed between upload and delete.
  • A scratch project, created and deleted per run. No mutation of the real project, but it means uploading the whole tree file by file, and a failed cleanup leaves a whole project behind rather than one file.
  • Local compile via latexmk. No network at all, but it gives up the thing that made --pdf worth having in [Feature] olcli diff — preview content-level changes before push #45 — that users without a local TeX installation still get a PDF.

I lean to the first, with the file named olcli-latexdiff.tex, placed next to the root document so relative \includegraphics paths still resolve, refused rather than clobbered if that path already exists, and deleted in a finally with the exact olcli rm command printed if the delete itself fails. The command would say what it is about to do before it does it.

2. --flatten on by default, --no-flatten to opt out. Without it the marked-up file still contains \input{sections/intro}, and a remote compile then resolves those against the files in the project — the old content — so a multi-file thesis would silently produce a PDF that marks up the root document and shows every input file unchanged. Flattening is what makes the output honest, and it also makes the .tex self-contained enough to compile anywhere.

latexdiff --flatten resolves \input relative to each side's own file, verified locally, so pointing it at the extracted remote tree and the working directory does the right thing with no cwd juggling.

3. Where the output goes: .olcli-diff/ inside the target directory. main-diff.tex is a .tex file in the project directory, so the obvious default would put a file into the working tree that push then uploads to Overleaf on the next run. scanLocalFiles skips dotted entries unconditionally, before any ignore rule, so a hidden directory is the one place output cannot leak into a push. -o overrides for anyone who wants it elsewhere.

4. Root document detection. --main wins; otherwise the .tex files containing an uncommented \documentclass are the candidates. One candidate is used, several ask for --main and list them, none is an error. If the root document is local-only, there is no old side and the command says so rather than diffing against an empty file.

5. Limits stated, not hidden. A figure added locally is not on the remote, so a --pdf compile of a document referencing it fails there — the CLSI log comes back and should be surfaced rather than turned into "compilation failed". latexdiff missing from PATH is a clear message naming how to install it, not a stack trace; the rest of olcli diff needs no external tools and keeps working.

Structure

src/latexdiff.ts, with root-document detection, argument construction, output naming and failure interpretation as pure functions over data, unit-tested with no account and no network — same shape as diff.ts and rename-plan.ts. The latexdiff spawn and the upload/compile/delete sequence stay in cli.ts with the rest of the IO. No new npm dependency.

--exit-code, the other follow-up from #48, stays out of this one.

Does the shape look right, and which way do you want #1 to go?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions