Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

All notable changes to this project will be documented in this file.

## [Unreleased]

### Added
- **`olcli diff --latexdiff` marks the revision up inside the document** ([#55](https://github.com/aloth/olcli/issues/55)) - the follow-up left open when the core `diff` command shipped in 0.10.0. A unified diff is the right artifact for a developer and the wrong one for a thesis advisor, who expects deletions struck through and additions underlined. It runs on the two sides `diff` has already fetched, so the markup describes exactly what the patch output does - struck through is what a push would overwrite, underlined is what it would upload - and costs no extra request
- Requires `latexdiff` on PATH, which ships with TeX Live and MacTeX. A missing binary is reported as a setup problem with the install command for the platform, not as a failure of `diff`; nothing else in the command needs an external tool
- `\input` and `\include` are inlined before comparing, with `--no-flatten` to opt out. Without it a remote compile resolves those against the files in the project - the *old* content - and produces a PDF marking up the root document while showing every input file as unchanged. Wrong in a way that is very hard to notice
- Output goes to `.olcli-diff/`, dotted because `scanLocalFiles` skips dotted entries before any ignore rule is consulted. A plain `main-diff.tex` next to the document would be uploaded to Overleaf by the next `push`
- The root document is the `.tex` file declaring `\documentclass`. Several candidates are reported and listed rather than resolved by preferring `main.tex`: marking up the wrong document produces a plausible PDF describing the wrong revision
- `--latexdiff-opt` passes options straight through (`--latexdiff-opt --math-markup=0`), since the remote tree is on disk only for the duration of the run and cannot be handed to `latexdiff` by hand afterwards
- **`--pdf` compiles the marked-up document on Overleaf**, so a reviewable PDF needs no local TeX installation - the reason the flag was proposed in [#45](https://github.com/aloth/olcli/issues/45)
- Overleaf's compile endpoint takes a path that must already be in the project; there is no way to compile a document that is not. So the markup is uploaded as `olcli-latexdiff.tex` next to the root document, compiled, downloaded, and removed. That is a real mutation of the project for the duration of one compile, and the command says so before it does it
- It refuses rather than overwrites if a file of that name already exists, deletes from a `finally` with nothing in between able to terminate the process first, and prints the exact `olcli rm` command if the delete itself fails or the run is interrupted
- Placed next to the root document rather than at the project root, so relative `\includegraphics` and `\bibliography` paths resolve exactly as they do for the document it was built from
- A compile failure writes the CLSI log next to the marked-up source instead of reporting only a status, and deletes a PDF left by an earlier run rather than leaving one that describes a different revision. The compile runs against the project, so a `.sty` or `.cls` that exists only locally is the usual cause and the message says so. A missing *figure* is not: Overleaf draws a placeholder box naming the file and still reports success
- **`src/latexdiff.ts`** - root document detection, argument construction, output naming and failure interpretation are functions over data, unit-tested with no Overleaf account and no `latexdiff` binary. 21 tests, in the suite CI already runs

## [0.12.0] - 2026-09-06

### Added
Expand Down
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Work with Overleaf projects directly from your command line. Edit locally with y
- ⬆️ **Push** local changes back to Overleaf
- 🔄 **Sync** bidirectionally with smart conflict detection
- 🔍 **Diff** local files against the live remote before pushing
- 📝 **Marked-up revisions** — `diff --latexdiff` produces the struck-through/underlined PDF advisors and journals ask for
- 🔀 **Git remote** — use Overleaf as a native git remote ([docs](docs/GIT-REMOTE.md))
- ✌️ **Two-way deletions** — files removed locally are deleted on Overleaf on next sync
- 🗑️ **Delete** and ✏️ **rename** remote files by path
Expand Down Expand Up @@ -240,6 +241,46 @@ than the last pull, because that is what `push` uploads; `diff` lists files
whose **contents** actually differ. A file you touched without editing appears
in the first and not the second.

#### Marked-up revisions with latexdiff

A unified diff is the right artifact for a developer and the wrong one for a
thesis advisor. `--latexdiff` marks the same revision up inside the document
instead — deletions struck through, additions underlined — which is what
advisors and journals ask for.

```bash
olcli diff --latexdiff # write .olcli-diff/main-diff.tex
olcli diff --latexdiff --pdf # ...and compile it, download .olcli-diff/main-diff.pdf
```

Requires `latexdiff` on your PATH. It ships with TeX Live and MacTeX; nothing
else in `olcli diff` needs an external tool.

**`--pdf` compiles on Overleaf, so you do not need a local TeX installation.**
The compile endpoint can only build a file that is in the project, so the
marked-up document is uploaded as `olcli-latexdiff.tex` next to your root
document, compiled, downloaded, and then removed. The command says so before it
does it, refuses to overwrite a file of that name if one already exists, and
prints the exact `olcli rm` command if the cleanup itself fails.

`\input` and `\include` are inlined before comparing (`--no-flatten` to opt
out). Without that, a remote compile would resolve those against the files
sitting in the project — the old content — and quietly produce a PDF showing
every input file as unchanged.

Output goes to `.olcli-diff/`, which is dotted so that `push` and `sync` never
pick it up; `-o <path>` puts it elsewhere. The root document is the `.tex` file
declaring `\documentclass`; if several do, `--main <path>` picks one rather
than the command guessing. `--latexdiff-opt` passes anything else straight
through, e.g. `--latexdiff-opt --math-markup=0`.

One limit worth knowing: `--pdf` compiles against the project, not against your
working directory, so anything the markup needs must already be on Overleaf. A
`.sty` or `.cls` you added locally fails the compile — the compiler log is
written next to the marked-up source when that happens. A *figure* you added
locally does not fail it; Overleaf draws a placeholder box naming the missing
file and the rest of the PDF is fine.

#### How deletion propagation works

`olcli` records a manifest of remote files in `.olcli.json`. On next sync:
Expand Down
9 changes: 8 additions & 1 deletion docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,13 @@ Which files need an Overleaf account to exercise, and which do not. This is the
main thing to know before adding a feature, because it decides where the logic
should go.

**Pure — data in, data out. No network, no filesystem, unit-tested:**
**Needs no Overleaf account, so unit-tested directly. Data in, data out;
`scan.ts` and `latexdiff.ts` also touch the local filesystem:**

| Module | Responsibility |
|---|---|
| `diff.ts` | Compare two file trees; render unified diffs |
| `latexdiff.ts` | Root document detection; build and run the `latexdiff` command |
| `ignore.ts` | The three ignore layers and the `.pdf`-next-to-`.tex` rule |
| `paths.ts` | Remote path normalization; zip-slip containment |
| `rename-plan.ts` | Plan bulk project renames before applying any |
Expand Down Expand Up @@ -147,6 +149,11 @@ exists at all: `push` and `sync` each carried their own copy of the same walk
loop and had already drifted apart, and `diff` would have made a third. The
same reasoning produced `rename-plan.ts` and `diff.ts`.

`latexdiff.ts` is the one module that shells out to something olcli does not
ship. That is confined to a single `execFile` call with an argv array — never a
shell — and a missing binary is reported as a setup problem with a fix rather
than as a failure of the command.

`client.ts` request *construction* can also be tested without an account, by
pointing the client at a local HTTP server that captures the outgoing request —
see `test/client.test.ts`.
Expand Down
Loading
Loading