overleaf-comments-export 0.4.0__tar.gz → 0.6.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.
Files changed (33) hide show
  1. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/LICENSE +1 -1
  2. overleaf_comments_export-0.6.0/PKG-INFO +268 -0
  3. overleaf_comments_export-0.6.0/README.md +231 -0
  4. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export/__main__.py +25 -0
  5. overleaf_comments_export-0.6.0/overleaf_comments_export/annotate.py +211 -0
  6. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export/export.py +49 -5
  7. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export/gui.py +21 -0
  8. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export/render.py +20 -5
  9. overleaf_comments_export-0.6.0/overleaf_comments_export.egg-info/PKG-INFO +268 -0
  10. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export.egg-info/SOURCES.txt +4 -1
  11. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/pyproject.toml +2 -2
  12. overleaf_comments_export-0.6.0/tests/test_annotate.py +189 -0
  13. overleaf_comments_export-0.6.0/tests/test_stable_output.py +122 -0
  14. overleaf_comments_export-0.4.0/PKG-INFO +0 -219
  15. overleaf_comments_export-0.4.0/README.md +0 -182
  16. overleaf_comments_export-0.4.0/overleaf_comments_export.egg-info/PKG-INFO +0 -219
  17. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export/__init__.py +0 -0
  18. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export/anchors.py +0 -0
  19. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export/client.py +0 -0
  20. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export/model.py +0 -0
  21. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export/sections.py +0 -0
  22. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export.egg-info/dependency_links.txt +0 -0
  23. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export.egg-info/entry_points.txt +0 -0
  24. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export.egg-info/requires.txt +0 -0
  25. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/overleaf_comments_export.egg-info/top_level.txt +0 -0
  26. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/setup.cfg +0 -0
  27. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/tests/test_anchors_sections.py +0 -0
  28. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/tests/test_client.py +0 -0
  29. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/tests/test_errors_and_auth.py +0 -0
  30. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/tests/test_export.py +0 -0
  31. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/tests/test_render.py +0 -0
  32. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/tests/test_replies_and_changes.py +0 -0
  33. {overleaf_comments_export-0.4.0 → overleaf_comments_export-0.6.0}/tests/test_response_letter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Shivang (https://github.com/Mangluu)
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,268 @@
1
+ Metadata-Version: 2.4
2
+ Name: overleaf-comments-export
3
+ Version: 0.6.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
+ [![CI](https://github.com/Mangluu/overleaf-comments-export/actions/workflows/ci.yml/badge.svg)](https://github.com/Mangluu/overleaf-comments-export/actions/workflows/ci.yml)
44
+ [![PyPI](https://img.shields.io/pypi/v/overleaf-comments-export.svg)](https://pypi.org/project/overleaf-comments-export/)
45
+ [![Downloads](https://img.shields.io/pypi/dm/overleaf-comments-export.svg)](https://pypi.org/project/overleaf-comments-export/)
46
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
47
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%20to%203.14-blue.svg)](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
+ | `annotated/` | Optional. Your LaTeX with the comments embedded, ready to compile. |
107
+ | `by-reviewer/<name>.md` | Optional. One file per reviewer, so you can work through them one person at a time. |
108
+
109
+ ## Working through comments with an AI
110
+
111
+ This is what the export is shaped for. Hand an assistant the folder and it can
112
+ work on any comment by id, because it already knows the quoted passage, the
113
+ section it lives in, and what the replies said.
114
+
115
+ Some things that work well.
116
+
117
+ - Draft a reply to C014 that answers the reviewer and says what we changed.
118
+ - Which comments are asking for the same thing? Group them.
119
+ - Fill in the response letter for every comment from A. Reviewer.
120
+
121
+ Tracked changes come through too, as insertions and deletions with the
122
+ surrounding text, so a deletion reads as `before ~~removed~~ after`.
123
+
124
+ ## Useful options
125
+
126
+ ```bash
127
+ --response-letter # draft a point-by-point reply document
128
+ --per-reviewer # one report per reviewer
129
+ --reviewer "Emma" # only threads this person touched
130
+ --no-resolved # only what is still open
131
+ --render-mode detailed # more source context around each comment
132
+ --stable # output that only changes when the comments change
133
+ --annotated-tex # a copy of your source with the comments embedded
134
+ ```
135
+
136
+ Run `overleaf-comments-export --help` for the full list.
137
+
138
+ ## Comments inside the PDF
139
+
140
+ `--annotated-tex` writes a copy of your LaTeX into `annotated/`, with each
141
+ comment placed where it was made.
142
+
143
+ ```bash
144
+ overleaf-comments-export --project-url <link> --out ./review --annotated-tex
145
+ ```
146
+
147
+ ```tex
148
+ We propose a novel framework\pdfcomment[author={A. Reviewer}]{[C014] A. Reviewer:
149
+ Needs a citation. | Reply (Co Author): Smith 2023 would work} for measuring
150
+ quality.
151
+ ```
152
+
153
+ Compile that and the PDF carries the comments, which is what people have been
154
+ asking Overleaf for since 2023. Use `--annotate-style todonotes` to put them in
155
+ the margin instead of making them clickable notes.
156
+
157
+ Your own source is never touched. The annotated copies keep their original
158
+ names and folder structure, so `\input` still resolves if you upload the folder.
159
+
160
+ Reviewer text is escaped before it goes anywhere near the file, so a comment
161
+ containing `50% of $x$` or a stray backslash cannot break the build.
162
+
163
+ ## Keeping the comments in git
164
+
165
+ By default each run writes `comments-<date>.md`, so you end up with one file per
166
+ run. That is fine for a one-off export and useless for version control.
167
+
168
+ `--stable` writes a single `comments.md` with no timestamps in it. Re-run it and
169
+ the file does not move unless the comments actually moved.
170
+
171
+ ```bash
172
+ overleaf-comments-export --project-url <link> --out ./review --stable
173
+ git add review/comments.md
174
+ git commit -m "reviewer comments as of today"
175
+ ```
176
+
177
+ Next time you pull the comments, `git diff` shows the new ones and nothing else.
178
+
179
+ ```diff
180
+ thread_count: 41
181
+ +thread_count: 42
182
+
183
+ +**C042** _open_ — "the axis labels"
184
+ +- **A. Reviewer** · 2026-08-14 09:12 UTC: units are missing here
185
+ ```
186
+
187
+ ## Signing in
188
+
189
+ The tool needs the session your browser already has. It reads that session and
190
+ nothing else, and it only ever reads.
191
+
192
+ | How | Notes |
193
+ |---|---|
194
+ | Safari or Firefox | Reads the cookie file directly. No password prompt. |
195
+ | Paste it yourself | Works on every computer and browser. The window shows you how, step by step. |
196
+ | 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. |
197
+
198
+ To paste it, open Overleaf, press F12, go to Application or Storage, then
199
+ Cookies, then `https://www.overleaf.com`, and copy the value of
200
+ `overleaf_session2`. Treat it like a password. It stops working when you sign
201
+ out. Nothing is stored unless you tick the box that says so.
202
+
203
+ ```bash
204
+ overleaf-comments-export --project-url <link> --out ./out --cookie "PASTE_HERE"
205
+ ```
206
+
207
+ ## When something goes wrong
208
+
209
+ | What you see | What it means |
210
+ |---|---|
211
+ | Could not look up www.overleaf.com | This computer is offline, or a VPN is in the way. Nothing to do with your project. |
212
+ | Overleaf refused the request | The session expired. Sign in again in your browser and re-run. |
213
+ | Could not read Overleaf cookies | Use the paste method above. |
214
+ | The window cannot open | Python's Tk toolkit is missing. The message tells you what to install for your system. |
215
+
216
+ Anything else, please [open an issue](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose).
217
+ Never paste your session cookie into an issue.
218
+
219
+ ## Related projects
220
+
221
+ Several people hit this same wall independently. Different approaches suit
222
+ different people, so here are the others.
223
+
224
+ - [adakite/extract-overleaf-comments](https://github.com/adakite/extract-overleaf-comments)
225
+ works from a saved copy of the page, and can put comments in the PDF margins.
226
+ - [salokr/overleaf-comment-exporter](https://github.com/salokr/overleaf-comment-exporter)
227
+ is a browser extension, so there is nothing to install on the command line.
228
+ - [IcarusLemon/overleaf-comments-cli](https://github.com/IcarusLemon/overleaf-comments-cli)
229
+ is another command line exporter, driving a real browser under the hood.
230
+
231
+ All of them exist because of
232
+ [this three year old request](https://github.com/overleaf/overleaf/issues/1126).
233
+ An official export would make every one of us unnecessary, which would be the
234
+ better outcome.
235
+
236
+ ## Honest limitations
237
+
238
+ This is an unofficial tool. It uses Overleaf's internal endpoints, which are
239
+ undocumented and can change with any release. It identifies itself honestly in
240
+ every request, backs off when asked to, and cannot modify your project. Even
241
+ so, it may stop working one day without warning. If that happens, please say so
242
+ in an issue, because you may be the first to notice.
243
+
244
+ It is not affiliated with or endorsed by Overleaf. Use it on projects you have
245
+ access to, in line with
246
+ [Overleaf's terms](https://www.overleaf.com/legal).
247
+
248
+ ## Feedback and contributing
249
+
250
+ Feedback shapes what gets built next.
251
+
252
+ - Something broke, or the output was wrong. [Open an issue.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
253
+ You do not need to be a programmer. Paste what the tool said and that is plenty.
254
+ - Want it to do something it does not. [Suggest a feature.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
255
+ Describe the task, not only the feature. The real task usually leads somewhere better.
256
+ - A question, or something you built with it. [Discussions.](https://github.com/Mangluu/overleaf-comments-export/discussions)
257
+ - Code. See [CONTRIBUTING.md](CONTRIBUTING.md). Two minutes to get the tests
258
+ running, and there are items marked *help wanted* in [ROADMAP.md](ROADMAP.md).
259
+
260
+ What is coming next is in [ROADMAP.md](ROADMAP.md). What already changed is in
261
+ [CHANGELOG.md](CHANGELOG.md).
262
+
263
+ Maintained by [Shivang Gupta](https://github.com/Mangluu), who wrote it to
264
+ handle the review comments on his own papers.
265
+
266
+ ## License
267
+
268
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,231 @@
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
+ [![CI](https://github.com/Mangluu/overleaf-comments-export/actions/workflows/ci.yml/badge.svg)](https://github.com/Mangluu/overleaf-comments-export/actions/workflows/ci.yml)
7
+ [![PyPI](https://img.shields.io/pypi/v/overleaf-comments-export.svg)](https://pypi.org/project/overleaf-comments-export/)
8
+ [![Downloads](https://img.shields.io/pypi/dm/overleaf-comments-export.svg)](https://pypi.org/project/overleaf-comments-export/)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
10
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%20to%203.14-blue.svg)](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
+ | `annotated/` | Optional. Your LaTeX with the comments embedded, ready to compile. |
70
+ | `by-reviewer/<name>.md` | Optional. One file per reviewer, so you can work through them one person at a time. |
71
+
72
+ ## Working through comments with an AI
73
+
74
+ This is what the export is shaped for. Hand an assistant the folder and it can
75
+ work on any comment by id, because it already knows the quoted passage, the
76
+ section it lives in, and what the replies said.
77
+
78
+ Some things that work well.
79
+
80
+ - Draft a reply to C014 that answers the reviewer and says what we changed.
81
+ - Which comments are asking for the same thing? Group them.
82
+ - Fill in the response letter for every comment from A. Reviewer.
83
+
84
+ Tracked changes come through too, as insertions and deletions with the
85
+ surrounding text, so a deletion reads as `before ~~removed~~ after`.
86
+
87
+ ## Useful options
88
+
89
+ ```bash
90
+ --response-letter # draft a point-by-point reply document
91
+ --per-reviewer # one report per reviewer
92
+ --reviewer "Emma" # only threads this person touched
93
+ --no-resolved # only what is still open
94
+ --render-mode detailed # more source context around each comment
95
+ --stable # output that only changes when the comments change
96
+ --annotated-tex # a copy of your source with the comments embedded
97
+ ```
98
+
99
+ Run `overleaf-comments-export --help` for the full list.
100
+
101
+ ## Comments inside the PDF
102
+
103
+ `--annotated-tex` writes a copy of your LaTeX into `annotated/`, with each
104
+ comment placed where it was made.
105
+
106
+ ```bash
107
+ overleaf-comments-export --project-url <link> --out ./review --annotated-tex
108
+ ```
109
+
110
+ ```tex
111
+ We propose a novel framework\pdfcomment[author={A. Reviewer}]{[C014] A. Reviewer:
112
+ Needs a citation. | Reply (Co Author): Smith 2023 would work} for measuring
113
+ quality.
114
+ ```
115
+
116
+ Compile that and the PDF carries the comments, which is what people have been
117
+ asking Overleaf for since 2023. Use `--annotate-style todonotes` to put them in
118
+ the margin instead of making them clickable notes.
119
+
120
+ Your own source is never touched. The annotated copies keep their original
121
+ names and folder structure, so `\input` still resolves if you upload the folder.
122
+
123
+ Reviewer text is escaped before it goes anywhere near the file, so a comment
124
+ containing `50% of $x$` or a stray backslash cannot break the build.
125
+
126
+ ## Keeping the comments in git
127
+
128
+ By default each run writes `comments-<date>.md`, so you end up with one file per
129
+ run. That is fine for a one-off export and useless for version control.
130
+
131
+ `--stable` writes a single `comments.md` with no timestamps in it. Re-run it and
132
+ the file does not move unless the comments actually moved.
133
+
134
+ ```bash
135
+ overleaf-comments-export --project-url <link> --out ./review --stable
136
+ git add review/comments.md
137
+ git commit -m "reviewer comments as of today"
138
+ ```
139
+
140
+ Next time you pull the comments, `git diff` shows the new ones and nothing else.
141
+
142
+ ```diff
143
+ thread_count: 41
144
+ +thread_count: 42
145
+
146
+ +**C042** _open_ — "the axis labels"
147
+ +- **A. Reviewer** · 2026-08-14 09:12 UTC: units are missing here
148
+ ```
149
+
150
+ ## Signing in
151
+
152
+ The tool needs the session your browser already has. It reads that session and
153
+ nothing else, and it only ever reads.
154
+
155
+ | How | Notes |
156
+ |---|---|
157
+ | Safari or Firefox | Reads the cookie file directly. No password prompt. |
158
+ | Paste it yourself | Works on every computer and browser. The window shows you how, step by step. |
159
+ | 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. |
160
+
161
+ To paste it, open Overleaf, press F12, go to Application or Storage, then
162
+ Cookies, then `https://www.overleaf.com`, and copy the value of
163
+ `overleaf_session2`. Treat it like a password. It stops working when you sign
164
+ out. Nothing is stored unless you tick the box that says so.
165
+
166
+ ```bash
167
+ overleaf-comments-export --project-url <link> --out ./out --cookie "PASTE_HERE"
168
+ ```
169
+
170
+ ## When something goes wrong
171
+
172
+ | What you see | What it means |
173
+ |---|---|
174
+ | Could not look up www.overleaf.com | This computer is offline, or a VPN is in the way. Nothing to do with your project. |
175
+ | Overleaf refused the request | The session expired. Sign in again in your browser and re-run. |
176
+ | Could not read Overleaf cookies | Use the paste method above. |
177
+ | The window cannot open | Python's Tk toolkit is missing. The message tells you what to install for your system. |
178
+
179
+ Anything else, please [open an issue](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose).
180
+ Never paste your session cookie into an issue.
181
+
182
+ ## Related projects
183
+
184
+ Several people hit this same wall independently. Different approaches suit
185
+ different people, so here are the others.
186
+
187
+ - [adakite/extract-overleaf-comments](https://github.com/adakite/extract-overleaf-comments)
188
+ works from a saved copy of the page, and can put comments in the PDF margins.
189
+ - [salokr/overleaf-comment-exporter](https://github.com/salokr/overleaf-comment-exporter)
190
+ is a browser extension, so there is nothing to install on the command line.
191
+ - [IcarusLemon/overleaf-comments-cli](https://github.com/IcarusLemon/overleaf-comments-cli)
192
+ is another command line exporter, driving a real browser under the hood.
193
+
194
+ All of them exist because of
195
+ [this three year old request](https://github.com/overleaf/overleaf/issues/1126).
196
+ An official export would make every one of us unnecessary, which would be the
197
+ better outcome.
198
+
199
+ ## Honest limitations
200
+
201
+ This is an unofficial tool. It uses Overleaf's internal endpoints, which are
202
+ undocumented and can change with any release. It identifies itself honestly in
203
+ every request, backs off when asked to, and cannot modify your project. Even
204
+ so, it may stop working one day without warning. If that happens, please say so
205
+ in an issue, because you may be the first to notice.
206
+
207
+ It is not affiliated with or endorsed by Overleaf. Use it on projects you have
208
+ access to, in line with
209
+ [Overleaf's terms](https://www.overleaf.com/legal).
210
+
211
+ ## Feedback and contributing
212
+
213
+ Feedback shapes what gets built next.
214
+
215
+ - Something broke, or the output was wrong. [Open an issue.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
216
+ You do not need to be a programmer. Paste what the tool said and that is plenty.
217
+ - Want it to do something it does not. [Suggest a feature.](https://github.com/Mangluu/overleaf-comments-export/issues/new/choose)
218
+ Describe the task, not only the feature. The real task usually leads somewhere better.
219
+ - A question, or something you built with it. [Discussions.](https://github.com/Mangluu/overleaf-comments-export/discussions)
220
+ - Code. See [CONTRIBUTING.md](CONTRIBUTING.md). Two minutes to get the tests
221
+ running, and there are items marked *help wanted* in [ROADMAP.md](ROADMAP.md).
222
+
223
+ What is coming next is in [ROADMAP.md](ROADMAP.md). What already changed is in
224
+ [CHANGELOG.md](CHANGELOG.md).
225
+
226
+ Maintained by [Shivang Gupta](https://github.com/Mangluu), who wrote it to
227
+ handle the review comments on his own papers.
228
+
229
+ ## License
230
+
231
+ MIT. See [LICENSE](LICENSE).
@@ -143,6 +143,28 @@ def main(argv: list[str] | None = None) -> int:
143
143
  "pre-filled with every open comment, grouped by who raised it, with "
144
144
  "blanks for your response.",
145
145
  )
146
+ parser.add_argument(
147
+ "--annotated-tex",
148
+ action="store_true",
149
+ help="Also write annotated/, a copy of your LaTeX source with each "
150
+ "comment embedded at the place it was made. Compile it to get a PDF "
151
+ "that carries the comments.",
152
+ )
153
+ parser.add_argument(
154
+ "--annotate-style",
155
+ choices=["pdfcomment", "todonotes"],
156
+ default="pdfcomment",
157
+ help="How comments appear in the annotated source. 'pdfcomment' makes "
158
+ "clickable PDF notes, 'todonotes' puts them in the margin.",
159
+ )
160
+ parser.add_argument(
161
+ "--stable",
162
+ action="store_true",
163
+ help="Write output that only changes when the comments change: one "
164
+ "comments.md instead of a dated filename, and no timestamps. Use this "
165
+ "when you keep the export in a git repository, so a diff shows the new "
166
+ "comments and nothing else.",
167
+ )
146
168
  parser.add_argument(
147
169
  "--per-reviewer",
148
170
  action="store_true",
@@ -212,6 +234,9 @@ def main(argv: list[str] | None = None) -> int:
212
234
  write_jsonl=args.write_jsonl,
213
235
  per_reviewer_reports=args.per_reviewer,
214
236
  response_letter=args.response_letter,
237
+ annotated_tex=args.annotated_tex,
238
+ annotate_style=args.annotate_style,
239
+ stable=args.stable,
215
240
  progress=lambda msg: print(msg, file=sys.stderr),
216
241
  )
217
242
  except UserFacingError as e: