overleaf-comments-export 0.3.0__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/LICENSE +1 -1
- overleaf_comments_export-0.5.0/PKG-INFO +241 -0
- overleaf_comments_export-0.5.0/README.md +204 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export/__main__.py +85 -2
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export/export.py +25 -5
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export/gui.py +21 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export/render.py +115 -3
- overleaf_comments_export-0.5.0/overleaf_comments_export.egg-info/PKG-INFO +241 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export.egg-info/SOURCES.txt +3 -1
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/pyproject.toml +7 -3
- overleaf_comments_export-0.5.0/tests/test_response_letter.py +111 -0
- overleaf_comments_export-0.5.0/tests/test_stable_output.py +122 -0
- overleaf_comments_export-0.3.0/PKG-INFO +0 -176
- overleaf_comments_export-0.3.0/README.md +0 -140
- overleaf_comments_export-0.3.0/overleaf_comments_export.egg-info/PKG-INFO +0 -176
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export/__init__.py +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export/anchors.py +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export/client.py +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export/model.py +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export/sections.py +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export.egg-info/dependency_links.txt +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export.egg-info/entry_points.txt +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export.egg-info/requires.txt +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/overleaf_comments_export.egg-info/top_level.txt +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/setup.cfg +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/tests/test_anchors_sections.py +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/tests/test_client.py +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/tests/test_errors_and_auth.py +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/tests/test_export.py +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/tests/test_render.py +0 -0
- {overleaf_comments_export-0.3.0 → overleaf_comments_export-0.5.0}/tests/test_replies_and_changes.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2026 Shivang
|
|
3
|
+
Copyright (c) 2026 Shivang Gupta <https://github.com/Mangluu>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: overleaf-comments-export
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Export comment threads and tracked changes from an Overleaf project to Markdown + JSON, optimized for AI-agent consumption.
|
|
5
|
+
Author-email: Shivang Gupta <47645533+Mangluu@users.noreply.github.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Mangluu/overleaf-comments-export
|
|
8
|
+
Project-URL: Issues, https://github.com/Mangluu/overleaf-comments-export/issues
|
|
9
|
+
Project-URL: Source, https://github.com/Mangluu/overleaf-comments-export
|
|
10
|
+
Keywords: overleaf,latex,research,comments,review,academic,tracked-changes,ai-agents
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: MacOS
|
|
15
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Text Processing :: Markup :: LaTeX
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: pyoverleaf>=0.1.7
|
|
29
|
+
Requires-Dist: browser-cookie3>=0.19
|
|
30
|
+
Requires-Dist: requests>=2.31
|
|
31
|
+
Requires-Dist: platformdirs>=4.0
|
|
32
|
+
Provides-Extra: gui
|
|
33
|
+
Requires-Dist: sv-ttk>=2.6; extra == "gui"
|
|
34
|
+
Provides-Extra: test
|
|
35
|
+
Requires-Dist: pytest>=8.0; extra == "test"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# overleaf-comments-export
|
|
39
|
+
|
|
40
|
+
Get the review comments out of an Overleaf paper, into Markdown and JSON you
|
|
41
|
+
can read, keep, commit, and hand to an AI assistant.
|
|
42
|
+
|
|
43
|
+
[](https://github.com/Mangluu/overleaf-comments-export/actions/workflows/ci.yml)
|
|
44
|
+
[](https://pypi.org/project/overleaf-comments-export/)
|
|
45
|
+
[](https://pypi.org/project/overleaf-comments-export/)
|
|
46
|
+
[](LICENSE)
|
|
47
|
+
[](https://www.python.org/)
|
|
48
|
+
|
|
49
|
+
Overleaf leaves comments out of both the source download and the Git sync, so
|
|
50
|
+
the only way to work through them is inside the editor, one at a time. On a
|
|
51
|
+
paper with ninety comments from three co-authors that stops being workable.
|
|
52
|
+
|
|
53
|
+
## What the output looks like
|
|
54
|
+
|
|
55
|
+
```markdown
|
|
56
|
+
## Summary
|
|
57
|
+
|
|
58
|
+
- **Threads:** 2 (2 open, 0 resolved)
|
|
59
|
+
- **Tracked changes:** 0
|
|
60
|
+
- **Most active reviewers:** A. Reviewer (2), Co Author (1)
|
|
61
|
+
|
|
62
|
+
### § Method
|
|
63
|
+
|
|
64
|
+
**Line 142** — 2 comments
|
|
65
|
+
|
|
66
|
+
> …We propose **▸a novel framework◂** for measuring perceived quality across conditions.
|
|
67
|
+
|
|
68
|
+
**C014** _open · 1 reply_ — "a novel framework"
|
|
69
|
+
- **A. Reviewer** · 2026-02-25 06:13 UTC: Needs a citation. Which studies show this?
|
|
70
|
+
- ↳ **Co Author** · 2026-02-26 10:00 UTC: Agree, Smith 2023 would work here.
|
|
71
|
+
|
|
72
|
+
**C015** _open_ — "coherent"
|
|
73
|
+
- **A. Reviewer** · 2026-02-27 13:46 UTC: This word is doing a lot of work. Define it.
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Every comment sits in its section, next to the words it was attached to, with
|
|
77
|
+
its replies underneath and a stable id you can point at.
|
|
78
|
+
|
|
79
|
+
## Install and run
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install overleaf-comments-export
|
|
83
|
+
overleaf-comments-export --gui
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
That opens a small window. Paste your project link, choose a folder, press the
|
|
87
|
+
button. If you prefer the terminal:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
overleaf-comments-export \
|
|
91
|
+
--project-url https://www.overleaf.com/project/YOUR_PROJECT_ID \
|
|
92
|
+
--out ./paper-comments
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Python 3.10 or newer, tested up to 3.14, on macOS, Windows, and Linux.
|
|
96
|
+
|
|
97
|
+
## What you get
|
|
98
|
+
|
|
99
|
+
| File | What it is |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `comments-<date>.md` | The readable export, or `comments.md` with `--stable`. Grouped by file, then section, then line. Stable ids `C001`, `T001`. |
|
|
102
|
+
| `comments.json` | The same data, structured. Threads, anchors, tracked changes, source context. |
|
|
103
|
+
| `comments.jsonl` | One self-contained record per comment, for pipelines. |
|
|
104
|
+
| `agents.md` | A short brief telling an AI assistant how to read the other two. |
|
|
105
|
+
| `response-letter.md` | Optional. A point-by-point reply document with a blank slot under every open comment. |
|
|
106
|
+
| `by-reviewer/<name>.md` | Optional. One file per reviewer, so you can work through them one person at a time. |
|
|
107
|
+
|
|
108
|
+
## Working through comments with an AI
|
|
109
|
+
|
|
110
|
+
This is what the export is shaped for. Hand an assistant the folder and it can
|
|
111
|
+
work on any comment by id, because it already knows the quoted passage, the
|
|
112
|
+
section it lives in, and what the replies said.
|
|
113
|
+
|
|
114
|
+
Some things that work well.
|
|
115
|
+
|
|
116
|
+
- Draft a reply to C014 that answers the reviewer and says what we changed.
|
|
117
|
+
- Which comments are asking for the same thing? Group them.
|
|
118
|
+
- Fill in the response letter for every comment from A. Reviewer.
|
|
119
|
+
|
|
120
|
+
Tracked changes come through too, as insertions and deletions with the
|
|
121
|
+
surrounding text, so a deletion reads as `before ~~removed~~ after`.
|
|
122
|
+
|
|
123
|
+
## Useful options
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
--response-letter # draft a point-by-point reply document
|
|
127
|
+
--per-reviewer # one report per reviewer
|
|
128
|
+
--reviewer "Emma" # only threads this person touched
|
|
129
|
+
--no-resolved # only what is still open
|
|
130
|
+
--render-mode detailed # more source context around each comment
|
|
131
|
+
--stable # output that only changes when the comments change
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Run `overleaf-comments-export --help` for the full list.
|
|
135
|
+
|
|
136
|
+
## Keeping the comments in git
|
|
137
|
+
|
|
138
|
+
By default each run writes `comments-<date>.md`, so you end up with one file per
|
|
139
|
+
run. That is fine for a one-off export and useless for version control.
|
|
140
|
+
|
|
141
|
+
`--stable` writes a single `comments.md` with no timestamps in it. Re-run it and
|
|
142
|
+
the file does not move unless the comments actually moved.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
overleaf-comments-export --project-url <link> --out ./review --stable
|
|
146
|
+
git add review/comments.md
|
|
147
|
+
git commit -m "reviewer comments as of today"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Next time you pull the comments, `git diff` shows the new ones and nothing else.
|
|
151
|
+
|
|
152
|
+
```diff
|
|
153
|
+
thread_count: 41
|
|
154
|
+
+thread_count: 42
|
|
155
|
+
|
|
156
|
+
+**C042** _open_ — "the axis labels"
|
|
157
|
+
+- **A. Reviewer** · 2026-08-14 09:12 UTC: units are missing here
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Signing in
|
|
161
|
+
|
|
162
|
+
The tool needs the session your browser already has. It reads that session and
|
|
163
|
+
nothing else, and it only ever reads.
|
|
164
|
+
|
|
165
|
+
| How | Notes |
|
|
166
|
+
|---|---|
|
|
167
|
+
| Safari or Firefox | Reads the cookie file directly. No password prompt. |
|
|
168
|
+
| Paste it yourself | Works on every computer and browser. The window shows you how, step by step. |
|
|
169
|
+
| Chrome, Edge, Brave | Works on macOS but asks for your Keychain password every run. Chrome 127 and newer on Windows cannot be read at all, so use the paste option there. |
|
|
170
|
+
|
|
171
|
+
To paste it, open Overleaf, press F12, go to Application or Storage, then
|
|
172
|
+
Cookies, then `https://www.overleaf.com`, and copy the value of
|
|
173
|
+
`overleaf_session2`. Treat it like a password. It stops working when you sign
|
|
174
|
+
out. Nothing is stored unless you tick the box that says so.
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
overleaf-comments-export --project-url <link> --out ./out --cookie "PASTE_HERE"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## When something goes wrong
|
|
181
|
+
|
|
182
|
+
| What you see | What it means |
|
|
183
|
+
|---|---|
|
|
184
|
+
| Could not look up www.overleaf.com | This computer is offline, or a VPN is in the way. Nothing to do with your project. |
|
|
185
|
+
| Overleaf refused the request | The session expired. Sign in again in your browser and re-run. |
|
|
186
|
+
| Could not read Overleaf cookies | Use the paste method above. |
|
|
187
|
+
| The window cannot open | Python's Tk toolkit is missing. The message tells you what to install for your system. |
|
|
188
|
+
|
|
189
|
+
Anything else, please [open an issue](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose).
|
|
190
|
+
Never paste your session cookie into an issue.
|
|
191
|
+
|
|
192
|
+
## Related projects
|
|
193
|
+
|
|
194
|
+
Several people hit this same wall independently. Different approaches suit
|
|
195
|
+
different people, so here are the others.
|
|
196
|
+
|
|
197
|
+
- [adakite/extract-overleaf-comments](https://github.com/adakite/extract-overleaf-comments)
|
|
198
|
+
works from a saved copy of the page, and can put comments in the PDF margins.
|
|
199
|
+
- [salokr/overleaf-comment-exporter](https://github.com/salokr/overleaf-comment-exporter)
|
|
200
|
+
is a browser extension, so there is nothing to install on the command line.
|
|
201
|
+
- [IcarusLemon/overleaf-comments-cli](https://github.com/IcarusLemon/overleaf-comments-cli)
|
|
202
|
+
is another command line exporter, driving a real browser under the hood.
|
|
203
|
+
|
|
204
|
+
All of them exist because of
|
|
205
|
+
[this three year old request](https://github.com/overleaf/overleaf/issues/1126).
|
|
206
|
+
An official export would make every one of us unnecessary, which would be the
|
|
207
|
+
better outcome.
|
|
208
|
+
|
|
209
|
+
## Honest limitations
|
|
210
|
+
|
|
211
|
+
This is an unofficial tool. It uses Overleaf's internal endpoints, which are
|
|
212
|
+
undocumented and can change with any release. It identifies itself honestly in
|
|
213
|
+
every request, backs off when asked to, and cannot modify your project. Even
|
|
214
|
+
so, it may stop working one day without warning. If that happens, please say so
|
|
215
|
+
in an issue, because you may be the first to notice.
|
|
216
|
+
|
|
217
|
+
It is not affiliated with or endorsed by Overleaf. Use it on projects you have
|
|
218
|
+
access to, in line with
|
|
219
|
+
[Overleaf's terms](https://www.overleaf.com/legal).
|
|
220
|
+
|
|
221
|
+
## Feedback and contributing
|
|
222
|
+
|
|
223
|
+
Feedback shapes what gets built next.
|
|
224
|
+
|
|
225
|
+
- Something broke, or the output was wrong. [Open an issue.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
|
|
226
|
+
You do not need to be a programmer. Paste what the tool said and that is plenty.
|
|
227
|
+
- Want it to do something it does not. [Suggest a feature.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
|
|
228
|
+
Describe the task, not only the feature. The real task usually leads somewhere better.
|
|
229
|
+
- A question, or something you built with it. [Discussions.](https://github.com/Mangluu/overleaf-comments-export/discussions)
|
|
230
|
+
- Code. See [CONTRIBUTING.md](CONTRIBUTING.md). Two minutes to get the tests
|
|
231
|
+
running, and there are items marked *help wanted* in [ROADMAP.md](ROADMAP.md).
|
|
232
|
+
|
|
233
|
+
What is coming next is in [ROADMAP.md](ROADMAP.md). What already changed is in
|
|
234
|
+
[CHANGELOG.md](CHANGELOG.md).
|
|
235
|
+
|
|
236
|
+
Maintained by [Shivang Gupta](https://github.com/Mangluu), who wrote it to
|
|
237
|
+
handle the review comments on his own papers.
|
|
238
|
+
|
|
239
|
+
## License
|
|
240
|
+
|
|
241
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# overleaf-comments-export
|
|
2
|
+
|
|
3
|
+
Get the review comments out of an Overleaf paper, into Markdown and JSON you
|
|
4
|
+
can read, keep, commit, and hand to an AI assistant.
|
|
5
|
+
|
|
6
|
+
[](https://github.com/Mangluu/overleaf-comments-export/actions/workflows/ci.yml)
|
|
7
|
+
[](https://pypi.org/project/overleaf-comments-export/)
|
|
8
|
+
[](https://pypi.org/project/overleaf-comments-export/)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://www.python.org/)
|
|
11
|
+
|
|
12
|
+
Overleaf leaves comments out of both the source download and the Git sync, so
|
|
13
|
+
the only way to work through them is inside the editor, one at a time. On a
|
|
14
|
+
paper with ninety comments from three co-authors that stops being workable.
|
|
15
|
+
|
|
16
|
+
## What the output looks like
|
|
17
|
+
|
|
18
|
+
```markdown
|
|
19
|
+
## Summary
|
|
20
|
+
|
|
21
|
+
- **Threads:** 2 (2 open, 0 resolved)
|
|
22
|
+
- **Tracked changes:** 0
|
|
23
|
+
- **Most active reviewers:** A. Reviewer (2), Co Author (1)
|
|
24
|
+
|
|
25
|
+
### § Method
|
|
26
|
+
|
|
27
|
+
**Line 142** — 2 comments
|
|
28
|
+
|
|
29
|
+
> …We propose **▸a novel framework◂** for measuring perceived quality across conditions.
|
|
30
|
+
|
|
31
|
+
**C014** _open · 1 reply_ — "a novel framework"
|
|
32
|
+
- **A. Reviewer** · 2026-02-25 06:13 UTC: Needs a citation. Which studies show this?
|
|
33
|
+
- ↳ **Co Author** · 2026-02-26 10:00 UTC: Agree, Smith 2023 would work here.
|
|
34
|
+
|
|
35
|
+
**C015** _open_ — "coherent"
|
|
36
|
+
- **A. Reviewer** · 2026-02-27 13:46 UTC: This word is doing a lot of work. Define it.
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Every comment sits in its section, next to the words it was attached to, with
|
|
40
|
+
its replies underneath and a stable id you can point at.
|
|
41
|
+
|
|
42
|
+
## Install and run
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install overleaf-comments-export
|
|
46
|
+
overleaf-comments-export --gui
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
That opens a small window. Paste your project link, choose a folder, press the
|
|
50
|
+
button. If you prefer the terminal:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
overleaf-comments-export \
|
|
54
|
+
--project-url https://www.overleaf.com/project/YOUR_PROJECT_ID \
|
|
55
|
+
--out ./paper-comments
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Python 3.10 or newer, tested up to 3.14, on macOS, Windows, and Linux.
|
|
59
|
+
|
|
60
|
+
## What you get
|
|
61
|
+
|
|
62
|
+
| File | What it is |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `comments-<date>.md` | The readable export, or `comments.md` with `--stable`. Grouped by file, then section, then line. Stable ids `C001`, `T001`. |
|
|
65
|
+
| `comments.json` | The same data, structured. Threads, anchors, tracked changes, source context. |
|
|
66
|
+
| `comments.jsonl` | One self-contained record per comment, for pipelines. |
|
|
67
|
+
| `agents.md` | A short brief telling an AI assistant how to read the other two. |
|
|
68
|
+
| `response-letter.md` | Optional. A point-by-point reply document with a blank slot under every open comment. |
|
|
69
|
+
| `by-reviewer/<name>.md` | Optional. One file per reviewer, so you can work through them one person at a time. |
|
|
70
|
+
|
|
71
|
+
## Working through comments with an AI
|
|
72
|
+
|
|
73
|
+
This is what the export is shaped for. Hand an assistant the folder and it can
|
|
74
|
+
work on any comment by id, because it already knows the quoted passage, the
|
|
75
|
+
section it lives in, and what the replies said.
|
|
76
|
+
|
|
77
|
+
Some things that work well.
|
|
78
|
+
|
|
79
|
+
- Draft a reply to C014 that answers the reviewer and says what we changed.
|
|
80
|
+
- Which comments are asking for the same thing? Group them.
|
|
81
|
+
- Fill in the response letter for every comment from A. Reviewer.
|
|
82
|
+
|
|
83
|
+
Tracked changes come through too, as insertions and deletions with the
|
|
84
|
+
surrounding text, so a deletion reads as `before ~~removed~~ after`.
|
|
85
|
+
|
|
86
|
+
## Useful options
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
--response-letter # draft a point-by-point reply document
|
|
90
|
+
--per-reviewer # one report per reviewer
|
|
91
|
+
--reviewer "Emma" # only threads this person touched
|
|
92
|
+
--no-resolved # only what is still open
|
|
93
|
+
--render-mode detailed # more source context around each comment
|
|
94
|
+
--stable # output that only changes when the comments change
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Run `overleaf-comments-export --help` for the full list.
|
|
98
|
+
|
|
99
|
+
## Keeping the comments in git
|
|
100
|
+
|
|
101
|
+
By default each run writes `comments-<date>.md`, so you end up with one file per
|
|
102
|
+
run. That is fine for a one-off export and useless for version control.
|
|
103
|
+
|
|
104
|
+
`--stable` writes a single `comments.md` with no timestamps in it. Re-run it and
|
|
105
|
+
the file does not move unless the comments actually moved.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
overleaf-comments-export --project-url <link> --out ./review --stable
|
|
109
|
+
git add review/comments.md
|
|
110
|
+
git commit -m "reviewer comments as of today"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Next time you pull the comments, `git diff` shows the new ones and nothing else.
|
|
114
|
+
|
|
115
|
+
```diff
|
|
116
|
+
thread_count: 41
|
|
117
|
+
+thread_count: 42
|
|
118
|
+
|
|
119
|
+
+**C042** _open_ — "the axis labels"
|
|
120
|
+
+- **A. Reviewer** · 2026-08-14 09:12 UTC: units are missing here
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Signing in
|
|
124
|
+
|
|
125
|
+
The tool needs the session your browser already has. It reads that session and
|
|
126
|
+
nothing else, and it only ever reads.
|
|
127
|
+
|
|
128
|
+
| How | Notes |
|
|
129
|
+
|---|---|
|
|
130
|
+
| Safari or Firefox | Reads the cookie file directly. No password prompt. |
|
|
131
|
+
| Paste it yourself | Works on every computer and browser. The window shows you how, step by step. |
|
|
132
|
+
| Chrome, Edge, Brave | Works on macOS but asks for your Keychain password every run. Chrome 127 and newer on Windows cannot be read at all, so use the paste option there. |
|
|
133
|
+
|
|
134
|
+
To paste it, open Overleaf, press F12, go to Application or Storage, then
|
|
135
|
+
Cookies, then `https://www.overleaf.com`, and copy the value of
|
|
136
|
+
`overleaf_session2`. Treat it like a password. It stops working when you sign
|
|
137
|
+
out. Nothing is stored unless you tick the box that says so.
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
overleaf-comments-export --project-url <link> --out ./out --cookie "PASTE_HERE"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## When something goes wrong
|
|
144
|
+
|
|
145
|
+
| What you see | What it means |
|
|
146
|
+
|---|---|
|
|
147
|
+
| Could not look up www.overleaf.com | This computer is offline, or a VPN is in the way. Nothing to do with your project. |
|
|
148
|
+
| Overleaf refused the request | The session expired. Sign in again in your browser and re-run. |
|
|
149
|
+
| Could not read Overleaf cookies | Use the paste method above. |
|
|
150
|
+
| The window cannot open | Python's Tk toolkit is missing. The message tells you what to install for your system. |
|
|
151
|
+
|
|
152
|
+
Anything else, please [open an issue](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose).
|
|
153
|
+
Never paste your session cookie into an issue.
|
|
154
|
+
|
|
155
|
+
## Related projects
|
|
156
|
+
|
|
157
|
+
Several people hit this same wall independently. Different approaches suit
|
|
158
|
+
different people, so here are the others.
|
|
159
|
+
|
|
160
|
+
- [adakite/extract-overleaf-comments](https://github.com/adakite/extract-overleaf-comments)
|
|
161
|
+
works from a saved copy of the page, and can put comments in the PDF margins.
|
|
162
|
+
- [salokr/overleaf-comment-exporter](https://github.com/salokr/overleaf-comment-exporter)
|
|
163
|
+
is a browser extension, so there is nothing to install on the command line.
|
|
164
|
+
- [IcarusLemon/overleaf-comments-cli](https://github.com/IcarusLemon/overleaf-comments-cli)
|
|
165
|
+
is another command line exporter, driving a real browser under the hood.
|
|
166
|
+
|
|
167
|
+
All of them exist because of
|
|
168
|
+
[this three year old request](https://github.com/overleaf/overleaf/issues/1126).
|
|
169
|
+
An official export would make every one of us unnecessary, which would be the
|
|
170
|
+
better outcome.
|
|
171
|
+
|
|
172
|
+
## Honest limitations
|
|
173
|
+
|
|
174
|
+
This is an unofficial tool. It uses Overleaf's internal endpoints, which are
|
|
175
|
+
undocumented and can change with any release. It identifies itself honestly in
|
|
176
|
+
every request, backs off when asked to, and cannot modify your project. Even
|
|
177
|
+
so, it may stop working one day without warning. If that happens, please say so
|
|
178
|
+
in an issue, because you may be the first to notice.
|
|
179
|
+
|
|
180
|
+
It is not affiliated with or endorsed by Overleaf. Use it on projects you have
|
|
181
|
+
access to, in line with
|
|
182
|
+
[Overleaf's terms](https://www.overleaf.com/legal).
|
|
183
|
+
|
|
184
|
+
## Feedback and contributing
|
|
185
|
+
|
|
186
|
+
Feedback shapes what gets built next.
|
|
187
|
+
|
|
188
|
+
- Something broke, or the output was wrong. [Open an issue.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
|
|
189
|
+
You do not need to be a programmer. Paste what the tool said and that is plenty.
|
|
190
|
+
- Want it to do something it does not. [Suggest a feature.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
|
|
191
|
+
Describe the task, not only the feature. The real task usually leads somewhere better.
|
|
192
|
+
- A question, or something you built with it. [Discussions.](https://github.com/Mangluu/overleaf-comments-export/discussions)
|
|
193
|
+
- Code. See [CONTRIBUTING.md](CONTRIBUTING.md). Two minutes to get the tests
|
|
194
|
+
running, and there are items marked *help wanted* in [ROADMAP.md](ROADMAP.md).
|
|
195
|
+
|
|
196
|
+
What is coming next is in [ROADMAP.md](ROADMAP.md). What already changed is in
|
|
197
|
+
[CHANGELOG.md](CHANGELOG.md).
|
|
198
|
+
|
|
199
|
+
Maintained by [Shivang Gupta](https://github.com/Mangluu), who wrote it to
|
|
200
|
+
handle the review comments on his own papers.
|
|
201
|
+
|
|
202
|
+
## License
|
|
203
|
+
|
|
204
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -4,6 +4,7 @@ import argparse
|
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
6
|
import sys
|
|
7
|
+
import traceback
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
|
|
9
10
|
from . import __version__
|
|
@@ -11,6 +12,35 @@ from .client import OverleafClient, UserFacingError
|
|
|
11
12
|
from .export import ExportResult, run_export
|
|
12
13
|
|
|
13
14
|
|
|
15
|
+
def _no_tkinter_message() -> str:
|
|
16
|
+
"""Platform-specific instructions for installing Python's GUI toolkit."""
|
|
17
|
+
if sys.platform == "darwin":
|
|
18
|
+
fix = (
|
|
19
|
+
"Install Python from python.org (it includes the GUI toolkit), or\n"
|
|
20
|
+
"with Homebrew run:\n\n"
|
|
21
|
+
" brew install python-tk"
|
|
22
|
+
)
|
|
23
|
+
elif sys.platform.startswith("win"):
|
|
24
|
+
fix = (
|
|
25
|
+
"Re-run the Python installer from python.org, choose \"Modify\", and\n"
|
|
26
|
+
"tick \"tcl/tk and IDLE\"."
|
|
27
|
+
)
|
|
28
|
+
else:
|
|
29
|
+
fix = (
|
|
30
|
+
"Install it with your package manager, for example:\n\n"
|
|
31
|
+
" Debian/Ubuntu : sudo apt install python3-tk\n"
|
|
32
|
+
" Fedora : sudo dnf install python3-tkinter\n"
|
|
33
|
+
" Arch : sudo pacman -S tk"
|
|
34
|
+
)
|
|
35
|
+
return (
|
|
36
|
+
"The window cannot open because this Python has no GUI toolkit "
|
|
37
|
+
"installed.\n\n"
|
|
38
|
+
f"{fix}\n\n"
|
|
39
|
+
"Or skip the window entirely and use the command line:\n\n"
|
|
40
|
+
" overleaf-comments-export --project-url <your project link> --out ./comments"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
14
44
|
def main(argv: list[str] | None = None) -> int:
|
|
15
45
|
parser = argparse.ArgumentParser(
|
|
16
46
|
prog="overleaf-comments-export",
|
|
@@ -106,6 +136,21 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
106
136
|
action="store_false",
|
|
107
137
|
help="Skip writing comments.jsonl (the streaming-friendly companion).",
|
|
108
138
|
)
|
|
139
|
+
parser.add_argument(
|
|
140
|
+
"--response-letter",
|
|
141
|
+
action="store_true",
|
|
142
|
+
help="Also write response-letter.md: a point-by-point reply document "
|
|
143
|
+
"pre-filled with every open comment, grouped by who raised it, with "
|
|
144
|
+
"blanks for your response.",
|
|
145
|
+
)
|
|
146
|
+
parser.add_argument(
|
|
147
|
+
"--stable",
|
|
148
|
+
action="store_true",
|
|
149
|
+
help="Write output that only changes when the comments change: one "
|
|
150
|
+
"comments.md instead of a dated filename, and no timestamps. Use this "
|
|
151
|
+
"when you keep the export in a git repository, so a diff shows the new "
|
|
152
|
+
"comments and nothing else.",
|
|
153
|
+
)
|
|
109
154
|
parser.add_argument(
|
|
110
155
|
"--per-reviewer",
|
|
111
156
|
action="store_true",
|
|
@@ -120,8 +165,31 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
120
165
|
args = parser.parse_args(argv)
|
|
121
166
|
|
|
122
167
|
if args.gui or (not args.project_url and not args.out):
|
|
123
|
-
|
|
124
|
-
|
|
168
|
+
try:
|
|
169
|
+
from .gui import launch_gui
|
|
170
|
+
except ImportError:
|
|
171
|
+
# tkinter is NOT bundled with Python everywhere — most Linux
|
|
172
|
+
# distributions ship it as a separate system package, and it is
|
|
173
|
+
# missing from some minimal/conda builds.
|
|
174
|
+
print(_no_tkinter_message(), file=sys.stderr)
|
|
175
|
+
return 1
|
|
176
|
+
try:
|
|
177
|
+
return launch_gui()
|
|
178
|
+
except Exception as e:
|
|
179
|
+
# Typically TclError on a headless machine (SSH, server, container).
|
|
180
|
+
if "display" in str(e).lower() or type(e).__name__ == "TclError":
|
|
181
|
+
print(
|
|
182
|
+
"There is no screen to open a window on.\n\n"
|
|
183
|
+
"This looks like a computer without a desktop (a server, or "
|
|
184
|
+
"a remote session). Use the command line instead, for "
|
|
185
|
+
"example:\n\n"
|
|
186
|
+
" overleaf-comments-export --project-url <your project link> "
|
|
187
|
+
"--out ./comments\n\n"
|
|
188
|
+
"Run with --help to see every option.",
|
|
189
|
+
file=sys.stderr,
|
|
190
|
+
)
|
|
191
|
+
return 1
|
|
192
|
+
raise
|
|
125
193
|
|
|
126
194
|
if not args.project_url or not args.out:
|
|
127
195
|
parser.error("--project-url and --out are required in CLI mode (or pass --gui).")
|
|
@@ -151,12 +219,27 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
151
219
|
render_mode=args.render_mode,
|
|
152
220
|
write_jsonl=args.write_jsonl,
|
|
153
221
|
per_reviewer_reports=args.per_reviewer,
|
|
222
|
+
response_letter=args.response_letter,
|
|
223
|
+
stable=args.stable,
|
|
154
224
|
progress=lambda msg: print(msg, file=sys.stderr),
|
|
155
225
|
)
|
|
156
226
|
except UserFacingError as e:
|
|
157
227
|
# Expected, explainable failures: no traceback, just what to do next.
|
|
158
228
|
print(f"\n{e}", file=sys.stderr)
|
|
159
229
|
return 1
|
|
230
|
+
except Exception:
|
|
231
|
+
# Unexpected: show the traceback, but also tell people where to send it.
|
|
232
|
+
# The moment something breaks is the only moment we have their attention.
|
|
233
|
+
traceback.print_exc()
|
|
234
|
+
print(
|
|
235
|
+
f"\nThat looks like a bug in overleaf-comments-export {__version__}.\n"
|
|
236
|
+
"Please report it (copy the lines above) at\n"
|
|
237
|
+
" https://github.com/Mangluu/overleaf-comments-export/issues/new/choose\n"
|
|
238
|
+
"It probably affects other people too, and it cannot be fixed if "
|
|
239
|
+
"nobody says anything.",
|
|
240
|
+
file=sys.stderr,
|
|
241
|
+
)
|
|
242
|
+
return 2
|
|
160
243
|
print(f"\nDone. Open: {result.markdown_path}")
|
|
161
244
|
return 0
|
|
162
245
|
|