python-color-math 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. python_color_math-0.2.0/.pre-commit-hooks.yaml +15 -0
  2. python_color_math-0.2.0/MANIFEST.in +6 -0
  3. python_color_math-0.2.0/PKG-INFO +261 -0
  4. python_color_math-0.2.0/README.md +206 -0
  5. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/__init__.py +10 -1
  6. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/adapters.py +46 -17
  7. python_color_math-0.2.0/color_math/completions.py +272 -0
  8. python_color_math-0.2.0/color_math/config.py +679 -0
  9. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/converters/block.py +21 -0
  10. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/converters/generic.py +20 -14
  11. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/converters/matrix.py +6 -0
  12. python_color_math-0.2.0/color_math/gui.py +528 -0
  13. python_color_math-0.2.0/color_math/main.py +855 -0
  14. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/__init__.py +8 -0
  15. python_color_math-0.2.0/color_math/parsers/alignment.py +74 -0
  16. python_color_math-0.2.0/color_math/parsers/constants.py +130 -0
  17. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/latex_spans.py +35 -2
  18. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/math_parser.py +142 -14
  19. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/taxonomy.py +84 -8
  20. python_color_math-0.2.0/color_math/parsers/variable_hash.py +222 -0
  21. python_color_math-0.2.0/color_math/py.typed +1 -0
  22. python_color_math-0.2.0/color_math/tutorial.py +183 -0
  23. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/utils/latex_helpers.py +177 -0
  24. {python_color_math-0.1.0 → python_color_math-0.2.0}/pyproject.toml +18 -10
  25. python_color_math-0.2.0/python_color_math/__init__.py +17 -0
  26. python_color_math-0.2.0/python_color_math/__main__.py +4 -0
  27. python_color_math-0.2.0/python_color_math.egg-info/PKG-INFO +261 -0
  28. {python_color_math-0.1.0 → python_color_math-0.2.0}/python_color_math.egg-info/SOURCES.txt +13 -1
  29. {python_color_math-0.1.0 → python_color_math-0.2.0}/python_color_math.egg-info/entry_points.txt +1 -0
  30. python_color_math-0.2.0/python_color_math.egg-info/top_level.txt +2 -0
  31. python_color_math-0.2.0/tests/test_cli.py +344 -0
  32. {python_color_math-0.1.0 → python_color_math-0.2.0}/tests/test_features.py +140 -4
  33. python_color_math-0.2.0/tests/test_gui.py +133 -0
  34. python_color_math-0.1.0/PKG-INFO +0 -167
  35. python_color_math-0.1.0/README.md +0 -116
  36. python_color_math-0.1.0/color_math/config.py +0 -351
  37. python_color_math-0.1.0/color_math/main.py +0 -162
  38. python_color_math-0.1.0/color_math/parsers/variable_hash.py +0 -126
  39. python_color_math-0.1.0/python_color_math.egg-info/PKG-INFO +0 -167
  40. python_color_math-0.1.0/python_color_math.egg-info/top_level.txt +0 -1
  41. {python_color_math-0.1.0 → python_color_math-0.2.0}/LICENSE +0 -0
  42. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/__main__.py +0 -0
  43. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/converters/__init__.py +0 -0
  44. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/converters/align.py +0 -0
  45. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/converters/derivative.py +0 -0
  46. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/converters/equation.py +0 -0
  47. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/converters/integral.py +0 -0
  48. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/converters/limit.py +0 -0
  49. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/converters/semantic.py +0 -0
  50. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/io.py +0 -0
  51. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/braket.py +0 -0
  52. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/delimiters.py +0 -0
  53. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/differentials.py +0 -0
  54. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/dimensionless.py +0 -0
  55. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/markdown_scanner.py +0 -0
  56. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/scanner.py +0 -0
  57. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/parsers/units.py +0 -0
  58. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/self_test.py +0 -0
  59. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/undo.py +0 -0
  60. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/utils/__init__.py +0 -0
  61. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/utils/coloring.py +0 -0
  62. {python_color_math-0.1.0 → python_color_math-0.2.0}/color_math/utils/spans.py +0 -0
  63. {python_color_math-0.1.0 → python_color_math-0.2.0}/python_color_math.egg-info/dependency_links.txt +0 -0
  64. {python_color_math-0.1.0 → python_color_math-0.2.0}/setup.cfg +0 -0
