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,74 @@
1
+ """Physical & engineering dimensionless numbers disambiguation."""
2
+ from __future__ import annotations
3
+ from dataclasses import dataclass
4
+ import re
5
+
6
+ from ..config import COLORS
7
+ from ..utils.spans import ColorSpan
8
+
9
+
10
+ @dataclass
11
+ class DimensionlessSpan:
12
+ start: int
13
+ end: int
14
+ text: str
15
+
16
+
17
+ COMMON_DIMENSIONLESS_NUMBERS = [
18
+ "Re", # Reynolds
19
+ "Ma", # Mach
20
+ "Pr", # Prandtl
21
+ "Nu", # Nusselt
22
+ "Kn", # Knudsen
23
+ "Sc", # Schmidt
24
+ "Pe", # Péclet
25
+ "Gr", # Grashof
26
+ "Ra", # Rayleigh
27
+ "We", # Weber
28
+ "Fr", # Froude
29
+ "St", # Strouhal
30
+ "Bi", # Biot
31
+ "Fo", # Fourier
32
+ ]
33
+
34
+
35
+ def find_dimensionless_spans(body: str) -> list[DimensionlessSpan]:
36
+ """Scans LaTeX math body to identify physical & engineering dimensionless numbers."""
37
+ spans: list[DimensionlessSpan] = []
38
+
39
+ def add_span(start: int, end: int, text: str) -> None:
40
+ if start >= end:
41
+ return
42
+ if not any(start < s.end and end > s.start for s in spans):
43
+ spans.append(DimensionlessSpan(start, end, text))
44
+
45
+ num_list = "|".join(COMMON_DIMENSIONLESS_NUMBERS)
46
+
47
+ # 1. Text or mathrm wrapped: \text{Re}, \mathrm{Ma}, etc.
48
+ text_re = re.compile(r"\\(?:text|mathrm)\s*\{\s*(" + num_list + r")\s*\}")
49
+ for m in text_re.finditer(body):
50
+ add_span(m.start(), m.end(), m.group(0))
51
+
52
+ # 2. Contiguous bare symbols: Re, Ma, Pr, etc.
53
+ # Must NOT be preceded by backslash (e.g. \Re) or any letter.
54
+ # Must NOT be followed by any letter.
55
+ bare_re = re.compile(r"(?:^|[^\\a-zA-Z])(" + num_list + r")(?![a-zA-Z])")
56
+ for m in bare_re.finditer(body):
57
+ symbol = m.group(1)
58
+ sym_start = m.start() + (len(m.group(0)) - len(symbol))
59
+ sym_end = sym_start + len(symbol)
60
+ add_span(sym_start, sym_end, symbol)
61
+
62
+ return sorted(spans, key=lambda s: s.start)
63
+
64
+
65
+ def collect_dimensionless_spans(
66
+ body: str,
67
+ palette: dict[str, str] | None = None,
68
+ dim_spans: list[DimensionlessSpan] | None = None,
69
+ ) -> list[ColorSpan]:
70
+ """Returns color spans for dimensionless numbers with main / cyan color."""
71
+ pal = palette or COLORS
72
+ dims = dim_spans if dim_spans is not None else find_dimensionless_spans(body)
73
+ color = pal.get("main", "#7aa2f7")
74
+ return [ColorSpan(d.start, d.end, color, priority=24) for d in dims]