xulbux 1.5.8__tar.gz → 1.5.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of xulbux might be problematic. Click here for more details.

Files changed (44) hide show
  1. xulbux-1.5.9/PKG-INFO +110 -0
  2. xulbux-1.5.9/README.md +55 -0
  3. {xulbux-1.5.8 → xulbux-1.5.9}/pyproject.toml +11 -8
  4. xulbux-1.5.9/setup.cfg +4 -0
  5. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/__init__.py +2 -2
  6. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/_cli_.py +3 -2
  7. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/_consts_.py +1 -0
  8. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_code.py +3 -3
  9. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_color.py +11 -15
  10. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_file.py +23 -23
  11. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_format_codes.py +53 -33
  12. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_json.py +2 -2
  13. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_regex.py +7 -10
  14. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_string.py +60 -72
  15. xulbux-1.5.9/src/xulbux.egg-info/PKG-INFO +110 -0
  16. xulbux-1.5.9/src/xulbux.egg-info/SOURCES.txt +30 -0
  17. xulbux-1.5.9/src/xulbux.egg-info/dependency_links.txt +1 -0
  18. xulbux-1.5.9/src/xulbux.egg-info/entry_points.txt +3 -0
  19. xulbux-1.5.9/src/xulbux.egg-info/requires.txt +10 -0
  20. xulbux-1.5.9/src/xulbux.egg-info/top_level.txt +1 -0
  21. xulbux-1.5.9/tests/test_format_codes.py +42 -0
  22. xulbux-1.5.8/.github/workflows/python-package.yml +0 -49
  23. xulbux-1.5.8/.gitignore +0 -31
  24. xulbux-1.5.8/CHANGELOG.md +0 -318
  25. xulbux-1.5.8/PKG-INFO +0 -101
  26. xulbux-1.5.8/README.md +0 -49
  27. xulbux-1.5.8/documentation/Home.md +0 -71
  28. xulbux-1.5.8/documentation/xx_code.md +0 -49
  29. xulbux-1.5.8/documentation/xx_color.md +0 -664
  30. xulbux-1.5.8/documentation/xx_console.md +0 -135
  31. xulbux-1.5.8/documentation/xx_data.md +0 -210
  32. xulbux-1.5.8/documentation/xx_env_path.md +0 -42
  33. xulbux-1.5.8/documentation/xx_string.md +0 -13
  34. {xulbux-1.5.8 → xulbux-1.5.9}/LICENSE +0 -0
  35. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_console.py +0 -0
  36. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_data.py +0 -0
  37. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_env_path.py +0 -0
  38. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_path.py +0 -0
  39. {xulbux-1.5.8/src/XulbuX → xulbux-1.5.9/src/xulbux}/xx_system.py +0 -0
  40. {xulbux-1.5.8 → xulbux-1.5.9}/tests/test_cmd_info.py +0 -0
  41. {xulbux-1.5.8 → xulbux-1.5.9}/tests/test_color.py +0 -0
  42. {xulbux-1.5.8 → xulbux-1.5.9}/tests/test_color_types.py +0 -0
  43. {xulbux-1.5.8 → xulbux-1.5.9}/tests/test_data.py +0 -0
  44. {xulbux-1.5.8 → xulbux-1.5.9}/tests/test_env_vars.py +0 -0
