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.
Files changed (44) hide show
  1. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/LICENSE +21 -21
  2. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/MANIFEST.in +13 -13
  3. {mathcraft_ocr-0.2.2/mathcraft_ocr.egg-info → mathcraft_ocr-0.2.3}/PKG-INFO +8 -4
  4. mathcraft_ocr-0.2.3/README.md +230 -0
  5. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/README_MATHCRAFT_OCR.md +7 -3
  6. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/__init__.py +1 -1
  7. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/cache.py +5 -1
  8. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/hardware.py +80 -2
  9. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3/mathcraft_ocr.egg-info}/PKG-INFO +8 -4
  10. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr.egg-info/SOURCES.txt +1 -1
  11. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/pyproject.toml +3 -7
  12. mathcraft_ocr-0.2.2/readme.md +0 -389
  13. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/__main__.py +0 -0
  14. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/__init__.py +0 -0
  15. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/common.py +0 -0
  16. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/formula_detector.py +0 -0
  17. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/formula_recognizer.py +0 -0
  18. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/text_detector.py +0 -0
  19. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/adapters/text_recognizer.py +0 -0
  20. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/api.py +0 -0
  21. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/cli.py +0 -0
  22. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/debug_blocks.py +0 -0
  23. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/doctor.py +0 -0
  24. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/downloader.py +0 -0
  25. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/error_patterns.py +0 -0
  26. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/errors.py +0 -0
  27. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/formula_lines.py +0 -0
  28. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/image.py +0 -0
  29. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/latex_alignment.py +0 -0
  30. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/latex_quality.py +0 -0
  31. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/layout.py +0 -0
  32. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/manifest.py +0 -0
  33. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/manifests/models.v1.json +0 -0
  34. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/profiles.py +0 -0
  35. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/providers.py +0 -0
  36. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/results.py +0 -0
  37. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/runtime.py +0 -0
  38. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/serialization.py +0 -0
  39. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr/worker.py +0 -0
  40. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr.egg-info/dependency_links.txt +0 -0
  41. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr.egg-info/entry_points.txt +0 -0
  42. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr.egg-info/requires.txt +0 -0
  43. {mathcraft_ocr-0.2.2 → mathcraft_ocr-0.2.3}/mathcraft_ocr.egg-info/top_level.txt +0 -0
  44. {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.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`.
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- __version__ = "0.2.2"
5
+ __version__ = "0.2.3"
6
6
 
7
7
  __all__ = [
8
8
  "DoctorReport",
@@ -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
- return Path.home() / ".mathcraft" / "models"
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 = _windows_memory_status()
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.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`.
@@ -1,8 +1,8 @@
1
1
  LICENSE
2
2
  MANIFEST.in
3
+ README.md
3
4
  README_MATHCRAFT_OCR.md
4
5
  pyproject.toml
5
- readme.md
6
6
  mathcraft_ocr/__init__.py
7
7
  mathcraft_ocr/__main__.py
8
8
  mathcraft_ocr/api.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mathcraft-ocr"
7
- version = "0.2.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
- "tools/deps/python311/"
87
+ "src/deps/python311/",
88
+ "src/get-pip.py"
93
89
  ]
94
90
  min_confidence = 70
95
91
  sort_by_size = true
@@ -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
- ![Stars](https://img.shields.io/github/stars/SakuraMathcraft/LaTeXSnipper?style=flat-square&label=Stars&color=FFD700)
9
- ![Forks](https://img.shields.io/github/forks/SakuraMathcraft/LaTeXSnipper?style=flat-square&label=Forks&color=1f6feb)
10
- ![Issues](https://img.shields.io/github/issues/SakuraMathcraft/LaTeXSnipper?style=flat-square&label=Issues&color=d1481e)
11
- ![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)
12
- ![Version](https://img.shields.io/badge/version-v2.3.2_Final_Stable-brightgreen?style=flat-square)
13
- ![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-orange?style=flat-square)
14
- ![Python](https://img.shields.io/badge/python-3.11-blue?style=flat-square)
15
-
16
- [![GitHub Release](https://img.shields.io/github/v/release/SakuraMathcraft/LaTeXSnipper?style=flat-square&include_prereleases)](https://github.com/SakuraMathcraft/LaTeXSnipper/releases)
17
- [![Last Commit](https://img.shields.io/github/last-commit/SakuraMathcraft/LaTeXSnipper?style=flat-square)](https://github.com/SakuraMathcraft/LaTeXSnipper/commits)
18
- [![Activity](https://img.shields.io/github/commit-activity/m/SakuraMathcraft/LaTeXSnipper?style=flat-square&label=Activity)](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
- [![Star History Chart](https://api.star-history.com/svg?repos=SakuraMathcraft/LaTeXSnipper&type=Date)](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