Repository navigation
Releases: Mangluu/overleaf-comments-export
Release list
v0.22.3, self-hosted links just work, and no more project zip
If you use a self-hosted Overleaf, you no longer need --base-url. The tool now talks to the server your project link names. Before this, unless you also passed --base-url, every request went to overleaf.com, where your project does not exist. The window did the same whenever its self-hosted box was unticked.
The whole project is no longer downloaded just to learn file names. When Overleaf did not list the files, the tool fetched the project zip and matched each document by its contents. On a paper with large figures that meant hundreds of megabytes for a few names. Each file's own download now names it, the way the browser extension does.
Also fixed
- A comment holding a control character, which text pasted from Word can carry, no longer stops the whole export when the spreadsheet is ticked.
- One comment can no longer leave the page you send to co-authors blank.
- On Windows, a reviewer named Con, Aux or Nul no longer breaks the one-file-per-reviewer reports.
The Windows and Linux apps attached below include all of this.
pip install --upgrade "overleaf-comments-export[all]"
v0.22.2, papers split across files are numbered through again
If you export a paper split across several files, run it again. Figure numbers and sections are right again.
The tool puts a multi-file paper in the order LaTeX reads it, so figures are numbered straight through and a comment in an included file gets the section it sits under. To do that it needs to know which file is the root, and it learned that from a tag on the Overleaf editor page. overleaf.com stopped sending that tag, so the order quietly stopped running. A comment on the third figure in a paper came back as Figure 1.
The tool now works out the root itself. It reads the paper's .tex files and picks the one that is a whole document on its own. Figures built with standalone and chapters built with subfiles are left out, and when two files tie, no order is claimed, because no number is better than the wrong one.
Also new in this release
- A spreadsheet.
--xlsx, or A spreadsheet in the window, writescomments.xlsxwith comments, replies and tracked changes on three sheets. - A page to send a co-author.
--html, or A page to send in the window, writes one self-containedcomments.htmlwith search and filters. It works offline. - Recent papers in the window. Choosing one fills in the link and the folder it went to.
The Windows and Linux apps attached below have spreadsheet support built in.
pip install --upgrade "overleaf-comments-export[all]"
v0.22.1 — a comment on a position is not a stale anchor
If your export said a lot of comments were stale, it was probably wrong.
Overleaf lets a comment attach to a point in the document rather than to a selection, and sends those with no anchored text. The check that decides whether an anchor is stale works by looking for its text, and both of its searches need text to look for, so an anchor with none fell straight through to "stale".
Nothing had moved. There was simply nothing to check.
On a real paper this flagged 74 of 131 comments as pointing at text that had changed when not one of them had, and wrote stale_anchor_count: 74 into the front matter. The Markdown printed ⚠ stale and _(empty anchor)_ on the same line, which is the contradiction that gave it away.
False alarms at that rate bury the anchors that genuinely have moved, which is the only reason the flag exists. Those are still reported.
Re-run any export where the stale count looked high and it should drop to the real number.
pip install --upgrade "overleaf-comments-export[gui,pdf]"
v0.22.0 — multi-file papers read in document order
If your paper is split across files, this fixes the worst thing the tool did.
Figure and table numbers restarted in every file, so a comment on Figure 2 was reported as Figure 1. Everything else imperfect in this tool produces nothing; that one produced a confident wrong answer and sent people to look at the wrong figure.
A comment in an included file also came back with no section at all, because \section{Results} sits in main.tex while the prose it names sits in results-body.tex.
Both came from the same cause: every file was read on its own, and LaTeX does not read them that way.
The project is now spliced into the single document LaTeX reads, following \input, \include and \subfile from the root document, with headings and float counters worked out across the whole thing. Files carrying no comments are fetched too, because a figure in one decides what number the next one gets.
Inclusion is handled at the point it happens rather than file by file. A file pulled in halfway through the root inherits only the headings above that point, and its content sits before everything below it.
If an included file cannot be read, no figure number is claimed at all and the export tells you. A missing number sends nobody anywhere; a wrong one sends them to the wrong figure.
Single-file papers are unaffected and fetch nothing extra.
pip install --upgrade "overleaf-comments-export[gui,pdf]"
v0.21.3 — undo the crash 0.21.2 introduced
If you are on 0.21.2, update. It crashed the window when you clicked Choose….
0.21.2 tried to stop the folder picker opening behind the window. It attached the picker to the window with parent=, which on macOS presents it as a sheet rather than a free-standing panel, and toggled -topmost around the call. The app then died with
NSInternalInconsistencyException: 'cannot run nil sheetWindow'
Both halves are gone. What remains is lifting and focusing the window, which are ordinary Tk calls that cannot fail that way, verified over repeated runs of the real handler.
If the picker will not open at all, the window now says so and points at the box beside the button. That box is an ordinary text field, so you can type or paste a folder path straight into it and export normally. It used to fail silently and leave no way forward.
Still unresolved: whether the picker can open behind the window. The measurements that led to 0.21.2 did not reproduce on a second attempt, so nothing in this release rests on them.
pip install --upgrade "overleaf-comments-export[gui,pdf]"
v0.21.2 — Choose… no longer looks like a hang
Clicking Choose… looked like it froze the window. It did not.
macOS opens a file dialog without giving it focus when the process is not frontmost, and this app is started by a launcher script rather than as a bundled application, so it usually is not. The dialog opened behind whatever you were looking at, and the window stopped redrawing because it was blocked waiting on it. From the outside that is indistinguishable from a hang.
Measured on macOS 26.6: with the dialog open the process sat blocked at zero percent CPU and the frontmost application never became ours. Passing parent= on its own did not fix it. The window is now brought forward first and the dialog is attached to it.
The same treatment for every warning and error box, since one of those opening behind the window is a message nobody can act on.
If you hit this before, you could get out of it by clicking the app's icon in the Dock, which surfaced the hidden dialog.
pip install --upgrade "overleaf-comments-export[gui,pdf]"
v0.21.1 — Windows fix for the new test matrix
A test fix. No change to what the tool exports.
The scenario matrix added in 0.21.0 failed on Windows, and the fault was the matrix's own. It runs the browser extension's core in node and read the output with text=True, which decodes using the locale encoding, and that is cp1252 on Windows. One scenario deliberately carries Greek and Chinese to catch exactly this class of thing, and the first thing it caught was the test that runs it.
A rule now fails the build for any subprocess call that decodes with the locale encoding instead of naming one. It found two more immediately, in the theme detection. Neither is reachable on Windows, which reads the theme from the registry rather than a subprocess, so neither was a live bug, but both name their encoding now.
pip install --upgrade "overleaf-comments-export[gui,pdf]"
v0.21.0 — an export appears all at once, or not at all
The three worthwhile items from the second review's architecture list.
An export appears all at once, or not at all. Every file is written into a staging folder inside the destination and moved into place in one step at the end. Before this, output went straight to your chosen folder one file at a time, so stopping an export, running out of disk, or a crash part-way left a folder holding some files from this run and some from the last one.
Because of it, "Stopped. Nothing was written." is now a promise the code can keep, and the machinery added in 0.18.0 to admit which files had already landed is gone along with the situation that needed it. A by-reviewer/ file left over from an earlier run is also no longer kept alongside current output.
The log is the one exception and is still written live, since it is what you read when an export fails and never reaches the end.
The settings file is created owner-only rather than made owner-only. It used to be written and then chmodded, so a live Overleaf session sat in a world-readable file for as long as that took. It is created 0600 now, written beside the real file and moved into place, so a crash part-way cannot leave a truncated one either.
The cross-implementation parity test runs a matrix instead of one happy path. Seven scenarios go through both Python and the browser extension and are compared: the baseline, orphan-only threads, a stale offset past the end of the file, a quoted title with Greek and Chinese in the comments, one thread with two anchors, a long reply chain, and tracked changes with no comments at all.
A single fixture is how the JSONL contract drifted apart without anything noticing. Dropping orphan records from the extension's JSONL is caught now, and only the orphan-only scenario catches it.
pip install --upgrade "overleaf-comments-export[gui,pdf]"
v0.20.0 — second review round
A second external review of 0.19.0. Every finding was real.
Releases were published to PyPI without any test having passed on them. CI runs on pushes to a branch, and publishing runs on a tag push, which is a different event, so CI never ran on the tagged commit at all. They were two unrelated runs racing each other: on 0.19.0 the upload finished about 35 seconds before CI did. The tests now run inside the publish workflow and publishing waits for them.
A thread with no anchor was invisible in the counts. open_count and resolved_count were worked out from anchored comments while thread_count came from threads, so a project whose ranges could not be read reported one thread, none open and none resolved. The Markdown had always counted threads, so the two files from one export disagreed with each other. Both count threads now.
Two reviewers could share one report. A B, A-B, A_B and A.B all become a-b, and the second by-reviewer file quietly replaced the first. Colliding names get a suffix now. Those reports were also handed every thread in the project, so each one claimed the whole project's totals in its front matter; each now sees only its own.
A title with a quote in it broke the Markdown front matter. A paper called A "quoted" paper ended the YAML scalar early and made the whole block unparseable.
The browser extension returned an out-of-range offset for a stale anchor. It computed the bounded value, used it for the line and column, and returned the raw one, so a 16-character document could report offset 10000 next to line 1. Python fixed this in 0.18.0 and the extension half was missed.
comments.jsonl is now derived from comments.json rather than assembled separately. That is how the two implementations drifted into writing different records under the same schema version: Python's carried no schema_version, no type, no project and no orphan threads. The cross-implementation parity test covers JSONL as well now.
pip install --upgrade "overleaf-comments-export[gui,pdf]"
v0.19.0 — audit fixes
Issues filed from the end-to-end audit, fixed one at a time.
The built PDF is only fetched from the site you signed in to (#8). The compile reply names the host to download from, and it was used as given. It is the one value in any response that decides where an authenticated request goes. It is checked against the site now, and anything else is ignored and logged.
Worth noting: the check compares against the site, not the exact host, because Overleaf's real answer is a sibling of www and not a child of it. Signed in to www.overleaf.com, the build comes back on clsi-a1b2.overleaf.com. The first version compared full hosts and would have broken every real PDF download. The test caught it before it shipped.
Settings that cannot be saved say so (#9). It used to fail in silence, so every box came back empty next time with no explanation and nothing in the log. It still never raises, since an export does not need the settings file, but it now logs the reason and says so once in the window.
Closing the window no longer leaves a stray callback. The queue pump rescheduled itself every 80ms and nothing cancelled it, so shutting the window fired one more callback against widgets that were already gone.
Why the certificate fallback sets an environment variable is now written down (#10), closed without a code change. The call that fails is inside a dependency and takes no CA bundle argument, so nothing set on our own session reaches it, and it only ever fires on a Python where nothing was verifying anyway. Three tests hold the guard.
The short-screen window limit (#11) is still open.
pip install --upgrade "overleaf-comments-export[gui,pdf]"