remarkable-tools 0.2.1__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.
@@ -0,0 +1,7 @@
1
+ Copyright 2025 Gustaf Hendeby
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,246 @@
1
+ Metadata-Version: 2.4
2
+ Name: remarkable-tools
3
+ Version: 0.2.1
4
+ Summary: A set of tools to interact with reMarkable tablets
5
+ Keywords: remarkable,pdf
6
+ Author: Gustaf Hendeby
7
+ Author-email: Gustaf Hendeby <hendeby@gmail.com>
8
+ License-Expression: MIT
9
+ License-File: LICENSE.md
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Dist: pikepdf>=10.5.1
13
+ Requires-Dist: requests>=2.32.5
14
+ Requires-Dist: textual>=8.0.0
15
+ Requires-Dist: textual-fspicker>=1.0.0
16
+ Requires-Python: >=3.14
17
+ Description-Content-Type: text/markdown
18
+
19
+ # remarkable
20
+
21
+ Utilities for interacting with a reMarkable tablet and post-processing exported PDFs.
22
+
23
+ This project installs two command-line scripts:
24
+
25
+ - `remarkable`: terminal UI and automation commands for browsing, downloading, and uploading documents.
26
+ - `remarkable-hlfix`: PDF post-processing tool that reduces highlight opacity.
27
+
28
+ ## Installation
29
+
30
+ Install the package in your current environment:
31
+
32
+ ```bash
33
+ uv sync
34
+ ```
35
+
36
+ Then run scripts with `uv run`:
37
+
38
+ ```bash
39
+ uv run remarkable --help
40
+ uv run remarkable-hlfix --help
41
+ ```
42
+
43
+ If installed as a tool or package entry point, you can call `remarkable` and `remarkable-hlfix` directly.
44
+
45
+ ## Script: remarkable
46
+
47
+ `remarkable` connects to the tablet over the reMarkable local interface (`http://10.11.99.1`) and supports both interactive and one-shot modes.
48
+
49
+ ### Configuration files
50
+
51
+ Defaults are loaded from these files (later files override earlier ones):
52
+
53
+ Linux/Unix:
54
+
55
+ 1. `/usr/local/etc/remarkableconfig`
56
+ 2. `$XDG_CONFIG_HOME/remarkable/config`
57
+ 3. `~/.config/remarkable/config`
58
+ 4. `~/.remarkableconfig`
59
+
60
+ Windows:
61
+
62
+ 1. `%PROGRAMDATA%/remarkable/config`
63
+ 2. `%APPDATA%/remarkable/config`
64
+ 3. `%LOCALAPPDATA%/remarkable/config`
65
+ 4. `%USERPROFILE%/.remarkableconfig`
66
+
67
+ Expected format:
68
+
69
+ ```toml
70
+ [general]
71
+ hl_fix = true
72
+ tag = ""
73
+ start_folder = ""
74
+ ```
75
+
76
+ Command-line arguments override config values.
77
+
78
+ ### Usage
79
+
80
+ Start the interactive browser:
81
+
82
+ ```bash
83
+ remarkable
84
+ ```
85
+
86
+ Start in a specific folder title path:
87
+
88
+ ```bash
89
+ remarkable "Work/Meetings"
90
+ ```
91
+
92
+ Download newest document and exit:
93
+
94
+ ```bash
95
+ remarkable --get-newest
96
+ ```
97
+
98
+ Download newest document matching a tag suffix:
99
+
100
+ ```bash
101
+ remarkable --get-newest --tag _notes
102
+ ```
103
+
104
+ Upload a file and exit:
105
+
106
+ ```bash
107
+ remarkable --upload-file ./document.pdf
108
+ ```
109
+
110
+ Disable highlight fixing for downloaded PDFs:
111
+
112
+ ```bash
113
+ remarkable --no-hl-fix
114
+ ```
115
+
116
+ Show installed/runtime version:
117
+
118
+ ```bash
119
+ remarkable --version
120
+ ```
121
+
122
+ ### Interactive keys
123
+
124
+ - `q`: quit
125
+ - `F5`: refresh
126
+ - `h`: toggle highlight fix for PDF downloads
127
+ - In folder list: `Enter` to open folder
128
+ - In document list: `d` to download PDF, `D` to download `.rmdoc`
129
+
130
+ ## Script: remarkable-hlfix
131
+
132
+ `remarkable-hlfix` rewrites a PDF so reMarkable-style highlights are no longer fully opaque.
133
+
134
+ Default behavior:
135
+
136
+ - Targets known reMarkable highlight colors.
137
+ - Reduces fully opaque highlight fill and stroke opacity from `1.0` to `0.4`.
138
+ - Preserves graphics-state scoping (`q`/`Q`) so opacity changes do not leak between sibling drawing blocks.
139
+
140
+ ### Usage
141
+
142
+ Basic conversion:
143
+
144
+ ```bash
145
+ remarkable-hlfix input.pdf output.pdf
146
+ ```
147
+
148
+ Run with default filenames (`input.pdf` -> `output.pdf`):
149
+
150
+ ```bash
151
+ remarkable-hlfix
152
+ ```
153
+
154
+ Apply to all fully opaque filled shapes instead of only known highlight colors:
155
+
156
+ ```bash
157
+ remarkable-hlfix input.pdf output.pdf --all-colors
158
+ ```
159
+
160
+ Tune minimum stroke width required before applying stroke transparency:
161
+
162
+ ```bash
163
+ remarkable-hlfix input.pdf output.pdf --min-stroke-width 4.0
164
+ ```
165
+
166
+ Detect highlight palette from one page and print a paste-ready color block:
167
+
168
+ ```bash
169
+ remarkable-hlfix input.pdf --calibrate-palette --calibration-page 1
170
+ ```
171
+
172
+ Show installed/runtime version:
173
+
174
+ ```bash
175
+ remarkable-hlfix --version
176
+ ```
177
+
178
+ ## Troubleshooting
179
+
180
+ ### remarkable cannot connect to device
181
+
182
+ Symptoms:
183
+
184
+ - Requests fail or time out.
185
+ - You see connection errors when listing folders or downloading files.
186
+
187
+ Checks:
188
+
189
+ 1. Ensure the tablet is connected over USB and USB web interface access is enabled.
190
+ 2. Verify the endpoint is reachable:
191
+
192
+ ```bash
193
+ curl -I http://10.11.99.1/documents/
194
+ ```
195
+
196
+ 3. If needed, retry after reconnecting the cable and restarting the tablet's USB web interface.
197
+
198
+ ### config-related startup failure
199
+
200
+ If you use a config file, ensure it contains a `[general]` table:
201
+
202
+ ```toml
203
+ [general]
204
+ hl_fix = true
205
+ tag = ""
206
+ start_folder = ""
207
+ ```
208
+
209
+ If you are testing quickly, run with explicit flags to avoid relying on config values.
210
+
211
+ ### downloaded PDF highlights look unchanged
212
+
213
+ Try one of these:
214
+
215
+ 1. Make sure highlight fixing is enabled (`--hl-fix` or toggle `h` in the UI).
216
+ 2. Run a direct pass with `remarkable-hlfix`.
217
+ 3. If your document uses non-standard colors, run calibration first:
218
+
219
+ ```bash
220
+ remarkable-hlfix input.pdf --calibrate-palette --calibration-page 1
221
+ ```
222
+
223
+ 4. If highlights are very thin, lower the stroke threshold:
224
+
225
+ ```bash
226
+ remarkable-hlfix input.pdf output.pdf --min-stroke-width 1.0
227
+ ```
228
+
229
+ ### remarkable-hlfix input errors
230
+
231
+ Common causes:
232
+
233
+ - Input path is wrong.
234
+ - File is encrypted or malformed.
235
+ - Calibration page number does not exist in the PDF.
236
+
237
+ Checks:
238
+
239
+ 1. Confirm file paths are correct.
240
+ 2. Start with the basic command:
241
+
242
+ ```bash
243
+ remarkable-hlfix input.pdf output.pdf
244
+ ```
245
+
246
+ 3. If that fails, try opening and re-saving the PDF with another tool, then run again.
@@ -0,0 +1,228 @@
1
+ # remarkable
2
+
3
+ Utilities for interacting with a reMarkable tablet and post-processing exported PDFs.
4
+
5
+ This project installs two command-line scripts:
6
+
7
+ - `remarkable`: terminal UI and automation commands for browsing, downloading, and uploading documents.
8
+ - `remarkable-hlfix`: PDF post-processing tool that reduces highlight opacity.
9
+
10
+ ## Installation
11
+
12
+ Install the package in your current environment:
13
+
14
+ ```bash
15
+ uv sync
16
+ ```
17
+
18
+ Then run scripts with `uv run`:
19
+
20
+ ```bash
21
+ uv run remarkable --help
22
+ uv run remarkable-hlfix --help
23
+ ```
24
+
25
+ If installed as a tool or package entry point, you can call `remarkable` and `remarkable-hlfix` directly.
26
+
27
+ ## Script: remarkable
28
+
29
+ `remarkable` connects to the tablet over the reMarkable local interface (`http://10.11.99.1`) and supports both interactive and one-shot modes.
30
+
31
+ ### Configuration files
32
+
33
+ Defaults are loaded from these files (later files override earlier ones):
34
+
35
+ Linux/Unix:
36
+
37
+ 1. `/usr/local/etc/remarkableconfig`
38
+ 2. `$XDG_CONFIG_HOME/remarkable/config`
39
+ 3. `~/.config/remarkable/config`
40
+ 4. `~/.remarkableconfig`
41
+
42
+ Windows:
43
+
44
+ 1. `%PROGRAMDATA%/remarkable/config`
45
+ 2. `%APPDATA%/remarkable/config`
46
+ 3. `%LOCALAPPDATA%/remarkable/config`
47
+ 4. `%USERPROFILE%/.remarkableconfig`
48
+
49
+ Expected format:
50
+
51
+ ```toml
52
+ [general]
53
+ hl_fix = true
54
+ tag = ""
55
+ start_folder = ""
56
+ ```
57
+
58
+ Command-line arguments override config values.
59
+
60
+ ### Usage
61
+
62
+ Start the interactive browser:
63
+
64
+ ```bash
65
+ remarkable
66
+ ```
67
+
68
+ Start in a specific folder title path:
69
+
70
+ ```bash
71
+ remarkable "Work/Meetings"
72
+ ```
73
+
74
+ Download newest document and exit:
75
+
76
+ ```bash
77
+ remarkable --get-newest
78
+ ```
79
+
80
+ Download newest document matching a tag suffix:
81
+
82
+ ```bash
83
+ remarkable --get-newest --tag _notes
84
+ ```
85
+
86
+ Upload a file and exit:
87
+
88
+ ```bash
89
+ remarkable --upload-file ./document.pdf
90
+ ```
91
+
92
+ Disable highlight fixing for downloaded PDFs:
93
+
94
+ ```bash
95
+ remarkable --no-hl-fix
96
+ ```
97
+
98
+ Show installed/runtime version:
99
+
100
+ ```bash
101
+ remarkable --version
102
+ ```
103
+
104
+ ### Interactive keys
105
+
106
+ - `q`: quit
107
+ - `F5`: refresh
108
+ - `h`: toggle highlight fix for PDF downloads
109
+ - In folder list: `Enter` to open folder
110
+ - In document list: `d` to download PDF, `D` to download `.rmdoc`
111
+
112
+ ## Script: remarkable-hlfix
113
+
114
+ `remarkable-hlfix` rewrites a PDF so reMarkable-style highlights are no longer fully opaque.
115
+
116
+ Default behavior:
117
+
118
+ - Targets known reMarkable highlight colors.
119
+ - Reduces fully opaque highlight fill and stroke opacity from `1.0` to `0.4`.
120
+ - Preserves graphics-state scoping (`q`/`Q`) so opacity changes do not leak between sibling drawing blocks.
121
+
122
+ ### Usage
123
+
124
+ Basic conversion:
125
+
126
+ ```bash
127
+ remarkable-hlfix input.pdf output.pdf
128
+ ```
129
+
130
+ Run with default filenames (`input.pdf` -> `output.pdf`):
131
+
132
+ ```bash
133
+ remarkable-hlfix
134
+ ```
135
+
136
+ Apply to all fully opaque filled shapes instead of only known highlight colors:
137
+
138
+ ```bash
139
+ remarkable-hlfix input.pdf output.pdf --all-colors
140
+ ```
141
+
142
+ Tune minimum stroke width required before applying stroke transparency:
143
+
144
+ ```bash
145
+ remarkable-hlfix input.pdf output.pdf --min-stroke-width 4.0
146
+ ```
147
+
148
+ Detect highlight palette from one page and print a paste-ready color block:
149
+
150
+ ```bash
151
+ remarkable-hlfix input.pdf --calibrate-palette --calibration-page 1
152
+ ```
153
+
154
+ Show installed/runtime version:
155
+
156
+ ```bash
157
+ remarkable-hlfix --version
158
+ ```
159
+
160
+ ## Troubleshooting
161
+
162
+ ### remarkable cannot connect to device
163
+
164
+ Symptoms:
165
+
166
+ - Requests fail or time out.
167
+ - You see connection errors when listing folders or downloading files.
168
+
169
+ Checks:
170
+
171
+ 1. Ensure the tablet is connected over USB and USB web interface access is enabled.
172
+ 2. Verify the endpoint is reachable:
173
+
174
+ ```bash
175
+ curl -I http://10.11.99.1/documents/
176
+ ```
177
+
178
+ 3. If needed, retry after reconnecting the cable and restarting the tablet's USB web interface.
179
+
180
+ ### config-related startup failure
181
+
182
+ If you use a config file, ensure it contains a `[general]` table:
183
+
184
+ ```toml
185
+ [general]
186
+ hl_fix = true
187
+ tag = ""
188
+ start_folder = ""
189
+ ```
190
+
191
+ If you are testing quickly, run with explicit flags to avoid relying on config values.
192
+
193
+ ### downloaded PDF highlights look unchanged
194
+
195
+ Try one of these:
196
+
197
+ 1. Make sure highlight fixing is enabled (`--hl-fix` or toggle `h` in the UI).
198
+ 2. Run a direct pass with `remarkable-hlfix`.
199
+ 3. If your document uses non-standard colors, run calibration first:
200
+
201
+ ```bash
202
+ remarkable-hlfix input.pdf --calibrate-palette --calibration-page 1
203
+ ```
204
+
205
+ 4. If highlights are very thin, lower the stroke threshold:
206
+
207
+ ```bash
208
+ remarkable-hlfix input.pdf output.pdf --min-stroke-width 1.0
209
+ ```
210
+
211
+ ### remarkable-hlfix input errors
212
+
213
+ Common causes:
214
+
215
+ - Input path is wrong.
216
+ - File is encrypted or malformed.
217
+ - Calibration page number does not exist in the PDF.
218
+
219
+ Checks:
220
+
221
+ 1. Confirm file paths are correct.
222
+ 2. Start with the basic command:
223
+
224
+ ```bash
225
+ remarkable-hlfix input.pdf output.pdf
226
+ ```
227
+
228
+ 3. If that fails, try opening and re-saving the PDF with another tool, then run again.
@@ -0,0 +1,50 @@
1
+ [project]
2
+ name = "remarkable-tools"
3
+ version = "0.2.1"
4
+ description = "A set of tools to interact with reMarkable tablets"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE.md"]
8
+ authors = [
9
+ { name = "Gustaf Hendeby", email = "hendeby@gmail.com" }
10
+ ]
11
+ keywords = ["remarkable", "pdf"]
12
+ classifiers = [
13
+ "Development Status :: 4 - Beta",
14
+ "Programming Language :: Python :: 3",
15
+ ]
16
+ requires-python = ">=3.14"
17
+ dependencies = [
18
+ "pikepdf>=10.5.1",
19
+ "requests>=2.32.5",
20
+ "textual>=8.0.0",
21
+ "textual-fspicker>=1.0.0",
22
+ ]
23
+
24
+ [dependency-groups]
25
+ dev = [
26
+ "pre-commit>=4.5.1",
27
+ "pytest>=9.0.2",
28
+ "pytest-cov>=6.0",
29
+ "ruff>=0.14.11",
30
+ ]
31
+
32
+ [build-system]
33
+ requires = ["uv_build>=0.11.14,<0.12"]
34
+ build-backend = "uv_build"
35
+
36
+ [tool.uv.build-backend]
37
+ module-name = "remarkable"
38
+
39
+ [project.scripts]
40
+ remarkable = "remarkable.ui:main"
41
+ remarkable-hlfix = "remarkable.hl_fix:main"
42
+
43
+ [tool.uv.sources]
44
+ remarkable-tools = { index = "testpypi" }
45
+
46
+ [[tool.uv.index]]
47
+ name = "testpypi"
48
+ url = "https://test.pypi.org/simple/"
49
+ publish-url = "https://test.pypi.org/legacy/"
50
+ explicit = true
File without changes
@@ -0,0 +1,72 @@
1
+ from __future__ import annotations
2
+
3
+ import importlib.metadata as importlib_metadata
4
+ import logging
5
+ import os
6
+ import tomllib
7
+ import typing
8
+ from pathlib import Path
9
+
10
+ log = logging.getLogger(__name__)
11
+
12
+
13
+ def deep_merge(
14
+ parent_source: dict[str, typing.Any], source: dict[str, typing.Any]
15
+ ) -> dict[str, typing.Any]:
16
+ result = parent_source.copy()
17
+ for k, v in source.items():
18
+ if k in result and isinstance(result[k], dict) and isinstance(v, dict):
19
+ result[k] = deep_merge(result[k], v)
20
+ else:
21
+ result[k] = v
22
+ return result
23
+
24
+
25
+ def get_config_paths(platform: str | None = None) -> list[Path]:
26
+ home = Path.home()
27
+ if (platform or os.name) == "nt":
28
+ config_paths: list[Path] = []
29
+ for env_var in ("PROGRAMDATA", "APPDATA", "LOCALAPPDATA"):
30
+ config_dir = os.getenv(env_var)
31
+ if config_dir:
32
+ config_paths.append(Path(config_dir) / "remarkable" / "config")
33
+ config_paths.append(home / ".remarkableconfig")
34
+ return config_paths
35
+
36
+ config_paths = [Path("/") / "usr" / "local" / "etc" / "remarkableconfig"]
37
+ xdg_config_home = os.getenv("XDG_CONFIG_HOME")
38
+ if xdg_config_home:
39
+ config_paths.append(Path(xdg_config_home) / "remarkable" / "config")
40
+ config_paths.append(home / ".config" / "remarkable" / "config")
41
+ config_paths.append(home / ".remarkableconfig")
42
+ return config_paths
43
+
44
+
45
+ def parse_config(default: dict[str, typing.Any]) -> dict[str, typing.Any]:
46
+ config_paths = get_config_paths()
47
+ config = default
48
+ for path in config_paths:
49
+ if not path.is_file():
50
+ continue
51
+ log.info("Loading configs from: %s", path)
52
+ with path.open("rb") as f:
53
+ data = tomllib.load(f)
54
+ log.info("Loaded config from %s: %s", path, data)
55
+ config = deep_merge(config, data)
56
+ return config
57
+
58
+
59
+ def get_runtime_version(dist_name: str = "remarkable") -> str:
60
+ """Return installed package version, or fall back to pyproject.toml."""
61
+ try:
62
+ return importlib_metadata.version(dist_name)
63
+ except importlib_metadata.PackageNotFoundError:
64
+ pass
65
+
66
+ pyproject_path = Path(__file__).resolve().parents[2] / "pyproject.toml"
67
+ try:
68
+ with pyproject_path.open("rb") as f:
69
+ pyproject_data = tomllib.load(f)
70
+ return str(pyproject_data["project"]["version"])
71
+ except OSError, tomllib.TOMLDecodeError, KeyError, TypeError:
72
+ return "unknown"