@@ -0,0 +1,15 @@
1
+ - id: color-math-check
2
+ name: color-math check (LaTeX math linter)
3
+ description: Verify that LaTeX math expressions in Markdown, LaTeX, and Jupyter notebooks are colored and cleanly formatted.
4
+ entry: color-math --check
5
+ language: python
6
+ types_or: [markdown, jupyter, tex]
7
+ require_serial: true
8
+
9
+ - id: color-math
10
+ name: color-math format
11
+ description: Automatically format and add semantic colors to LaTeX math expressions in Markdown, LaTeX, and Jupyter notebooks.
12
+ entry: color-math -w
13
+ language: python
14
+ types_or: [markdown, jupyter, tex]
15
+ require_serial: true
@@ -0,0 +1,6 @@
1
+ include LICENSE
2
+ include README.md
3
+ include pyproject.toml
4
+ include .pre-commit-hooks.yaml
5
+ include color_math/py.typed
6
+ recursive-include color_math *.py
@@ -0,0 +1,261 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-color-math
3
+ Version: 0.2.0
4
+ Summary: A fast, local semantic LaTeX colorizer for Markdown, Jupyter, and LaTeX math equations.
5
+ Author: Aditya
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Aditya
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/36ty-blip/python-color-math
29
+ Project-URL: Documentation, https://github.com/36ty-blip/python-color-math#readme
30
+ Project-URL: Repository, https://github.com/36ty-blip/python-color-math
31
+ Project-URL: Issues, https://github.com/36ty-blip/python-color-math/issues
32
+ Project-URL: Changelog, https://github.com/36ty-blip/python-color-math/releases
33
+ Keywords: obsidian,latex,math,markdown,jupyter,colorizer,katex,mathjax,cli
34
+ Classifier: Development Status :: 4 - Beta
35
+ Classifier: Environment :: Console
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: Intended Audience :: Education
38
+ Classifier: Intended Audience :: Science/Research
39
+ Classifier: License :: OSI Approved :: MIT License
40
+ Classifier: Operating System :: OS Independent
41
+ Classifier: Programming Language :: Python :: 3
42
+ Classifier: Programming Language :: Python :: 3 :: Only
43
+ Classifier: Programming Language :: Python :: 3.10
44
+ Classifier: Programming Language :: Python :: 3.11
45
+ Classifier: Programming Language :: Python :: 3.12
46
+ Classifier: Programming Language :: Python :: 3.13
47
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
48
+ Classifier: Topic :: Text Processing :: Markup
49
+ Classifier: Topic :: Text Processing :: Markup :: LaTeX
50
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
51
+ Requires-Python: >=3.10
52
+ Description-Content-Type: text/markdown
53
+ License-File: LICENSE
54
+ Dynamic: license-file
55
+
56
+ # 🎨 Python Color Math
57
+
58
+ > Semantic color for LaTeX equations in Markdown, Jupyter notebooks, and native TeX documents — without handing your notation to a computer algebra system.
59
+
60
+ `python-color-math` parses mathematical expressions and inserts MathJax/KaTeX-compatible `\textcolor{...}{...}` wrappers. It operates completely locally, preserves existing LaTeX structure, and leaves prose, fenced code, TeX comments, and `\verb` payloads untouched.
61
+
62
+ ---
63
+
64
+ ## 🌈 Before & After
65
+
66
+ **Input:**
67
+ ```latex
68
+ $$ \frac{d}{dx} f(g(y)) = f'(g(y)) \cdot g'(y)y' $$
69
+ ```
70
+
71
+ **Output:**
72
+ ```latex
73
+ $$ \frac{d}{dx}\textcolor{#7aa2f7}{f(g(y))} \textcolor{white}{=} \textcolor{#bb9af7}{f'(g(y))}\textcolor{white}{\cdot} \textcolor{#9ece6a}{g'(y)}\textcolor{#9ece6a}{y'} $$
74
+ ```
75
+
76
+ ---
77
+
78
+ ## 🚀 Quick Start
79
+
80
+ ### Installation
81
+
82
+ ```bash
83
+ pip install python-color-math
84
+ ```
85
+
86
+ *(Or locally from cloned source: `pip install -e .`)*
87
+
88
+ > [!TIP]
89
+ > **Commands & PATH**:
90
+ > - Registers both the short **`color-math`** and full **`python-color-math`** commands.
91
+ > - If Python's `Scripts/` folder is not on your `PATH`, run directly via Python without touching environment variables:
92
+ > `python -m color_math [options]` *(or `python -m python_color_math`)*.
93
+ > - *Linux users*: Python's standard GUI library is available via `sudo apt install python3-tk`.
94
+
95
+ ---
96
+
97
+ ## ⚡ Three Ways to Use
98
+
99
+ ### 1. 🎓 Interactive Terminal Tutorial
100
+ New to Color Math? Take the 2-minute paced CLI tour with live examples:
101
+ ```bash
102
+ color-math --tutorial
103
+ ```
104
+
105
+ ### 2. 🖥️ Graphical Pop-up Window (GUI)
106
+ Prefer visual controls? Launch the native High-DPI pop-up window:
107
+ ```bash
108
+ color-math --ui
109
+ # or:
110
+ color-math --gui
111
+ ```
112
+ - **Preview vs Write Toggle**: Inspect diffs safely or write directly to disk.
113
+ - **Visual Color Picker**: Click color chips to select custom hex values.
114
+ - **Theme & Preset Selectors**: Switch curated palettes and engine toggles in 1 click.
115
+ - **1-Click Reset**: Restore factory Tokyo Night defaults anytime.
116
+
117
+ ### 3. ⌨️ Fast Terminal Commands
118
+ ```bash
119
+ # Safe preview in terminal (leaves notes unchanged)
120
+ color-math note.md
121
+
122
+ # Save changes directly back to the note
123
+ color-math note.md -w
124
+
125
+ # Process an entire folder recursively
126
+ color-math notes/ -r -w
127
+
128
+ # Color a raw LaTeX string directly
129
+ color-math "$$\frac{d}{dx} x^2 = 2x$$"
130
+
131
+ # Read and color from standard input pipeline
132
+ cat note.md | color-math -
133
+
134
+ # Inspect syntax-colored unified diff without touching disk
135
+ color-math note.md --diff
136
+ ```
137
+
138
+ ---
139
+
140
+ ## 📋 Cheat Sheet (Command Reference)
141
+
142
+ | Task | Command | Description |
143
+ | :--- | :--- | :--- |
144
+ | **Visual Window** | `color-math --ui` *(or `--gui`)* | Open interactive High-DPI GUI |
145
+ | **Interactive Tour** | `color-math --tutorial` | 2-minute interactive terminal guide |
146
+ | **Preview** | `color-math note.md` | Safe preview (leaves disk untouched) |
147
+ | **Save / Write** | `color-math note.md -w` *(or `-i`)* | Write changes in-place |
148
+ | **Batch Folder** | `color-math notes/ -r -w` | Recursively color directory |
149
+ | **Unified Diff** | `color-math note.md --diff` | Inspect exact line changes (colorized) |
150
+ | **Linter / CI Mode** | `color-math notes/ -r --check` | Exit `0` if clean, `1` if notes need coloring |
151
+ | **Machine JSON** | `color-math notes/ -r --check --json` | Structured JSON output for CI and pipelines |
152
+ | **Stdin Pipeline** | `cat note.md \| color-math -` | Read and color math from standard input |
153
+ | **Curated Themes** | `color-math note.md --theme catppuccin -w` | Select `default`, `catppuccin`, `nord`, or `light` |
154
+ | **Feature Preset** | `color-math note.md --preset minimal -w` | Presets: `all` (default), `minimal` |
155
+ | **Custom Colors** | `color-math note.md -c unit=#73daca -w` | Override any of 12 individual color roles |
156
+ | **Reset Palette** | `color-math --reset-colors` | Restore factory Tokyo Night palette |
157
+ | **Inspect Colors** | `color-math --show-colors` | Display palette, descriptions, & terminal swatches |
158
+ | **Undo / Strip** | `color-math note.md --undo -w` | Strip color wrappers back to plain LaTeX |
159
+ | **Export Config** | `color-math --init-config` | Generate a documented `.colormath.json` |
160
+
161
+ ---
162
+
163
+ ## 🧠 Engine Features & Disambiguation
164
+
165
+ Control recognition features with `--preset {all,minimal}` (default: `all`) or individual flags:
166
+
167
+ - **Calculus Differentials (`--differentials`)**: Disambiguates `dx`, `dt`, `d\theta`, and derivatives (`\frac{d}{dx}`, `\frac{\partial \psi}{\partial t}`) while leaving standalone distance variables `$d$` untouched.
168
+ - **Physical Units (`--units`)**: Recognizes metric prefixes and unit compounds (`\mu m`, `m/s`, `kg`, `nm`).
169
+ - **Rainbow Delimiters (`--rainbow-delimiters`)**: Recursively colors nested brackets `()`, `[]`, `{}` by depth to eliminate delimiter blindness.
170
+ - **Quantum Bra-Ket (`--braket`)**: Dirac notation (`|\psi\rangle`, `\langle\phi|`, `\langle\phi|\psi\rangle`).
171
+ - **Dimensionless Groups (`--dimensionless`)**: Recognizes engineering numbers (`Re`, `Ma`, `Pr`, `Nu`).
172
+ - **Semantic Taxonomy (`--taxonomy`)**: Colors constants ($\pi, \hbar, \infty$), Greek parameters ($\alpha, \theta$), and standard functions ($\sin, \cos, \ln$).
173
+ - **Variable Data-Flow (`--variable-data-flow`)**: Deterministically hashes variable names to track variable flow across equations.
174
+
175
+ ---
176
+
177
+ ## 📁 Supported File Formats
178
+
179
+ `python-color-math` automatically detects file formats by extension:
180
+ - **Markdown**: `.md`, `.markdown`, `.qmd` (Quarto)
181
+ - **Jupyter Notebooks**: `.ipynb` (transforms only Markdown cells)
182
+ - **Native LaTeX**: `.tex`, `.latex` (adds `\usepackage{xcolor}` compatibility)
183
+ - **Anki Flashcards**: `.tsv`, `.txt` (select via `--format anki`)
184
+
185
+ ---
186
+
187
+ ## ↩️ Complete Reversibility (Undo)
188
+
189
+ Never worry about locking your documents into color wrappers:
190
+ ```bash
191
+ # Preview what plain LaTeX would look like
192
+ color-math note.md --undo
193
+
194
+ # Restore plain LaTeX back to disk
195
+ color-math note.md --undo -w
196
+
197
+ # Strip colors from an entire vault
198
+ color-math notes/ -r --undo -w
199
+ ```
200
+ *Undo cleanly removes generated `\textcolor{...}{...}` and compatible legacy `\color{...}{...}` wrappers.*
201
+
202
+ ---
203
+
204
+ ## 🐚 Shell Autocompletion
205
+
206
+ Generate fast, native completions with full support for all flags, themes, presets, and file formats:
207
+
208
+ ```bash
209
+ # Bash
210
+ color-math --generate-completion bash >> ~/.bash_completion
211
+
212
+ # Zsh
213
+ color-math --generate-completion zsh > ~/.zsh/completion/_color-math
214
+
215
+ # Fish
216
+ color-math --generate-completion fish > ~/.config/fish/completions/color-math.fish
217
+
218
+ # PowerShell
219
+ color-math --generate-completion powershell | Out-String | Invoke-Expression
220
+ # Or persist to your $PROFILE:
221
+ Add-Content $PROFILE "`ncolor-math --generate-completion powershell | Out-String | Invoke-Expression"
222
+ ```
223
+
224
+ ---
225
+
226
+ ## 🪝 Pre-commit Integration
227
+
228
+ Integrate `color-math` into your git workflow using [pre-commit](https://pre-commit.com):
229
+
230
+ ```yaml
231
+ repos:
232
+ - repo: https://github.com/36ty-blip/color-math
233
+ rev: v0.2.0
234
+ hooks:
235
+ # Formatter: colorizes modified Markdown, LaTeX, and Jupyter files in-place
236
+ - id: color-math
237
+ # Linter: verifies math formatting without modifying files (fails if uncolored)
238
+ # - id: color-math-check
239
+ ```
240
+
241
+ ---
242
+
243
+ ## ⚙️ Configuration & Standards
244
+
245
+ `python-color-math` adheres to modern CLI standards ([clig.dev](https://clig.dev/)):
246
+ - **Config Hierarchy**: `--config <file>` > `./.colormath.json` (project local) > Global user config (`%APPDATA%\color-math\config.json` on Windows or `~/.config/color-math/config.json` on Linux/macOS) > Factory defaults.
247
+ - **Color Standards**: Honors `NO_COLOR` ([no-color.org](https://no-color.org)), `FORCE_COLOR`, and `TERM=dumb`.
248
+ - **CI / Pre-commit**: Combine `--check --json` for structured reporting in automated pipelines.
249
+
250
+ ---
251
+
252
+ ## 🤝 Obsidian Companion Plugin
253
+
254
+ Looking for dynamic real-time equation coloring inside Obsidian without modifying notes on disk? Check out the sister plugin:
255
+ 👉 [**Obsidian Color Math**](https://github.com/36ty-blip/obsidian-color-math) *(Pure TypeScript, runs natively on Obsidian Desktop & Mobile).*
256
+
257
+ ---
258
+
259
+ ## 📄 License
260
+
261
+ Released under the [MIT License](LICENSE).
@@ -0,0 +1,206 @@
1
+ # 🎨 Python Color Math
2
+
3
+ > Semantic color for LaTeX equations in Markdown, Jupyter notebooks, and native TeX documents — without handing your notation to a computer algebra system.
4
+
5
+ `python-color-math` parses mathematical expressions and inserts MathJax/KaTeX-compatible `\textcolor{...}{...}` wrappers. It operates completely locally, preserves existing LaTeX structure, and leaves prose, fenced code, TeX comments, and `\verb` payloads untouched.
6
+
7
+ ---
8
+
9
+ ## 🌈 Before & After
10
+
11
+ **Input:**
12
+ ```latex
13
+ $$ \frac{d}{dx} f(g(y)) = f'(g(y)) \cdot g'(y)y' $$
14
+ ```
15
+
16
+ **Output:**
17
+ ```latex
18
+ $$ \frac{d}{dx}\textcolor{#7aa2f7}{f(g(y))} \textcolor{white}{=} \textcolor{#bb9af7}{f'(g(y))}\textcolor{white}{\cdot} \textcolor{#9ece6a}{g'(y)}\textcolor{#9ece6a}{y'} $$
19
+ ```
20
+
21
+ ---
22
+
23
+ ## 🚀 Quick Start
24
+
25
+ ### Installation
26
+
27
+ ```bash
28
+ pip install python-color-math
29
+ ```
30
+
31
+ *(Or locally from cloned source: `pip install -e .`)*
32
+
33
+ > [!TIP]
34
+ > **Commands & PATH**:
35
+ > - Registers both the short **`color-math`** and full **`python-color-math`** commands.
36
+ > - If Python's `Scripts/` folder is not on your `PATH`, run directly via Python without touching environment variables:
37
+ > `python -m color_math [options]` *(or `python -m python_color_math`)*.
38
+ > - *Linux users*: Python's standard GUI library is available via `sudo apt install python3-tk`.
39
+
40
+ ---
41
+
42
+ ## ⚡ Three Ways to Use
43
+
44
+ ### 1. 🎓 Interactive Terminal Tutorial
45
+ New to Color Math? Take the 2-minute paced CLI tour with live examples:
46
+ ```bash
47
+ color-math --tutorial
48
+ ```
49
+
50
+ ### 2. 🖥️ Graphical Pop-up Window (GUI)
51
+ Prefer visual controls? Launch the native High-DPI pop-up window:
52
+ ```bash
53
+ color-math --ui
54
+ # or:
55
+ color-math --gui
56
+ ```
57
+ - **Preview vs Write Toggle**: Inspect diffs safely or write directly to disk.
58
+ - **Visual Color Picker**: Click color chips to select custom hex values.
59
+ - **Theme & Preset Selectors**: Switch curated palettes and engine toggles in 1 click.
60
+ - **1-Click Reset**: Restore factory Tokyo Night defaults anytime.
61
+
62
+ ### 3. ⌨️ Fast Terminal Commands
63
+ ```bash
64
+ # Safe preview in terminal (leaves notes unchanged)
65
+ color-math note.md
66
+
67
+ # Save changes directly back to the note
68
+ color-math note.md -w
69
+
70
+ # Process an entire folder recursively
71
+ color-math notes/ -r -w
72
+
73
+ # Color a raw LaTeX string directly
74
+ color-math "$$\frac{d}{dx} x^2 = 2x$$"
75
+
76
+ # Read and color from standard input pipeline
77
+ cat note.md | color-math -
78
+
79
+ # Inspect syntax-colored unified diff without touching disk
80
+ color-math note.md --diff
81
+ ```
82
+
83
+ ---
84
+
85
+ ## 📋 Cheat Sheet (Command Reference)
86
+
87
+ | Task | Command | Description |
88
+ | :--- | :--- | :--- |
89
+ | **Visual Window** | `color-math --ui` *(or `--gui`)* | Open interactive High-DPI GUI |
90
+ | **Interactive Tour** | `color-math --tutorial` | 2-minute interactive terminal guide |
91
+ | **Preview** | `color-math note.md` | Safe preview (leaves disk untouched) |
92
+ | **Save / Write** | `color-math note.md -w` *(or `-i`)* | Write changes in-place |
93
+ | **Batch Folder** | `color-math notes/ -r -w` | Recursively color directory |
94
+ | **Unified Diff** | `color-math note.md --diff` | Inspect exact line changes (colorized) |
95
+ | **Linter / CI Mode** | `color-math notes/ -r --check` | Exit `0` if clean, `1` if notes need coloring |
96
+ | **Machine JSON** | `color-math notes/ -r --check --json` | Structured JSON output for CI and pipelines |
97
+ | **Stdin Pipeline** | `cat note.md \| color-math -` | Read and color math from standard input |
98
+ | **Curated Themes** | `color-math note.md --theme catppuccin -w` | Select `default`, `catppuccin`, `nord`, or `light` |
99
+ | **Feature Preset** | `color-math note.md --preset minimal -w` | Presets: `all` (default), `minimal` |
100
+ | **Custom Colors** | `color-math note.md -c unit=#73daca -w` | Override any of 12 individual color roles |
101
+ | **Reset Palette** | `color-math --reset-colors` | Restore factory Tokyo Night palette |
102
+ | **Inspect Colors** | `color-math --show-colors` | Display palette, descriptions, & terminal swatches |
103
+ | **Undo / Strip** | `color-math note.md --undo -w` | Strip color wrappers back to plain LaTeX |
104
+ | **Export Config** | `color-math --init-config` | Generate a documented `.colormath.json` |
105
+
106
+ ---
107
+
108
+ ## 🧠 Engine Features & Disambiguation
109
+
110
+ Control recognition features with `--preset {all,minimal}` (default: `all`) or individual flags:
111
+
112
+ - **Calculus Differentials (`--differentials`)**: Disambiguates `dx`, `dt`, `d\theta`, and derivatives (`\frac{d}{dx}`, `\frac{\partial \psi}{\partial t}`) while leaving standalone distance variables `$d$` untouched.
113
+ - **Physical Units (`--units`)**: Recognizes metric prefixes and unit compounds (`\mu m`, `m/s`, `kg`, `nm`).
114
+ - **Rainbow Delimiters (`--rainbow-delimiters`)**: Recursively colors nested brackets `()`, `[]`, `{}` by depth to eliminate delimiter blindness.
115
+ - **Quantum Bra-Ket (`--braket`)**: Dirac notation (`|\psi\rangle`, `\langle\phi|`, `\langle\phi|\psi\rangle`).
116
+ - **Dimensionless Groups (`--dimensionless`)**: Recognizes engineering numbers (`Re`, `Ma`, `Pr`, `Nu`).
117
+ - **Semantic Taxonomy (`--taxonomy`)**: Colors constants ($\pi, \hbar, \infty$), Greek parameters ($\alpha, \theta$), and standard functions ($\sin, \cos, \ln$).
118
+ - **Variable Data-Flow (`--variable-data-flow`)**: Deterministically hashes variable names to track variable flow across equations.
119
+
120
+ ---
121
+
122
+ ## 📁 Supported File Formats
123
+
124
+ `python-color-math` automatically detects file formats by extension:
125
+ - **Markdown**: `.md`, `.markdown`, `.qmd` (Quarto)
126
+ - **Jupyter Notebooks**: `.ipynb` (transforms only Markdown cells)
127
+ - **Native LaTeX**: `.tex`, `.latex` (adds `\usepackage{xcolor}` compatibility)
128
+ - **Anki Flashcards**: `.tsv`, `.txt` (select via `--format anki`)
129
+
130
+ ---
131
+
132
+ ## ↩️ Complete Reversibility (Undo)
133
+
134
+ Never worry about locking your documents into color wrappers:
135
+ ```bash
136
+ # Preview what plain LaTeX would look like
137
+ color-math note.md --undo
138
+
139
+ # Restore plain LaTeX back to disk
140
+ color-math note.md --undo -w
141
+
142
+ # Strip colors from an entire vault
143
+ color-math notes/ -r --undo -w
144
+ ```
145
+ *Undo cleanly removes generated `\textcolor{...}{...}` and compatible legacy `\color{...}{...}` wrappers.*
146
+
147
+ ---
148
+
149
+ ## 🐚 Shell Autocompletion
150
+
151
+ Generate fast, native completions with full support for all flags, themes, presets, and file formats:
152
+
153
+ ```bash
154
+ # Bash
155
+ color-math --generate-completion bash >> ~/.bash_completion
156
+
157
+ # Zsh
158
+ color-math --generate-completion zsh > ~/.zsh/completion/_color-math
159
+
160
+ # Fish
161
+ color-math --generate-completion fish > ~/.config/fish/completions/color-math.fish
162
+
163
+ # PowerShell
164
+ color-math --generate-completion powershell | Out-String | Invoke-Expression
165
+ # Or persist to your $PROFILE:
166
+ Add-Content $PROFILE "`ncolor-math --generate-completion powershell | Out-String | Invoke-Expression"
167
+ ```
168
+
169
+ ---
170
+
171
+ ## 🪝 Pre-commit Integration
172
+
173
+ Integrate `color-math` into your git workflow using [pre-commit](https://pre-commit.com):
174
+
175
+ ```yaml
176
+ repos:
177
+ - repo: https://github.com/36ty-blip/color-math
178
+ rev: v0.2.0
179
+ hooks:
180
+ # Formatter: colorizes modified Markdown, LaTeX, and Jupyter files in-place
181
+ - id: color-math
182
+ # Linter: verifies math formatting without modifying files (fails if uncolored)
183
+ # - id: color-math-check
184
+ ```
185
+
186
+ ---
187
+
188
+ ## ⚙️ Configuration & Standards
189
+
190
+ `python-color-math` adheres to modern CLI standards ([clig.dev](https://clig.dev/)):
191
+ - **Config Hierarchy**: `--config <file>` > `./.colormath.json` (project local) > Global user config (`%APPDATA%\color-math\config.json` on Windows or `~/.config/color-math/config.json` on Linux/macOS) > Factory defaults.
192
+ - **Color Standards**: Honors `NO_COLOR` ([no-color.org](https://no-color.org)), `FORCE_COLOR`, and `TERM=dumb`.
193
+ - **CI / Pre-commit**: Combine `--check --json` for structured reporting in automated pipelines.
194
+
195
+ ---
196
+
197
+ ## 🤝 Obsidian Companion Plugin
198
+
199
+ Looking for dynamic real-time equation coloring inside Obsidian without modifying notes on disk? Check out the sister plugin:
200
+ 👉 [**Obsidian Color Math**](https://github.com/36ty-blip/obsidian-color-math) *(Pure TypeScript, runs natively on Obsidian Desktop & Mobile).*
201
+
202
+ ---
203
+
204
+ ## 📄 License
205
+
206
+ Released under the [MIT License](LICENSE).
@@ -5,4 +5,13 @@ from .config import ColorMathOptions
5
5
  from .converters.block import convert_text
6
6
  from .undo import uncolor_text
7
7
 
8
- __all__ = ["ColorMathOptions", "convert_text", "detect_format", "transform_document", "uncolor_text"]
8
+ __version__ = "0.2.0"
9
+
10
+ __all__ = [
11
+ "__version__",
12
+ "ColorMathOptions",
13
+ "convert_text",
14
+ "detect_format",
15
+ "transform_document",
16
+ "uncolor_text",
17
+ ]
@@ -6,6 +6,7 @@ import json
6
6
  import re
7
7
  from pathlib import Path
8
8
 
9
+ from .config import ColorMathOptions
9
10
  from .converters.block import convert_math_block, convert_text
10
11
  from .undo import uncolor_fragment, uncolor_text
11
12
  from .utils.latex_helpers import read_comment_end, read_verb_end
@@ -49,26 +50,42 @@ def detect_format(path: Path | None, requested: str = "auto") -> str:
49
50
  return "markdown"
50
51
 
51
52
 
52
- def transform_document(text: str, format_name: str, undo: bool = False) -> str:
53
+ def transform_document(
54
+ text: str,
55
+ format_name: str,
56
+ undo: bool = False,
57
+ palette: dict[str, str] | None = None,
58
+ options: ColorMathOptions | None = None,
59
+ ) -> str:
53
60
  if format_name == "markdown":
54
- return uncolor_text(text) if undo else convert_text(text)
61
+ return uncolor_text(text) if undo else convert_text(text, palette=palette, options=options)
55
62
  if format_name == "jupyter":
56
- return _transform_notebook(text, undo)
63
+ return _transform_notebook(text, undo, palette=palette, options=options)
57
64
  if format_name == "anki":
58
- return _transform_delimited(text, ANKI_DELIMITERS, undo)
65
+ return _transform_delimited(text, ANKI_DELIMITERS, undo, palette=palette, options=options)
59
66
  if format_name == "tex":
60
- return _transform_tex(text, undo)
67
+ return _transform_tex(text, undo, palette=palette, options=options)
61
68
  raise AdapterError(f"unsupported format: {format_name}")
62
69
 
63
70
 
64
- def _transform_fragment(text: str, undo: bool) -> str:
71
+ def _transform_fragment(
72
+ text: str,
73
+ undo: bool,
74
+ palette: dict[str, str] | None = None,
75
+ options: ColorMathOptions | None = None,
76
+ ) -> str:
65
77
  if undo:
66
78
  return uncolor_fragment(text)
67
- converted = convert_math_block(f"$${text}$$")
79
+ converted = convert_math_block(f"$${text}$$", palette=palette, options=options)
68
80
  return converted[2:-2]
69
81
 
70
82
 
71
- def _transform_notebook(text: str, undo: bool) -> str:
83
+ def _transform_notebook(
84
+ text: str,
85
+ undo: bool,
86
+ palette: dict[str, str] | None = None,
87
+ options: ColorMathOptions | None = None,
88
+ ) -> str:
72
89
  try:
73
90
  notebook = json.loads(text)
74
91
  except json.JSONDecodeError as error:
@@ -89,7 +106,7 @@ def _transform_notebook(text: str, undo: bool) -> str:
89
106
  else:
90
107
  raise AdapterError(f"markdown cell {index + 1} has an invalid source")
91
108
 
92
- converted = uncolor_text(joined) if undo else convert_text(joined)
109
+ converted = uncolor_text(joined) if undo else convert_text(joined, palette=palette, options=options)
93
110
  if converted == joined:
94
111
  continue
95
112
  cell["source"] = (
@@ -145,6 +162,8 @@ def _transform_delimited(
145
162
  text: str,
146
163
  delimiters: tuple[tuple[str, str], ...],
147
164
  undo: bool,
165
+ palette: dict[str, str] | None = None,
166
+ options: ColorMathOptions | None = None,
148
167
  ) -> str:
149
168
  output: list[str] = []
150
169
  index = 0
@@ -154,7 +173,7 @@ def _transform_delimited(
154
173
  if end < 0:
155
174
  break
156
175
  output.append(text[index:start + len(opening)])
157
- output.append(_transform_fragment(text[start + len(opening):end], undo))
176
+ output.append(_transform_fragment(text[start + len(opening):end], undo, palette=palette, options=options))
158
177
  output.append(closing)
159
178
  index = end + len(closing)
160
179
  output.append(text[index:])
@@ -190,7 +209,12 @@ def _find_dollar(text: str, start: int, width: int) -> int:
190
209
  return -1
191
210
 
192
211
 
193
- def _transform_tex_math(text: str, undo: bool) -> str:
212
+ def _transform_tex_math(
213
+ text: str,
214
+ undo: bool,
215
+ palette: dict[str, str] | None = None,
216
+ options: ColorMathOptions | None = None,
217
+ ) -> str:
194
218
  output: list[str] = []
195
219
  index = 0
196
220
  while index < len(text):
@@ -220,7 +244,7 @@ def _transform_tex_math(text: str, undo: bool) -> str:
220
244
  continue
221
245
  if end_start >= 0 and name in MATH_ENVIRONMENTS:
222
246
  end = end_start + len(closing)
223
- output.append(_transform_fragment(text[index:end], undo))
247
+ output.append(_transform_fragment(text[index:end], undo, palette=palette, options=options))
224
248
  index = end
225
249
  continue
226
250
 
@@ -233,7 +257,7 @@ def _transform_tex_math(text: str, undo: bool) -> str:
233
257
  end_start = _find_active(text, closing, index + len(opening))
234
258
  if end_start >= 0:
235
259
  output.append(opening)
236
- output.append(_transform_fragment(text[index + len(opening):end_start], undo))
260
+ output.append(_transform_fragment(text[index + len(opening):end_start], undo, palette=palette, options=options))
237
261
  output.append(closing)
238
262
  index = end_start + len(closing)
239
263
  continue
@@ -244,7 +268,7 @@ def _transform_tex_math(text: str, undo: bool) -> str:
244
268
  if end_start >= 0:
245
269
  delimiter = "$" * width
246
270
  output.append(delimiter)
247
- output.append(_transform_fragment(text[index + width:end_start], undo))
271
+ output.append(_transform_fragment(text[index + width:end_start], undo, palette=palette, options=options))
248
272
  output.append(delimiter)
249
273
  index = end_start + width
250
274
  continue
@@ -282,7 +306,12 @@ def _native_support(text: str) -> str:
282
306
  return translated[:insertion] + block + translated[insertion:]
283
307
 
284
308
 
285
- def _transform_tex(text: str, undo: bool) -> str:
309
+ def _transform_tex(
310
+ text: str,
311
+ undo: bool,
312
+ palette: dict[str, str] | None = None,
313
+ options: ColorMathOptions | None = None,
314
+ ) -> str:
286
315
  if undo:
287
- return _transform_tex_math(NATIVE_BLOCK_RE.sub("", text), True)
288
- return _native_support(_transform_tex_math(text, False))
316
+ return _transform_tex_math(NATIVE_BLOCK_RE.sub("", text), True, palette=palette, options=options)
317
+ return _native_support(_transform_tex_math(text, False, palette=palette, options=options))