python-color-math 0.1.0__py3-none-any.whl

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 (40) hide show
  1. color_math/__init__.py +8 -0
  2. color_math/__main__.py +5 -0
  3. color_math/adapters.py +288 -0
  4. color_math/config.py +351 -0
  5. color_math/converters/__init__.py +27 -0
  6. color_math/converters/align.py +18 -0
  7. color_math/converters/block.py +126 -0
  8. color_math/converters/derivative.py +266 -0
  9. color_math/converters/equation.py +5 -0
  10. color_math/converters/generic.py +101 -0
  11. color_math/converters/integral.py +16 -0
  12. color_math/converters/limit.py +16 -0
  13. color_math/converters/matrix.py +143 -0
  14. color_math/converters/semantic.py +76 -0
  15. color_math/io.py +53 -0
  16. color_math/main.py +162 -0
  17. color_math/parsers/__init__.py +64 -0
  18. color_math/parsers/braket.py +109 -0
  19. color_math/parsers/delimiters.py +151 -0
  20. color_math/parsers/differentials.py +71 -0
  21. color_math/parsers/dimensionless.py +74 -0
  22. color_math/parsers/latex_spans.py +1050 -0
  23. color_math/parsers/markdown_scanner.py +463 -0
  24. color_math/parsers/math_parser.py +366 -0
  25. color_math/parsers/scanner.py +351 -0
  26. color_math/parsers/taxonomy.py +124 -0
  27. color_math/parsers/units.py +98 -0
  28. color_math/parsers/variable_hash.py +126 -0
  29. color_math/self_test.py +224 -0
  30. color_math/undo.py +63 -0
  31. color_math/utils/__init__.py +30 -0
  32. color_math/utils/coloring.py +61 -0
  33. color_math/utils/latex_helpers.py +232 -0
  34. color_math/utils/spans.py +77 -0
  35. python_color_math-0.1.0.dist-info/METADATA +167 -0
  36. python_color_math-0.1.0.dist-info/RECORD +40 -0
  37. python_color_math-0.1.0.dist-info/WHEEL +5 -0
  38. python_color_math-0.1.0.dist-info/entry_points.txt +2 -0
  39. python_color_math-0.1.0.dist-info/licenses/LICENSE +21 -0
  40. python_color_math-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,61 @@
