mathcraft-ocr 0.2.2__tar.gz → 0.2.3__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.
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/LICENSE +21 -21
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/MANIFEST.in +13 -13
- {mathcraft_ocr-0.2.2/mathcraft_ocr.egg-info → mathcraft_ocr-0.2.3}/PKG-INFO +8 -4
- mathcraft_ocr-0.2.3/README.md +230 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/README_MATHCRAFT_OCR.md +7 -3
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/__init__.py +1 -1
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/cache.py +5 -1
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/hardware.py +80 -2
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3/mathcraft_ocr.egg-info}/PKG-INFO +8 -4
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr.egg-info/SOURCES.txt +1 -1
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/pyproject.toml +3 -7
- mathcraft_ocr-0.2.2/readme.md +0 -389
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/__main__.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/__init__.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/common.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/formula_detector.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/formula_recognizer.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/text_detector.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/text_recognizer.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/api.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/cli.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/debug_blocks.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/doctor.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/downloader.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/error_patterns.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/errors.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/formula_lines.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/image.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/latex_alignment.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/latex_quality.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/layout.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/manifest.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/manifests/models.v1.json +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/profiles.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/providers.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/results.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/runtime.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/serialization.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/worker.py +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr.egg-info/dependency_links.txt +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr.egg-info/entry_points.txt +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr.egg-info/requires.txt +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr.egg-info/top_level.txt +0 -0
- {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/setup.cfg +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 MathCraft
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MathCraft
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
include LICENSE
|
|
1
|
+
include LICENSE
|
|
2
2
|
include README_MATHCRAFT_OCR.md
|
|
3
|
-
include pyproject.toml
|
|
4
|
-
graft mathcraft_ocr
|
|
5
|
-
prune build
|
|
6
|
-
prune dist
|
|
7
|
-
prune docs
|
|
8
|
-
prune release_assets
|
|
9
|
-
prune scripts
|
|
10
|
-
prune src
|
|
11
|
-
prune test
|
|
12
|
-
prune test_pdf
|
|
13
|
-
global-exclude __pycache__
|
|
14
|
-
global-exclude *.py[cod]
|
|
3
|
+
include pyproject.toml
|
|
4
|
+
graft mathcraft_ocr
|
|
5
|
+
prune build
|
|
6
|
+
prune dist
|
|
7
|
+
prune docs
|
|
8
|
+
prune release_assets
|
|
9
|
+
prune scripts
|
|
10
|
+
prune src
|
|
11
|
+
prune test
|
|
12
|
+
prune test_pdf
|
|
13
|
+
global-exclude __pycache__
|
|
14
|
+
global-exclude *.py[cod]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mathcraft-ocr
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: ONNX-only OCR runtime for mathematical documents
|
|
5
5
|
Author: SakuraMathcraft
|
|
6
6
|
License-Expression: MIT
|
|
@@ -139,10 +139,12 @@ mathcraft worker --provider auto
|
|
|
139
139
|
|
|
140
140
|
## Model Cache
|
|
141
141
|
|
|
142
|
-
MathCraft reads models from:
|
|
142
|
+
MathCraft reads models from a platform-specific default user data root:
|
|
143
143
|
|
|
144
144
|
```text
|
|
145
|
-
%APPDATA%\MathCraft\models
|
|
145
|
+
Windows: %APPDATA%\MathCraft\models
|
|
146
|
+
macOS: ~/Library/Application Support/LaTeXSnipper/MathCraft/models
|
|
147
|
+
Linux: ${XDG_DATA_HOME:-~/.local/share}/LaTeXSnipper/MathCraft/models
|
|
146
148
|
```
|
|
147
149
|
|
|
148
150
|
or from a custom root:
|
|
@@ -169,7 +171,9 @@ mathcraft doctor --provider auto
|
|
|
169
171
|
Open a new PowerShell window after removing the persistent variable. The default root is:
|
|
170
172
|
|
|
171
173
|
```text
|
|
172
|
-
%APPDATA%\MathCraft\models
|
|
174
|
+
Windows: %APPDATA%\MathCraft\models
|
|
175
|
+
macOS: ~/Library/Application Support/LaTeXSnipper/MathCraft/models
|
|
176
|
+
Linux: ${XDG_DATA_HOME:-~/.local/share}/LaTeXSnipper/MathCraft/models
|
|
173
177
|
```
|
|
174
178
|
|
|
175
179
|
Model artifacts are downloaded from the MathCraft-Models release assets declared in `mathcraft_ocr/manifests/models.v1.json`.
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# MathCraft Models
|
|
2
|
+
|
|
3
|
+
Model assets for **MathCraft OCR**, the ONNX-only OCR runtime used by LaTeXSnipper.
|
|
4
|
+
|
|
5
|
+
MathCraft OCR recognizes formulae, text, and mixed mathematical documents with a compact ONNX model set. This repository provides the model release assets and the source package for the PyPI package `mathcraft-ocr` used by LaTeXSnipper.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
Current PyPI release line: `mathcraft-ocr 0.2.3`.
|
|
10
|
+
|
|
11
|
+
Install the library and CLI without choosing an ONNX Runtime backend:
|
|
12
|
+
|
|
13
|
+
```powershell
|
|
14
|
+
pip install mathcraft-ocr
|
|
15
|
+
mathcraft --help
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Install exactly one ONNX Runtime backend before running OCR inference.
|
|
19
|
+
|
|
20
|
+
CPU:
|
|
21
|
+
|
|
22
|
+
```powershell
|
|
23
|
+
pip install "mathcraft-ocr[cpu]"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
GPU:
|
|
27
|
+
|
|
28
|
+
```powershell
|
|
29
|
+
pip install "mathcraft-ocr[gpu]"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Use only one ONNX Runtime backend in the same environment. Do not install `onnxruntime` and `onnxruntime-gpu` together.
|
|
33
|
+
|
|
34
|
+
LaTeXSnipper's dependency wizard selects the ONNX Runtime GPU wheel line from the detected CUDA toolkit. CUDA 11.x uses the ONNX Runtime CUDA 11 package feed, CUDA 12.x uses the stable PyPI GPU wheels, and CUDA 13.x uses the ONNX Runtime CUDA 13 nightly feed. Static `mathcraft-ocr[gpu]` package metadata cannot inspect the local CUDA toolkit, so CUDA 11.x users installing manually should use the CUDA 11 feed shown by the wizard.
|
|
35
|
+
|
|
36
|
+
Upgrade the current release with a chosen backend:
|
|
37
|
+
|
|
38
|
+
```powershell
|
|
39
|
+
pip install -U "mathcraft-ocr[gpu]"
|
|
40
|
+
mathcraft --help
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Check the runtime:
|
|
44
|
+
|
|
45
|
+
```powershell
|
|
46
|
+
mathcraft doctor --provider auto
|
|
47
|
+
mathcraft models check
|
|
48
|
+
mathcraft warmup --profile mixed --provider auto
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Recognize an image:
|
|
52
|
+
|
|
53
|
+
```powershell
|
|
54
|
+
mathcraft ocr "C:\path\to\formula.png" --profile formula --provider auto --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Mixed OCR to Markdown:
|
|
58
|
+
|
|
59
|
+
```powershell
|
|
60
|
+
mathcraft ocr "C:\path\to\page.png" --profile mixed --provider auto --output result.md
|
|
61
|
+
mathcraft ocr "C:\path\to\page.png" --profile mixed --provider auto --output-dir "D:\MathCraft\outputs"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
When a file is written, the CLI prints the resolved output path:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
[MATHCRAFT_OUTPUT] written to D:\MathCraft\outputs\page.md
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
PowerShell custom model cache:
|
|
71
|
+
|
|
72
|
+
```powershell
|
|
73
|
+
$env:MATHCRAFT_HOME="D:\MathCraft\models"
|
|
74
|
+
mathcraft doctor --provider auto
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Persistent user-level cache path:
|
|
78
|
+
|
|
79
|
+
```powershell
|
|
80
|
+
setx MATHCRAFT_HOME "D:\MathCraft\models"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Open a new terminal after `setx`.
|
|
84
|
+
|
|
85
|
+
Restore the default cache path:
|
|
86
|
+
|
|
87
|
+
```powershell
|
|
88
|
+
[Environment]::SetEnvironmentVariable("MATHCRAFT_HOME", $null, "User")
|
|
89
|
+
Remove-Item Env:\MATHCRAFT_HOME -ErrorAction SilentlyContinue
|
|
90
|
+
mathcraft doctor --provider auto
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Open a new terminal after removing the persistent variable. The default root is platform-specific:
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
Windows: %APPDATA%\MathCraft\models
|
|
97
|
+
macOS: ~/Library/Application Support/LaTeXSnipper/MathCraft/models
|
|
98
|
+
Linux: ${XDG_DATA_HOME:-~/.local/share}/LaTeXSnipper/MathCraft/models
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Python API
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from mathcraft_ocr import MathCraftRuntime
|
|
105
|
+
|
|
106
|
+
runtime = MathCraftRuntime(provider_preference="auto")
|
|
107
|
+
result = runtime.recognize_mixed(r"C:\path\to\page.png")
|
|
108
|
+
|
|
109
|
+
print(result.text)
|
|
110
|
+
for block in result.blocks:
|
|
111
|
+
print(block.role, block.kind, block.text[:80])
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Profiles
|
|
115
|
+
|
|
116
|
+
| Profile | Use Case | Output |
|
|
117
|
+
| --- | --- | --- |
|
|
118
|
+
| `formula` | Formula screenshots | LaTeX formula text |
|
|
119
|
+
| `text` | Plain text OCR | Text |
|
|
120
|
+
| `mixed` | Text + formula documents | Markdown-ready structured text |
|
|
121
|
+
|
|
122
|
+
## Runtime Release Notes
|
|
123
|
+
|
|
124
|
+
`mathcraft-ocr 0.2.3` fixes cross-platform hardware sizing. Memory detection now uses optional `psutil`, Windows API, POSIX `sysconf`, and macOS `vm_stat`, so CPU batch sizing no longer falls back to Windows-only memory data on Linux or macOS. It also moves the default writable model cache to platform-native user data locations on macOS and Linux. The active `v1.0.0` ONNX model asset set is unchanged.
|
|
125
|
+
|
|
126
|
+
Earlier `0.2.x` releases improved runtime-side formula post-processing without changing the active `v1.0.0` ONNX model asset set. They keep compact fraction expressions whole, avoid splitting matrix-like wide formulas, add relation-aware `aligned` output, and retry severe segmented-line artifacts with safer whole-line or whole-image recognition.
|
|
127
|
+
|
|
128
|
+
Earlier `0.2.x` releases updated the runtime-side formula recognition path with line-aware formula splitting and reassembly. This improved long multi-line formula handling without changing the active `v1.0.0` ONNX model asset set.
|
|
129
|
+
|
|
130
|
+
## Model Set
|
|
131
|
+
|
|
132
|
+
Active release: `v1.0.0`
|
|
133
|
+
|
|
134
|
+
| Model ID | Runtime | Purpose |
|
|
135
|
+
| --- | --- | --- |
|
|
136
|
+
| `mathcraft-formula-det` | ONNX | Mathematical formula region detection |
|
|
137
|
+
| `mathcraft-formula-rec` | ONNX | Formula-to-LaTeX recognition |
|
|
138
|
+
| `mathcraft-text-det` | ONNX | Fast multilingual text detection |
|
|
139
|
+
| `mathcraft-text-rec` | ONNX | Fast multilingual text recognition |
|
|
140
|
+
|
|
141
|
+
Release assets:
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
mathcraft-formula-det.zip
|
|
145
|
+
mathcraft-formula-rec.zip
|
|
146
|
+
mathcraft-text-det.zip
|
|
147
|
+
mathcraft-text-rec.zip
|
|
148
|
+
SHA256SUMS.txt
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Default writable model root:
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
Windows: %APPDATA%\MathCraft\models
|
|
155
|
+
macOS: ~/Library/Application Support/LaTeXSnipper/MathCraft/models
|
|
156
|
+
Linux: ${XDG_DATA_HOME:-~/.local/share}/LaTeXSnipper/MathCraft/models
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The runtime checks the manifest before initialization. Missing or incomplete model folders are repaired automatically by downloading only the affected model asset.
|
|
160
|
+
|
|
161
|
+
Interrupted downloads are resumable. Partial archives are stored under the active writable model root:
|
|
162
|
+
|
|
163
|
+
```text
|
|
164
|
+
<MATHCRAFT_HOME>\.downloads\<model_id>.zip.part
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
After a model archive is fully downloaded, verified, and extracted, the `.part` file is removed automatically.
|
|
168
|
+
|
|
169
|
+
## Results
|
|
170
|
+
|
|
171
|
+
The examples below are generated from MathCraft's structured block output. Boxes show detected roles, order, column metadata, score, and layout flags.
|
|
172
|
+
|
|
173
|
+
### Abstract Algebra, page 18
|
|
174
|
+
|
|
175
|
+
Formula-heavy English mathematical prose with dense inline and display formulae.
|
|
176
|
+
|
|
177
|
+
<img width="1700" height="2200" alt="debug_blocks" src="https://github.com/user-attachments/assets/855d0694-4068-4e32-ac5e-80f0c4178332" />
|
|
178
|
+
|
|
179
|
+
### Dynamics journal, page 5
|
|
180
|
+
|
|
181
|
+
Formula-dominant journal page with display equations, anchors, labels, headers, and page numbers.
|
|
182
|
+
|
|
183
|
+
<img width="1700" height="2200" alt="debug_blocks" src="https://github.com/user-attachments/assets/b1498ee9-32fd-4d56-bbfb-876881758587" />
|
|
184
|
+
|
|
185
|
+
### Chinese lecture note, page 1
|
|
186
|
+
|
|
187
|
+
Chinese mathematical document page with mixed text and formula blocks.
|
|
188
|
+
|
|
189
|
+
<img width="1654" height="2339" alt="debug_blocks" src="https://github.com/user-attachments/assets/5d153b2d-d089-4ee2-9ee7-c7f52eb099c9" />
|
|
190
|
+
|
|
191
|
+
### Limits and series, page 1
|
|
192
|
+
|
|
193
|
+
Sparse title/cover-style page used to check layout stability.
|
|
194
|
+
|
|
195
|
+
<img width="1221" height="1898" alt="debug_blocks" src="https://github.com/user-attachments/assets/6c6404e0-bea4-4811-b135-feff3a063a18" />
|
|
196
|
+
|
|
197
|
+
## Benchmark Snapshot
|
|
198
|
+
|
|
199
|
+
Local `block_layout_regression_v4` telemetry:
|
|
200
|
+
|
|
201
|
+
| Metric | Value |
|
|
202
|
+
| --- | ---: |
|
|
203
|
+
| Pages | 10 |
|
|
204
|
+
| Total blocks | 495 |
|
|
205
|
+
| Text characters | 21,417 |
|
|
206
|
+
| Markdown lines | 304 |
|
|
207
|
+
| Mean page time | 8.34 s |
|
|
208
|
+
| Fastest page | 1.33 s |
|
|
209
|
+
| Slowest page | 18.53 s |
|
|
210
|
+
|
|
211
|
+
Environment:
|
|
212
|
+
|
|
213
|
+
```text
|
|
214
|
+
Provider: CUDAExecutionProvider
|
|
215
|
+
Runtime: MathCraft OCR v1
|
|
216
|
+
Backend: ONNX Runtime
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Why It Is Stable
|
|
220
|
+
|
|
221
|
+
- ONNX Runtime only, no active PyTorch inference dependency.
|
|
222
|
+
- Stable MathCraft-owned model IDs and folders.
|
|
223
|
+
- Manifest-based file checks and cache repair.
|
|
224
|
+
- Resumable model downloads for slow or interrupted networks.
|
|
225
|
+
- Formula detection before text OCR.
|
|
226
|
+
- Structured blocks for headings, paragraphs, display formulae, headers, page numbers, and columns.
|
|
227
|
+
|
|
228
|
+
## LaTeXSnipper
|
|
229
|
+
|
|
230
|
+
LaTeXSnipper already integrates MathCraft OCR. Normal users do not need to install this package manually.
|
|
@@ -93,10 +93,12 @@ mathcraft worker --provider auto
|
|
|
93
93
|
|
|
94
94
|
## Model Cache
|
|
95
95
|
|
|
96
|
-
MathCraft reads models from:
|
|
96
|
+
MathCraft reads models from a platform-specific default user data root:
|
|
97
97
|
|
|
98
98
|
```text
|
|
99
|
-
%APPDATA%\MathCraft\models
|
|
99
|
+
Windows: %APPDATA%\MathCraft\models
|
|
100
|
+
macOS: ~/Library/Application Support/LaTeXSnipper/MathCraft/models
|
|
101
|
+
Linux: ${XDG_DATA_HOME:-~/.local/share}/LaTeXSnipper/MathCraft/models
|
|
100
102
|
```
|
|
101
103
|
|
|
102
104
|
or from a custom root:
|
|
@@ -123,7 +125,9 @@ mathcraft doctor --provider auto
|
|
|
123
125
|
Open a new PowerShell window after removing the persistent variable. The default root is:
|
|
124
126
|
|
|
125
127
|
```text
|
|
126
|
-
%APPDATA%\MathCraft\models
|
|
128
|
+
Windows: %APPDATA%\MathCraft\models
|
|
129
|
+
macOS: ~/Library/Application Support/LaTeXSnipper/MathCraft/models
|
|
130
|
+
Linux: ${XDG_DATA_HOME:-~/.local/share}/LaTeXSnipper/MathCraft/models
|
|
127
131
|
```
|
|
128
132
|
|
|
129
133
|
Model artifacts are downloaded from the MathCraft-Models release assets declared in `mathcraft_ocr/manifests/models.v1.json`.
|
|
@@ -14,7 +14,11 @@ def default_user_models_dir() -> Path:
|
|
|
14
14
|
appdata = os.environ.get("APPDATA", "")
|
|
15
15
|
if appdata:
|
|
16
16
|
return Path(appdata) / "MathCraft" / "models"
|
|
17
|
-
|
|
17
|
+
if sys.platform == "darwin":
|
|
18
|
+
return Path.home() / "Library" / "Application Support" / "LaTeXSnipper" / "MathCraft" / "models"
|
|
19
|
+
xdg_data_home = os.environ.get("XDG_DATA_HOME", "").strip()
|
|
20
|
+
data_root = Path(xdg_data_home) if xdg_data_home else Path.home() / ".local" / "share"
|
|
21
|
+
return data_root / "LaTeXSnipper" / "MathCraft" / "models"
|
|
18
22
|
|
|
19
23
|
|
|
20
24
|
def resolve_user_models_dir(cache_dir: str | Path | None = None) -> Path:
|
|
@@ -8,6 +8,7 @@ from functools import lru_cache
|
|
|
8
8
|
import json
|
|
9
9
|
import os
|
|
10
10
|
import subprocess
|
|
11
|
+
import sys
|
|
11
12
|
|
|
12
13
|
from .providers import GPU_PROVIDER_NAMES, ProviderInfo
|
|
13
14
|
|
|
@@ -25,7 +26,7 @@ class HardwareInfo:
|
|
|
25
26
|
|
|
26
27
|
@lru_cache(maxsize=1)
|
|
27
28
|
def detect_hardware_info() -> HardwareInfo:
|
|
28
|
-
total_mb, free_mb =
|
|
29
|
+
total_mb, free_mb = _memory_status()
|
|
29
30
|
gpu_name, gpu_total_mb, gpu_free_mb, gpu_driver = _query_nvidia_smi()
|
|
30
31
|
if not gpu_name:
|
|
31
32
|
gpu_name, gpu_total_mb, gpu_driver = _query_windows_video_controller()
|
|
@@ -40,6 +41,79 @@ def detect_hardware_info() -> HardwareInfo:
|
|
|
40
41
|
)
|
|
41
42
|
|
|
42
43
|
|
|
44
|
+
def _memory_status() -> tuple[int, int]:
|
|
45
|
+
for probe in (_psutil_memory_status, _windows_memory_status, _posix_memory_status):
|
|
46
|
+
total_mb, free_mb = probe()
|
|
47
|
+
if total_mb > 0:
|
|
48
|
+
if free_mb <= 0:
|
|
49
|
+
_, macos_free_mb = _macos_vm_stat_memory_status()
|
|
50
|
+
free_mb = macos_free_mb
|
|
51
|
+
return total_mb, free_mb
|
|
52
|
+
return 0, 0
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _psutil_memory_status() -> tuple[int, int]:
|
|
56
|
+
try:
|
|
57
|
+
import psutil # type: ignore[import-not-found]
|
|
58
|
+
|
|
59
|
+
mem = psutil.virtual_memory()
|
|
60
|
+
return _bytes_to_mb(int(mem.total)), _bytes_to_mb(int(mem.available))
|
|
61
|
+
except Exception:
|
|
62
|
+
return 0, 0
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _posix_memory_status() -> tuple[int, int]:
|
|
66
|
+
if os.name == "nt":
|
|
67
|
+
return 0, 0
|
|
68
|
+
try:
|
|
69
|
+
page_size = int(os.sysconf("SC_PAGE_SIZE"))
|
|
70
|
+
phys_pages = int(os.sysconf("SC_PHYS_PAGES"))
|
|
71
|
+
except Exception:
|
|
72
|
+
return 0, 0
|
|
73
|
+
total_mb = _bytes_to_mb(page_size * phys_pages)
|
|
74
|
+
free_mb = 0
|
|
75
|
+
try:
|
|
76
|
+
avail_pages = int(os.sysconf("SC_AVPHYS_PAGES"))
|
|
77
|
+
free_mb = _bytes_to_mb(page_size * avail_pages)
|
|
78
|
+
except Exception:
|
|
79
|
+
pass
|
|
80
|
+
return total_mb, free_mb
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _macos_vm_stat_memory_status() -> tuple[int, int]:
|
|
84
|
+
if sys.platform != "darwin":
|
|
85
|
+
return 0, 0
|
|
86
|
+
try:
|
|
87
|
+
proc = subprocess.run(
|
|
88
|
+
["vm_stat"],
|
|
89
|
+
check=False,
|
|
90
|
+
capture_output=True,
|
|
91
|
+
text=True,
|
|
92
|
+
encoding="utf-8",
|
|
93
|
+
errors="replace",
|
|
94
|
+
timeout=2.0,
|
|
95
|
+
)
|
|
96
|
+
except Exception:
|
|
97
|
+
return 0, 0
|
|
98
|
+
if proc.returncode != 0:
|
|
99
|
+
return 0, 0
|
|
100
|
+
page_size = 4096
|
|
101
|
+
free_pages = 0
|
|
102
|
+
for raw_line in proc.stdout.splitlines():
|
|
103
|
+
line = raw_line.strip()
|
|
104
|
+
if line.startswith("Mach Virtual Memory Statistics:") and "page size of" in line:
|
|
105
|
+
page_size = _safe_int(line.rsplit("page size of", 1)[-1].split("bytes", 1)[0])
|
|
106
|
+
if page_size <= 0:
|
|
107
|
+
page_size = 4096
|
|
108
|
+
continue
|
|
109
|
+
if line.startswith(("Pages free:", "Pages inactive:", "Pages speculative:")):
|
|
110
|
+
value = line.split(":", 1)[-1].strip().rstrip(".")
|
|
111
|
+
free_pages += _safe_int(value)
|
|
112
|
+
if free_pages <= 0:
|
|
113
|
+
return 0, 0
|
|
114
|
+
return 0, _bytes_to_mb(page_size * free_pages)
|
|
115
|
+
|
|
116
|
+
|
|
43
117
|
def choose_rec_batch_num(
|
|
44
118
|
provider_info: ProviderInfo,
|
|
45
119
|
hardware: HardwareInfo | None = None,
|
|
@@ -198,6 +272,10 @@ def _windows_memory_status() -> tuple[int, int]:
|
|
|
198
272
|
|
|
199
273
|
def _safe_int(value: str) -> int:
|
|
200
274
|
try:
|
|
201
|
-
return int(float(str(value).strip()))
|
|
275
|
+
return int(float(str(value).strip().replace(",", "")))
|
|
202
276
|
except Exception:
|
|
203
277
|
return 0
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def _bytes_to_mb(value: int) -> int:
|
|
281
|
+
return max(0, int(value) // (1024 * 1024))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mathcraft-ocr
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: ONNX-only OCR runtime for mathematical documents
|
|
5
5
|
Author: SakuraMathcraft
|
|
6
6
|
License-Expression: MIT
|
|
@@ -139,10 +139,12 @@ mathcraft worker --provider auto
|
|
|
139
139
|
|
|
140
140
|
## Model Cache
|
|
141
141
|
|
|
142
|
-
MathCraft reads models from:
|
|
142
|
+
MathCraft reads models from a platform-specific default user data root:
|
|
143
143
|
|
|
144
144
|
```text
|
|
145
|
-
%APPDATA%\MathCraft\models
|
|
145
|
+
Windows: %APPDATA%\MathCraft\models
|
|
146
|
+
macOS: ~/Library/Application Support/LaTeXSnipper/MathCraft/models
|
|
147
|
+
Linux: ${XDG_DATA_HOME:-~/.local/share}/LaTeXSnipper/MathCraft/models
|
|
146
148
|
```
|
|
147
149
|
|
|
148
150
|
or from a custom root:
|
|
@@ -169,7 +171,9 @@ mathcraft doctor --provider auto
|
|
|
169
171
|
Open a new PowerShell window after removing the persistent variable. The default root is:
|
|
170
172
|
|
|
171
173
|
```text
|
|
172
|
-
%APPDATA%\MathCraft\models
|
|
174
|
+
Windows: %APPDATA%\MathCraft\models
|
|
175
|
+
macOS: ~/Library/Application Support/LaTeXSnipper/MathCraft/models
|
|
176
|
+
Linux: ${XDG_DATA_HOME:-~/.local/share}/LaTeXSnipper/MathCraft/models
|
|
173
177
|
```
|
|
174
178
|
|
|
175
179
|
Model artifacts are downloaded from the MathCraft-Models release assets declared in `mathcraft_ocr/manifests/models.v1.json`.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mathcraft-ocr"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.3"
|
|
8
8
|
description = "ONNX-only OCR runtime for mathematical documents"
|
|
9
9
|
readme = "README_MATHCRAFT_OCR.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -79,17 +79,13 @@ exclude = ["src*", "test*", "scripts*", "docs*", "release_assets*", "build*", "d
|
|
|
79
79
|
[tool.setuptools.package-data]
|
|
80
80
|
mathcraft_ocr = ["manifests/*.json"]
|
|
81
81
|
|
|
82
|
-
[tool.pytest.ini_options]
|
|
83
|
-
pythonpath = ["src"]
|
|
84
|
-
testpaths = ["test"]
|
|
85
|
-
addopts = ["--ignore=python311", "--ignore=tools/deps", "--ignore=.venv", "--ignore=build", "--ignore=dist"]
|
|
86
|
-
|
|
87
82
|
[tool.vulture]
|
|
88
83
|
paths = ["src"]
|
|
89
84
|
exclude = [
|
|
90
85
|
"build/",
|
|
91
86
|
"python311/",
|
|
92
|
-
"
|
|
87
|
+
"src/deps/python311/",
|
|
88
|
+
"src/get-pip.py"
|
|
93
89
|
]
|
|
94
90
|
min_confidence = 70
|
|
95
91
|
sort_by_size = true
|
mathcraft_ocr-0.2.2/readme.md
DELETED
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
# LaTeXSnipper ✨
|
|
2
|
-
|
|
3
|
-
<div align="center">
|
|
4
|
-
|
|
5
|
-
> A desktop math workspace for **capture -> recognize -> handwrite -> edit -> compute**
|
|
6
|
-
<img width="1919" height="1020" alt="封面" src="https://github.com/user-attachments/assets/9d00310b-d1b6-4321-b961-8837b3efb864" />
|
|
7
|
-
|
|
8
|
-

|
|
9
|
-

|
|
10
|
-

|
|
11
|
-

|
|
12
|
-

|
|
13
|
-

|
|
14
|
-

|
|
15
|
-
|
|
16
|
-
[](https://github.com/SakuraMathcraft/LaTeXSnipper/releases)
|
|
17
|
-
[](https://github.com/SakuraMathcraft/LaTeXSnipper/commits)
|
|
18
|
-
[](https://github.com/SakuraMathcraft/LaTeXSnipper/graphs/commit-activity)
|
|
19
|
-
|
|
20
|
-
[FAQ](docs/faq.md) · [Releases](https://github.com/SakuraMathcraft/LaTeXSnipper/releases)
|
|
21
|
-
|
|
22
|
-
### Star History
|
|
23
|
-
|
|
24
|
-
[](https://star-history.com/#SakuraMathcraft/LaTeXSnipper&Date)
|
|
25
|
-
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## Overview
|
|
31
|
-
|
|
32
|
-
**LaTeXSnipper** is no longer just a "screenshot formula -> LaTeX" utility.
|
|
33
|
-
It is a desktop workspace built for end-to-end math content workflows:
|
|
34
|
-
|
|
35
|
-
- Capture and recognize mathematical content from screenshots
|
|
36
|
-
- Continue editing and computing in the integrated math workbench
|
|
37
|
-
- Handwrite expressions in a dedicated canvas and convert to LaTeX
|
|
38
|
-
- Send results back to the main editor or copy to clipboard
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## Feature Walkthrough
|
|
43
|
-
|
|
44
|
-
### Math Workbench
|
|
45
|
-
|
|
46
|
-
<img width="1308" height="834" alt="数学工作台-暗色" src="https://github.com/user-attachments/assets/320a84b3-293d-4947-bc95-fbac88b1f664" />
|
|
47
|
-
|
|
48
|
-
The Math Workbench supports a complete workflow:
|
|
49
|
-
|
|
50
|
-
1. Capture and recognize formulas from the main window
|
|
51
|
-
2. Load results into the workbench in one click
|
|
52
|
-
3. Edit expressions in the `MathLive` area
|
|
53
|
-
4. Use the virtual math keyboard for fractions, superscripts, integrals, series, and more
|
|
54
|
-
5. Run `Compute / Simplify / Numeric / Expand / Factor / Solve`
|
|
55
|
-
6. Write results back to the editor or copy as LaTeX / MathJSON
|
|
56
|
-
|
|
57
|
-
### Auto Typesetting Document Window
|
|
58
|
-
|
|
59
|
-
<img width="1919" height="1014" alt="v2 3深色" src="https://github.com/user-attachments/assets/c6dffd39-26d9-4e54-aba9-a4b010d3603e" />
|
|
60
|
-
|
|
61
|
-
The Auto Typesetting Document Window supports source-level editing with synchronized preview:
|
|
62
|
-
|
|
63
|
-
1. Open "Auto Typesetting" from the handwriting window
|
|
64
|
-
2. Edit full source in the left `TeX Document` pane
|
|
65
|
-
3. Insert complex expressions with the built-in formula editor
|
|
66
|
-
4. Compile and preview PDF directly
|
|
67
|
-
5. Navigate bi-directionally between source and PDF via SyncTeX
|
|
68
|
-
6. Export `.tex` or `PDF` when needed
|
|
69
|
-
|
|
70
|
-
### Handwriting Recognition
|
|
71
|
-
|
|
72
|
-
<img width="1408" height="916" alt="手写识别readme" src="https://github.com/user-attachments/assets/3fe98e41-218e-452c-96c1-cc805ab3e0f2" />
|
|
73
|
-
|
|
74
|
-
The handwriting window supports the following flow:
|
|
75
|
-
|
|
76
|
-
1. Open "Handwriting Recognition" from the main window
|
|
77
|
-
2. Write formulas directly on an isolated canvas
|
|
78
|
-
3. Trigger MathCraft mixed OCR automatically after pen-up, so handwritten text and formulas can be kept together
|
|
79
|
-
4. See live `LaTeX output` and rendered preview on the right
|
|
80
|
-
5. Use "Auto Typesetting" when handwritten notes contain document text, Chinese or English labels, and multi-line formulas
|
|
81
|
-
6. Copy LaTeX directly or insert it back into the main editor
|
|
82
|
-
|
|
83
|
-
### PDF Recognition and Bilingual Reading
|
|
84
|
-
|
|
85
|
-
The main window includes PDF recognition and a separate bilingual reading tool:
|
|
86
|
-
|
|
87
|
-
1. Use "PDF Recognition" to select page count, output format, and render DPI
|
|
88
|
-
2. Built-in MathCraft PDF recognition uses mixed mode for text and formula recovery
|
|
89
|
-
3. External PDF recognition supports OpenAI-compatible, Ollama, and MinerU providers
|
|
90
|
-
4. Save editable Markdown or LaTeX results from the PDF result window
|
|
91
|
-
5. Use "Bilingual Reading" to open a text-layer PDF, view the current page, and translate with Argos, Azure, Google Cloud, or DeepL
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
## Core Features
|
|
96
|
-
|
|
97
|
-
| Feature | Description |
|
|
98
|
-
|------|------|
|
|
99
|
-
| 📸 Formula recognition | MathCraft OCR for formulas, text, and mixed content |
|
|
100
|
-
| 📄 PDF recognition | Page-based PDF recognition with Markdown/LaTeX output and DPI control |
|
|
101
|
-
| 🌐 Bilingual reading | PDF text-layer reading with local Argos or remote translation engines |
|
|
102
|
-
| ✍️ Handwriting recognition | Dedicated handwriting window with auto-recognition and live preview |
|
|
103
|
-
| 🧮 Math workbench | Separate workspace for editing, computation, and write-back |
|
|
104
|
-
| ⌨️ Formula editing | Integrated `MathLive math-field` with virtual math keyboard |
|
|
105
|
-
| 🔄 Multi-format export | 30 export choices across LaTeX, Markdown, MathML, HTML, OMML, SVG, Typst, Word, EPUB, RTF, wiki formats, and more |
|
|
106
|
-
| 📐 Core computation | Compute, simplify, numeric evaluate, expand, factor, solve |
|
|
107
|
-
| 🧠 Advanced fallback | Local `SymPy/mpmath` engine for harder expressions |
|
|
108
|
-
| 🌙 Theme support | Light/Dark adaptation across windows and tools |
|
|
109
|
-
| 🔐 Offline-first | Recognition and advanced solving can run locally for privacy |
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
## Computation Coverage
|
|
114
|
-
|
|
115
|
-
The workbench currently covers common scenarios such as:
|
|
116
|
-
|
|
117
|
-
- Polynomial expansion
|
|
118
|
-
- Factorization
|
|
119
|
-
- Equation solving
|
|
120
|
-
- Irrational/complex root fallback solving
|
|
121
|
-
- Definite and improper integrals
|
|
122
|
-
- Infinite series
|
|
123
|
-
- Infinite products
|
|
124
|
-
- Limits
|
|
125
|
-
- Derivatives
|
|
126
|
-
- Numeric approximation and constant recognition
|
|
127
|
-
|
|
128
|
-
For heavy expressions, the engine uses automatic fallback:
|
|
129
|
-
|
|
130
|
-
1. Try frontend `Compute Engine` first
|
|
131
|
-
2. Switch to local advanced engine on timeout/failure/unreliable results
|
|
132
|
-
3. Use `SymPy/mpmath` for robust fallback
|
|
133
|
-
4. Recover closed forms for selected known constants from numeric output
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
## Export Formats
|
|
138
|
-
|
|
139
|
-
LaTeXSnipper exposes a shared export menu in the main window and favorites window.
|
|
140
|
-
|
|
141
|
-
Built-in formula export formats:
|
|
142
|
-
|
|
143
|
-
- LaTeX inline, display, and equation
|
|
144
|
-
- Markdown inline and block math
|
|
145
|
-
- MathML standard, `.mml`, `<m>`, and attribute forms
|
|
146
|
-
- HTML, Word OMML, and SVG code
|
|
147
|
-
|
|
148
|
-
Optional Pandoc export formats are enabled after installing the `PANDOC` layer in the dependency wizard:
|
|
149
|
-
|
|
150
|
-
- Word `.docx`, ODT `.odt`, EPUB `.epub`, InDesign `.icml`
|
|
151
|
-
- RTF, plain text, standalone HTML, LaTeX `.tex`, Typst `.typ`
|
|
152
|
-
- GitHub Markdown, CommonMark, reStructuredText
|
|
153
|
-
- MediaWiki, DokuWiki, Org-mode, Textile, Jira Wiki, and man page output
|
|
154
|
-
|
|
155
|
-
Pandoc is optional. If it is not installed, the core recognition, editing, handwriting, preview, and built-in export formats continue to work normally.
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
## Quick Start
|
|
160
|
-
|
|
161
|
-
### Option 1: Download the executable
|
|
162
|
-
|
|
163
|
-
1. Visit the [Releases page](https://github.com/SakuraMathcraft/LaTeXSnipper/releases)
|
|
164
|
-
2. Download the latest `LaTeXSnipperSetup-<version>.exe`
|
|
165
|
-
3. Run the installer
|
|
166
|
-
4. Complete environment setup via the dependency wizard on first launch
|
|
167
|
-
5. Start capturing, handwriting, or using the math workbench
|
|
168
|
-
|
|
169
|
-
### Option 2: Run from source
|
|
170
|
-
|
|
171
|
-
Windows:
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
git clone https://github.com/SakuraMathcraft/LaTeXSnipper.git
|
|
175
|
-
cd LaTeXSnipper
|
|
176
|
-
|
|
177
|
-
python -m venv .venv
|
|
178
|
-
.\.venv\Scripts\activate
|
|
179
|
-
|
|
180
|
-
pip install -r requirements.txt
|
|
181
|
-
python src/main.py
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
Linux:
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
git clone https://github.com/SakuraMathcraft/LaTeXSnipper.git
|
|
188
|
-
cd LaTeXSnipper
|
|
189
|
-
|
|
190
|
-
python3 -m venv .venv
|
|
191
|
-
source .venv/bin/activate
|
|
192
|
-
|
|
193
|
-
pip install -r requirements-linux.txt
|
|
194
|
-
python src/main.py
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
macOS:
|
|
198
|
-
|
|
199
|
-
```bash
|
|
200
|
-
git clone https://github.com/SakuraMathcraft/LaTeXSnipper.git
|
|
201
|
-
cd LaTeXSnipper
|
|
202
|
-
|
|
203
|
-
python3 -m venv .venv
|
|
204
|
-
source .venv/bin/activate
|
|
205
|
-
|
|
206
|
-
pip install -r requirements-macos.txt
|
|
207
|
-
python src/main.py
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
---
|
|
211
|
-
|
|
212
|
-
## Platform Support
|
|
213
|
-
|
|
214
|
-
| Platform | Status | Notes |
|
|
215
|
-
|------|------|------|
|
|
216
|
-
| Windows | Primary release target | Native global hotkey, Qt capture, GitHub/Inno and Store/MSIX packaging. |
|
|
217
|
-
| Linux | Supported via provider layer | `pynput` global hotkey, Qt capture first, optional Wayland/X11 CLI or portal fallbacks. |
|
|
218
|
-
| macOS | Supported via provider layer | Native global hotkey, Qt capture with `screencapture` fallback, Screen Recording permission may be required. |
|
|
219
|
-
|
|
220
|
-
Close/background behavior follows each desktop platform. Windows hides the main
|
|
221
|
-
window to the system tray when it is closed. Linux does the same when a system
|
|
222
|
-
tray is available, and asks before exiting if no tray is available. macOS keeps
|
|
223
|
-
the app running when the main window is closed/minimized; Dock or menu Quit is
|
|
224
|
-
the explicit exit path. The macOS global hotkey uses Carbon and normally does
|
|
225
|
-
not require Accessibility permission, while screenshot capture requires Screen
|
|
226
|
-
Recording permission.
|
|
227
|
-
|
|
228
|
-
The dependency wizard manages Python dependency layers only. It does not install
|
|
229
|
-
or uninstall system packages. On Linux, tools such as `grim`, `maim`, and
|
|
230
|
-
`gnome-screenshot` can improve screenshot fallback behavior, but they are
|
|
231
|
-
installed by the user or distribution package manager, not by LaTeXSnipper.
|
|
232
|
-
The default screenshot shortcut is `Ctrl+F` on all three platforms. The shortcut
|
|
233
|
-
setting currently accepts `Ctrl+letter` and `Ctrl+Shift+letter` combinations so
|
|
234
|
-
custom shortcuts remain inside the cross-platform supported set. Linux global
|
|
235
|
-
shortcuts are still subject to desktop environment and Wayland compositor policy.
|
|
236
|
-
Linux and macOS both create optional runtime dependency environments in the
|
|
237
|
-
user state directory, so they need a usable system Python 3.10+ with venv/pip
|
|
238
|
-
support. Debian/Ubuntu `.deb` installs declare `python3` and `python3-venv`;
|
|
239
|
-
macOS users should install Python through Homebrew (`brew install python`) or
|
|
240
|
-
the official python.org macOS installer when the system does not provide a
|
|
241
|
-
usable `python3`.
|
|
242
|
-
The dependency wizard shows its UI before running `ensurepip`, `pip` upgrade,
|
|
243
|
-
or `setuptools`/`wheel` repair; those steps run after the user starts dependency
|
|
244
|
-
installation.
|
|
245
|
-
|
|
246
|
-
### Packaging
|
|
247
|
-
|
|
248
|
-
Windows packaging:
|
|
249
|
-
|
|
250
|
-
- `LaTeXSnipper.spec`
|
|
251
|
-
- `Inno/latexsnipper.iss`
|
|
252
|
-
- `scripts/build_store_msix.ps1`
|
|
253
|
-
|
|
254
|
-
Linux packaging:
|
|
255
|
-
|
|
256
|
-
- `LaTeXSnipper-linux.spec`
|
|
257
|
-
- `scripts/build_deb.sh`
|
|
258
|
-
- `packaging/debian/`
|
|
259
|
-
|
|
260
|
-
macOS packaging:
|
|
261
|
-
|
|
262
|
-
- `LaTeXSnipper-macos.spec`
|
|
263
|
-
- `scripts/build_macos.sh`
|
|
264
|
-
|
|
265
|
-
Linux/macOS build scripts prepare isolated, platform-scoped build runtimes under
|
|
266
|
-
`tools/deps/`, for example `tools/deps/python311-linux-x86_64`. The Windows IDE
|
|
267
|
-
interpreter is `tools/deps/python311`. The repository-root `python311` directory
|
|
268
|
-
is treated as a template runtime and must not be mutated by packaging scripts.
|
|
269
|
-
|
|
270
|
-
GitHub Actions release builds run the platform package jobs in one workflow:
|
|
271
|
-
|
|
272
|
-
- Windows: Inno installer; SignPath-signed artifact is preferred, with an unsigned fallback when signing is unavailable.
|
|
273
|
-
- Linux: Debian/Ubuntu `.deb` package from `scripts/build_deb.sh`.
|
|
274
|
-
- macOS: `.app.zip` and `.dmg` artifacts from `scripts/build_macos.sh`.
|
|
275
|
-
|
|
276
|
-
The release workflow expects these GitHub Actions variables:
|
|
277
|
-
`SIGNPATH_ORGANIZATION_ID`, `SIGNPATH_PROJECT_SLUG`,
|
|
278
|
-
`SIGNPATH_SIGNING_POLICY_SLUG`, and
|
|
279
|
-
`SIGNPATH_ARTIFACT_CONFIGURATION_SLUG`. It also requires the
|
|
280
|
-
`SIGNPATH_API_TOKEN` secret. The SignPath artifact configuration is mirrored in
|
|
281
|
-
`.signpath/artifact-configurations/windows-installer.xml`; copy that XML into
|
|
282
|
-
the matching SignPath project artifact configuration.
|
|
283
|
-
|
|
284
|
-
---
|
|
285
|
-
|
|
286
|
-
## Project Structure
|
|
287
|
-
|
|
288
|
-
```text
|
|
289
|
-
LaTeXSnipper/
|
|
290
|
-
|-- mathcraft_ocr/ # Standalone MathCraft OCR runtime and CLI
|
|
291
|
-
|-- src/
|
|
292
|
-
| |-- main.py # Main desktop application entry
|
|
293
|
-
| |-- backend/ # OCR wrapper, CUDA diagnostics, capture, platform services
|
|
294
|
-
| |-- bootstrap/ # Dependency wizard and runtime verification
|
|
295
|
-
| |-- capture/ # Screenshot capture controllers
|
|
296
|
-
| |-- core/ # Document composition, export contracts, restart contracts
|
|
297
|
-
| |-- cross_platform/ # OS-specific screenshot and platform helpers
|
|
298
|
-
| |-- editor/ # Math workbench and formula editing UI
|
|
299
|
-
| |-- exporting/ # Formula, Markdown, Pandoc, and document export helpers
|
|
300
|
-
| |-- handwriting/ # Handwriting canvas, PDF preview, document tools
|
|
301
|
-
| |-- preview/ # MathJax preview and render helpers
|
|
302
|
-
| |-- recognition/ # OCR and PDF recognition controllers
|
|
303
|
-
| |-- runtime/ # Startup, config, history, logging, distribution, runtime helpers
|
|
304
|
-
| |-- ui/ # Main window, settings, dialogs, and UI controllers
|
|
305
|
-
| |-- update/ # GitHub release update checks and installer launch flow
|
|
306
|
-
| |-- workers/ # Background worker helpers
|
|
307
|
-
| `-- assets/ # Icons and bundled web/math resources
|
|
308
|
-
|-- tools/
|
|
309
|
-
| `-- deps/ # Local developer/build dependency environment
|
|
310
|
-
|-- user_manual/ # Local manual source and generated PDF
|
|
311
|
-
|-- Inno/ # GitHub Release installer scripts
|
|
312
|
-
|-- packaging/ # Debian and MSIX packaging resources
|
|
313
|
-
|-- scripts/ # Build, release, and regression utilities
|
|
314
|
-
|-- docs/ # Design and architecture notes
|
|
315
|
-
|-- LaTeXSnipper.spec # PyInstaller GitHub build (Windows)
|
|
316
|
-
|-- LaTeXSnipper-linux.spec # PyInstaller Linux build
|
|
317
|
-
|-- LaTeXSnipper-macos.spec # PyInstaller macOS build
|
|
318
|
-
|-- pyproject.toml
|
|
319
|
-
|-- requirements.txt
|
|
320
|
-
|-- requirements-linux.txt
|
|
321
|
-
|-- requirements-macos.txt
|
|
322
|
-
|-- requirements-build.txt
|
|
323
|
-
|-- version_info.txt
|
|
324
|
-
`-- README.md
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
---
|
|
328
|
-
|
|
329
|
-
## Contributing
|
|
330
|
-
|
|
331
|
-
Contributions are welcome:
|
|
332
|
-
|
|
333
|
-
1. Fork the repository
|
|
334
|
-
2. Create a feature branch
|
|
335
|
-
3. Commit your changes
|
|
336
|
-
4. Push your branch
|
|
337
|
-
5. Open a Pull Request
|
|
338
|
-
|
|
339
|
-
All pull requests must follow [Developer Code Standards](docs/developer_code_standards.md).
|
|
340
|
-
Before requesting review, run:
|
|
341
|
-
|
|
342
|
-
```powershell
|
|
343
|
-
.\tools\deps\python311\python.exe -m ruff check .
|
|
344
|
-
.\tools\deps\python311\python.exe -m pytest test
|
|
345
|
-
.\tools\deps\python311\python.exe -m pyright
|
|
346
|
-
.\tools\deps\python311\python.exe -m compileall -q src mathcraft_ocr test
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
Cross-platform PRs must not change the Windows dependency surface or installer
|
|
350
|
-
behavior unless Windows is explicitly in scope and separately validated.
|
|
351
|
-
|
|
352
|
-
Recommended focus areas:
|
|
353
|
-
|
|
354
|
-
- Handwriting UX
|
|
355
|
-
- Math workbench UX
|
|
356
|
-
- Advanced solver stability
|
|
357
|
-
- Packaged runtime verification
|
|
358
|
-
- Theme consistency across windows
|
|
359
|
-
|
|
360
|
-
---
|
|
361
|
-
|
|
362
|
-
## License
|
|
363
|
-
|
|
364
|
-
This project is open-sourced under the [MIT License](LICENSE).
|
|
365
|
-
|
|
366
|
-
---
|
|
367
|
-
|
|
368
|
-
## Acknowledgements
|
|
369
|
-
|
|
370
|
-
Special thanks to:
|
|
371
|
-
|
|
372
|
-
- [pix2tex](https://github.com/lukas-blecher/LaTeX-OCR)
|
|
373
|
-
- [MathLive](https://github.com/arnog/mathlive)
|
|
374
|
-
- [MathLive Compute Engine](https://mathlive.io/compute-engine/)
|
|
375
|
-
- [SymPy](https://www.sympy.org/)
|
|
376
|
-
- [mpmath](https://mpmath.org/)
|
|
377
|
-
- [MathJax](https://www.mathjax.org/)
|
|
378
|
-
- [PyQt6](https://www.riverbankcomputing.com/software/pyqt/)
|
|
379
|
-
- [QFluentWidgets](https://github.com/zhiyiYo/PyQt-Fluent-Widgets)
|
|
380
|
-
|
|
381
|
-
---
|
|
382
|
-
|
|
383
|
-
<div align="center">
|
|
384
|
-
|
|
385
|
-
| Download | Issues | Discussions | Wiki |
|
|
386
|
-
|---|---|---|---|
|
|
387
|
-
| [Latest Release](https://github.com/SakuraMathcraft/LaTeXSnipper/releases/latest) | [Open an Issue](https://github.com/SakuraMathcraft/LaTeXSnipper/issues) | [Discussions](https://github.com/SakuraMathcraft/LaTeXSnipper/discussions) | [Project Wiki](https://github.com/SakuraMathcraft/LaTeXSnipper/wiki) |
|
|
388
|
-
|
|
389
|
-
</div>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|