raztint 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.
- raztint/__init__.py +39 -0
- raztint/raztint.py +291 -0
- raztint-0.1.0.dist-info/METADATA +416 -0
- raztint-0.1.0.dist-info/RECORD +6 -0
- raztint-0.1.0.dist-info/WHEEL +4 -0
- raztint-0.1.0.dist-info/licenses/LICENSE +21 -0
raztint/__init__.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from .raztint import RazTint
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
|
|
5
|
+
tint = RazTint()
|
|
6
|
+
|
|
7
|
+
ok = tint.ok
|
|
8
|
+
err = tint.err
|
|
9
|
+
warn = tint.warn
|
|
10
|
+
info = tint.info
|
|
11
|
+
|
|
12
|
+
black = tint.black
|
|
13
|
+
red = tint.red
|
|
14
|
+
green = tint.green
|
|
15
|
+
yellow = tint.yellow
|
|
16
|
+
blue = tint.blue
|
|
17
|
+
magenta = tint.magenta
|
|
18
|
+
cyan = tint.cyan
|
|
19
|
+
white = tint.white
|
|
20
|
+
gray = tint.gray
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"RazTint",
|
|
24
|
+
"tint",
|
|
25
|
+
"ok",
|
|
26
|
+
"err",
|
|
27
|
+
"warn",
|
|
28
|
+
"info",
|
|
29
|
+
"black",
|
|
30
|
+
"red",
|
|
31
|
+
"green",
|
|
32
|
+
"yellow",
|
|
33
|
+
"blue",
|
|
34
|
+
"magenta",
|
|
35
|
+
"cyan",
|
|
36
|
+
"white",
|
|
37
|
+
"gray",
|
|
38
|
+
"__version__",
|
|
39
|
+
]
|
raztint/raztint.py
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from functools import lru_cache
|
|
5
|
+
from typing import ClassVar
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RazTint:
|
|
9
|
+
"""A zero-dependency Python library for ANSI coloring and smart CLI icons.
|
|
10
|
+
|
|
11
|
+
RazTint provides automatic environment detection for colors and icons,
|
|
12
|
+
with support for Nerd Fonts, Unicode, and ASCII fallbacks.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
COLORS: ClassVar[dict[str, str]] = {
|
|
16
|
+
"BLACK": "30",
|
|
17
|
+
"RED": "31",
|
|
18
|
+
"GREEN": "32",
|
|
19
|
+
"YELLOW": "33",
|
|
20
|
+
"BLUE": "34",
|
|
21
|
+
"MAGENTA": "35",
|
|
22
|
+
"CYAN": "36",
|
|
23
|
+
"WHITE": "37",
|
|
24
|
+
"GRAY": "90",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
ICONS: ClassVar[dict[str, dict[str, str]]] = {
|
|
28
|
+
"ok": {"nerd": "", "std": "✓", "ascii": "[OK]", "color": "GREEN"},
|
|
29
|
+
"err": {"nerd": "", "std": "✗", "ascii": "[ERR]", "color": "RED"},
|
|
30
|
+
"warn": {"nerd": "", "std": "!", "ascii": "[WARN]", "color": "YELLOW"},
|
|
31
|
+
"info": {"nerd": "", "std": "i", "ascii": "[INFO]", "color": "BLUE"},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
ok: Callable[[], str]
|
|
35
|
+
err: Callable[[], str]
|
|
36
|
+
warn: Callable[[], str]
|
|
37
|
+
info: Callable[[], str]
|
|
38
|
+
|
|
39
|
+
black: Callable[[str], str]
|
|
40
|
+
red: Callable[[str], str]
|
|
41
|
+
green: Callable[[str], str]
|
|
42
|
+
yellow: Callable[[str], str]
|
|
43
|
+
blue: Callable[[str], str]
|
|
44
|
+
magenta: Callable[[str], str]
|
|
45
|
+
cyan: Callable[[str], str]
|
|
46
|
+
white: Callable[[str], str]
|
|
47
|
+
gray: Callable[[str], str]
|
|
48
|
+
|
|
49
|
+
def __init__(self) -> None:
|
|
50
|
+
self.use_color: bool = self._supports_color()
|
|
51
|
+
self.icon_mode: str = self._get_icon_mode()
|
|
52
|
+
|
|
53
|
+
for name, code in self.COLORS.items():
|
|
54
|
+
setattr(self, name.lower(), self._make_color_func(code))
|
|
55
|
+
|
|
56
|
+
for name, data in self.ICONS.items():
|
|
57
|
+
color_key = data.get("color", "WHITE")
|
|
58
|
+
color_code = self.COLORS.get(color_key, "37")
|
|
59
|
+
setattr(
|
|
60
|
+
self,
|
|
61
|
+
name,
|
|
62
|
+
self._make_icon_func(data, color_code),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def _make_color_func(self, code: str) -> Callable[[str], str]:
|
|
66
|
+
return lambda text: self.color(text, code)
|
|
67
|
+
|
|
68
|
+
def _make_icon_func(self, data: dict[str, str], code: str) -> Callable[[], str]:
|
|
69
|
+
def fn() -> str:
|
|
70
|
+
if self.icon_mode == "nerd":
|
|
71
|
+
symbol = data["nerd"]
|
|
72
|
+
elif self.icon_mode == "std":
|
|
73
|
+
symbol = data["std"]
|
|
74
|
+
else:
|
|
75
|
+
symbol = data["ascii"]
|
|
76
|
+
|
|
77
|
+
return self.color(symbol, code)
|
|
78
|
+
|
|
79
|
+
return fn
|
|
80
|
+
|
|
81
|
+
def color(self, text: str, fg_code: str) -> str:
|
|
82
|
+
"""Apply ANSI color code to text.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
text: The text to colorize
|
|
86
|
+
fg_code: ANSI foreground color code (e.g., "31" for red)
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Colored text with ANSI escape sequences if color is enabled,
|
|
90
|
+
otherwise returns plain text.
|
|
91
|
+
"""
|
|
92
|
+
if not self.use_color:
|
|
93
|
+
return text
|
|
94
|
+
return f"\033[{fg_code}m{text}\033[0m"
|
|
95
|
+
|
|
96
|
+
def set_color(self, enabled: bool) -> None:
|
|
97
|
+
"""Enable or disable color output programmatically.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
enabled: True to enable colors, False to disable
|
|
101
|
+
"""
|
|
102
|
+
self.use_color = enabled
|
|
103
|
+
|
|
104
|
+
def _supports_color(self) -> bool:
|
|
105
|
+
if os.getenv("NO_COLOR") or os.getenv("RAZTINT_NO_COLOR"):
|
|
106
|
+
return False
|
|
107
|
+
|
|
108
|
+
force = os.getenv("RAZTINT_FORCE_COLOR", "").lower()
|
|
109
|
+
if force in ("1", "true", "yes", "on"):
|
|
110
|
+
return True
|
|
111
|
+
|
|
112
|
+
stream = sys.stdout
|
|
113
|
+
if not hasattr(stream, "isatty") or not stream.isatty():
|
|
114
|
+
return False
|
|
115
|
+
if os.name == "nt":
|
|
116
|
+
return self._enable_windows_vt_mode()
|
|
117
|
+
term = os.getenv("TERM", "")
|
|
118
|
+
return bool(term and term.lower() != "dumb")
|
|
119
|
+
|
|
120
|
+
@classmethod
|
|
121
|
+
def _get_icon_mode(cls) -> str:
|
|
122
|
+
encoding = getattr(sys.stdout, "encoding", None) or "utf-8"
|
|
123
|
+
try:
|
|
124
|
+
"".encode(encoding)
|
|
125
|
+
except Exception:
|
|
126
|
+
return "ascii"
|
|
127
|
+
|
|
128
|
+
# Check for explicit nerd fonts preference
|
|
129
|
+
force_nerd = os.getenv("RAZTINT_USE_NERD_ICONS", "").lower()
|
|
130
|
+
if force_nerd in ("1", "true", "yes", "on"):
|
|
131
|
+
return "nerd"
|
|
132
|
+
|
|
133
|
+
# Check for explicit disable
|
|
134
|
+
force_no_nerd = os.getenv("RAZTINT_NO_NERD_ICONS", "").lower()
|
|
135
|
+
if force_no_nerd in ("1", "true", "yes", "on"):
|
|
136
|
+
return "std"
|
|
137
|
+
|
|
138
|
+
# Auto-detect nerd fonts
|
|
139
|
+
if cls._has_nerd_fonts():
|
|
140
|
+
return "nerd"
|
|
141
|
+
|
|
142
|
+
# Default to standard icons
|
|
143
|
+
return "std"
|
|
144
|
+
|
|
145
|
+
@classmethod
|
|
146
|
+
@lru_cache(maxsize=1)
|
|
147
|
+
def _has_nerd_fonts(cls) -> bool:
|
|
148
|
+
"""Detect if nerd fonts are available in the terminal."""
|
|
149
|
+
# Check environment variables that indicate nerd fonts
|
|
150
|
+
nerd_env = os.getenv("NERDFONTS") or os.getenv("NERD_FONTS")
|
|
151
|
+
if nerd_env and nerd_env.lower() in ("1", "true", "yes", "on"):
|
|
152
|
+
return True
|
|
153
|
+
|
|
154
|
+
# Check font name from environment
|
|
155
|
+
font_name = os.getenv("FONT_NAME", "").lower()
|
|
156
|
+
if font_name and any(
|
|
157
|
+
name in font_name
|
|
158
|
+
for name in [
|
|
159
|
+
"nerd",
|
|
160
|
+
"nf-",
|
|
161
|
+
"hack nerd",
|
|
162
|
+
"fira code nerd",
|
|
163
|
+
"jetbrains mono nerd",
|
|
164
|
+
"meslo nerd",
|
|
165
|
+
"cascadia code nerd",
|
|
166
|
+
]
|
|
167
|
+
):
|
|
168
|
+
return True
|
|
169
|
+
|
|
170
|
+
# Check terminal font setting
|
|
171
|
+
term_font = os.getenv("TERM_FONT", "").lower()
|
|
172
|
+
if term_font and any(
|
|
173
|
+
name in term_font
|
|
174
|
+
for name in [
|
|
175
|
+
"nerd",
|
|
176
|
+
"nf-",
|
|
177
|
+
"hack nerd",
|
|
178
|
+
"fira code nerd",
|
|
179
|
+
"jetbrains mono nerd",
|
|
180
|
+
"meslo nerd",
|
|
181
|
+
"cascadia code nerd",
|
|
182
|
+
]
|
|
183
|
+
):
|
|
184
|
+
return True
|
|
185
|
+
|
|
186
|
+
return bool(cls._check_installed_nerd_fonts())
|
|
187
|
+
|
|
188
|
+
@staticmethod
|
|
189
|
+
@lru_cache(maxsize=1)
|
|
190
|
+
def _check_installed_nerd_fonts() -> bool:
|
|
191
|
+
"""Check if nerd fonts are installed on the system."""
|
|
192
|
+
import subprocess
|
|
193
|
+
|
|
194
|
+
if os.name == "nt":
|
|
195
|
+
# Windows: Check registry or font directory
|
|
196
|
+
|
|
197
|
+
try:
|
|
198
|
+
powershell_path = "powershell"
|
|
199
|
+
result = subprocess.run(
|
|
200
|
+
[
|
|
201
|
+
powershell_path,
|
|
202
|
+
"-Command",
|
|
203
|
+
"Get-ChildItem 'C:\\Windows\\Fonts'"
|
|
204
|
+
" | Where-Object {$_.Name -like '*Nerd*'} "
|
|
205
|
+
" | Select-Object -First 1",
|
|
206
|
+
],
|
|
207
|
+
capture_output=True,
|
|
208
|
+
text=True,
|
|
209
|
+
timeout=2,
|
|
210
|
+
)
|
|
211
|
+
if result.returncode == 0 and result.stdout.strip():
|
|
212
|
+
return True
|
|
213
|
+
except FileNotFoundError:
|
|
214
|
+
return False
|
|
215
|
+
except Exception:
|
|
216
|
+
return False
|
|
217
|
+
|
|
218
|
+
elif sys.platform == "darwin":
|
|
219
|
+
# macOS: Check via system_profiler or font directory
|
|
220
|
+
try:
|
|
221
|
+
result = subprocess.run(
|
|
222
|
+
["system_profiler", "SPFontsDataType"],
|
|
223
|
+
capture_output=True,
|
|
224
|
+
text=True,
|
|
225
|
+
timeout=2,
|
|
226
|
+
)
|
|
227
|
+
if result.returncode == 0:
|
|
228
|
+
output = result.stdout.lower()
|
|
229
|
+
if any(name.lower() in output for name in ["nerd", "nf-"]):
|
|
230
|
+
return True
|
|
231
|
+
except Exception:
|
|
232
|
+
pass
|
|
233
|
+
|
|
234
|
+
# Also check common font directories
|
|
235
|
+
font_dirs = [
|
|
236
|
+
os.path.expanduser("~/Library/Fonts"),
|
|
237
|
+
"/Library/Fonts",
|
|
238
|
+
"/System/Library/Fonts",
|
|
239
|
+
]
|
|
240
|
+
for font_dir in font_dirs:
|
|
241
|
+
if os.path.isdir(font_dir):
|
|
242
|
+
try:
|
|
243
|
+
for item in os.listdir(font_dir):
|
|
244
|
+
if "nerd" in item.lower() or "nf-" in item.lower():
|
|
245
|
+
return True
|
|
246
|
+
except Exception:
|
|
247
|
+
continue
|
|
248
|
+
|
|
249
|
+
else:
|
|
250
|
+
# Linux: Use fc-list (fontconfig)
|
|
251
|
+
try:
|
|
252
|
+
result = subprocess.run(
|
|
253
|
+
["fc-list", ":", "family"],
|
|
254
|
+
capture_output=True,
|
|
255
|
+
text=True,
|
|
256
|
+
timeout=2,
|
|
257
|
+
)
|
|
258
|
+
if result.returncode == 0:
|
|
259
|
+
output = result.stdout.lower()
|
|
260
|
+
nerd_indicators = ["nerd", "nf-", "hack nerd", "fira code nerd"]
|
|
261
|
+
if any(indicator in output for indicator in nerd_indicators):
|
|
262
|
+
return True
|
|
263
|
+
except Exception:
|
|
264
|
+
pass
|
|
265
|
+
|
|
266
|
+
return False
|
|
267
|
+
|
|
268
|
+
def _enable_windows_vt_mode(self) -> bool:
|
|
269
|
+
import ctypes
|
|
270
|
+
|
|
271
|
+
windll = getattr(ctypes, "windll", None)
|
|
272
|
+
if windll is None:
|
|
273
|
+
return False
|
|
274
|
+
|
|
275
|
+
kernel32 = getattr(windll, "kernel32", None)
|
|
276
|
+
if kernel32 is None:
|
|
277
|
+
return False
|
|
278
|
+
|
|
279
|
+
handle = kernel32.GetStdHandle(-11)
|
|
280
|
+
if handle in (0, -1):
|
|
281
|
+
return False
|
|
282
|
+
|
|
283
|
+
mode = ctypes.c_uint32()
|
|
284
|
+
if not kernel32.GetConsoleMode(handle, ctypes.byref(mode)):
|
|
285
|
+
return False
|
|
286
|
+
|
|
287
|
+
enable_virtual_terminal_processing = 0x0004
|
|
288
|
+
success = kernel32.SetConsoleMode(
|
|
289
|
+
handle, mode.value | enable_virtual_terminal_processing
|
|
290
|
+
)
|
|
291
|
+
return bool(success)
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: raztint
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A zero-dependency Python library for ANSI coloring and smart CLI icons with automatic environment detection
|
|
5
|
+
Project-URL: Homepage, https://github.com/razbuild/raztint
|
|
6
|
+
Project-URL: Documentation, https://github.com/razbuild/raztint#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/razbuild/raztint
|
|
8
|
+
Project-URL: Issues, https://github.com/razbuild/raztint/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/razbuild/raztint/releases
|
|
10
|
+
Author-email: Raz <real.raz.dev@gmail.com>
|
|
11
|
+
Maintainer-email: Raz <real.raz.dev@gmail.com>
|
|
12
|
+
License: MIT
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: ansi,cli,color,colour,console,cross-platform,icons,nerd-fonts,terminal,terminal-colors,text-coloring
|
|
15
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Topic :: System :: Systems Administration
|
|
24
|
+
Classifier: Topic :: Terminals
|
|
25
|
+
Classifier: Topic :: Utilities
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.13
|
|
28
|
+
Provides-Extra: coverage
|
|
29
|
+
Requires-Dist: coverage; extra == 'coverage'
|
|
30
|
+
Requires-Dist: pytest-cov; extra == 'coverage'
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: black; extra == 'dev'
|
|
33
|
+
Requires-Dist: coverage; extra == 'dev'
|
|
34
|
+
Requires-Dist: mypy; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
37
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
38
|
+
Provides-Extra: formatter
|
|
39
|
+
Requires-Dist: black; extra == 'formatter'
|
|
40
|
+
Provides-Extra: lint
|
|
41
|
+
Requires-Dist: ruff; extra == 'lint'
|
|
42
|
+
Provides-Extra: test
|
|
43
|
+
Requires-Dist: pytest; extra == 'test'
|
|
44
|
+
Requires-Dist: pytest-cov; extra == 'test'
|
|
45
|
+
Provides-Extra: typecheck
|
|
46
|
+
Requires-Dist: mypy; extra == 'typecheck'
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+

|
|
52
|
+

|
|
53
|
+

|
|
54
|
+

|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Preview
|
|
60
|
+
|
|
61
|
+
A zero-dependency Python library for ANSI coloring and smart CLI icons with automatic environment detection.
|
|
62
|
+
|
|
63
|
+
| Unicode | Nerd Font |
|
|
64
|
+
|---------|-----------|
|
|
65
|
+
|  |  |
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
RazTint supports:
|
|
70
|
+
- Zero Dependencies: Built entirely with the Python standard library.
|
|
71
|
+
- Smart Icon Sets: Automatically degrades from **Nerd Fonts** → **Unicode** → **ASCII** based on the environment.
|
|
72
|
+
- Automatic Detection: Detects `NO_COLOR`, `TERM`, and `isatty` to enable/disable features appropriately.
|
|
73
|
+
- Windows Support: Automatically enables Virtual Terminal (VT) processing on Windows systems using `ctypes`.
|
|
74
|
+
- Type Hinted: Fully typed for excellent IDE support and autocompletion.
|
|
75
|
+
- Configurable: Granular control via Environment Variables.
|
|
76
|
+
|
|
77
|
+
This library is suitable for CLIs, logs, and tools that need portable, readable terminal output.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Why RazTint?
|
|
82
|
+
|
|
83
|
+
RazTint is intentionally minimal and zero-dependency.
|
|
84
|
+
If you need a lightweight alternative to `colorama` or `rich` for:
|
|
85
|
+
|
|
86
|
+
- Simple CLI tools
|
|
87
|
+
- Scripts
|
|
88
|
+
- Logging utilities
|
|
89
|
+
- Cross-platform terminal output
|
|
90
|
+
|
|
91
|
+
RazTint gives you:
|
|
92
|
+
- Zero dependencies
|
|
93
|
+
- Automatic icon fallback (Nerd → Unicode → ASCII)
|
|
94
|
+
- Automatic color detection
|
|
95
|
+
- Configurable behaviour with environment variables
|
|
96
|
+
- Very small runtime overhead
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Features
|
|
101
|
+
|
|
102
|
+
- Zero Dependencies: Built entirely with the Python standard library.
|
|
103
|
+
|
|
104
|
+
- Smart Icon Sets: Automatically degrades from Nerd Fonts → Unicode → ASCII based on the environment.
|
|
105
|
+
|
|
106
|
+
- Automatic Detection: Detects NO_COLOR, TERM, and isatty to enable/disable features appropriately.
|
|
107
|
+
|
|
108
|
+
- Windows Support: Automatically enables Virtual Terminal (VT) processing on Windows systems using ctypes.
|
|
109
|
+
|
|
110
|
+
- Type Hinted: Fully typed for excellent IDE support and autocompletion.
|
|
111
|
+
|
|
112
|
+
- Configurable: Granular control via Environment Variables.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
# Installation
|
|
117
|
+
|
|
118
|
+
## From PyPI
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
pip install raztint
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## With pipx
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pipx install raztint
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## From source
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
git clone https://github.com/razbuild/raztint.git
|
|
134
|
+
cd raztint
|
|
135
|
+
|
|
136
|
+
pip install -e . # -e allows you to modify the source code in place
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## How to install Nerd Font?
|
|
140
|
+
|
|
141
|
+
To install Nerd Fonts, visit the official [website](https://www.nerdfonts.com/font-downloads).
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Quick Start
|
|
146
|
+
|
|
147
|
+
You can import functions directly for quick usage, or instantiate the class for more control.
|
|
148
|
+
|
|
149
|
+
### Functional Usage
|
|
150
|
+
|
|
151
|
+
The easiest way to use RazTint is importing the pre-instantiated helpers:
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from raztint import green, red, ok, err, info, warn
|
|
155
|
+
|
|
156
|
+
# Coloring text
|
|
157
|
+
print(green("Success! The operation completed."))
|
|
158
|
+
print(red("Critical Error: Database not found."))
|
|
159
|
+
|
|
160
|
+
# Using Icons (Auto-adapts to Nerd Font/Unicode/ASCII)
|
|
161
|
+
print(f"{ok()} File saved successfully.")
|
|
162
|
+
print(f"{err()} Connection failed.")
|
|
163
|
+
print(f"{info()} Analysis in progress...")
|
|
164
|
+
print(f"{warn()} Disk space low.")
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Class-based Usage
|
|
168
|
+
|
|
169
|
+
Useful if you need to toggle color support dynamically within an application instance or want a scoped instance.
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from raztint import RazTint
|
|
173
|
+
|
|
174
|
+
tint = RazTint()
|
|
175
|
+
|
|
176
|
+
# Toggle features manually if needed
|
|
177
|
+
tint.set_color(False)
|
|
178
|
+
|
|
179
|
+
print(tint.blue("This will be plain text now because color is disabled."))
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Using the `tint` Instance
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from raztint import tint
|
|
186
|
+
|
|
187
|
+
print(tint.red("text"))
|
|
188
|
+
print(tint.ok(), "hello")
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
## Icons & Detection
|
|
193
|
+
|
|
194
|
+
### Icon Functions
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from raztint import ok, err, warn, info
|
|
198
|
+
|
|
199
|
+
print(ok(), "Operation completed")
|
|
200
|
+
print(err(), "An error happened")
|
|
201
|
+
print(warn(), "Be careful")
|
|
202
|
+
print(info(), "For your information")
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Icon Modes
|
|
206
|
+
RazTint attempts to make your CLI look as good as possible by detecting the font capabilities of the terminal.
|
|
207
|
+
|
|
208
|
+
| Mode | ok | err | warn | info | Condition |
|
|
209
|
+
|------|----|-----|------|------|-----------|
|
|
210
|
+
| Nerd | | | | | Detected Nerd Font via Env/Registry |
|
|
211
|
+
| Std | ✓ | ✗ | ! | i | UTF-8 supported, no Nerd Font |
|
|
212
|
+
| ASCII | [OK] | [ERR] | [WARN] | [INFO] | Fallback |
|
|
213
|
+
|
|
214
|
+
> Note: Icons may not render correctly in GitHub preview depending on your browser font.
|
|
215
|
+
|
|
216
|
+
### Detection Logic
|
|
217
|
+
|
|
218
|
+
RazTint determines the best available icon and color mode using the following rules:
|
|
219
|
+
|
|
220
|
+
1. Nerd Font Mode:
|
|
221
|
+
- Enabled if:
|
|
222
|
+
- `RAZTINT_USE_NERD_ICONS` environment variable is set to `1`, `true`, `yes`, or `on`, OR
|
|
223
|
+
- `NERDFONTS` or `NERD_FONTS` environment variable is set, OR
|
|
224
|
+
- `FONT_NAME` or `TERM_FONT` environment variable contains "nerd" or "nf-", OR
|
|
225
|
+
- A Nerd Font is detected via system checks:
|
|
226
|
+
- **Linux**: Uses `fc-list` (fontconfig) to check installed fonts
|
|
227
|
+
- **macOS**: Checks via `system_profiler` and font directories (`~/Library/Fonts`, `/Library/Fonts`)
|
|
228
|
+
- **Windows**: Checks `C:\Windows\Fonts` directory via PowerShell
|
|
229
|
+
|
|
230
|
+
2. Standard Unicode Mode:
|
|
231
|
+
- Enabled when UTF-8 encoding is available AND
|
|
232
|
+
- `RAZTINT_NO_NERD_ICONS` is set (explicitly disables Nerd Fonts), OR
|
|
233
|
+
- Nerd Fonts are not detected and not forced via `RAZTINT_USE_NERD_ICONS`
|
|
234
|
+
|
|
235
|
+
3. ASCII Mode:
|
|
236
|
+
- Used when:
|
|
237
|
+
- Output encoding is not UTF-8 (cannot encode Nerd Font or Unicode characters), OR
|
|
238
|
+
- System encoding test fails for Unicode characters
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Configuration
|
|
243
|
+
|
|
244
|
+
You can control **RazTint** behavior using environment variables. This is useful for CI/CD pipelines or user overrides.
|
|
245
|
+
|
|
246
|
+
| Environment Variable | Value | Description |
|
|
247
|
+
|----------------------|-------|-------------|
|
|
248
|
+
| `NO_COLOR` | any | Disables all color output (standard specification). |
|
|
249
|
+
| `RAZTINT_NO_COLOR` | any | Specific override to disable RazTint colors. |
|
|
250
|
+
| `RAZTINT_FORCE_COLOR` | `1`, `true`, `yes`, `on` | Forces color output even if not a TTY. |
|
|
251
|
+
| `RAZTINT_USE_NERD_ICONS` | `1`, `true`, `yes`, `on` | Forces the use of Nerd Font icons. |
|
|
252
|
+
| `RAZTINT_NO_NERD_ICONS` | `1`, `true`, `yes`, `on` | Disables Nerd Font detection (falls back to Standard Unicode mode). |
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
### Programmatically:
|
|
256
|
+
```python
|
|
257
|
+
from raztint import tint
|
|
258
|
+
tint.set_color(False)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Disable Colors
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
NO_COLOR=1
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Icon Behavior Configuration
|
|
268
|
+
|
|
269
|
+
### Always Use Nerd Icons
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
RAZTINT_USE_NERD_ICONS=1
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Force-enable Colors
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
RAZTINT_FORCE_COLOR=1
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Disable Nerd Icons
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
RAZTINT_NO_NERD_ICONS=1
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
# API Reference
|
|
290
|
+
|
|
291
|
+
## Color Functions
|
|
292
|
+
|
|
293
|
+
The following functions return strings wrapped with ANSI styling when supported:
|
|
294
|
+
|
|
295
|
+
- `black(text)`
|
|
296
|
+
|
|
297
|
+
- `red(text)`
|
|
298
|
+
|
|
299
|
+
- `green(text)`
|
|
300
|
+
|
|
301
|
+
- `yellow(text)`
|
|
302
|
+
|
|
303
|
+
- `blue(text)`
|
|
304
|
+
|
|
305
|
+
- `magenta(text)`
|
|
306
|
+
|
|
307
|
+
- `cyan(text)`
|
|
308
|
+
|
|
309
|
+
- `white(text)`
|
|
310
|
+
|
|
311
|
+
- `gray(text)`
|
|
312
|
+
|
|
313
|
+
Internally, these use `tint.color()`.
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Icon Functions
|
|
318
|
+
|
|
319
|
+
These return appropriate status symbols based on environment detection:
|
|
320
|
+
|
|
321
|
+
- `ok()` - Returns a success icon (green checkmark)
|
|
322
|
+
|
|
323
|
+
- `err()` - Returns an error icon (red cross)
|
|
324
|
+
|
|
325
|
+
- `warn()` - Returns a warning icon (yellow exclamation)
|
|
326
|
+
|
|
327
|
+
- `info()` - Returns an info icon (blue 'i')
|
|
328
|
+
|
|
329
|
+
RazTint selects the best available style in this order:
|
|
330
|
+
1. Nerd Font icons (if installed)
|
|
331
|
+
2. Unicode icons (if UTF-8 is supported)
|
|
332
|
+
3. ASCII fallback
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## RazTint Class Methods
|
|
337
|
+
|
|
338
|
+
When using the `RazTint` class directly, you have access to additional methods:
|
|
339
|
+
|
|
340
|
+
### `color(text: str, fg_code: str) -> str`
|
|
341
|
+
|
|
342
|
+
Low-level method to apply ANSI color codes to text. Returns the text with ANSI escape sequences when color is enabled, otherwise returns plain text.
|
|
343
|
+
|
|
344
|
+
**Parameters:**
|
|
345
|
+
- `text`: The text to colorize
|
|
346
|
+
- `fg_code`: ANSI color code (e.g., "31" for red, "32" for green)
|
|
347
|
+
|
|
348
|
+
**Example:**
|
|
349
|
+
```python
|
|
350
|
+
from raztint import RazTint
|
|
351
|
+
|
|
352
|
+
tint = RazTint()
|
|
353
|
+
colored = tint.color("Hello", "31") # Red text
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### `set_color(enabled: bool) -> None`
|
|
357
|
+
|
|
358
|
+
Enable or disable color output programmatically.
|
|
359
|
+
|
|
360
|
+
**Parameters:**
|
|
361
|
+
- `enabled`: `True` to enable colors, `False` to disable
|
|
362
|
+
|
|
363
|
+
**Example:**
|
|
364
|
+
```python
|
|
365
|
+
from raztint import RazTint
|
|
366
|
+
|
|
367
|
+
tint = RazTint()
|
|
368
|
+
tint.set_color(False) # Disable colors
|
|
369
|
+
print(tint.red("This will be plain text"))
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
## RazTint Class Attributes
|
|
373
|
+
|
|
374
|
+
### `use_color: bool`
|
|
375
|
+
|
|
376
|
+
Boolean indicating whether color output is currently enabled. This is automatically set based on environment detection but can be modified via `set_color()`.
|
|
377
|
+
|
|
378
|
+
### `icon_mode: str`
|
|
379
|
+
|
|
380
|
+
Current icon mode being used. Possible values:
|
|
381
|
+
- `"nerd"` - Nerd Font icons
|
|
382
|
+
- `"std"` - Standard Unicode icons
|
|
383
|
+
- `"ascii"` - ASCII fallback icons
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
# Automatic Behavior
|
|
388
|
+
|
|
389
|
+
RazTint intelligently detects and adapts to the environment:
|
|
390
|
+
|
|
391
|
+
## Color Detection
|
|
392
|
+
|
|
393
|
+
Color support is determined by checking (in order):
|
|
394
|
+
1. `NO_COLOR` or `RAZTINT_NO_COLOR` environment variables (disables colors)
|
|
395
|
+
2. `RAZTINT_FORCE_COLOR` environment variable (forces colors)
|
|
396
|
+
3. Whether output is connected to a TTY (`sys.stdout.isatty()`)
|
|
397
|
+
4. On Windows: Attempts to enable Virtual Terminal processing
|
|
398
|
+
5. `TERM` environment variable (must not be "dumb")
|
|
399
|
+
|
|
400
|
+
If color is not supported, all color functions return plain text.
|
|
401
|
+
|
|
402
|
+
## Icon Detection
|
|
403
|
+
|
|
404
|
+
Icon mode is determined by checking (in order):
|
|
405
|
+
1. Encoding capability (can the system encode Nerd Font characters?)
|
|
406
|
+
2. `RAZTINT_USE_NERD_ICONS` or `RAZTINT_NO_NERD_ICONS` environment variables
|
|
407
|
+
3. System-level Nerd Font detection (see Detection Logic section)
|
|
408
|
+
4. Falls back to Standard Unicode or ASCII based on encoding support
|
|
409
|
+
|
|
410
|
+
If unsupported, RazTint transparently falls back to non-colored text and simpler icons.
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
# License
|
|
415
|
+
|
|
416
|
+
MIT License
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
raztint/__init__.py,sha256=fl7_e1yt1zUZxOIk8der2UL5fGkVStC34LDGer3vTjg,522
|
|
2
|
+
raztint/raztint.py,sha256=JXMnscr9ow_sc19kMF9LP2JtvmVIrHwW7s_kHpI9dgM,9375
|
|
3
|
+
raztint-0.1.0.dist-info/METADATA,sha256=fNDPd0kiyoew87iqHh3c0KftYmTGzF5_Yv6ZqnvOmhU,12193
|
|
4
|
+
raztint-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
5
|
+
raztint-0.1.0.dist-info/licenses/LICENSE,sha256=97DdE5_8oBBt-1FEnbQ1gx37IeAw2jLwXffrm3yjCG4,1059
|
|
6
|
+
raztint-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Raz
|
|
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.
|