1
+ # utils/coloring.py
2
+
3
+ from ..config import (
4
+ COLORS,
5
+ BIG_OPERATORS,
6
+ INTEGRALS,
7
+ LIMIT_OPERATORS,
8
+ ARROWS,
9
+ SET_SYMBOLS,
10
+ SPACING_COMMANDS,
11
+ MULTIPLICATION_SYMBOLS,
12
+ )
13
+
14
+
15
+ def latex_color(color: str, value: str) -> str:
16
+ """
17
+ Wrap LaTeX text in a color command.
18
+
19
+ Example:
20
+ ("red", "x")
21
+ -> "\\textcolor{red}{x}"
22
+ """
23
+ return rf"\textcolor{{{color}}}{{{value}}}"
24
+
25
+
26
+ def command_color(command: str) -> str:
27
+ """
28
+ Determine which color category a LaTeX command belongs to.
29
+
30
+ Example:
31
+ "\\sum" -> orange
32
+ "\\rightarrow" -> arrow color
33
+ "\\in" -> set color
34
+ """
35
+
36
+ # Big math operators
37
+ if (
38
+ command in BIG_OPERATORS
39
+ or command in INTEGRALS
40
+ or command in LIMIT_OPERATORS
41
+ ):
42
+ return COLORS["orange"]
43
+
44
+ # Arrows
45
+ if command in ARROWS:
46
+ return COLORS["arrow"]
47
+
48
+ # Set theory symbols
49
+ if command in SET_SYMBOLS:
50
+ return COLORS["set"]
51
+
52
+ # Spacing commands
53
+ if command in SPACING_COMMANDS:
54
+ return COLORS["spacing"]
55
+
56
+ # Multiplication symbols
57
+ if command in MULTIPLICATION_SYMBOLS:
58
+ return COLORS["dot"]
59
+
60
+ # Default relations (=, <, >, etc.)
61
+ return COLORS["relation"]
@@ -0,0 +1,232 @@
1
+ # latex_helpers.py
2
+
3
+ import re
4
+
5
+
6
+ COMMAND_RE = re.compile(r"\\[A-Za-z]+|\\.")
7
+
8
+
9
+ def read_comment_end(text: str, start: int) -> int:
10
+ """Return the index after one TeX comment, including its newline."""
11
+ index = start + 1
12
+ while index < len(text) and text[index] not in "\r\n":
13
+ index += 1
14
+ if text.startswith("\r\n", index):
15
+ return index + 2
16
+ return min(index + 1, len(text))
17
+
18
+
19
+ def read_verb_end(text: str, start: int) -> tuple[int, bool] | None:
20
+ r"""Read an exact ``\verb``/``\verb*`` payload without inspecting it."""
21
+ if not text.startswith(r"\verb", start):
22
+ return None
23
+ command_end = start + len(r"\verb")
24
+ if command_end < len(text) and text[command_end].isalpha():
25
+ return None
26
+ if command_end < len(text) and text[command_end] == "*":
27
+ command_end += 1
28
+ if command_end >= len(text) or text[command_end].isspace():
29
+ return len(text), False
30
+
31
+ delimiter = text[command_end]
32
+ closing = text.find(delimiter, command_end + 1)
33
+ return (
34
+ (len(text), False)
35
+ if closing < 0
36
+ else (closing + 1, True)
37
+ )
38
+
39
+
40
+ def read_braced(text: str, start: int) -> tuple[str, int] | None:
41
+ """
42
+ Read a balanced {...} group starting at index 'start'.
43
+
44
+ Returns:
45
+ (captured_text, end_index)
46
+
47
+ Example:
48
+ "{abc}" -> ("{abc}", 5)
49
+ """
50
+ if start >= len(text) or text[start] != "{":
51
+ return None
52
+
53
+ depth = 0
54
+ index = start
55
+
56
+ while index < len(text):
57
+ char = text[index]
58
+
59
+ if char == "%":
60
+ index = read_comment_end(text, index)
61
+ continue
62
+
63
+ if char == "\\":
64
+ verb = read_verb_end(text, index)
65
+ if verb is not None:
66
+ index, closed = verb
67
+ if not closed:
68
+ return None
69
+ continue
70
+ command = COMMAND_RE.match(text, index)
71
+ index = command.end() if command is not None else index + 1
72
+ continue
73
+
74
+ if char == "{":
75
+ depth += 1
76
+ elif char == "}":
77
+ depth -= 1
78
+ if depth == 0:
79
+ return text[start:index + 1], index + 1
80
+
81
+ index += 1
82
+
83
+ return None
84
+
85
+
86
+ def read_script_argument(text: str, start: int) -> tuple[str, int] | None:
87
+ """
88
+ Read argument after _ or ^
89
+
90
+ Handles:
91
+ x^{abc}
92
+ x^n
93
+ x^\\alpha
94
+ """
95
+
96
+ if start >= len(text):
97
+ return None
98
+
99
+ # Braced argument
100
+ if text[start] == "{":
101
+ return read_braced(text, start)
102
+
103
+ if text[start] in "$\r\n":
104
+ return None
105
+
106
+ # Latex command
107
+ if text[start] == "\\":
108
+ match = re.match(r"\\[A-Za-z]+|\\.", text[start:])
109
+ if match:
110
+ return match.group(0), start + len(match.group(0))
111
+
112
+ # Single character
113
+ return text[start], start + 1
114
+
115
+
116
+ def read_script(text: str, start: int) -> tuple[str, int, bool] | None:
117
+ """
118
+ Read full superscript/subscript.
119
+
120
+ Example:
121
+ "^2"
122
+ "_{abc}"
123
+ "^\\alpha"
124
+ """
125
+
126
+ marker = text[start] # _ or ^
127
+
128
+ argument_start = start + 1
129
+
130
+ if argument_start < len(text) and text[argument_start] == "{":
131
+ argument_data = read_braced(text, argument_start)
132
+
133
+ if argument_data is None:
134
+ return text[start:], len(text), False
135
+
136
+ argument, end = argument_data
137
+ return f"{marker}{argument}", end, True
138
+
139
+ argument_data = read_script_argument(text, argument_start)
140
+
141
+ if argument_data is None:
142
+ return None
143
+
144
+ argument, end = argument_data
145
+
146
+ return f"{marker}{argument}", end, True
147
+
148
+
149
+ def read_color_wrapper(text: str, start: int) -> tuple[str, int] | None:
150
+ """
151
+ Read a scoped color wrapper and return its unbraced value and end index.
152
+
153
+ Supports current ``\\textcolor{red}{x}`` output and legacy
154
+ ``\\color{red}{x}`` output. Command names are matched exactly, so macros
155
+ such as ``\\colorbox`` and ``\\colorful`` are left alone.
156
+ """
157
+ command = next(
158
+ (
159
+ candidate
160
+ for candidate in (r"\textcolor", r"\color")
161
+ if text.startswith(candidate, start)
162
+ and (
163
+ start + len(candidate) == len(text)
164
+ or not text[start + len(candidate)].isalpha()
165
+ )
166
+ ),
167
+ None,
168
+ )
169
+ if command is None:
170
+ return None
171
+
172
+ index = start + len(command)
173
+
174
+ while index < len(text) and text[index].isspace():
175
+ index += 1
176
+
177
+ color_data = read_braced(text, index)
178
+ if color_data is None:
179
+ return None
180
+
181
+ _, index = color_data
182
+
183
+ while index < len(text) and text[index].isspace():
184
+ index += 1
185
+
186
+ value_data = read_braced(text, index)
187
+ if value_data is None:
188
+ return None
189
+
190
+ value, end = value_data
191
+ return value[1:-1], end
192
+
193
+
194
+ def read_color_command(text: str, start: int) -> tuple[str, int] | None:
195
+ """
196
+ Detect an existing scoped color command.
197
+
198
+ Examples:
199
+ \\textcolor{red}{x}
200
+ \\color{red}{x}
201
+
202
+ Returns:
203
+ (full_command, end_index)
204
+ or None
205
+ """
206
+ wrapper = read_color_wrapper(text, start)
207
+ if wrapper is None:
208
+ return None
209
+
210
+ _, end = wrapper
211
+ return text[start:end], end
212
+
213
+
214
+ def contains_color_wrapper(text: str) -> bool:
215
+ """Find active wrappers, ignoring TeX comments and verbatim payloads."""
216
+ index = 0
217
+ while index < len(text):
218
+ if text[index] == "%":
219
+ index = read_comment_end(text, index)
220
+ continue
221
+ if text[index] == "\\":
222
+ if read_color_wrapper(text, index) is not None:
223
+ return True
224
+ verb = read_verb_end(text, index)
225
+ if verb is not None:
226
+ index = verb[0]
227
+ continue
228
+ command = COMMAND_RE.match(text, index)
229
+ index = command.end() if command is not None else index + 1
230
+ continue
231
+ index += 1
232
+ return False
@@ -0,0 +1,77 @@
1
+ """Apply source-preserving color wrappers to exact LaTeX ranges."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+
8
+ @dataclass(frozen=True)
9
+ class ColorSpan:
10
+ """A half-open source range that should receive one color."""
11
+
12
+ start: int
13
+ end: int
14
+ color: str
15
+ priority: int = 0
16
+
17
+
18
+ def _crosses(left: ColorSpan, right: ColorSpan) -> bool:
19
+ return (
20
+ left.start < right.start < left.end < right.end
21
+ or right.start < left.start < right.end < left.end
22
+ )
23
+
24
+
25
+ def select_color_spans(source: str, spans: list[ColorSpan]) -> list[ColorSpan]:
26
+ """Keep valid nested/disjoint spans, preferring higher-priority edits."""
27
+
28
+ candidates: dict[tuple[int, int], ColorSpan] = {}
29
+ for span in spans:
30
+ if not (0 <= span.start < span.end <= len(source)):
31
+ continue
32
+ key = (span.start, span.end)
33
+ previous = candidates.get(key)
34
+ if previous is None or span.priority > previous.priority:
35
+ candidates[key] = span
36
+
37
+ accepted: list[ColorSpan] = []
38
+ for span in sorted(
39
+ candidates.values(),
40
+ key=lambda item: (-item.priority, item.start, -(item.end - item.start)),
41
+ ):
42
+ if any(_crosses(span, other) for other in accepted):
43
+ continue
44
+ accepted.append(span)
45
+
46
+ return sorted(accepted, key=lambda item: (item.start, -item.end))
47
+
48
+
49
+ def apply_color_spans(source: str, spans: list[ColorSpan]) -> str:
50
+ """Insert ``\\textcolor`` wrappers without changing the source itself."""
51
+
52
+ selected = select_color_spans(source, spans)
53
+ openings: dict[int, list[ColorSpan]] = {}
54
+ closings: dict[int, list[ColorSpan]] = {}
55
+ for span in selected:
56
+ openings.setdefault(span.start, []).append(span)
57
+ closings.setdefault(span.end, []).append(span)
58
+
59
+ pieces: list[str] = []
60
+ for index in range(len(source) + 1):
61
+ # Close inner spans first, then open outer spans first.
62
+ for _ in sorted(
63
+ closings.get(index, ()),
64
+ key=lambda item: item.start,
65
+ reverse=True,
66
+ ):
67
+ pieces.append("}")
68
+ for span in sorted(
69
+ openings.get(index, ()),
70
+ key=lambda item: item.end,
71
+ reverse=True,
72
+ ):
73
+ pieces.append(rf"\textcolor{{{span.color}}}{{")
74
+ if index < len(source):
75
+ pieces.append(source[index])
76
+
77
+ return "".join(pieces)
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-color-math
3
+ Version: 0.1.0
4
+ Summary: Pure Python semantic LaTeX and MathJax colorizer for Obsidian Markdown, KaTeX, and math notes.
5
+ Author: 36ty-blip
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: Repository, https://github.com/36ty-blip/python-color-math
30
+ Project-URL: Issues, https://github.com/36ty-blip/python-color-math/issues
31
+ Keywords: obsidian,latex,math,markdown,colorizer,katex,mathjax,cli
32
+ Classifier: Development Status :: 4 - Beta
33
+ Classifier: Environment :: Console
34
+ Classifier: Intended Audience :: Science/Research
35
+ Classifier: Intended Audience :: Education
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Operating System :: OS Independent
38
+ Classifier: Programming Language :: Python :: 3
39
+ Classifier: Programming Language :: Python :: 3 :: Only
40
+ Classifier: Programming Language :: Python :: 3.10
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Programming Language :: Python :: 3.12
43
+ Classifier: Programming Language :: Python :: 3.13
44
+ Classifier: Programming Language :: Python :: 3.14
45
+ Classifier: Topic :: Text Processing :: Markup
46
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
47
+ Requires-Python: >=3.10
48
+ Description-Content-Type: text/markdown
49
+ License-File: LICENSE
50
+ Dynamic: license-file
51
+
52
+ # ๐ŸŽจ color-math (Python)
53
+
54
+ > Pure Python semantic LaTeX and MathJax colorizer for Obsidian Markdown notes, KaTeX documents, and scientific workflows. Zero dependencies.
55
+
56
+ [![CI](https://github.com/36ty-blip/python-color-math/actions/workflows/ci.yml/badge.svg)](https://github.com/36ty-blip/python-color-math/actions/workflows/ci.yml)
57
+ [![PyPI](https://img.shields.io/pypi/v/python-color-math.svg)](https://pypi.org/project/python-color-math/)
58
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
59
+ [![Python: 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
60
+
61
+ `python-color-math` is a fast, standalone command-line tool and Python library that automatically parses LaTeX and MathJax expressions and wraps elements in semantic `\textcolor{...}{...}` annotations. It works across plain Markdown, Obsidian notes, Quarto documents, Jupyter notebooks, and raw LaTeX files without modifying surrounding prose or code blocks.
62
+
63
+ > [!NOTE]
64
+ > **Looking for the Obsidian Plugin?** Check out [obsidian-color-math](https://github.com/36ty-blip/obsidian-color-math) for real-time live preview math coloring directly inside Obsidian!
65
+
66
+ ---
67
+
68
+ ## โœจ Features
69
+
70
+ - **Zero External Dependencies**: Runs entirely on the Python Standard Library (Python 3.10+).
71
+ - **Physical Units & Metric Prefixes**: Distinguishes units (`\mu m`, `m/s`, `nm`, `kg`) from variables, shielding algebraic variables like $m$ in $F = ma$ or $E = mc^2$.
72
+ - **Calculus Differentials & Derivatives**: Recognizes infinitesimal differentials ($dx$, $dt$, $d\theta$) and derivative fractions ($\frac{d}{dx}$, $\frac{\partial \psi}{\partial t}$), while preserving standalone distance $d$ and relations like $d\iff e$.
73
+ - **Dirac Quantum Bra-Ket Notation**: Formats kets ($|\psi\rangle$), bras ($\langle\phi|$), and expectation values ($\langle\phi|\hat{H}|\psi\rangle$) while protecting absolute values ($|x| < 5$).
74
+ - **Dimensionless Numbers**: Identifies contiguous engineering numbers ($Re$, $Ma$, $Pr$, $Nu$) without capturing separated variables ($R\,e$).
75
+ - **Rainbow Delimiters**: Stack-based delimiter matching that colors nested parentheses, brackets, and braces by nesting depth.
76
+ - **Mathematical Symbol Taxonomy**: Categorizes constants ($\pi, \hbar, \infty$), Greek parameters ($\alpha, \theta, \lambda$), functions ($\sin, \cos, \ln$), and bound summation/limit indices.
77
+ - **Variable Data-Flow Hashing**: Deterministically hashes identifiers across an equation so each unique variable maintains a consistent color across terms.
78
+ - **Boxed Equations**: Preserves `\boxed{...}` wrappers while coloring internal mathematical structures.
79
+ - **Signature Tokyo Night Palette**: Muted pastel tones calibrated for readability and reduced eye strain.
80
+ - **Markdown & TeX Safety**: Fenced code blocks, inline code, TeX comments, and `\verb` blocks are protected and left unmodified.
81
+ - **Lossless & Reversible**: Includes a `--undo` command to cleanly strip all injected colors back to original LaTeX notation.
82
+
83
+ ---
84
+
85
+ ## ๐Ÿš€ Installation
86
+
87
+ Install from PyPI:
88
+
89
+ ```bash
90
+ pip install python-color-math
91
+ ```
92
+
93
+ Or install from source:
94
+
95
+ ```bash
96
+ git clone https://github.com/36ty-blip/python-color-math.git
97
+ cd python-color-math
98
+ pip install .
99
+ ```
100
+
101
+ ---
102
+
103
+ ## ๐Ÿ’ป CLI Usage
104
+
105
+ ### Process a Markdown or LaTeX file
106
+
107
+ ```bash
108
+ # Colorize equations in a single note
109
+ color-math note.md
110
+
111
+ # Colorize an entire directory of notes recursively
112
+ color-math ./vault/
113
+
114
+ # Preview changes without modifying files (Dry Run)
115
+ color-math --dry-run note.md
116
+
117
+ # Revert and clean colors back to plain LaTeX
118
+ color-math --undo note.md
119
+ ```
120
+
121
+ ### Stdin / Pipe Support
122
+
123
+ Pipe equations directly through the CLI:
124
+
125
+ ```bash
126
+ echo "$$\frac{d}{dx}f(g(x)) = f'(g(x)) \cdot g'(x)$$" | color-math
127
+ ```
128
+
129
+ ---
130
+
131
+ ## ๐Ÿ Python API
132
+
133
+ Use `color-math` directly as a library in your Python applications, scripts, or data pipelines:
134
+
135
+ ```python
136
+ from color_math import colorize_latex, ColorMathOptions
137
+
138
+ latex = r"\frac{d}{dx}f(g(x)) = f'(g(x)) \cdot g'(x)"
139
+
140
+ # Basic coloring with default Tokyo Night palette
141
+ colored = colorize_latex(latex)
142
+ print(colored)
143
+
144
+ # Enable extended features (Rainbow delimiters, Variable hashing, etc.)
145
+ opts = ColorMathOptions.all_enabled()
146
+ extended_colored = colorize_latex(latex, options=opts)
147
+ ```
148
+
149
+ ---
150
+
151
+ ## ๐Ÿงช Testing
152
+
153
+ Run the comprehensive test suites (51 tests):
154
+
155
+ ```bash
156
+ # Run feature test suite
157
+ python -m unittest discover tests
158
+
159
+ # Run regression self-test suite
160
+ python -m tests.self_test
161
+ ```
162
+
163
+ ---
164
+
165
+ ## ๐Ÿ“„ License
166
+
167
+ MIT License. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,40 @@
1
+ color_math/__init__.py,sha256=Mzp9sKJJHZPEHWiy0UnH1tu6WJ0-VltFtyx_-pU7Dek,336
2
+ color_math/__main__.py,sha256=lU6t3BklI-5H9EdprlceWLr0UcDmfXUu3Th0tjk2ANA,81
3
+ color_math/adapters.py,sha256=4WtoioVJqTRsgiukHvxHHGEd4Mr9v0ATnZituriaXu8,10215
4
+ color_math/config.py,sha256=S_fq5uSoIXPMI8TSlIUc9d4uPsp-zFlR3hvAINIDf9k,5835
5
+ color_math/io.py,sha256=iCWMY1ufPZzFCwuHTn_axNetek8PRXGNnrmz59CrlGw,1591
6
+ color_math/main.py,sha256=lBbgYkNGZLsyxDIF_LXnFNvBZUsTwUpuRXoe4HZa1gU,4393
7
+ color_math/self_test.py,sha256=O-BLG2c_3jXPl9NfuMIKChUxGFih8DtVchdBMI3X2-o,7735
8
+ color_math/undo.py,sha256=2LZCYybQICeDbHGk-KBcGczf0qp8D4_3Af8clD2nYlw,1773
9
+ color_math/converters/__init__.py,sha256=1D8U549JFGecslNKnvdpS1yslzMk30xkFM9ymjeYtDE,718
10
+ color_math/converters/align.py,sha256=bfOuoX_GQXLCqPtONlHCRZIsTv9DA8am5J0S8X8AVO8,461
11
+ color_math/converters/block.py,sha256=VB4CpgvW2Ms1vXG0biUSQdcMWD1bIw562Kuij3iZoUY,3139
12
+ color_math/converters/derivative.py,sha256=hVreur2qv2uH2wrvJQ5j00y5Jpefa4hwUCwmKkVsP20,8241
13
+ color_math/converters/equation.py,sha256=NoUXfLayzkoJJ2cBZmV-9-LLy156K4Ak03-wPx7t67M,105
14
+ color_math/converters/generic.py,sha256=iVg-kTsvadZrQ3MSdpBhEye-wf6MW_Qnru9jO0e5WbA,3426
15
+ color_math/converters/integral.py,sha256=V-HkZVcCLzELR9wCbUz0Lgc3cTIvy4DCuEfEFzCy_jg,414
16
+ color_math/converters/limit.py,sha256=xcakNIFUb_2zC9jHOZmAx9QgzWUbzVp31b1jgfCgP5Q,425
17
+ color_math/converters/matrix.py,sha256=0AHpCLMmGIzMwiMSZ8PpK1-JdCYnoCXzhkmlhmNYyxw,4672
18
+ color_math/converters/semantic.py,sha256=fxAu76l8K57GI2oLvfYSrHpFt1hMWBhBHyt9giLbPy0,1902
19
+ color_math/parsers/__init__.py,sha256=EiZFGRm7aanSJzh5mAA4F8_I94T85kOtJrz9iZBADwc,1722
20
+ color_math/parsers/braket.py,sha256=9FOLa26Yvf9vl-AKF5fjSITw3gS0MEtM-Ke9XkFdmhE,3919
21
+ color_math/parsers/delimiters.py,sha256=vcf29d0QRtAPN5wuxHqdxW8EQ6kVvuwG2fqDLW9lAGE,5057
22
+ color_math/parsers/differentials.py,sha256=VjrVNX38JcGreTeAWo_azwqK3c2hsUrIx38FyX0NXRA,3009
23
+ color_math/parsers/dimensionless.py,sha256=_pGw10Os5iVenry7JWcEE3vtodmt7EAacrkE4obYwOA,2307
24
+ color_math/parsers/latex_spans.py,sha256=UGcSh4qzuCcZjT_tZMsB2RsoSjyLSckXDhzukpioe4Q,31343
25
+ color_math/parsers/markdown_scanner.py,sha256=6KfEeHJ-F9xsaarIKmdyeN2CwQORQLs95q26uY7_JXI,12790
26
+ color_math/parsers/math_parser.py,sha256=pbYfIfJDjUMhfuPzMuLukqtzZXW6mMshQqE4uulKqRM,10415
27
+ color_math/parsers/scanner.py,sha256=eTolv8sg8q7ILg4-CfOFbgSw1ZMpidQDYi0HRnN_R8U,11338
28
+ color_math/parsers/taxonomy.py,sha256=XDCirS4kOKcHQf-6ldqdaeQfr81rJXLnXmdYY9X68FA,5036
29
+ color_math/parsers/units.py,sha256=EhvTdIlels3Tw2MSyt4c7XRSlC4eG4Bz4Hg351SdNSg,3656
30
+ color_math/parsers/variable_hash.py,sha256=-OhQbE7psG4WfqsENFQL75lk9YsFwelRDEmRDXTkTis,5200
31
+ color_math/utils/__init__.py,sha256=y5qebQLJwQjuOuI54QnbDeCr7SEdFQm4-9KgIruWQfc,497
32
+ color_math/utils/coloring.py,sha256=nCihj00f_lOuQ79l_crc7BJ30e6rh9nztOwDMwvEMwc,1240
33
+ color_math/utils/latex_helpers.py,sha256=JMNApj--EvEDMXkRyoRpUqbaJysaMGD0BiEAIvRE_vY,5886
34
+ color_math/utils/spans.py,sha256=vYsvSk3QfRqZswFDQ1OtiXOBIzN_36OtE5AP4xaenFI,2396
35
+ python_color_math-0.1.0.dist-info/licenses/LICENSE,sha256=hveQNxqYFqK9Brs_ruH-8shF2D61hIVKYdCjiE-1wMY,1063
36
+ python_color_math-0.1.0.dist-info/METADATA,sha256=LkbUg3wjQvmAWp8hMi6zb2h7YV6qdQF4Zr5b1p3prRA,7079
37
+ python_color_math-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
38
+ python_color_math-0.1.0.dist-info/entry_points.txt,sha256=tYE8pBqTiwj22sVIVaSAiP-ZWbFry_ZN1nssVb6wOPc,52
39
+ python_color_math-0.1.0.dist-info/top_level.txt,sha256=Pxuur7TFdlMD0AW61wir5nCIgzFAupL67n1tWe1B5A8,11
40
+ python_color_math-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ color-math = color_math.main:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aditya
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.
@@ -0,0 +1 @@
1
+ color_math