xulbux-1.5.9/PKG-INFO ADDED
@@ -0,0 +1,110 @@
1
+ Metadata-Version: 2.1
2
+ Name: xulbux
3
+ Version: 1.5.9
4
+ Summary: A library which includes a lot of really helpful functions.
5
+ Author-email: XulbuX <xulbux.real@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2024 XulbuX
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: Bug Reports, https://github.com/XulbuX-dev/PythonLibraryXulbuX/issues
29
+ Project-URL: Changelog, https://github.com/XulbuX-dev/PythonLibraryXulbuX/blob/main/CHANGELOG.md
30
+ Project-URL: Documentation, https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki
31
+ Project-URL: Homepage, https://github.com/XulbuX-dev/PythonLibraryXulbuX
32
+ Project-URL: License, https://github.com/XulbuX-dev/PythonLibraryXulbuX/blob/main/LICENSE
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
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.10
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: License :: OSI Approved :: MIT License
41
+ Classifier: Operating System :: OS Independent
42
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
43
+ Requires-Python: >=3.10.0
44
+ Description-Content-Type: text/markdown
45
+ License-File: LICENSE
46
+ Requires-Dist: keyboard>=0.13.5
47
+ Requires-Dist: mouse>=0.7.1
48
+ Requires-Dist: pyperclip>=1.9.0
49
+ Requires-Dist: regex>=2023.10.3
50
+ Provides-Extra: dev
51
+ Requires-Dist: pytest>=7.4.2; extra == "dev"
52
+ Requires-Dist: black>=23.7.0; extra == "dev"
53
+ Requires-Dist: isort>=5.12.0; extra == "dev"
54
+ Requires-Dist: flake8>=6.1.0; extra == "dev"
55
+
56
+ # **$\color{#8085FF}\Huge\textsf{XulbuX}$**
57
+
58
+ **$\color{#8085FF}\textsf{XulbuX}$** is a library which includes a lot of really helpful classes, types and functions.
59
+
60
+ For precise information about the library, see the library's [Wiki page](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki).<br>
61
+ For the libraries latest changes, see the [change log](https://github.com/XulbuX-dev/PythonLibraryXulbuX/blob/main/CHANGELOG.md).
62
+
63
+
64
+ ## Installation
65
+
66
+ To install the library and all its dependencies, open a console and run the command:
67
+ ```prolog
68
+ pip install xulbux
69
+ ```
70
+
71
+ To upgrade the library to the latest available version, run the following command in your console:
72
+ ```prolog
73
+ pip install --upgrade xulbux
74
+ ```
75
+
76
+
77
+ ## Usage
78
+
79
+ Import the full library under the alias `xx`, so it's classes, types and functions are accessible with `xx.Class.method()`, `xx.type()` and `xx.function()`:
80
+ ```python
81
+ import xulbux as xx
82
+ ```
83
+ So you don't have to write `xx` in front of the library's types, you can import them directly:
84
+ ```python
85
+ from xulbux import rgba, hsla, hexa
86
+ ```
87
+
88
+
89
+ # Modules
90
+
91
+ | | |
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`</h3> | advanced working with files (*create files, rename file-extensions, ...*) |
99
+ | <h3>`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
+
106
+
107
+ <br>
108
+
109
+ --------------------------------------------------------------
110
+ [View this library on PyPI](https://pypi.org/project/XulbuX/)
xulbux-1.5.9/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # **$\color{#8085FF}\Huge\textsf{XulbuX}$**
2
+
3
+ **$\color{#8085FF}\textsf{XulbuX}$** is a library which includes a lot of really helpful classes, types and functions.
4
+
5
+ For precise information about the library, see the library's [Wiki page](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki).<br>
6
+ For the libraries latest changes, see the [change log](https://github.com/XulbuX-dev/PythonLibraryXulbuX/blob/main/CHANGELOG.md).
7
+
8
+
9
+ ## Installation
10
+
11
+ To install the library and all its dependencies, open a console and run the command:
12
+ ```prolog
13
+ pip install xulbux
14
+ ```
15
+
16
+ To upgrade the library to the latest available version, run the following command in your console:
17
+ ```prolog
18
+ pip install --upgrade xulbux
19
+ ```
20
+
21
+
22
+ ## Usage
23
+
24
+ Import the full library under the alias `xx`, so it's classes, types and functions are accessible with `xx.Class.method()`, `xx.type()` and `xx.function()`:
25
+ ```python
26
+ import xulbux as xx
27
+ ```
28
+ So you don't have to write `xx` in front of the library's types, you can import them directly:
29
+ ```python
30
+ from xulbux import rgba, hsla, hexa
31
+ ```
32
+
33
+
34
+ # Modules
35
+
36
+ | | |
37
+ | :------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------- |
38
+ | <h3>[`xx_code`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_code)</h3> | advanced code-string operations (*changing the indent, finding function calls, ...*) |
39
+ | <h3>[`xx_color`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_color)</h3> | everything around colors (*converting, blending, searching colors in strings, ...*) |
40
+ | <h3>[`xx_console`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_console)</h3> | advanced actions related to the console (*pretty logging, advanced inputs, ...*) |
41
+ | <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, ...*) |
42
+ | <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, ...*) |
43
+ | <h3>`xx_file`</h3> | advanced working with files (*create files, rename file-extensions, ...*) |
44
+ | <h3>`xx_format_codes`</h3> | easy pretty printing with custom format codes (*print, inputs, custom format codes to ANSI, ...*) |
45
+ | <h3>`xx_json`</h3> | advanced working with json files (*read, create, update, ...*) |
46
+ | <h3>`xx_path`</h3> | advanced path operations (*get paths, smart-extend relative paths, delete paths, ...*) |
47
+ | <h3>`xx_regex`</h3> | generated regex pattern-templates (*match bracket- and quote pairs, match colors, ...*) |
48
+ | <h3>[`xx_string`](https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki/xx_string)</h3> | helpful actions when working with strings. (*normalize, escape, decompose, ...*) |
49
+ | <h3>`xx_system`</h3> | advanced system actions (*restart with message, check installed Python libs, ...*) |
50
+
51
+
52
+ <br>
53
+
54
+ --------------------------------------------------------------
55
+ [View this library on PyPI](https://pypi.org/project/XulbuX/)
@@ -1,15 +1,14 @@
1
1
  [build-system]
2
- requires = ["hatchling"]
3
- build-backend = "hatchling.build"
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "xulbux"
7
- version = "1.5.8"
7
+ version = "1.5.9"
8
8
  authors = [{ name = "XulbuX", email = "xulbux.real@gmail.com" }]
9
9
  description = "A library which includes a lot of really helpful functions."
10
10
  readme = "README.md"
11
11
  license = { file = "LICENSE" }
12
- changelog = "CHANGELOG.md"
13
12
  requires-python = ">=3.10.0"
14
13
  dependencies = [
15
14
  "keyboard>=0.13.5",
@@ -63,11 +62,13 @@ keywords = [
63
62
  ]
64
63
 
65
64
  [project.urls]
66
- "Homepage" = "https://github.com/XulbuX-dev/PythonLibraryXulbuX"
67
65
  "Bug Reports" = "https://github.com/XulbuX-dev/PythonLibraryXulbuX/issues"
66
+ "Changelog" = "https://github.com/XulbuX-dev/PythonLibraryXulbuX/blob/main/CHANGELOG.md"
68
67
  "Documentation" = "https://github.com/XulbuX-dev/PythonLibraryXulbuX/wiki"
68
+ "Homepage" = "https://github.com/XulbuX-dev/PythonLibraryXulbuX"
69
+ "License" = "https://github.com/XulbuX-dev/PythonLibraryXulbuX/blob/main/LICENSE"
69
70
  "Source Code" = "https://github.com/XulbuX-dev/PythonLibraryXulbuX/tree/main/src"
70
- "Changelog" = "https://github.com/XulbuX-dev/PythonLibraryXulbuX/blob/main/CHANGELOG.md"
71
+
71
72
 
72
73
  [project.scripts]
73
74
  xx-help = "xulbux._cli_:help_command"
@@ -107,8 +108,9 @@ max-complexity = 18
107
108
  select = ["B", "C", "E", "F", "W", "T4", "B9"]
108
109
  per-file-ignores = ["__init__.py:F401,F403"]
109
110
 
110
- [tool.hatch.build.targets.wheel]
111
- packages = ["src/xulbux"]
111
+ [tool.setuptools]
112
+ packages = ["xulbux"]
113
+ package-dir = { "" = "src" }
112
114
 
113
115
  [tool.pytest.ini_options]
114
116
  minversion = "7.0"
@@ -120,4 +122,5 @@ testpaths = [
120
122
  "tests/test_color.py",
121
123
  "tests/test_data.py",
122
124
  "tests/test_env_vars.py",
125
+ "tests/test_format_codes.py",
123
126
  ]
xulbux-1.5.9/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -19,12 +19,12 @@
19
19
  • REGEX PATTERN TEMPLATES xx.Regex
20
20
  """
21
21
 
22
- __version__ = "1.5.8"
22
+ __version__ = "1.5.9"
23
23
  __author__ = "XulbuX"
24
24
  __email__ = "xulbux.real@gmail.com"
25
25
  __license__ = "MIT"
26
26
  __copyright__ = "Copyright (c) 2024 XulbuX"
27
- __url__ = "https://github.com/XulbuX-dev/Python/tree/main/Libraries/XulbuX"
27
+ __url__ = "https://github.com/XulbuX-dev/PythonLibraryXulbuX"
28
28
  __description__ = "A library which includes a lot of really helpful functions."
29
29
  __all__ = [
30
30
  "_consts_",
@@ -32,7 +32,7 @@ def help_command():
32
32
  [dim](•) CUSTOM TYPES:
33
33
  [dim](•) [{color['class']}]rgba[{color['punctuators']}]/([i|{color['types']}]int[_|{color['punctuators']}],[i|{color['types']}]int[_|{color['punctuators']}],[i|{color['types']}]int[_|{color['punctuators']}],[i|{color['types']}]float[_|{color['punctuators']}])[*]
34
34
  [dim](•) [{color['class']}]hsla[{color['punctuators']}]/([i|{color['types']}]int[_|{color['punctuators']}],[i|{color['types']}]int[_|{color['punctuators']}],[i|{color['types']}]int[_|{color['punctuators']}],[i|{color['types']}]float[_|{color['punctuators']}])[*]
35
- [dim](•) [{color['class']}]hexa[{color['punctuators']}]/([i|{color['types']}]str[_|{color['punctuators']}])[*]
35
+ [dim](•) [{color['class']}]hexa[{color['punctuators']}]/([i|{color['types']}]str[_|{color['punctuators']}]|[i|{color['types']}]int[_|{color['punctuators']}])[*]
36
36
  [dim](•) PATH OPERATIONS [{color['lib']}]xx[{color['punctuators']}].[{color['class']}]Path[*]
37
37
  [dim](•) FILE OPERATIONS [{color['lib']}]xx[{color['punctuators']}].[{color['class']}]File[*]
38
38
  [dim](•) JSON FILE OPERATIONS [{color['lib']}]xx[{color['punctuators']}].[{color['class']}]Json[*]
@@ -47,6 +47,7 @@ def help_command():
47
47
  [dim](•) REGEX PATTERN TEMPLATES [{color['lib']}]xx[{color['punctuators']}].[{color['class']}]Regex[*]
48
48
  [_]
49
49
  [dim](Press any key to exit...)
50
- """
50
+ """,
51
+ default_color=DEFAULT.text_color,
51
52
  )
52
53
  Console.pause_exit(pause=True)
@@ -58,6 +58,7 @@ class ANSI:
58
58
 
59
59
  global CHAR, START, SEP, END
60
60
 
61
+ char_esc = r"\x1b"
61
62
  CHAR = char = "\x1b"
62
63
  START = start = "["
63
64
  SEP = sep = ";"
@@ -16,7 +16,7 @@ class Code:
16
16
  @staticmethod
17
17
  def get_tab_spaces(code: str) -> int:
18
18
  """Will try to get the amount of spaces used for indentation."""
19
- code_lines = String.get_string_lines(code, remove_empty_lines=True)
19
+ code_lines = String.get_lines(code, remove_empty_lines=True)
20
20
  indents = [len(line) - len(line.lstrip()) for line in code_lines]
21
21
  non_zero_indents = [i for i in indents if i > 0]
22
22
  return min(non_zero_indents) if non_zero_indents else 0
@@ -26,8 +26,8 @@ class Code:
26
26
  """Replaces all tabs with `new_tab_size` spaces.<br>
27
27
  If `remove_empty_lines` is `True`, empty lines will be removed in the process.
28
28
  """
29
- code_lines = String.get_string_lines(code, remove_empty_lines=True)
30
- lines = code_lines if remove_empty_lines else String.get_string_lines(code)
29
+ code_lines = String.get_lines(code, remove_empty_lines=True)
30
+ lines = code_lines if remove_empty_lines else String.get_lines(code)
31
31
  tab_spaces = Code.get_tab_spaces(code)
32
32
  if (tab_spaces == new_tab_size) or tab_spaces == 0:
33
33
  if remove_empty_lines:
@@ -904,28 +904,25 @@ class Color:
904
904
 
905
905
  @staticmethod
906
906
  def text_color_for_on_bg(
907
- title_bg_color: rgba | hexa = 0xFFF,
907
+ text_bg_color: rgba | hexa = 0xFFF,
908
908
  ) -> rgba | hexa:
909
- (was_hexa, hexa_prefix), was_int = Color.is_valid_hexa(title_bg_color, get_prefix=True), isinstance(
910
- title_bg_color, int
911
- )
912
- title_bg_color = Color.to_rgba(title_bg_color)
913
- brightness = 0.2126 * title_bg_color[0] + 0.7152 * title_bg_color[1] + 0.0722 * title_bg_color[2]
909
+ was_hexa, was_int = Color.is_valid_hexa(text_bg_color), isinstance(text_bg_color, int)
910
+ text_bg_color = Color.to_rgba(text_bg_color)
911
+ brightness = 0.2126 * text_bg_color[0] + 0.7152 * text_bg_color[1] + 0.0722 * text_bg_color[2]
914
912
  return (
915
- (hexa(f"{hexa_prefix}FFF") if was_hexa else rgba(255, 255, 255))
913
+ (hexa("#FFF") if was_hexa else rgba(255, 255, 255))
916
914
  if brightness < 128
917
- else ((0x000 if was_int else hexa(f"{hexa_prefix}000")) if was_hexa else rgba(0, 0, 0))
915
+ else ((0x000 if was_int else hexa("#000")) if was_hexa else rgba(0, 0, 0))
918
916
  )
919
917
 
920
918
  @staticmethod
921
- def adjust_lightness(color: rgba | hexa, brightness_change: float) -> rgba | hexa:
919
+ def adjust_lightness(color: rgba | hexa, lightness_change: float) -> rgba | hexa:
922
920
  """In- or decrease the lightness of the input color.\n
923
921
  ----------------------------------------------------------------------------------------------------
924
922
  **color** (rgba|hexa): HEX or RGBA color<br>
925
- **brightness_change** (float): float between -1.0 (darken by `100%`) and 1.0 (lighten by `100%`)\n
923
+ **lightness_change** (float): float between -1.0 (darken by `100%`) and 1.0 (lighten by `100%`)\n
926
924
  ----------------------------------------------------------------------------------------------------
927
- **returns** (rgba|hexa): the adjusted color in the format of the input color
928
- """
925
+ **returns** (rgba|hexa): the adjusted color in the format of the input color"""
929
926
  was_hexa = Color.is_valid_hexa(color)
930
927
  color = Color.to_hsla(color)
931
928
  h, s, l, a = (
@@ -934,7 +931,7 @@ class Color:
934
931
  color[2],
935
932
  color[3] if Color.has_alpha(color) else None,
936
933
  )
937
- l = int(max(0, min(100, l + brightness_change * 100)))
934
+ l = int(max(0, min(100, l + lightness_change * 100)))
938
935
  return Color.to_hexa((h, s, l, a)) if was_hexa else Color.to_rgba((h, s, l, a))
939
936
 
940
937
  @staticmethod
@@ -944,8 +941,7 @@ class Color:
944
941
  **color** (rgba|hexa): HEX or RGBA color<br>
945
942
  **saturation_change** (float): float between -1.0 (saturate by `100%`) and 1.0 (desaturate by `100%`)\n
946
943
  ---------------------------------------------------------------------------------------------------------
947
- **returns** (rgba|hexa): the adjusted color in the format of the input color
948
- """
944
+ **returns** (rgba|hexa): the adjusted color in the format of the input color"""
949
945
  was_hexa = Color.is_valid_hexa(color)
950
946
  color = Color.to_hsla(color)
951
947
  h, s, l, a = (
@@ -6,29 +6,6 @@ import os as _os
6
6
 
7
7
  class File:
8
8
 
9
- @staticmethod
10
- def _make_path(
11
- filename: str,
12
- filetype: str,
13
- search_in: str | list[str] = None,
14
- prefer_base_dir: bool = True,
15
- correct_path: bool = False,
16
- ) -> str:
17
- """Get the path to a file in the cwd, the base-dir, or predefined directories.\n
18
- --------------------------------------------------------------------------------------
19
- If the `filename` is not found in the above directories, it will be searched<br>
20
- in the `search_in` directory/directories. If the file is still not found, it will<br>
21
- return the path to the file in the base-dir per default or to the file in the<br>
22
- cwd if `prefer_base_dir` is set to `False`."""
23
- if not filename.lower().endswith(f".{filetype.lower()}"):
24
- filename = f"{filename}.{filetype.lower()}"
25
- try:
26
- return Path.extend(filename, search_in, True, correct_path)
27
- except FileNotFoundError:
28
- return (
29
- _os.path.join(Path.get(base_dir=True), filename) if prefer_base_dir else _os.path.join(_os.getcwd(), filename)
30
- )
31
-
32
9
  @staticmethod
33
10
  def rename_extension(file_path: str, new_extension: str) -> str:
34
11
  directory, filename_with_ext = _os.path.split(file_path)
@@ -54,3 +31,26 @@ class File:
54
31
  f.write(content)
55
32
  full_path = _os.path.abspath(file)
56
33
  return full_path
34
+
35
+ @staticmethod
36
+ def make_path(
37
+ filename: str,
38
+ filetype: str,
39
+ search_in: str | list[str] = None,
40
+ prefer_base_dir: bool = True,
41
+ correct_path: bool = False,
42
+ ) -> str:
43
+ """Create the path to a file in the cwd, the base-dir, or predefined directories.\n
44
+ --------------------------------------------------------------------------------------
45
+ If the `filename` is not found in the above directories, it will be searched<br>
46
+ in the `search_in` directory/directories. If the file is still not found, it will<br>
47
+ return the path to the file in the base-dir per default or to the file in the<br>
48
+ cwd if `prefer_base_dir` is set to `False`."""
49
+ if not filename.lower().endswith(f".{filetype.lower()}"):
50
+ filename = f"{filename}.{filetype.lower()}"
51
+ try:
52
+ return Path.extend(filename, search_in, True, correct_path)
53
+ except FileNotFoundError:
54
+ return (
55
+ _os.path.join(Path.get(base_dir=True), filename) if prefer_base_dir else _os.path.join(_os.getcwd(), filename)
56
+ )
@@ -124,7 +124,8 @@ class FormatCodes:
124
124
  def to_ansi(
125
125
  string: str, default_color: hexa | rgba = None, brightness_steps: int = 20, _default_start: bool = True
126
126
  ) -> str:
127
- result = ""
127
+ result, bg_kwd, color_pref = string, {"bg"}, {"br", "bright"}
128
+
128
129
  if Color.is_valid_rgba(default_color, False):
129
130
  use_default = True
130
131
  elif Color.is_valid_hexa(default_color, False):
@@ -135,32 +136,48 @@ class FormatCodes:
135
136
  string = COMPILED["*"].sub(r"[\1_|default\2]", string) # REPLACE `[…|*|…]` WITH `[…|_|default|…]`
136
137
  string = COMPILED["*color"].sub(r"[\1default\2]", string) # REPLACE `[…|*color|…]` WITH `[…|default|…]`
137
138
 
139
+ def is_valid_color(color: str) -> bool:
140
+ return color in ANSI.color_map or Color.is_valid_rgba(color) or Color.is_valid_hexa(color)
141
+
138
142
  def replace_keys(match: _re.Match) -> str:
139
- format_keys = match.group(1)
140
- esc = match.group(2)
143
+ formats = match.group(1)
144
+ escaped = match.group(2)
141
145
  auto_reset_txt = match.group(3)
142
- if not format_keys:
146
+ if auto_reset_txt and auto_reset_txt.count("[") > 0 and auto_reset_txt.count("]") > 0:
147
+ auto_reset_txt = FormatCodes.to_ansi(auto_reset_txt, default_color, brightness_steps, False)
148
+ if not formats:
143
149
  return match.group(0)
144
- format_keys = [k.strip() for k in format_keys.split("|") if k.strip()]
145
- ansi_formats = [FormatCodes.__get_replacement(k, default_color, brightness_steps) for k in format_keys]
146
- if auto_reset_txt and not esc:
147
- reset_keys = [
148
- (
149
- "_color"
150
- if k in ANSI.color_map or Color.is_valid_rgba(k) or Color.is_valid_hexa(k)
151
- else (
152
- "_bg"
153
- if ({"bg", "bright", "br"} & set(k.lower().split(":")))
154
- and len(k.split(":")) <= 3
155
- and any(
156
- k[i:] in ANSI.color_map or Color.is_valid_rgba(k[i:]) or Color.is_valid_hexa(k[i:])
157
- for i in range(len(k))
158
- )
159
- else f"_{k}"
160
- )
161
- )
162
- for k in format_keys
163
- ]
150
+ if formats.count("[") > 0 and formats.count("]") > 0:
151
+ formats = FormatCodes.to_ansi(formats, default_color, brightness_steps, False)
152
+ format_keys = [k.strip() for k in formats.split("|") if k.strip()]
153
+ ansi_formats = [
154
+ r if (r := FormatCodes.__get_replacement(k, default_color, brightness_steps)) != k else f"[{k}]"
155
+ for k in format_keys
156
+ ]
157
+ if auto_reset_txt and not escaped:
158
+ reset_keys = []
159
+ for k in format_keys:
160
+ k_lower = k.lower()
161
+ k_parts = k_lower.split(":")
162
+ k_set = set(k_parts)
163
+ if bg_kwd & k_set and len(k_parts) <= 3:
164
+ if k_set & color_pref:
165
+ for i in range(len(k)):
166
+ if is_valid_color(k[i:]):
167
+ reset_keys.extend(["_bg", "_color"])
168
+ break
169
+ else:
170
+ for i in range(len(k)):
171
+ if is_valid_color(k[i:]):
172
+ reset_keys.append("_bg")
173
+ break
174
+ elif is_valid_color(k) or any(
175
+ k_lower.startswith(pref_colon := f"{prefix}:") and is_valid_color(k[len(pref_colon) :])
176
+ for prefix in color_pref
177
+ ):
178
+ reset_keys.append("_color")
179
+ else:
180
+ reset_keys.append(f"_{k}")
164
181
  ansi_resets = [
165
182
  r
166
183
  for k in reset_keys
@@ -170,24 +187,27 @@ class FormatCodes:
170
187
  ]
171
188
  else:
172
189
  ansi_resets = []
173
- if not all(f.startswith(f"{ANSI.char}{ANSI.start}") for f in ansi_formats):
190
+ if not (len(ansi_formats) == 1 and ansi_formats[0].count(f"{ANSI.char}{ANSI.start}") >= 1) and not all(
191
+ f.startswith(f"{ANSI.char}{ANSI.start}") for f in ansi_formats
192
+ ):
174
193
  return match.group(0)
175
194
  return (
176
195
  "".join(ansi_formats)
177
196
  + (
178
197
  f"({FormatCodes.to_ansi(auto_reset_txt, default_color, brightness_steps, False)})"
179
- if esc and auto_reset_txt
198
+ if escaped and auto_reset_txt
180
199
  else auto_reset_txt if auto_reset_txt else ""
181
200
  )
182
- + ("" if esc else "".join(ansi_resets))
201
+ + ("" if escaped else "".join(ansi_resets))
183
202
  )
184
203
 
185
- return (
186
- (FormatCodes.__get_default_ansi(default_color) if _default_start else "")
187
- + (result := "\n".join(COMPILED["format"].sub(replace_keys, line) for line in string.split("\n")))
188
- if use_default
189
- else result
190
- )
204
+ result = "\n".join(COMPILED["format"].sub(replace_keys, line) for line in string.split("\n"))
205
+ return (FormatCodes.__get_default_ansi(default_color) if _default_start else "") + result if use_default else result
206
+
207
+ @staticmethod
208
+ def escape_ansi(ansi_string: str, escaped_char: str = ANSI.char_esc) -> str:
209
+ """Makes the string printable with the ANSI formats visible."""
210
+ return ansi_string.replace(ANSI.char, escaped_char)
191
211
 
192
212
  @staticmethod
193
213
  @lru_cache(maxsize=64)
@@ -22,7 +22,7 @@ class Json:
22
22
  the the section from `comment_start` to `comment_end` is ignored.<br>
23
23
  If `return_original` is set to `True`, the original JSON is returned<br>
24
24
  additionally. (returns: `[processed_json, original_json]`)"""
25
- file_path = File._make_path(json_file, "json", prefer_base_dir=True)
25
+ file_path = File.make_path(json_file, "json", prefer_base_dir=True)
26
26
  with open(file_path, "r") as f:
27
27
  content = f.read()
28
28
  try:
@@ -42,7 +42,7 @@ class Json:
42
42
  compactness: int = 1,
43
43
  force: bool = False,
44
44
  ) -> str:
45
- file_path = File._make_path(new_file, "json", prefer_base_dir=True)
45
+ file_path = File.make_path(new_file, "json", prefer_base_dir=True)
46
46
  if _os.path.exists(file_path) and not force:
47
47
  with open(file_path, "r", encoding="utf-8") as existing_f:
48
48
  existing_content = _json.load(existing_f)
@@ -22,16 +22,14 @@ class Regex:
22
22
  **`quote`** the quote type (single or double)<br>
23
23
  **`string`** everything inside the found quote pair\n
24
24
  ------------------------------------------------------------------------------------
25
- **Attention:** Requires non standard library `regex` not standard library `re`!
26
- """
25
+ **Attention:** Requires non standard library `regex` not standard library `re`!"""
27
26
  return r'(?P<quote>[\'"])(?P<string>(?:\\.|(?!\g<quote>).)*?)\g<quote>'
28
27
 
29
28
  @staticmethod
30
29
  def brackets(bracket1: str = "(", bracket2: str = ")", is_group: bool = False) -> str:
31
30
  """Matches everything inside brackets, including other nested brackets.\n
32
31
  ------------------------------------------------------------------------------------
33
- **Attention:** Requires non standard library `regex` not standard library `re`!
34
- """
32
+ **Attention:** Requires non standard library `regex` not standard library `re`!"""
35
33
  g, b1, b2 = (
36
34
  "" if is_group else "?:",
37
35
  _re.escape(bracket1) if len(bracket1) == 1 else bracket1,
@@ -51,10 +49,10 @@ class Regex:
51
49
  is_group: bool = False,
52
50
  ) -> str:
53
51
  """Matches everything except `disallowed_pattern`, unless the `disallowed_pattern` is found inside a string (`'...'` or `"..."`).\n
54
- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
55
- The `ignore_pattern` is just always ignored. For example if `disallowed_pattern` is `>` and `ignore_pattern` is `->`, the `->`-arrows will be allowed, even though they have `>` in them.<br>
56
- If `is_group` is `True`, you will be able to reference the matched content as a group (e.g. <code>match.group(<i>int</i>)</code> or <code>r'\\<i>int</i>'</code>).
57
- """
52
+ ------------------------------------------------------------------------------------------------------------------------------------
53
+ The `ignore_pattern` is just always ignored. For example if `disallowed_pattern` is `>` and `ignore_pattern` is `->`, the `->`<br>
54
+ -arrows will be allowed, even though they have `>` in them. If `is_group` is `True`, you will be able to reference the matched<br>
55
+ content as a group (e.g. <code>match.group(<i>int</i>)</code> or <code>r'\\<i>int</i>'</code>)."""
58
56
  return rf'({"" if is_group else "?:"}(?:(?!{ignore_pattern}).)*(?:(?!{Regex.outside_strings(disallowed_pattern)}).)*)'
59
57
 
60
58
  @staticmethod
@@ -64,8 +62,7 @@ class Regex:
64
62
  **`2`** the function's arguments\n
65
63
  If no `func_name` is given, it will match any function call.\n
66
64
  ------------------------------------------------------------------------------------
67
- **Attention:** Requires non standard library `regex` not standard library `re`!
68
- """
65
+ **Attention:** Requires non standard library `regex` not standard library `re`!"""
69
66
  return r"(?<=\b)(" + (func_name if func_name else r"[\w_]+") + r")\s*" + Regex.brackets("(", ")", is_group=True)
70
67
 
71
68
  @staticmethod