xulbux 1.6.2__py3-none-any.whl → 1.6.4__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.
Potentially problematic release.
This version of xulbux might be problematic. Click here for more details.
- xulbux/__init__.py +1 -1
- xulbux/_consts_.py +2 -2
- xulbux/xx_format_codes.py +186 -112
- xulbux/xx_regex.py +41 -30
- xulbux/xx_system.py +1 -1
- {xulbux-1.6.2.dist-info → xulbux-1.6.4.dist-info}/METADATA +15 -15
- {xulbux-1.6.2.dist-info → xulbux-1.6.4.dist-info}/RECORD +11 -11
- {xulbux-1.6.2.dist-info → xulbux-1.6.4.dist-info}/LICENSE +0 -0
- {xulbux-1.6.2.dist-info → xulbux-1.6.4.dist-info}/WHEEL +0 -0
- {xulbux-1.6.2.dist-info → xulbux-1.6.4.dist-info}/entry_points.txt +0 -0
- {xulbux-1.6.2.dist-info → xulbux-1.6.4.dist-info}/top_level.txt +0 -0
xulbux/__init__.py
CHANGED
xulbux/_consts_.py
CHANGED
|
@@ -58,12 +58,12 @@ class ANSI:
|
|
|
58
58
|
|
|
59
59
|
global CHAR, START, SEP, END
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
escaped_char = "\\x1b"
|
|
62
62
|
CHAR = char = "\x1b"
|
|
63
63
|
START = start = "["
|
|
64
64
|
SEP = sep = ";"
|
|
65
65
|
END = end = "m"
|
|
66
|
-
|
|
66
|
+
default_color_modifiers = {"lighten": "+l", "darken": "-d"}
|
|
67
67
|
|
|
68
68
|
def seq(parts: int = 1) -> str:
|
|
69
69
|
"""Generate an ANSI sequence with `parts` amount of placeholders."""
|
xulbux/xx_format_codes.py
CHANGED
|
@@ -1,38 +1,78 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
These codes, when used within following functions, will change the look of log within the console:
|
|
2
|
+
Methods to transform formatting codes to ANSI and use them for pretty console output:
|
|
4
3
|
- `FormatCodes.print()` (print a special format-codes containing string)
|
|
5
4
|
- `FormatCodes.input()` (input with a special format-codes containing prompt)
|
|
6
5
|
- `FormatCodes.to_ansi()` (transform all special format-codes into ANSI codes in a string)\n
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
------------------------------------------------------------------------------------------------------------------------------------
|
|
7
|
+
### The Easy Formatting
|
|
8
|
+
|
|
9
|
+
First, let's take a look at a small example of what a highly styled print string with formatting could look like using this module:
|
|
10
|
+
```regex
|
|
11
|
+
This here is just unformatted text. [b|u|br:blue](Next we have text that is bright blue + bold + underlined.)\\n
|
|
12
|
+
[#000|bg:#F67](Then there's also black text with a red background.) And finally the ([i](boring)) plain text again.
|
|
13
13
|
```
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
|
|
15
|
+
How all of this exactly works is explained in the sections below. 🠫
|
|
16
|
+
|
|
17
|
+
------------------------------------------------------------------------------------------------------------------------------------
|
|
18
|
+
#### Formatting Codes and Keys
|
|
19
|
+
|
|
20
|
+
In this module, you can apply styles and colors using simple formatting codes.
|
|
21
|
+
These formatting codes consist of one or multiple different formatting keys in between square brackets.
|
|
22
|
+
|
|
23
|
+
If a formatting code is placed in a print-string, the formatting of that code will be applied to everything behind it until its
|
|
24
|
+
formatting is reset. If applying multiple styles and colors in the same place, instead of writing the formatting keys all into
|
|
25
|
+
separate brackets (e.g. `[x][y][z]`), they can also be put in a single pair of brackets, separated by pipes (e.g. `[x|y|z]`).
|
|
26
|
+
|
|
27
|
+
A list of all possible formatting keys can be found under all possible formatting keys.
|
|
28
|
+
|
|
29
|
+
------------------------------------------------------------------------------------------------------------------------------------
|
|
30
|
+
#### Auto Resetting Formatting Codes
|
|
31
|
+
|
|
32
|
+
Certain formatting can automatically be reset, behind a certain amount of text, just like shown in the following example:
|
|
33
|
+
```regex
|
|
34
|
+
This is plain text, [br:blue](which is bright blue now.) Now it was automatically reset to plain again.
|
|
19
35
|
```
|
|
20
|
-
|
|
21
|
-
This
|
|
22
|
-
|
|
23
|
-
|
|
36
|
+
|
|
37
|
+
This will only reset formatting codes, that have a specific reset listed below.
|
|
38
|
+
That means if you use it where another formatting is already applied, that formatting is still there after the automatic reset:
|
|
39
|
+
```regex
|
|
40
|
+
[cyan]This is cyan text, [dim](which is dimmed now.) Now it's not dimmed any more but still cyan.
|
|
24
41
|
```
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
42
|
+
|
|
43
|
+
If you want to ignore the auto-reset functionality of `()` brackets, you can put a `\\` or `/` between them and
|
|
44
|
+
the formatting code:
|
|
45
|
+
```regex
|
|
46
|
+
[cyan]This is cyan text, [u]/(which is underlined now.) And now it is still underlined and cyan.
|
|
28
47
|
```
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
All possible
|
|
32
|
-
|
|
33
|
-
- RGB colors:
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
|
|
49
|
+
------------------------------------------------------------------------------------------------------------------------------------
|
|
50
|
+
#### All possible Formatting Keys
|
|
51
|
+
|
|
52
|
+
- RGB colors:
|
|
53
|
+
Change the text color directly with an RGB color inside the square brackets. (With or without `rgb()` brackets doesn't matter.)
|
|
54
|
+
Examples:
|
|
55
|
+
- `[rgb(115, 117, 255)]`
|
|
56
|
+
- `[(255, 0, 136)]`
|
|
57
|
+
- `[255, 0, 136]`
|
|
58
|
+
- HEX colors:
|
|
59
|
+
Change the text color directly with a HEX color inside the square brackets. (If `RGB` or `RRGGBB` formatting code is used,
|
|
60
|
+
and if there's a `#` or `0x` prefix, doesn't matter.)
|
|
61
|
+
Examples:
|
|
62
|
+
- `[#7788FF]`
|
|
63
|
+
- `[7788FF]`
|
|
64
|
+
- `[#78F]`
|
|
65
|
+
- `[78F]`
|
|
66
|
+
- background RGB / HEX colors:
|
|
67
|
+
Change the background color directly with an RGB or HEX color inside the square brackets, using the `background:` `BG:` prefix.
|
|
68
|
+
(Same RGB / HEX formatting code rules as for text color.)
|
|
69
|
+
Examples:
|
|
70
|
+
- `[background:rgb(115, 117, 255)]`
|
|
71
|
+
- `[BG:(255, 0, 136)]`
|
|
72
|
+
- `[background:#7788FF]`
|
|
73
|
+
- `[BG:#78F]`
|
|
74
|
+
- standard console colors:
|
|
75
|
+
Change the text color to one of the standard console colors by just writing the color name in the square brackets.
|
|
36
76
|
- `[black]`
|
|
37
77
|
- `[red]`
|
|
38
78
|
- `[green]`
|
|
@@ -41,39 +81,64 @@ All possible formatting codes:
|
|
|
41
81
|
- `[magenta]`
|
|
42
82
|
- `[cyan]`
|
|
43
83
|
- `[white]`
|
|
44
|
-
- bright
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
84
|
+
- bright console colors:
|
|
85
|
+
Use the prefix `bright:` `BR:` to use the bright variant of the standard console color.
|
|
86
|
+
Examples:
|
|
87
|
+
- `[bright:black]` `[BR:black]`
|
|
88
|
+
- `[bright:red]` `[BR:red]`
|
|
89
|
+
- ...
|
|
90
|
+
- Background console colors:
|
|
91
|
+
Use the prefix `background:` `BG:` to set the background to a standard console color. (Not all consoles support bright
|
|
92
|
+
standard colors.)
|
|
93
|
+
Examples:
|
|
94
|
+
- `[background:black]` `[BG:black]`
|
|
95
|
+
- `[background:red]` `[BG:red]`
|
|
96
|
+
- ...
|
|
97
|
+
- Bright background console colors:
|
|
98
|
+
Combine the prefixes `background:` / `BG:` and `bright:` / `BR:` to set the background to a bright console color.
|
|
99
|
+
(The order of the prefixes doesn't matter.)
|
|
100
|
+
Examples:
|
|
101
|
+
- `[background:bright:black]` `[BG:BR:black]`
|
|
102
|
+
- `[background:bright:red]` `[BG:BR:red]`
|
|
103
|
+
- ...
|
|
104
|
+
- Text styles:
|
|
105
|
+
Use the built-in text formatting to change the style of the text. There are long and short forms for each formatting code.
|
|
106
|
+
(Not all consoles support all text styles.)
|
|
107
|
+
- `[bold]` `[b]`
|
|
50
108
|
- `[dim]`
|
|
51
|
-
- `[italic]`
|
|
52
|
-
- `[underline]`
|
|
53
|
-
- `[inverse]
|
|
54
|
-
- `[hidden]
|
|
55
|
-
- `[strikethrough]`
|
|
56
|
-
- `[double-underline]`
|
|
57
|
-
-
|
|
58
|
-
|
|
109
|
+
- `[italic]` `[i]`
|
|
110
|
+
- `[underline]` `[u]`
|
|
111
|
+
- `[inverse]` `[invert]` `[in]`
|
|
112
|
+
- `[hidden]` `[hide]` `[h]`
|
|
113
|
+
- `[strikethrough]` `[s]`
|
|
114
|
+
- `[double-underline]` `[du]`
|
|
115
|
+
- Specific reset:
|
|
116
|
+
Use these reset codes to remove a specific style, color or background. Again, there are long and
|
|
117
|
+
short forms for each reset code.
|
|
118
|
+
- `[_bold]` `[_b]`
|
|
59
119
|
- `[_dim]`
|
|
60
|
-
- `[_italic]`
|
|
61
|
-
- `[_underline]`
|
|
62
|
-
- `[_inverse]
|
|
63
|
-
- `[_hidden]
|
|
64
|
-
- `[_strikethrough]`
|
|
65
|
-
- `[_double-underline]`
|
|
66
|
-
- `[_color]`
|
|
67
|
-
- `[_background]`
|
|
68
|
-
-
|
|
120
|
+
- `[_italic]` `[_i]`
|
|
121
|
+
- `[_underline]` `[_u]`
|
|
122
|
+
- `[_inverse]` `[_invert]` `[_in]`
|
|
123
|
+
- `[_hidden]` `[_hide]` `[_h]`
|
|
124
|
+
- `[_strikethrough]` `[_s]`
|
|
125
|
+
- `[_double-underline]` `[_du]`
|
|
126
|
+
- `[_color]` `[_c]`
|
|
127
|
+
- `[_background]` `[_bg]`
|
|
128
|
+
- Total reset:
|
|
129
|
+
This will reset all previously applied formatting codes.
|
|
69
130
|
- `[_]`
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
131
|
+
|
|
132
|
+
------------------------------------------------------------------------------------------------------------------------------------
|
|
133
|
+
#### Additional Formatting Codes when a `default_color` is set
|
|
134
|
+
|
|
135
|
+
1. `[*]` resets everything, just like `[_]`, but the text color will remain in `default_color`
|
|
136
|
+
2. `[*color]` will reset the text color, just like `[_color]`, but then also make it `default_color`
|
|
137
|
+
3. `[default]` will just color the text in `default_color`
|
|
138
|
+
4. `[background:default]` `[BG:default]` will color the background in `default_color`
|
|
139
|
+
|
|
140
|
+
Unlike the standard console colors, the default color can be changed by using the following modifiers:
|
|
141
|
+
|
|
77
142
|
- `[l]` will lighten the `default_color` text by `brightness_steps`%
|
|
78
143
|
- `[ll]` will lighten the `default_color` text by `2 × brightness_steps`%
|
|
79
144
|
- `[lll]` will lighten the `default_color` text by `3 × brightness_steps`%
|
|
@@ -81,7 +146,7 @@ Unlike the standard cmd colors, the default color can be changed by using the fo
|
|
|
81
146
|
- `[d]` will darken the `default_color` text by `brightness_steps`%
|
|
82
147
|
- `[dd]` will darken the `default_color` text by `2 × brightness_steps`%
|
|
83
148
|
- `[ddd]` will darken the `default_color` text by `3 × brightness_steps`%
|
|
84
|
-
- ... etc
|
|
149
|
+
- ... etc.
|
|
85
150
|
Per default, you can also use `+` and `-` to get lighter and darker `default_color` versions.
|
|
86
151
|
"""
|
|
87
152
|
|
|
@@ -90,38 +155,43 @@ from .xx_string import String
|
|
|
90
155
|
from .xx_regex import Regex
|
|
91
156
|
from .xx_color import *
|
|
92
157
|
|
|
93
|
-
from functools import lru_cache
|
|
94
158
|
import ctypes as _ctypes
|
|
95
159
|
import regex as _rx
|
|
96
160
|
import sys as _sys
|
|
97
161
|
import re as _re
|
|
98
162
|
|
|
99
|
-
|
|
163
|
+
_CONSOLE_ANSI_CONFIGURED = False
|
|
164
|
+
|
|
165
|
+
_PREFIX = {
|
|
100
166
|
"BG": {"background", "bg"},
|
|
101
167
|
"BR": {"bright", "br"},
|
|
102
168
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
"
|
|
106
|
-
"BR": rf"(?:{'|'.join(PREFIX['BR'])})\s*:",
|
|
169
|
+
_PREFIX_RX = {
|
|
170
|
+
"BG": rf"(?:{'|'.join(_PREFIX['BG'])})\s*:",
|
|
171
|
+
"BR": rf"(?:{'|'.join(_PREFIX['BR'])})\s*:",
|
|
107
172
|
}
|
|
108
|
-
|
|
173
|
+
_COMPILED = { # PRECOMPILE REGULAR EXPRESSIONS
|
|
109
174
|
"*": _re.compile(r"\[\s*([^]_]*?)\s*\*\s*([^]_]*?)\]"),
|
|
110
175
|
"*color": _re.compile(r"\[\s*([^]_]*?)\s*\*color\s*([^]_]*?)\]"),
|
|
111
|
-
"
|
|
112
|
-
Regex.brackets("[", "]", is_group=True)
|
|
176
|
+
"formatting": _rx.compile(
|
|
177
|
+
Regex.brackets("[", "]", is_group=True)
|
|
178
|
+
+ r"(?:\s*([/\\]?)\s*"
|
|
179
|
+
+ Regex.brackets("(", ")", is_group=True, ignore_in_strings=False)
|
|
180
|
+
+ r")?"
|
|
113
181
|
),
|
|
114
|
-
"bg?_default": _re.compile(r"(?i)((?:" +
|
|
115
|
-
"bg_default": _re.compile(r"(?i)" +
|
|
182
|
+
"bg?_default": _re.compile(r"(?i)((?:" + _PREFIX_RX["BG"] + r")?)\s*default"),
|
|
183
|
+
"bg_default": _re.compile(r"(?i)" + _PREFIX_RX["BG"] + r"\s*default"),
|
|
116
184
|
"modifier": _re.compile(
|
|
117
185
|
r"(?i)((?:BG\s*:)?)\s*("
|
|
118
|
-
+ "|".join(
|
|
186
|
+
+ "|".join(
|
|
187
|
+
[f"{_re.escape(m)}+" for m in ANSI.default_color_modifiers["lighten"] + ANSI.default_color_modifiers["darken"]]
|
|
188
|
+
)
|
|
119
189
|
+ r")$"
|
|
120
190
|
),
|
|
121
191
|
"rgb": _re.compile(
|
|
122
|
-
r"(?i)^\s*(" +
|
|
192
|
+
r"(?i)^\s*(" + _PREFIX_RX["BG"] + r")?\s*(?:rgb|rgba)?\s*\(?\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)?\s*$"
|
|
123
193
|
),
|
|
124
|
-
"hex": _re.compile(r"(?i)^\s*(" +
|
|
194
|
+
"hex": _re.compile(r"(?i)^\s*(" + _PREFIX_RX["BG"] + r")?\s*(?:#|0x)?([0-9A-F]{6}|[0-9A-F]{3})\s*$"),
|
|
125
195
|
}
|
|
126
196
|
|
|
127
197
|
|
|
@@ -130,14 +200,14 @@ class FormatCodes:
|
|
|
130
200
|
@staticmethod
|
|
131
201
|
def print(
|
|
132
202
|
*values: object,
|
|
133
|
-
default_color:
|
|
203
|
+
default_color: rgba | hexa = None,
|
|
134
204
|
brightness_steps: int = 20,
|
|
135
205
|
sep: str = " ",
|
|
136
206
|
end: str = "\n",
|
|
137
207
|
flush: bool = True,
|
|
138
208
|
) -> None:
|
|
139
|
-
"""
|
|
140
|
-
|
|
209
|
+
"""A print function, whose print values can be formatted using formatting codes.\n
|
|
210
|
+
-----------------------------------------------------------------------------------
|
|
141
211
|
For exact information about how to use special formatting codes, see the
|
|
142
212
|
`xx_format_codes` module documentation."""
|
|
143
213
|
FormatCodes.__config_console()
|
|
@@ -148,29 +218,32 @@ class FormatCodes:
|
|
|
148
218
|
@staticmethod
|
|
149
219
|
def input(
|
|
150
220
|
prompt: object = "",
|
|
151
|
-
default_color:
|
|
221
|
+
default_color: rgba | hexa = None,
|
|
152
222
|
brightness_steps: int = 20,
|
|
153
223
|
reset_ansi: bool = False,
|
|
154
224
|
) -> str:
|
|
155
|
-
"""An input,
|
|
156
|
-
|
|
157
|
-
If `reset_ansi` is true, all ANSI formatting will be reset, after the
|
|
158
|
-
|
|
159
|
-
|
|
225
|
+
"""An input, whose prompt can be formatted using formatting codes.\n
|
|
226
|
+
-------------------------------------------------------------------------
|
|
227
|
+
If `reset_ansi` is true, all ANSI formatting will be reset, after the
|
|
228
|
+
user confirms the input and the program continues to run.\n
|
|
229
|
+
-------------------------------------------------------------------------
|
|
160
230
|
For exact information about how to use special formatting codes, see the
|
|
161
231
|
`xx_format_codes` module documentation."""
|
|
162
232
|
FormatCodes.__config_console()
|
|
163
|
-
user_input = input(FormatCodes.to_ansi(prompt, default_color, brightness_steps))
|
|
233
|
+
user_input = input(FormatCodes.to_ansi(str(prompt), default_color, brightness_steps))
|
|
164
234
|
if reset_ansi:
|
|
165
|
-
_sys.stdout.write("
|
|
235
|
+
_sys.stdout.write(f"{ANSI.char}[0m")
|
|
166
236
|
return user_input
|
|
167
237
|
|
|
168
238
|
@staticmethod
|
|
169
239
|
def to_ansi(
|
|
170
|
-
string: str,
|
|
240
|
+
string: str,
|
|
241
|
+
default_color: rgba | hexa = None,
|
|
242
|
+
brightness_steps: int = 20,
|
|
243
|
+
_default_start: bool = True,
|
|
171
244
|
) -> str:
|
|
172
|
-
"""Convert the
|
|
173
|
-
|
|
245
|
+
"""Convert the formatting codes inside a string to ANSI formatting.\n
|
|
246
|
+
-------------------------------------------------------------------------
|
|
174
247
|
For exact information about how to use special formatting codes, see the
|
|
175
248
|
`xx_format_codes` module documentation."""
|
|
176
249
|
if Color.is_valid_rgba(default_color, False):
|
|
@@ -180,8 +253,8 @@ class FormatCodes:
|
|
|
180
253
|
else:
|
|
181
254
|
use_default = False
|
|
182
255
|
if use_default:
|
|
183
|
-
string =
|
|
184
|
-
string =
|
|
256
|
+
string = _COMPILED["*"].sub(r"[\1_|default\2]", string) # REPLACE `[…|*|…]` WITH `[…|_|default|…]`
|
|
257
|
+
string = _COMPILED["*color"].sub(r"[\1default\2]", string) # REPLACE `[…|*color|…]` WITH `[…|default|…]`
|
|
185
258
|
|
|
186
259
|
def is_valid_color(color: str) -> bool:
|
|
187
260
|
return color in ANSI.color_map or Color.is_valid_rgba(color) or Color.is_valid_hexa(color)
|
|
@@ -206,8 +279,8 @@ class FormatCodes:
|
|
|
206
279
|
for k in format_keys:
|
|
207
280
|
k_lower = k.lower()
|
|
208
281
|
k_set = set(k_lower.split(":"))
|
|
209
|
-
if
|
|
210
|
-
if k_set &
|
|
282
|
+
if _PREFIX["BG"] & k_set and len(k_set) <= 3:
|
|
283
|
+
if k_set & _PREFIX["BR"]:
|
|
211
284
|
for i in range(len(k)):
|
|
212
285
|
if is_valid_color(k[i:]):
|
|
213
286
|
reset_keys.extend(["_bg", "_color"])
|
|
@@ -219,7 +292,7 @@ class FormatCodes:
|
|
|
219
292
|
break
|
|
220
293
|
elif is_valid_color(k) or any(
|
|
221
294
|
k_lower.startswith(pref_colon := f"{prefix}:") and is_valid_color(k[len(pref_colon) :])
|
|
222
|
-
for prefix in
|
|
295
|
+
for prefix in _PREFIX["BR"]
|
|
223
296
|
):
|
|
224
297
|
reset_keys.append("_color")
|
|
225
298
|
else:
|
|
@@ -247,40 +320,42 @@ class FormatCodes:
|
|
|
247
320
|
+ ("" if escaped else "".join(ansi_resets))
|
|
248
321
|
)
|
|
249
322
|
|
|
250
|
-
string = "\n".join(
|
|
323
|
+
string = "\n".join(_COMPILED["formatting"].sub(replace_keys, line) for line in string.split("\n"))
|
|
251
324
|
return (FormatCodes.__get_default_ansi(default_color) if _default_start else "") + string if use_default else string
|
|
252
325
|
|
|
253
326
|
@staticmethod
|
|
254
|
-
def escape_ansi(ansi_string: str
|
|
255
|
-
"""
|
|
256
|
-
return ansi_string.replace(ANSI.char, escaped_char)
|
|
327
|
+
def escape_ansi(ansi_string: str) -> str:
|
|
328
|
+
"""Escapes all ANSI codes in a string, so they are visible when output to the console."""
|
|
329
|
+
return ansi_string.replace(ANSI.char, ANSI.escaped_char)
|
|
257
330
|
|
|
258
331
|
@staticmethod
|
|
259
|
-
@lru_cache(maxsize=64)
|
|
260
332
|
def __config_console() -> None:
|
|
261
333
|
"""Configure the console to be able to interpret ANSI formatting."""
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
334
|
+
global _CONSOLE_ANSI_CONFIGURED
|
|
335
|
+
if not _CONSOLE_ANSI_CONFIGURED:
|
|
336
|
+
_sys.stdout.flush()
|
|
337
|
+
kernel32 = _ctypes.windll.kernel32
|
|
338
|
+
h = kernel32.GetStdHandle(-11)
|
|
339
|
+
mode = _ctypes.c_ulong()
|
|
340
|
+
kernel32.GetConsoleMode(h, _ctypes.byref(mode))
|
|
341
|
+
kernel32.SetConsoleMode(h, mode.value | 0x0004)
|
|
342
|
+
_CONSOLE_ANSI_CONFIGURED = True
|
|
268
343
|
|
|
269
344
|
@staticmethod
|
|
270
345
|
def __get_default_ansi(
|
|
271
346
|
default_color: tuple,
|
|
272
347
|
format_key: str = None,
|
|
273
348
|
brightness_steps: int = None,
|
|
274
|
-
_modifiers: tuple[str, str] = (ANSI.
|
|
349
|
+
_modifiers: tuple[str, str] = (ANSI.default_color_modifiers["lighten"], ANSI.default_color_modifiers["darken"]),
|
|
275
350
|
) -> str | None:
|
|
276
|
-
"""Get the `default_color` and lighter/darker versions of it
|
|
277
|
-
if not brightness_steps or (format_key and
|
|
278
|
-
return (ANSI.seq_bg_color if format_key and
|
|
351
|
+
"""Get the `default_color` and lighter/darker versions of it as ANSI code."""
|
|
352
|
+
if not brightness_steps or (format_key and _COMPILED["bg?_default"].search(format_key)):
|
|
353
|
+
return (ANSI.seq_bg_color if format_key and _COMPILED["bg_default"].search(format_key) else ANSI.seq_color).format(
|
|
279
354
|
*default_color[:3]
|
|
280
355
|
)
|
|
281
356
|
if not (format_key in _modifiers[0] or format_key in _modifiers[1]):
|
|
282
357
|
return None
|
|
283
|
-
match =
|
|
358
|
+
match = _COMPILED["modifier"].match(format_key)
|
|
284
359
|
if not match:
|
|
285
360
|
return None
|
|
286
361
|
is_bg, modifiers = match.groups()
|
|
@@ -320,8 +395,8 @@ class FormatCodes:
|
|
|
320
395
|
None,
|
|
321
396
|
)
|
|
322
397
|
)
|
|
323
|
-
rgb_match = _re.match(
|
|
324
|
-
hex_match = _re.match(
|
|
398
|
+
rgb_match = _re.match(_COMPILED["rgb"], format_key)
|
|
399
|
+
hex_match = _re.match(_COMPILED["hex"], format_key)
|
|
325
400
|
try:
|
|
326
401
|
if rgb_match:
|
|
327
402
|
is_bg = rgb_match.group(1)
|
|
@@ -341,15 +416,14 @@ class FormatCodes:
|
|
|
341
416
|
return _format_key
|
|
342
417
|
|
|
343
418
|
@staticmethod
|
|
344
|
-
@lru_cache(maxsize=64)
|
|
345
419
|
def __normalize_key(format_key: str) -> str:
|
|
346
420
|
"""Normalizes the given format key."""
|
|
347
421
|
k_parts = format_key.replace(" ", "").lower().split(":")
|
|
348
422
|
prefix_str = "".join(
|
|
349
423
|
f"{prefix_key.lower()}:"
|
|
350
|
-
for prefix_key, prefix_values in
|
|
424
|
+
for prefix_key, prefix_values in _PREFIX.items()
|
|
351
425
|
if any(k_part in prefix_values for k_part in k_parts)
|
|
352
426
|
)
|
|
353
427
|
return prefix_str + ":".join(
|
|
354
|
-
part for part in k_parts if part not in {val for values in
|
|
428
|
+
part for part in k_parts if part not in {val for values in _PREFIX.values() for val in values}
|
|
355
429
|
)
|
xulbux/xx_regex.py
CHANGED
|
@@ -9,6 +9,7 @@ Really long regex code presets:
|
|
|
9
9
|
`hsla_str` match a HSLA color
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
+
import regex as _rx
|
|
12
13
|
import re as _re
|
|
13
14
|
|
|
14
15
|
|
|
@@ -17,25 +18,33 @@ class Regex:
|
|
|
17
18
|
@staticmethod
|
|
18
19
|
def quotes() -> str:
|
|
19
20
|
"""Matches everything inside quotes. (strings)\n
|
|
20
|
-
|
|
21
|
+
--------------------------------------------------------------------------------
|
|
21
22
|
Will create two named groups:
|
|
22
23
|
- `quote` the quote type (single or double)
|
|
23
24
|
- `string` everything inside the found quote pair\n
|
|
24
|
-
|
|
25
|
+
--------------------------------------------------------------------------------
|
|
25
26
|
Attention: Requires non standard library `regex` not standard library `re`!"""
|
|
26
27
|
return r'(?P<quote>[\'"])(?P<string>(?:\\.|(?!\g<quote>).)*?)\g<quote>'
|
|
27
28
|
|
|
28
29
|
@staticmethod
|
|
29
|
-
def brackets(bracket1: str = "(", bracket2: str = ")", is_group: bool = False) -> str:
|
|
30
|
+
def brackets(bracket1: str = "(", bracket2: str = ")", is_group: bool = False, ignore_in_strings: bool = True) -> str:
|
|
30
31
|
"""Matches everything inside brackets, including other nested brackets.\n
|
|
31
|
-
|
|
32
|
+
--------------------------------------------------------------------------------
|
|
33
|
+
If `is_group` is true, you will be able to reference the matched content as a
|
|
34
|
+
group (e.g. `match.group(…)` or `r'\\…'`).
|
|
35
|
+
If `ignore_in_strings` is true and a bracket is inside a string (e.g. `'...'`
|
|
36
|
+
or `"..."`), it will not be counted as the matching closing bracket.\n
|
|
37
|
+
--------------------------------------------------------------------------------
|
|
32
38
|
Attention: Requires non standard library `regex` not standard library `re`!"""
|
|
33
39
|
g, b1, b2 = (
|
|
34
40
|
"" if is_group else "?:",
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
_rx.escape(bracket1) if len(bracket1) == 1 else bracket1,
|
|
42
|
+
_rx.escape(bracket2) if len(bracket2) == 1 else bracket2,
|
|
37
43
|
)
|
|
38
|
-
|
|
44
|
+
if ignore_in_strings:
|
|
45
|
+
return rf'{b1}\s*({g}(?:[^{b1}{b2}"\']|"(?:\\.|[^"\\])*"|\'(?:\\.|[^\'\\])*\'|{b1}(?:[^{b1}{b2}"\']|"(?:\\.|[^"\\])*"|\'(?:\\.|[^\'\\])*\'|(?R))*{b2})*)\s*{b2}'
|
|
46
|
+
else:
|
|
47
|
+
return rf"{b1}\s*({g}(?:[^{b1}{b2}]|{b1}(?:[^{b1}{b2}]|(?R))*{b2})*)\s*{b2}"
|
|
39
48
|
|
|
40
49
|
@staticmethod
|
|
41
50
|
def outside_strings(pattern: str = r".*") -> str:
|
|
@@ -48,22 +57,27 @@ class Regex:
|
|
|
48
57
|
ignore_pattern: str = "",
|
|
49
58
|
is_group: bool = False,
|
|
50
59
|
) -> str:
|
|
51
|
-
"""Matches everything except `disallowed_pattern`, unless the `disallowed_pattern`
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
"""Matches everything except `disallowed_pattern`, unless the `disallowed_pattern`
|
|
61
|
+
is found inside a string (`'...'` or `"..."`).\n
|
|
62
|
+
------------------------------------------------------------------------------------
|
|
63
|
+
The `ignore_pattern` is just always ignored. For example if `disallowed_pattern` is
|
|
64
|
+
`>` and `ignore_pattern` is `->`, the `->`-arrows will be allowed, even though they
|
|
65
|
+
have `>` in them.
|
|
66
|
+
If `is_group` is true, you will be able to reference the matched content as a group
|
|
67
|
+
(e.g. `match.group(…)` or `r'\\…'`)."""
|
|
56
68
|
return rf'({"" if is_group else "?:"}(?:(?!{ignore_pattern}).)*(?:(?!{Regex.outside_strings(disallowed_pattern)}).)*)'
|
|
57
69
|
|
|
58
70
|
@staticmethod
|
|
59
71
|
def func_call(func_name: str = None) -> str:
|
|
60
|
-
"""Match a function call
|
|
61
|
-
|
|
62
|
-
|
|
72
|
+
"""Match a function call, and get back two groups:
|
|
73
|
+
1. function name
|
|
74
|
+
2. the function's arguments\n
|
|
63
75
|
If no `func_name` is given, it will match any function call.\n
|
|
64
|
-
|
|
76
|
+
--------------------------------------------------------------------------------
|
|
65
77
|
Attention: Requires non standard library `regex` not standard library `re`!"""
|
|
66
|
-
return
|
|
78
|
+
return (
|
|
79
|
+
r"(?<=\b)(" + (r"[\w_]+" if func_name is None else func_name) + r")\s*" + Regex.brackets("(", ")", is_group=True)
|
|
80
|
+
)
|
|
67
81
|
|
|
68
82
|
@staticmethod
|
|
69
83
|
def rgba_str(fix_sep: str = ",", allow_alpha: bool = True) -> str:
|
|
@@ -76,11 +90,10 @@ class Regex:
|
|
|
76
90
|
- `(r, g, b, a)` (if `allow_alpha=True`)
|
|
77
91
|
- `r, g, b`
|
|
78
92
|
- `r, g, b, a` (if `allow_alpha=True`)\n
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
- `
|
|
82
|
-
- `
|
|
83
|
-
- `b` 0-255 (amount: blue)
|
|
93
|
+
#### Valid ranges:
|
|
94
|
+
- `r` 0-255 (int: red)
|
|
95
|
+
- `g` 0-255 (int: green)
|
|
96
|
+
- `b` 0-255 (int: blue)
|
|
84
97
|
- `a` 0-1 (float: opacity)\n
|
|
85
98
|
----------------------------------------------------------------------------
|
|
86
99
|
If the `fix_sep` is set to nothing, any char that is not a letter or number
|
|
@@ -112,11 +125,10 @@ class Regex:
|
|
|
112
125
|
- `(h, s, l, a)` (if `allow_alpha=True`)
|
|
113
126
|
- `h, s, l`
|
|
114
127
|
- `h, s, l, a` (if `allow_alpha=True`)\n
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
- `
|
|
118
|
-
- `
|
|
119
|
-
- `l` 0-100 (percentage: lightness)
|
|
128
|
+
#### Valid ranges:
|
|
129
|
+
- `h` 0-360 (int: hue)
|
|
130
|
+
- `s` 0-100 (int: saturation)
|
|
131
|
+
- `l` 0-100 (int: lightness)
|
|
120
132
|
- `a` 0-1 (float: opacity)\n
|
|
121
133
|
----------------------------------------------------------------------------
|
|
122
134
|
If the `fix_sep` is set to nothing, any char that is not a letter or number
|
|
@@ -146,9 +158,8 @@ class Regex:
|
|
|
146
158
|
- `RGBA` (if `allow_alpha=True`)
|
|
147
159
|
- `RRGGBB`
|
|
148
160
|
- `RRGGBBAA` (if `allow_alpha=True`)\n
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
each channel from 0-9 and A-F (case insensitive)"""
|
|
161
|
+
#### Valid ranges:
|
|
162
|
+
every channel from 0-9 and A-F (case insensitive)"""
|
|
152
163
|
return (
|
|
153
164
|
r"(?i)^(?:#|0x)?[0-9A-F]{8}|[0-9A-F]{6}|[0-9A-F]{4}|[0-9A-F]{3}$"
|
|
154
165
|
if allow_alpha
|
xulbux/xx_system.py
CHANGED
|
@@ -41,7 +41,7 @@ class System:
|
|
|
41
41
|
if not force:
|
|
42
42
|
output = _subprocess.check_output("tasklist", shell=True).decode()
|
|
43
43
|
processes = [line.split()[0] for line in output.splitlines()[3:] if line.strip()]
|
|
44
|
-
if len(processes) > 2: # EXCLUDING THE PYTHON PROCESS AND
|
|
44
|
+
if len(processes) > 2: # EXCLUDING THE PYTHON PROCESS AND CONSOLE
|
|
45
45
|
raise RuntimeError("Processes are still running. Use the parameter `force=True` to restart anyway.")
|
|
46
46
|
if prompt:
|
|
47
47
|
_os.system(f'shutdown /r /t {wait} /c "{prompt}"')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: xulbux
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.4
|
|
4
4
|
Summary: A library which includes a lot of really helpful functions.
|
|
5
5
|
Author-email: XulbuX <xulbux.real@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -31,7 +31,7 @@ Project-URL: Documentation, https://github.com/XulbuX-dev/PythonLibraryXulbuX/wi
|
|
|
31
31
|
Project-URL: Homepage, https://github.com/XulbuX-dev/PythonLibraryXulbuX
|
|
32
32
|
Project-URL: License, https://github.com/XulbuX-dev/PythonLibraryXulbuX/blob/main/LICENSE
|
|
33
33
|
Project-URL: Source Code, https://github.com/XulbuX-dev/PythonLibraryXulbuX/tree/main/src
|
|
34
|
-
Keywords: xulbux,python,library,utility,helper,functions,tools,classes,types,methods,cmd,code,color,data,structures,env,environment,file,format,json,path,regex,string,system,operations,presets
|
|
34
|
+
Keywords: xulbux,python,library,utility,helper,functions,tools,classes,types,methods,cmd,console,code,color,data,structures,env,environment,file,format,json,path,regex,string,system,operations,presets
|
|
35
35
|
Classifier: Intended Audience :: Developers
|
|
36
36
|
Classifier: Programming Language :: Python :: 3
|
|
37
37
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -89,19 +89,19 @@ from xulbux import rgba, hsla, hexa
|
|
|
89
89
|
# Modules
|
|
90
90
|
|
|
91
91
|
| | |
|
|
92
|
-
|
|
|
93
|
-
| <h3>[`xx_code`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_code)</h3>
|
|
94
|
-
| <h3>[`xx_color`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_color)</h3>
|
|
95
|
-
| <h3>[`xx_console`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_console)</h3>
|
|
96
|
-
| <h3>[`xx_data`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_data)</h3>
|
|
97
|
-
| <h3>[`xx_env_path`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_env_path)</h3>
|
|
98
|
-
| <h3>[`xx_file`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_file)</h3>
|
|
99
|
-
| <h3
|
|
100
|
-
| <h3>`xx_json`</h3>
|
|
101
|
-
| <h3>`xx_path`</h3>
|
|
102
|
-
| <h3>`xx_regex`</h3>
|
|
103
|
-
| <h3>[`xx_string`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_string)</h3>
|
|
104
|
-
| <h3>`xx_system`</h3>
|
|
92
|
+
| :--------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------- |
|
|
93
|
+
| <h3>[`xx_code`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_code)</h3> | advanced code-string operations (*changing the indent, finding function calls, ...*) |
|
|
94
|
+
| <h3>[`xx_color`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_color)</h3> | everything around colors (*converting, blending, searching colors in strings, ...*) |
|
|
95
|
+
| <h3>[`xx_console`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_console)</h3> | advanced actions related to the console (*pretty logging, advanced inputs, ...*) |
|
|
96
|
+
| <h3>[`xx_data`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_data)</h3> | advanced operations with data structures (*compare, generate path ID's, pretty print/format, ...*) |
|
|
97
|
+
| <h3>[`xx_env_path`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_env_path)</h3> | getting and editing the PATH variable (*get paths, check for paths, add paths, ...*) |
|
|
98
|
+
| <h3>[`xx_file`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_file)</h3> | advanced working with files (*create files, rename file-extensions, ...*) |
|
|
99
|
+
| <h3>[`xx_format_codes`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_format_codes)</h3> | easy pretty printing with custom format codes (*print, inputs, custom format codes to ANSI, ...*) |
|
|
100
|
+
| <h3>`xx_json`</h3> | advanced working with json files (*read, create, update, ...*) |
|
|
101
|
+
| <h3>`xx_path`</h3> | advanced path operations (*get paths, smart-extend relative paths, delete paths, ...*) |
|
|
102
|
+
| <h3>`xx_regex`</h3> | generated regex pattern-templates (*match bracket- and quote pairs, match colors, ...*) |
|
|
103
|
+
| <h3>[`xx_string`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_string)</h3> | helpful actions when working with strings. (*normalize, escape, decompose, ...*) |
|
|
104
|
+
| <h3>`xx_system`</h3> | advanced system actions (*restart with message, check installed Python libs, ...*) |
|
|
105
105
|
|
|
106
106
|
|
|
107
107
|
<br>
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
xulbux/__init__.py,sha256=
|
|
1
|
+
xulbux/__init__.py,sha256=VbGUDMdLbSCMOJk62Fm7QTSyKiC9AtQmO_VutJgjwIY,1658
|
|
2
2
|
xulbux/_cli_.py,sha256=U25ZrtpQgpKXtvOSTBBbh7-AJ_WTeZ95A66DQARAqzo,3558
|
|
3
|
-
xulbux/_consts_.py,sha256=
|
|
3
|
+
xulbux/_consts_.py,sha256=0JWj691rOojP8KKE_AJpF8O5WwMRJH4fAvzkwLXd1VM,4591
|
|
4
4
|
xulbux/xx_code.py,sha256=yBP5WxCxNxjBiS6nVAmUBJpD0hX6fgnh5RWq-NmrnaY,5222
|
|
5
5
|
xulbux/xx_color.py,sha256=cDlgrekH88ZEBj8leIIlJbYzsf1RdS8RW3oGvuUfvC0,45129
|
|
6
6
|
xulbux/xx_console.py,sha256=rd31686X9eXB8__lcLaV7unWzIdXGM2yMOt9zNCsGbs,15079
|
|
7
7
|
xulbux/xx_data.py,sha256=OEKLbI1XeNTrittdz3s3mvQk8YrBoSovj9O1H-b7ArY,25844
|
|
8
8
|
xulbux/xx_env_path.py,sha256=iv3Jw0TsNDbbL_NySnazvIP9Iv9swymhiJIr2B3EG8k,4388
|
|
9
9
|
xulbux/xx_file.py,sha256=-58YnqKvrs5idIF91UzEki7o7qnskFvnQYkBaRrp7Vw,3122
|
|
10
|
-
xulbux/xx_format_codes.py,sha256=
|
|
10
|
+
xulbux/xx_format_codes.py,sha256=ywF0MfGZRlWuYopLUAFBm9g-vAkXE8IIumII90gaCIE,19836
|
|
11
11
|
xulbux/xx_json.py,sha256=q60lOj8Xg8c4L9cBu6SBZdJzFC7QbjDfFwcKKzBKj5w,5173
|
|
12
12
|
xulbux/xx_path.py,sha256=_xkH9cowPdi3nHw2q_TvN_i_5oG6GJut-QwPBLxnrAQ,4519
|
|
13
|
-
xulbux/xx_regex.py,sha256=
|
|
13
|
+
xulbux/xx_regex.py,sha256=S1-MIk2qG4vHdxuaHGhMe5PHfY1SF9kncg8iQ8HJgS4,8002
|
|
14
14
|
xulbux/xx_string.py,sha256=Wa3qHxnk7AIpAVAn1vI_GBtkfYFwy4F_Xtj83ojEPKc,7168
|
|
15
|
-
xulbux/xx_system.py,sha256=
|
|
16
|
-
xulbux-1.6.
|
|
17
|
-
xulbux-1.6.
|
|
18
|
-
xulbux-1.6.
|
|
19
|
-
xulbux-1.6.
|
|
20
|
-
xulbux-1.6.
|
|
21
|
-
xulbux-1.6.
|
|
15
|
+
xulbux/xx_system.py,sha256=M3VGU3Tf3nDU59DjIJgDXJOqNB80Vr0wf15Vcnb5UCo,6430
|
|
16
|
+
xulbux-1.6.4.dist-info/LICENSE,sha256=6NflEcvzFEe8_JFVNCPVwZBwBhlLLd4vqQi8WiX_Xk4,1084
|
|
17
|
+
xulbux-1.6.4.dist-info/METADATA,sha256=TabSXy5WGWo8P5zrwjklaOnO73Ay3JeHn3MA16nT33U,6948
|
|
18
|
+
xulbux-1.6.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
19
|
+
xulbux-1.6.4.dist-info/entry_points.txt,sha256=a3womfLIMZKnOFiyy-xnVb4g2qkZsHR5FbKKkljcGns,94
|
|
20
|
+
xulbux-1.6.4.dist-info/top_level.txt,sha256=FkK4EZajwfP36fnlrPaR98OrEvZpvdEOdW1T5zTj6og,7
|
|
21
|
+
xulbux-1.6.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|