chromatic-python 0.3.3__tar.gz → 0.3.4__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.
- {chromatic_python-0.3.3/chromatic_python.egg-info → chromatic_python-0.3.4}/PKG-INFO +1 -1
- chromatic_python-0.3.4/chromatic/__main__.py +105 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/_version.py +3 -3
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/color/core.py +93 -123
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/color/core.pyi +3 -2
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/color/palette.py +20 -25
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/color/palette.pyi +2 -4
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/userfont.py +17 -2
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/demo.py +78 -134
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/image/_array.py +14 -14
- {chromatic_python-0.3.3 → chromatic_python-0.3.4/chromatic_python.egg-info}/PKG-INFO +1 -1
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic_python.egg-info/SOURCES.txt +1 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/.gitattributes +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/.gitignore +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/LICENSE +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/README.md +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/__init__.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/__init__.pyi +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/_typing.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/color/__init__.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/color/__init__.pyi +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/color/colorconv.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/color/iterators.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/__init__.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/__init__.pyi +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/_fetchers.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/butterfly.jpg +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/escher.png +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/fonts/consolas.ttf +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/fonts/vga437.ttf +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/goblin_virus.png +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/registry.json +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/userfont.pyi +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/data/userfont.schema.json +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/image/__init__.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/image/__init__.pyi +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/image/_curses.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic/image/_glyph_proc.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic_python.egg-info/dependency_links.txt +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic_python.egg-info/requires.txt +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic_python.egg-info/top_level.txt +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/logo/logo.ANS +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/logo/logo.PNG +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/pyproject.toml +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/requirements.txt +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/setup.cfg +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/tests/__init__.py +0 -0
- {chromatic_python-0.3.3 → chromatic_python-0.3.4}/tests/test_color_str.py +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
from . import __version__, __name__ as prog
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def banner():
|
|
5
|
+
from chromatic import read_ans
|
|
6
|
+
from base64 import b64decode
|
|
7
|
+
import io
|
|
8
|
+
|
|
9
|
+
art = read_ans(
|
|
10
|
+
io.TextIOWrapper(
|
|
11
|
+
io.BytesIO(
|
|
12
|
+
b64decode(
|
|
13
|
+
b"""\
|
|
14
|
+
G1swbQ0KICAgICAgICAgICAgICAgICAgG1s5MG36ICAg+vogICAgICAgICAgG1swOzM0bfobWzMy
|
|
15
|
+
bfobWzkxbfobWzkwbSAbWzA7MzRt+vobWzkzbfobWzkxbfobWzA7MzVt+vobWzkwbSAgICAgICAg
|
|
16
|
+
ICAg+iAgIPr6DQobWzBtICAgICAgICAgG1s5MG36ICAgIPouICD6IC4g+vogG1swOzM0bfobWzMy
|
|
17
|
+
bfobWzk0bfobWzkwbSAbWzA7MzVt+htbMzRt+i4bWzkxbfobWzkybS4bWzA7MzRt+htbMzJt+htb
|
|
18
|
+
MzFt+htbMzJtLhtbOTFtLhtbMDszNG36G1s5Mm36G1swOzMxbfobWzMybS4bWzkzbS4bWzA7MzJt
|
|
19
|
+
+htbOTFt+htbOTBt+htbMDszNW36G1szNG36G1szMm36G1s5NG36G1s5MG36G1swOzM1bfobWzkw
|
|
20
|
+
bSAg+iAuIPr6IC4g+iAgICD6DQobWzBtICAgG1s5MG0gICAuICAgIC4g+jouICAgICAgG1swOzM0
|
|
21
|
+
bS4bWzMybS4bWzk0bS4bWzkwbS4bWzA7MzVtLhtbMzRtLhtbMzJtLhtbOTFtLhtbMDszNG06G1s5
|
|
22
|
+
NG36G1s5Mm06G1swOzMxbS4bWzM1bTouG1s5MG0gICAgIBtbMDszNG0uLhtbOTJtLhtbMDszMW0u
|
|
23
|
+
G1szMm36G1s5NG36G1swOzMybS4bWzkxbS4bWzkwbSAbWzA7MzVtLhtbMzRtLhtbMzJtLhtbOTRt
|
|
24
|
+
LhtbOTBtIBtbMDszNW0uG1s5MG0gICAgICAuLiD6IC4gICAgLg0KG1swbSAbWzkwbSAgICA6ICAg
|
|
25
|
+
IDogIGw6IC4gICAgG1swOzM0bTobWzMybTobWzk0bTobWzkwbSAbWzA7MzVtOhtbMzRtOhtbMzJt
|
|
26
|
+
OhtbOTFtOhtbMDszNG1sOhtbOTJtbBtbMDszMW06G1szMm0uG1s5NG0uG1s5MG0gG1swOzM1bS4b
|
|
27
|
+
WzkwbSAgG1swOzMybSAgG1szNG0uOhtbOTRtLhtbOTJtOhtbMDszMW06G1szNW06G1szNG06G1sz
|
|
28
|
+
Mm06G1s5MW06G1s5MG1sG1swOzM1bTobWzM0bTobWzMybTobWzk0bTobWzkwbSAbWzA7MzVtOhtb
|
|
29
|
+
OTBtICAgICAuOjogICA6ICAgIDobWzA7MzJtG1szN20NChtbOTBtICAgIGwgICAgbCAgJGwgICA6
|
|
30
|
+
ICAbWzA7MzRtbBtbMzJtbBtbOTRtbBtbOTBtIBtbMDszNW1sG1szNG1sG1szMm1sG1s5MW1sG1sw
|
|
31
|
+
OzM0bSRsG1s5Mm0kG1swOzMxbWwbWzM1bSQbWzM0bTobWzMybTobWzk0bTobWzkwbSAbWzA7MzVt
|
|
32
|
+
OhtbOTBtIBtbMDszMm0gG1szNG06G1szMm06G1s5NG06G1swOzM0bWxsG1s5Mm1sG1swOzMxbWwb
|
|
33
|
+
WzM1bWwbWzM0bWwbWzMybWwbWzkxbWwbWzkwbSAbWzA7MzVtbBtbMzRtbBtbMzJtbBtbOTRtbBtb
|
|
34
|
+
OTBtIBtbMDszNW1sG1s5MG0gICA6ICBsbCAgIGwgICAgbBtbMDszMm0bWzM3bQ0KG1s5MG0gICAk
|
|
35
|
+
ICAgICQgICAkICAgICBsG1swOzM0bSQbWzMybSQbWzk0bSQbWzkwbSAbWzA7MzVtJBtbMzRtJBtb
|
|
36
|
+
MzJtJBtbOTFtJBtbOTBtIBtbMDszNG0kG1szMm0kG1szMW0kG1s5MG0gG1swOzM1bSQbWzkwbSQb
|
|
37
|
+
WzA7MzRtbBtbMzJtbBtbOTRtbBtbOTBtIBtbMDszNW1sG1szNG1sG1szMm1sG1s5NG1sG1s5MG0g
|
|
38
|
+
G1swOzM1bWwbWzM0bSQkG1s5Mm0kG1swOzMxbSQbWzM1bSQbWzM0bSQbWzMybSQbWzkxbSQbWzkw
|
|
39
|
+
bSAbWzA7MzVtJBtbMzRtJBtbMzJtJBtbOTRtJBtbOTBtIBtbMDszNW0kG1s5MG0gbCAgICAkJCAg
|
|
40
|
+
ICQgICAgJBtbMDszMm0bWzM3bQ0KG1s5MG0gICDbICAgINsgICDb3CAgICAgG1swOzM0bdsbWzMy
|
|
41
|
+
bdsbWzk0bdsbWzkwbSQbWzA7MzVt2xtbMzRt2xtbMzJt2xtbOTFt2xtbOTBt3BtbMDszNG3b3Btb
|
|
42
|
+
MzFt2xtbOTJt3BtbMDszNW3b3BtbOTBtIBtbMDszNG0kG1szMm0kG1s5NG0kG1swOzM0bSQbWzMy
|
|
43
|
+
bSQbWzk0bSQbWzkwbSAbWzA7MzVtJBtbMzRt3NsbWzkzbdwbWzkybdsbWzA7MzFt2xtbMzVt2xtb
|
|
44
|
+
MzRt2xtbMzJt2xtbOTFt2xtbOTBtIBtbMDszNW3bG1szNG3bG1szMm3bG1s5NG3bG1s5MG0gG1sw
|
|
45
|
+
OzM1bdsbWzkwbSQgICAg3NvbICAg2yAgICDbG1swOzMybRtbMzdtDQobWzkwbSAgICfcICAgJ9wg
|
|
46
|
+
ICfcN9wuICAbWzA7MzRtJ9wbWzk0bSfcG1swOzM1bScbWzM0bSfcG1s5MW0n3BtbMDszNG0n3Btb
|
|
47
|
+
MzFtJ9wbWzkybTfcLhtbMDszNG3b3BtbOTRt2xtbOTFt3C4bWzk0bdsbWzA7MzRt3BtbOTNtLtw3
|
|
48
|
+
G1s5Mm3cG1swOzMxbdwnG1szNG3cJxtbOTFt3CcbWzA7MzVt3BtbMzRt3CcbWzk0bdwnG1swOzM1
|
|
49
|
+
bdwnG1s5MG3bIC7cN9zcJyAg3CcgICDcJxtbMDszMm0bWzM3bQ0KG1s5MG0gICAgJzfcLiAnN9wu
|
|
50
|
+
JzfcLmpfLBtbMDszNG0nNxtbOTRtJzfcLhtbMDszNG03G1s5MW0nN9wuG1swOzMxbSc33C4bWzkx
|
|
51
|
+
bWobWzA7MzFtXyxq3CxfG1s5MW1qG1swOzMxbS7cNycbWzkxbS7cNycbWzA7MzRt3BtbOTRtLtw3
|
|
52
|
+
JxtbMDszNW03JxtbOTBt3Cxfai7cNycu3DcnIC7cNycbWzA7MzJtG1szN20NChtbOTBtICAgICAg
|
|
53
|
+
ICffN2rcLF83LrCyN2os3GobWzA7MzRtJ98bWzk0bSffN2rcLF8bWzkxbTcbWzk0bS4bWzA7MzFt
|
|
54
|
+
sLI3aizcajeysBtbOTRtLhtbOTFtNxtbOTRtXyzcajffJxtbMDszNW3fJxtbOTBtN2os3Go3srAu
|
|
55
|
+
N18s3Go33ycbWzA7MzJtG1szN20NChtbOTBtICAgICAgICAgICzcajey3N8n39wnJ9zfJ98bWzA7
|
|
56
|
+
MzRtLNwbWzk0bSzcajeyG1swOzMxbdzfG1s5MW0n39wbWzA7MzFtJxtbOTNtJxtbOTFt3N8nG1sw
|
|
57
|
+
OzMxbd/cG1s5NG2yN2rcLBtbMDszNW3cLBtbOTBt3N8n39wnJ9zfJ9/csjdq3CwbWzA7MzJtG1sz
|
|
58
|
+
N20NChtbOTBtICAgICAgICDc3yewICDdsNzdIN0g3t3eG1swOzM0bdzfG1s5NG3c3ycbWzkxbbAb
|
|
59
|
+
WzA7MzRt3bAbWzMxbd2wG1s5NG3cG1s5Mm3dG1swOzMybd0bWzkxbd0bWzA7MzRt3RtbOTFt3t0b
|
|
60
|
+
Wzkzbd7dG1s5NG3cG1swOzMxbbDdG1szNG2wJxtbOTFtsBtbOTRtJ9/cG1swOzM1bd/cG1s5MG3d
|
|
61
|
+
IN0g3t3e3dyw3SAgsCff3BtbMDszMm0bWzM3bQ0KG1s5MG0gICAgICAg3t0gIN/cICDf3N4gICDb
|
|
62
|
+
IBtbMDszNG3e3RtbOTRt3t0bWzA7MzRt39wbWzkxbd/cG1swOzM0bd/cG1szMW3f3BtbOTRt3htb
|
|
63
|
+
MDszNW3cG1szNG3bG1szMm3bG1s5MW3bG1swOzM0bd7cG1s5NG3eG1swOzMxbdzfG1szNG3c3xtb
|
|
64
|
+
OTFt3N8bWzA7MzRt3t0bWzk0bd7dG1swOzM1bd7dG1s5MG0gICDbICDe3N8gINzfICDe3RtbMDsz
|
|
65
|
+
Mm0bWzM3bQ0KG1s5MG0gICAgICAg2yAgICAgNy7c3zcu3SDe3RtbMDszNG3bG1szMm3bG1s5NG3b
|
|
66
|
+
G1s5MG3cG1swOzM1bdsbWzkwbTcbWzA7MzRtNy4bWzkxbTcuG1s5NG3c3xtbMDszMW03LhtbOTFt
|
|
67
|
+
3RtbMDszNG3dG1s5MW3e3RtbMDszMW0uNxtbOTRt39wbWzkxbS43G1swOzM1bS43G1s5MG0gG1sw
|
|
68
|
+
OzM0bdsbWzMybdsbWzk0bdsbWzkwbd8bWzA7MzVt2xtbOTBtLt0g3t0uN9/cLjcgICAgINsbWzA7
|
|
69
|
+
MzJtG1szN20NChtbOTBtICAgICAgIN7dICAgIC7f3z/cJ9/cP98bWzA7MzRt3t0bWzk0bd7dG1sw
|
|
70
|
+
OzM1bd7dG1szNG0u3xtbOTRtLt8bWzkxbd8/3BtbMDszMW0n39w/3ycbWzkxbdw/3xtbOTRt3y4b
|
|
71
|
+
WzA7MzVt3y4bWzM0bd7dG1s5NG3e3RtbMDszNW3e3RtbOTBtJ9/cP98n3D/f3y4gICAg3t0bWzA7
|
|
72
|
+
MzJtG1szN20NChtbOTBtICAgICAgICDf3CAg3F8u3D9fLtzfP9wuG1swOzM0bd/cG1s5NG3f3Btb
|
|
73
|
+
MDszNG3cXxtbOTJt3BtbOTFtXy7cPxtbMDszMW1fLtzfP9wuXxtbOTFtP9wuXxtbMDszNW0uG1sz
|
|
74
|
+
NG3c3xtbOTRt3N8bWzA7MzVt3N8bWzkwbV8u3N8/3C5fP9wuXyAgINzfG1swOzMybRtbMzdtDQob
|
|
75
|
+
WzkwbSAgICAgICAgICLfP9wuXyDf3yIgICAiIt8bWzA7MzRtIt8bWzk0bSLfP9wuXxtbMDszNG3f
|
|
76
|
+
G1szMW3f3yIbWzM1bd8bWzM0bSIiG1s5Mm0iG1swOzMxbSLf3xtbMzRtLhtbOTRtXy7cP98iG1sw
|
|
77
|
+
OzM1bd8iG1s5MG3f3yIgICAiIt/fIF8u3D/fIhtbMDszMm0bWzM3bQ0KG1s5MG0gICAgICAgICAg
|
|
78
|
+
ICAgIt/fICAgICAgICAgIN/fIhtbMDszNG0i3xtbOTRtIt/fG1swOzM1bd/fG1s5MG0gICAbWzA7
|
|
79
|
+
MzJtICAbWzkwbSAbWzA7MzRt398bWzk0bd/fIhtbMDszNW3fIhtbOTBtICLf3yAgICAgICAgICDf
|
|
80
|
+
3yIbWzA7MzJtG1szN20NChtbMG0NChtbOTBtezogXjgwfRtbMG0="""
|
|
81
|
+
)
|
|
82
|
+
),
|
|
83
|
+
encoding="cp437",
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
return art.format(f"{prog} {__version__}")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def main():
|
|
91
|
+
import argparse
|
|
92
|
+
|
|
93
|
+
parser = argparse.ArgumentParser(
|
|
94
|
+
prog=prog,
|
|
95
|
+
description=banner(),
|
|
96
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
97
|
+
)
|
|
98
|
+
parser.add_argument(
|
|
99
|
+
"--version", action="version", version=f"%(prog)s {__version__}"
|
|
100
|
+
)
|
|
101
|
+
parser.parse_args()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if __name__ == '__main__':
|
|
105
|
+
main()
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.3.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 3,
|
|
31
|
+
__version__ = version = '0.3.4'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 3, 4)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'gb93479602'
|
|
@@ -11,6 +11,7 @@ __all__ = [
|
|
|
11
11
|
'color_chain',
|
|
12
12
|
'colorbytes',
|
|
13
13
|
'get_ansi_type',
|
|
14
|
+
'is_vt_enabled',
|
|
14
15
|
'randcolor',
|
|
15
16
|
'rgb2ansi_escape',
|
|
16
17
|
]
|
|
@@ -18,6 +19,7 @@ __all__ = [
|
|
|
18
19
|
import os
|
|
19
20
|
import random
|
|
20
21
|
import re
|
|
22
|
+
import sys
|
|
21
23
|
from collections import Counter
|
|
22
24
|
from collections.abc import Buffer
|
|
23
25
|
from copy import deepcopy
|
|
@@ -53,9 +55,9 @@ from .colorconv import (
|
|
|
53
55
|
)
|
|
54
56
|
from .._typing import AnsiColorAlias, ColorDictKeys, Int3Tuple
|
|
55
57
|
|
|
56
|
-
os.system('')
|
|
58
|
+
# os.system('')
|
|
57
59
|
|
|
58
|
-
CSI: Final[bytes] = b'
|
|
60
|
+
CSI: Final[bytes] = b'\x1b['
|
|
59
61
|
SGR_RESET: Final[bytes] = CSI + b'0m'
|
|
60
62
|
SGR_RESET_S: Final[str] = SGR_RESET.decode()
|
|
61
63
|
|
|
@@ -346,42 +348,48 @@ class ansicolor24Bit(colorbytes):
|
|
|
346
348
|
alias = '24b'
|
|
347
349
|
|
|
348
350
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
'ANSICON',
|
|
352
|
-
'COLORTERM',
|
|
353
|
-
'ConEmuANSI',
|
|
354
|
-
'PYCHARM_HOSTED',
|
|
355
|
-
'TERM',
|
|
356
|
-
'TERMINAL_EMULATOR',
|
|
357
|
-
'TERM_PROGRAM',
|
|
358
|
-
'WT_SESSION',
|
|
359
|
-
]
|
|
360
|
-
)
|
|
361
|
-
|
|
351
|
+
if os.name == 'nt':
|
|
352
|
+
from ctypes import windll, wintypes
|
|
362
353
|
|
|
363
|
-
def
|
|
364
|
-
|
|
365
|
-
|
|
354
|
+
def _enable_vt_processing(handle: int):
|
|
355
|
+
ENABLE_VT_PROCESSING = 0x0004
|
|
356
|
+
k32 = windll.kernel32
|
|
357
|
+
k32.GetStdHandle.restype = wintypes.HANDLE
|
|
358
|
+
k32.GetConsoleMode.restype = k32.SetConsoleMode.restype = wintypes.BOOL
|
|
359
|
+
h = k32.GetStdHandle(handle)
|
|
360
|
+
if h == -1:
|
|
361
|
+
return False
|
|
362
|
+
mode = wintypes.DWORD()
|
|
363
|
+
if not k32.GetConsoleMode(h, byref(mode)):
|
|
364
|
+
return False
|
|
365
|
+
mode.value |= ENABLE_VT_PROCESSING
|
|
366
|
+
return bool(k32.SetConsoleMode(h, mode))
|
|
367
|
+
|
|
368
|
+
def is_vt_enabled():
|
|
369
|
+
if os.environ.keys() & {
|
|
370
|
+
'ANSICON',
|
|
371
|
+
'COLORTERM',
|
|
372
|
+
'ConEmuANSI',
|
|
373
|
+
'PYCHARM_HOSTED',
|
|
374
|
+
'TERM',
|
|
375
|
+
'TERMINAL_EMULATOR',
|
|
376
|
+
'TERM_PROGRAM',
|
|
377
|
+
'WT_SESSION',
|
|
378
|
+
}:
|
|
379
|
+
return True
|
|
380
|
+
ok = False
|
|
381
|
+
for fd, handle in [(sys.stdout, -11), (sys.stderr, -12)]:
|
|
382
|
+
if getattr(fd, "isatty", lambda: False)():
|
|
383
|
+
ok |= _enable_vt_processing(handle)
|
|
384
|
+
return ok
|
|
366
385
|
|
|
367
|
-
|
|
386
|
+
else:
|
|
368
387
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
kernel32 = windll.kernel32
|
|
372
|
-
kernel32.GetStdHandle.restype = wintypes.HANDLE
|
|
373
|
-
kernel32.GetConsoleMode.restype = kernel32.SetConsoleMode.restype = wintypes.BOOL
|
|
374
|
-
handle = kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
|
|
375
|
-
if handle == -1:
|
|
376
|
-
return False
|
|
377
|
-
mode = wintypes.DWORD()
|
|
378
|
-
if not kernel32.GetConsoleMode(handle, byref(mode)):
|
|
379
|
-
return False
|
|
380
|
-
mode.value |= ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
|
381
|
-
return kernel32.SetConsoleMode(handle, mode)
|
|
388
|
+
def is_vt_enabled():
|
|
389
|
+
return True
|
|
382
390
|
|
|
383
391
|
|
|
384
|
-
DEFAULT_ANSI = ansicolor8Bit if
|
|
392
|
+
DEFAULT_ANSI = ansicolor8Bit if is_vt_enabled() else ansicolor4Bit
|
|
385
393
|
|
|
386
394
|
AnsiColorFormat: TypeAlias = ansicolor4Bit | ansicolor8Bit | ansicolor24Bit
|
|
387
395
|
AnsiColorType: TypeAlias = type[AnsiColorFormat]
|
|
@@ -393,7 +401,7 @@ _ANSI_COLOR_TYPES = cast(
|
|
|
393
401
|
_ANSI_FORMAT_MAP = {k: x for x in _ANSI_COLOR_TYPES for k in [x, x.alias]}
|
|
394
402
|
|
|
395
403
|
|
|
396
|
-
@lru_cache
|
|
404
|
+
@lru_cache(maxsize=len(_ANSI_COLOR_TYPES))
|
|
397
405
|
def _is_ansi_type(typ: type):
|
|
398
406
|
try:
|
|
399
407
|
return typ in _ANSI_COLOR_TYPES
|
|
@@ -401,7 +409,7 @@ def _is_ansi_type(typ: type):
|
|
|
401
409
|
return False
|
|
402
410
|
|
|
403
411
|
|
|
404
|
-
@lru_cache
|
|
412
|
+
@lru_cache(maxsize=len(_ANSI_FORMAT_MAP))
|
|
405
413
|
def get_ansi_type(typ):
|
|
406
414
|
try:
|
|
407
415
|
return _ANSI_FORMAT_MAP[typ]
|
|
@@ -432,7 +440,7 @@ def set_default_ansi(typ):
|
|
|
432
440
|
|
|
433
441
|
|
|
434
442
|
@lru_cache(maxsize=1)
|
|
435
|
-
def
|
|
443
|
+
def sgr_pattern():
|
|
436
444
|
uint8_re = r"(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)"
|
|
437
445
|
ansicolor_re = f"[3-4]8;(?:2(?:;{uint8_re}){{3}}|5;{uint8_re})"
|
|
438
446
|
sgr_param_re = (
|
|
@@ -445,7 +453,7 @@ def sgr_re_pattern():
|
|
|
445
453
|
def _split_ansi_escape(__s: str) -> list[tuple['SgrSequence', str]] | None:
|
|
446
454
|
out = []
|
|
447
455
|
i = 0
|
|
448
|
-
for m in
|
|
456
|
+
for m in sgr_pattern().finditer(__s):
|
|
449
457
|
text = __s[i : (j := m.start())]
|
|
450
458
|
if i != j:
|
|
451
459
|
out.append(text)
|
|
@@ -643,8 +651,9 @@ def _iter_normalized_sgr[_T: (
|
|
|
643
651
|
Buffer,
|
|
644
652
|
SupportsInt,
|
|
645
653
|
)](__iter: bytes | bytearray | Iterable[_T]) -> Iterator[int | AnsiColorFormat]:
|
|
646
|
-
__iter:
|
|
647
|
-
|
|
654
|
+
if isinstance(__iter, (bytes, bytearray)):
|
|
655
|
+
__iter = __iter.split(b';')
|
|
656
|
+
for elt in __iter:
|
|
648
657
|
match elt:
|
|
649
658
|
case (colorbytes() as cb) | SgrParamBuffer(colorbytes() as cb):
|
|
650
659
|
yield cb
|
|
@@ -938,44 +947,43 @@ _END_RESET_PATTERN = re.compile(r"\x1b\[0?m$")
|
|
|
938
947
|
_unset: Any = object()
|
|
939
948
|
|
|
940
949
|
|
|
941
|
-
def
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
950
|
+
def _colorstr[_T: ColorStr](
|
|
951
|
+
cls: type[_T],
|
|
952
|
+
obj=_unset,
|
|
953
|
+
/,
|
|
954
|
+
fg=None,
|
|
955
|
+
bg=None,
|
|
956
|
+
*,
|
|
957
|
+
encoding=_unset,
|
|
958
|
+
errors=_unset,
|
|
959
|
+
ansi_type=_unset,
|
|
960
|
+
reset=True,
|
|
961
|
+
) -> _T:
|
|
962
|
+
if buf_kwargs := {
|
|
963
|
+
k: v
|
|
964
|
+
for k, v in locals().items()
|
|
965
|
+
if k in {"encoding", "errors"} and v is not _unset
|
|
966
|
+
}:
|
|
952
967
|
if not isinstance(obj, Buffer):
|
|
953
|
-
raise ValueError(
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
if isinstance(obj, (bytes, bytearray)):
|
|
960
|
-
obj = obj.decode(encoding, errors)
|
|
961
|
-
else:
|
|
962
|
-
obj = bytes(obj).decode(encoding, errors)
|
|
968
|
+
raise ValueError(f"unexpected keyword arguments: {set(buf_kwargs)}")
|
|
969
|
+
elif not isinstance(obj, (bytes, bytearray)):
|
|
970
|
+
obj = bytes(obj)
|
|
971
|
+
obj = obj.decode(**buf_kwargs)
|
|
972
|
+
sgr = SgrSequence()
|
|
973
|
+
|
|
963
974
|
if obj is not _unset:
|
|
964
975
|
if isinstance(obj, str):
|
|
965
976
|
base_str = str(obj)
|
|
966
|
-
|
|
967
|
-
|
|
977
|
+
sgr_match = sgr_pattern().match
|
|
978
|
+
while m := sgr_match(base_str):
|
|
979
|
+
sgr.extend(m[0].removeprefix("\x1b[").removesuffix('m').encode())
|
|
968
980
|
base_str = base_str[m.end() :]
|
|
969
981
|
base_str = _END_RESET_PATTERN.sub('', base_str)
|
|
970
982
|
else:
|
|
971
983
|
base_str = str(obj)
|
|
972
984
|
else:
|
|
973
985
|
base_str = ''
|
|
974
|
-
if
|
|
975
|
-
raise ValueError
|
|
976
|
-
if reset is _unset:
|
|
977
|
-
reset = True
|
|
978
|
-
elif type(reset) is not bool:
|
|
986
|
+
if type(reset) is not bool:
|
|
979
987
|
reset = bool(reset)
|
|
980
988
|
if ansi_type is not _unset:
|
|
981
989
|
ansi_type = get_ansi_type(ansi_type)
|
|
@@ -987,34 +995,8 @@ def _make_colorstr[_T: ColorStr](cls: type[_T], obj=_unset, *args, **kwargs) ->
|
|
|
987
995
|
key=lambda x: x[1],
|
|
988
996
|
)[0]
|
|
989
997
|
try:
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
case []:
|
|
993
|
-
fg = bg = None
|
|
994
|
-
case [_ as fg]:
|
|
995
|
-
bg = None
|
|
996
|
-
case [_ as fg, _ as bg]:
|
|
997
|
-
pass
|
|
998
|
-
case _:
|
|
999
|
-
raise ValueError
|
|
1000
|
-
elif fg is _unset:
|
|
1001
|
-
match args:
|
|
1002
|
-
case []:
|
|
1003
|
-
fg = None
|
|
1004
|
-
case [_ as fg]:
|
|
1005
|
-
pass
|
|
1006
|
-
case _:
|
|
1007
|
-
raise ValueError
|
|
1008
|
-
elif bg is _unset:
|
|
1009
|
-
match args:
|
|
1010
|
-
case []:
|
|
1011
|
-
bg = None
|
|
1012
|
-
case [_ as bg]:
|
|
1013
|
-
pass
|
|
1014
|
-
case _:
|
|
1015
|
-
raise ValueError
|
|
1016
|
-
for k, v in dict.items({'fg': fg, 'bg': bg}):
|
|
1017
|
-
if v is None:
|
|
998
|
+
for k, v in locals().items():
|
|
999
|
+
if k not in {"fg", "bg"} or v is None:
|
|
1018
1000
|
continue
|
|
1019
1001
|
match v:
|
|
1020
1002
|
case Color(rgb=(_ as r, _ as g, _ as b)):
|
|
@@ -1028,27 +1010,21 @@ def _make_colorstr[_T: ColorStr](cls: type[_T], obj=_unset, *args, **kwargs) ->
|
|
|
1028
1010
|
case _:
|
|
1029
1011
|
raise TypeError(type(v))
|
|
1030
1012
|
sgr.append(ansi_type.from_rgb((k, (r, g, b))).to_param_buffer())
|
|
1031
|
-
except
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
[typ] = e.args
|
|
1038
|
-
err = TypeError(
|
|
1039
|
-
"expected integer or vector of 3 integers, "
|
|
1040
|
-
f"got {typ.__name__!r} object instead"
|
|
1041
|
-
)
|
|
1013
|
+
except TypeError as e:
|
|
1014
|
+
[typ] = e.args
|
|
1015
|
+
err = TypeError(
|
|
1016
|
+
"expected integer or vector of 3 integers, "
|
|
1017
|
+
f"got {typ.__name__!r} object instead"
|
|
1018
|
+
)
|
|
1042
1019
|
err.__cause__ = e.__cause__
|
|
1043
1020
|
raise err
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
)
|
|
1021
|
+
suffix = SGR_RESET_S if reset else ''
|
|
1022
|
+
inst: Any = str.__new__(cls, f"{sgr}{base_str}{suffix}")
|
|
1047
1023
|
inst.__dict__ |= {
|
|
1048
1024
|
'_sgr': sgr,
|
|
1049
1025
|
'_base_str': base_str,
|
|
1050
1026
|
'_ansi_type': ansi_type,
|
|
1051
|
-
'_reset':
|
|
1027
|
+
'_reset': suffix,
|
|
1052
1028
|
}
|
|
1053
1029
|
return inst
|
|
1054
1030
|
|
|
@@ -1062,7 +1038,7 @@ class ColorStr(str):
|
|
|
1062
1038
|
sgr = kwargs.get('sgr', self._sgr)
|
|
1063
1039
|
base_str = kwargs.get('base_str', self.base_str)
|
|
1064
1040
|
suffix = SGR_RESET_S if kwargs.get('reset', self.reset) else ''
|
|
1065
|
-
inst
|
|
1041
|
+
inst = super().__new__(type(self), f"{sgr}{base_str}{suffix}")
|
|
1066
1042
|
inst.__dict__ |= vars(self) | {f'_{k}': v for k, v in kwargs.items()}
|
|
1067
1043
|
return inst
|
|
1068
1044
|
|
|
@@ -1070,7 +1046,7 @@ class ColorStr(str):
|
|
|
1070
1046
|
r"""Returns a 3-tuple of parts of the string
|
|
1071
1047
|
(sgr, base string, '\x1B[0m' or '')
|
|
1072
1048
|
"""
|
|
1073
|
-
return str(self._sgr), self.base_str,
|
|
1049
|
+
return str(self._sgr), self.base_str, self._reset
|
|
1074
1050
|
|
|
1075
1051
|
def as_ansi_type(self, __ansi_type):
|
|
1076
1052
|
"""Convert all ANSI colors in the `ColorStr` to a single ANSI type.
|
|
@@ -1091,10 +1067,7 @@ class ColorStr(str):
|
|
|
1091
1067
|
if self.rgb_dict and ansi_type is not self.ansi_format:
|
|
1092
1068
|
sgr = SgrSequence(self._sgr)
|
|
1093
1069
|
sgr.rgb_dict = sgr._rgb_dict, ansi_type
|
|
1094
|
-
inst =
|
|
1095
|
-
type(self),
|
|
1096
|
-
''.join([str(sgr), self.base_str, SGR_RESET_S if self.reset else '']),
|
|
1097
|
-
)
|
|
1070
|
+
inst = super().__new__(type(self), f"{sgr}{self.base_str}{self._reset}")
|
|
1098
1071
|
inst.__dict__ |= vars(self) | {'_sgr': sgr, '_ansi_type': ansi_type}
|
|
1099
1072
|
return inst
|
|
1100
1073
|
return self
|
|
@@ -1288,10 +1261,7 @@ class ColorStr(str):
|
|
|
1288
1261
|
sgr.remove(bx)
|
|
1289
1262
|
else:
|
|
1290
1263
|
sgr.append(bx)
|
|
1291
|
-
inst = super().__new__(
|
|
1292
|
-
type(self),
|
|
1293
|
-
''.join([str(sgr), self.base_str, SGR_RESET_S if self.reset else '']),
|
|
1294
|
-
)
|
|
1264
|
+
inst = super().__new__(type(self), f"{sgr}{self.base_str}{self._reset}")
|
|
1295
1265
|
inst.__dict__ |= vars(self) | {
|
|
1296
1266
|
'_sgr': sgr,
|
|
1297
1267
|
'_ansi_type': sgr.ansi_type() or self.ansi_format,
|
|
@@ -1371,7 +1341,7 @@ class ColorStr(str):
|
|
|
1371
1341
|
)
|
|
1372
1342
|
)
|
|
1373
1343
|
|
|
1374
|
-
def ljust(self, __width, __fillchar=
|
|
1344
|
+
def ljust(self, __width, __fillchar=' '):
|
|
1375
1345
|
return self._weak_var_update(base_str=self.base_str.ljust(__width, __fillchar))
|
|
1376
1346
|
|
|
1377
1347
|
def lower(self):
|
|
@@ -1519,7 +1489,7 @@ class ColorStr(str):
|
|
|
1519
1489
|
return self._weak_var_update(base_str=self.base_str * __value)
|
|
1520
1490
|
|
|
1521
1491
|
def __new__(cls, obj=_unset, *args, **kwargs):
|
|
1522
|
-
return
|
|
1492
|
+
return _colorstr(cls, obj, *args, **kwargs)
|
|
1523
1493
|
|
|
1524
1494
|
def __repr__(self):
|
|
1525
1495
|
return f'{type(self).__name__}({str(self)!r})'
|
|
@@ -1574,7 +1544,7 @@ class ColorStr(str):
|
|
|
1574
1544
|
|
|
1575
1545
|
@property
|
|
1576
1546
|
def reset(self):
|
|
1577
|
-
return
|
|
1547
|
+
return bool(self._reset)
|
|
1578
1548
|
|
|
1579
1549
|
@property
|
|
1580
1550
|
def rgb_dict(self):
|
|
@@ -54,7 +54,7 @@ from chromatic._typing import (
|
|
|
54
54
|
TupleOf3,
|
|
55
55
|
)
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
def is_vt_enabled() -> bool: ...
|
|
58
58
|
@overload
|
|
59
59
|
def get_ansi_type[_T: AnsiColorType](typ: _T) -> _T: ...
|
|
60
60
|
@overload
|
|
@@ -68,7 +68,7 @@ def randcolor() -> Color: ...
|
|
|
68
68
|
def rgb2ansi_escape(
|
|
69
69
|
fmt: AnsiColorAlias | AnsiColorType, mode: ColorDictKeys, rgb: Int3Tuple
|
|
70
70
|
) -> bytes: ...
|
|
71
|
-
def
|
|
71
|
+
def sgr_pattern() -> re.Pattern[str]: ...
|
|
72
72
|
|
|
73
73
|
class ansicolor4Bit(colorbytes):
|
|
74
74
|
alias: ClassVar[L['4b']]
|
|
@@ -266,6 +266,7 @@ class ColorStr(str):
|
|
|
266
266
|
@property
|
|
267
267
|
def rgb_dict(self) -> MappingProxyType[ColorDictKeys, Int3Tuple]: ...
|
|
268
268
|
_sgr: SgrSequence
|
|
269
|
+
_reset: L["\x1b[0m", ""]
|
|
269
270
|
|
|
270
271
|
class _ColorChainKwargs(TypedDict, total=False):
|
|
271
272
|
ansi_type: AnsiColorAlias | type[AnsiColorFormat]
|
|
@@ -417,7 +417,7 @@ class _color_ns_getter:
|
|
|
417
417
|
raise err
|
|
418
418
|
|
|
419
419
|
|
|
420
|
-
def rgb_dispatch(names
|
|
420
|
+
def rgb_dispatch(*names: str):
|
|
421
421
|
def decorator(__f):
|
|
422
422
|
def fix_signature(__f):
|
|
423
423
|
from .._typing import eval_annotation
|
|
@@ -430,9 +430,9 @@ def rgb_dispatch(names=()):
|
|
|
430
430
|
if not (isbuiltin(__f) or getattr(__f, '__module__', '') == 'builtins'):
|
|
431
431
|
raise
|
|
432
432
|
return signature(lambda *args, **kwargs: ...)
|
|
433
|
-
variadic =
|
|
433
|
+
variadic = {
|
|
434
434
|
name for name in [argspec.varargs, argspec.varkw] if name is not None
|
|
435
|
-
|
|
435
|
+
}
|
|
436
436
|
all_arg_names = variadic.union(argspec.args + argspec.kwonlyargs)
|
|
437
437
|
rgb_args = all_arg_names.intersection(
|
|
438
438
|
dict.get({'*': argspec.varargs, '**': argspec.varkw}, arg, arg)
|
|
@@ -491,21 +491,16 @@ def rgb_dispatch(names=()):
|
|
|
491
491
|
setattr(__f, '__signature__', wrapper_sig)
|
|
492
492
|
return update_wrapper(wrapper, __f)
|
|
493
493
|
|
|
494
|
-
if callable(names):
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
494
|
+
if names and callable(names[0]):
|
|
495
|
+
func, *names = names
|
|
496
|
+
else:
|
|
497
|
+
func = None
|
|
498
|
+
for x in names:
|
|
499
|
+
if type(x) is not str:
|
|
500
500
|
raise TypeError(
|
|
501
|
-
f"
|
|
502
|
-
f"got tuple containing {clsname!r} object instead"
|
|
501
|
+
f"found {type(x).__name__!r} object in names, expected only str"
|
|
503
502
|
)
|
|
504
|
-
|
|
505
|
-
raise TypeError(
|
|
506
|
-
"expected callable or variable names tuple, "
|
|
507
|
-
f"got {type(names).__name__!r} object instead"
|
|
508
|
-
)
|
|
503
|
+
return decorator if func is None else decorator(func)
|
|
509
504
|
|
|
510
505
|
|
|
511
506
|
def _make_named_color_map() -> ...:
|
|
@@ -564,19 +559,19 @@ named_color = _make_named_color_map()
|
|
|
564
559
|
|
|
565
560
|
def named_color_idents():
|
|
566
561
|
return [
|
|
567
|
-
ColorStr(name.
|
|
562
|
+
ColorStr(name.translate({0x5F: 0x20}).lower(), color, ansi_type='24b')
|
|
568
563
|
for name, color in ColorNamespace.asdict().items()
|
|
569
564
|
]
|
|
570
565
|
|
|
571
566
|
|
|
572
|
-
def __getattr__(name:
|
|
573
|
-
|
|
574
|
-
return
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
raise AttributeError(f"
|
|
567
|
+
def __getattr__(name: str) -> ...:
|
|
568
|
+
try:
|
|
569
|
+
return globals().setdefault(
|
|
570
|
+
name, {'Back': AnsiBack, 'Fore': AnsiFore, 'Style': AnsiStyle}[name]()
|
|
571
|
+
)
|
|
572
|
+
except KeyError:
|
|
573
|
+
pass
|
|
574
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
580
575
|
|
|
581
576
|
|
|
582
577
|
if TYPE_CHECKING:
|
|
@@ -291,11 +291,9 @@ class ColorNamespace[NamedColor = Color](DynamicNamespace[NamedColor]):
|
|
|
291
291
|
named_color: MappingProxyType[tuple[Literal['4b', '24b'], str], Color]
|
|
292
292
|
|
|
293
293
|
@overload
|
|
294
|
-
def rgb_dispatch[_F: Callable[..., Any]](__f: _F,
|
|
294
|
+
def rgb_dispatch[_F: Callable[..., Any]](__f: _F, /, *names: str) -> _F: ...
|
|
295
295
|
@overload
|
|
296
|
-
def rgb_dispatch[_F: Callable[..., Any]](
|
|
297
|
-
names: tuple[str, ...] = (),
|
|
298
|
-
) -> Callable[[_F], _F]: ...
|
|
296
|
+
def rgb_dispatch[_F: Callable[..., Any]](*names: str) -> Callable[[_F], _F]: ...
|
|
299
297
|
|
|
300
298
|
Back: AnsiBack
|
|
301
299
|
Fore: AnsiFore
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
3
|
import os.path as osp
|
|
4
|
-
from dataclasses import dataclass,
|
|
4
|
+
from dataclasses import field, dataclass, MISSING, fields
|
|
5
5
|
from types import MappingProxyType
|
|
6
6
|
from typing import AnyStr, TYPE_CHECKING
|
|
7
7
|
|
|
@@ -23,7 +23,7 @@ if not osp.exists(os.environ["CHROMATIC_FONTDIR"]):
|
|
|
23
23
|
_TRUETYPE_EXT = frozenset({'.ttf', '.ttc'})
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
@dataclass(frozen=True, slots=True)
|
|
26
|
+
@dataclass(frozen=True, slots=True, repr=False)
|
|
27
27
|
class UserFont:
|
|
28
28
|
font: str
|
|
29
29
|
size: int = field(default=24, kw_only=True)
|
|
@@ -38,6 +38,21 @@ class UserFont:
|
|
|
38
38
|
osp.join(os.environ["CHROMATIC_DATADIR"], self.font), strict=True
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
+
def __repr__(self):
|
|
42
|
+
cls = type(self)
|
|
43
|
+
inst_fields = {}
|
|
44
|
+
for f in fields(cls): # noqa
|
|
45
|
+
v = getattr(self, f.name)
|
|
46
|
+
if f.default is MISSING or v != f.default:
|
|
47
|
+
inst_fields[f.name] = v
|
|
48
|
+
try:
|
|
49
|
+
inst_fields["font"] = os.fspath(self)
|
|
50
|
+
except (OSError, FileNotFoundError):
|
|
51
|
+
pass
|
|
52
|
+
return f"{cls.__name__}(%s)" % ', '.join(
|
|
53
|
+
f"{k}={v!r}" for k, v in inst_fields.items()
|
|
54
|
+
)
|
|
55
|
+
|
|
41
56
|
def to_truetype(self):
|
|
42
57
|
from PIL.ImageFont import truetype
|
|
43
58
|
|
|
@@ -4,9 +4,15 @@ import sys
|
|
|
4
4
|
import time
|
|
5
5
|
from os import PathLike
|
|
6
6
|
from pathlib import PurePath
|
|
7
|
+
from random import choices as get_random
|
|
7
8
|
from types import FunctionType
|
|
8
9
|
from typing import Callable
|
|
9
10
|
|
|
11
|
+
from numpy import ndarray
|
|
12
|
+
from skimage.metrics import mean_squared_error
|
|
13
|
+
|
|
14
|
+
import chromatic as cm
|
|
15
|
+
|
|
10
16
|
|
|
11
17
|
class FunctionNamespace:
|
|
12
18
|
|
|
@@ -21,35 +27,23 @@ DEMO_FUNCS = FunctionNamespace()
|
|
|
21
27
|
@DEMO_FUNCS.register
|
|
22
28
|
def escher_dragon_ascii():
|
|
23
29
|
"""Displays the image-to-ASCII transform of 'Dragon' by M.C. Escher."""
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
input_img = escher()
|
|
28
|
-
font = userfont['vga437']
|
|
30
|
+
input_img = cm.data.escher()
|
|
31
|
+
font = cm.userfont['vga437']
|
|
29
32
|
char_set = r" ._-~+<vX♦'^Vx>|πΦ0Ω#$║╫"
|
|
30
|
-
|
|
31
|
-
ascii_str = img2ascii(
|
|
33
|
+
ascii_str = cm.img2ascii(
|
|
32
34
|
input_img, font, factor=240, char_set=char_set, sort_glyphs=True
|
|
33
35
|
)
|
|
34
|
-
|
|
35
|
-
ascii_img = ascii2img(ascii_str, font, font_size=16, fg='white', bg='black')
|
|
36
|
-
|
|
36
|
+
ascii_img = cm.ascii2img(ascii_str, font, font_size=16, fg='white', bg='black')
|
|
37
37
|
ascii_img.show()
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
@DEMO_FUNCS.register
|
|
41
41
|
def escher_dragon_256color():
|
|
42
42
|
"""Displays the image-to-ANSI transform of 'Dragon' by M.C. Escher in 8-bit color."""
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
font = userfont['vga437']
|
|
48
|
-
|
|
49
|
-
ansi_array = img2ansi(input_img, font, factor=240, ansi_type='8b', equalize=True)
|
|
50
|
-
|
|
51
|
-
ansi_img = ansi2img(ansi_array, font, font_size=16)
|
|
52
|
-
|
|
43
|
+
input_img = cm.data.escher()
|
|
44
|
+
font = cm.userfont['vga437']
|
|
45
|
+
ansi_array = cm.img2ansi(input_img, font, factor=240, ansi_type='8b', equalize=True)
|
|
46
|
+
ansi_img = cm.ansi2img(ansi_array, font, font_size=16)
|
|
53
47
|
ansi_img.show()
|
|
54
48
|
|
|
55
49
|
|
|
@@ -59,101 +53,72 @@ def butterfly_16color():
|
|
|
59
53
|
|
|
60
54
|
Good ol' C-x M-c M-butterfly...
|
|
61
55
|
"""
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
from chromatic.data import userfont, butterfly
|
|
65
|
-
|
|
66
|
-
input_img = butterfly()
|
|
67
|
-
|
|
68
|
-
font = userfont['vga437']
|
|
69
|
-
|
|
56
|
+
input_img = cm.data.butterfly()
|
|
57
|
+
font = cm.data.userfont['vga437']
|
|
70
58
|
char_set = r"'·,•-_→+<>ⁿ*%⌂7√Iï∞πbz£9yîU{}1αHSw♥æ?GX╕╒éà⌡MF╝╩ΘûǃQ½☻Ŷ┤▄╪║▒█"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
59
|
+
ansi_array = cm.img2ansi(
|
|
60
|
+
input_img,
|
|
61
|
+
font,
|
|
62
|
+
factor=200,
|
|
63
|
+
char_set=char_set,
|
|
64
|
+
equalize=True,
|
|
65
|
+
ansi_type=cm.ansicolor4Bit,
|
|
74
66
|
)
|
|
75
|
-
|
|
76
|
-
ansi_img = ansi2img(ansi_array, font, font_size=16)
|
|
77
|
-
|
|
67
|
+
ansi_img = cm.ansi2img(ansi_array, font, font_size=16)
|
|
78
68
|
ansi_img.show()
|
|
79
69
|
|
|
80
70
|
|
|
81
71
|
@DEMO_FUNCS.register
|
|
82
72
|
def butterfly_truecolor():
|
|
83
73
|
"""Displays the image-to-ANSI transform of 'Spider Lily & Papilio xuthus' in 24-bit color."""
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
input_img = butterfly()
|
|
88
|
-
|
|
89
|
-
font = userfont['vga437']
|
|
90
|
-
|
|
91
|
-
ansi_array = img2ansi(
|
|
74
|
+
input_img = cm.data.butterfly()
|
|
75
|
+
font = cm.userfont['vga437']
|
|
76
|
+
ansi_array = cm.img2ansi(
|
|
92
77
|
input_img, font, factor=200, ansi_type='24b', equalize='white_point'
|
|
93
78
|
)
|
|
94
|
-
|
|
95
|
-
ansi_img = ansi2img(ansi_array, font, font_size=16)
|
|
96
|
-
|
|
79
|
+
ansi_img = cm.ansi2img(ansi_array, font, font_size=16)
|
|
97
80
|
ansi_img.show()
|
|
98
81
|
|
|
99
82
|
|
|
100
83
|
@DEMO_FUNCS.register
|
|
101
84
|
def butterfly_randcolor():
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
input_img = butterfly()
|
|
107
|
-
|
|
108
|
-
font = userfont['vga437']
|
|
109
|
-
|
|
110
|
-
ansi_array = img2ansi(
|
|
85
|
+
input_img = cm.data.butterfly()
|
|
86
|
+
font = cm.userfont['vga437']
|
|
87
|
+
ansi_array = cm.img2ansi(
|
|
111
88
|
input_img, font, factor=200, ansi_type='8b', equalize='white_point'
|
|
112
89
|
)
|
|
113
|
-
|
|
114
90
|
for row in range(len(ansi_array)):
|
|
115
91
|
for idx, cs in enumerate(ansi_array[row]):
|
|
116
92
|
if (fg := cs.fg) is not None:
|
|
117
|
-
_, _, v = rgb2hsv(fg.rgb)
|
|
118
|
-
h, s, _ = rgb2hsv(randcolor().rgb)
|
|
119
|
-
ansi_array[row][idx] = cs.recolor(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
93
|
+
_, _, v = cm.color.rgb2hsv(fg.rgb)
|
|
94
|
+
h, s, _ = cm.color.rgb2hsv(cm.color.randcolor().rgb)
|
|
95
|
+
ansi_array[row][idx] = cs.recolor(
|
|
96
|
+
fg=cm.Color.from_rgb(cm.color.hsv2rgb((h, s, v)))
|
|
97
|
+
)
|
|
98
|
+
ansi_img = cm.ansi2img(ansi_array, font, font_size=16)
|
|
123
99
|
ansi_img.show()
|
|
124
100
|
|
|
125
101
|
|
|
126
102
|
@DEMO_FUNCS.register
|
|
127
103
|
def goblin_virus_truecolor():
|
|
128
104
|
"""`G-O-B-L-I-N VIRUS <https://imgur.com/n0Mng2P>`__"""
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
input_img = goblin_virus()
|
|
133
|
-
|
|
134
|
-
font = userfont['vga437']
|
|
135
|
-
|
|
105
|
+
input_img = cm.data.goblin_virus()
|
|
106
|
+
font = cm.userfont['vga437']
|
|
136
107
|
char_set = r' .-|_⌐¬^:()═+<>v≥≤«*»x└┘π╛╘┴┐┌┬╧╚╙X╒╜╨#0╓╝╩╤╥│╔┤├╞╗╦┼╪║╟╠╫╣╬░▒▓█▄▌▐▀'
|
|
137
|
-
|
|
138
|
-
ansi_array = img2ansi(
|
|
108
|
+
ansi_array = cm.img2ansi(
|
|
139
109
|
input_img, font, factor=200, char_set=char_set, ansi_type='24b', equalize=False
|
|
140
110
|
)
|
|
141
|
-
|
|
142
|
-
ansi_img = ansi2img(ansi_array, font, font_size=16)
|
|
143
|
-
|
|
111
|
+
ansi_img = cm.ansi2img(ansi_array, font, font_size=16)
|
|
144
112
|
ansi_img.show()
|
|
145
113
|
|
|
146
114
|
|
|
147
115
|
@DEMO_FUNCS.register
|
|
148
116
|
def named_colors():
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
print(f"{'.'.join([ColorNamespace.__module__, ColorNamespace.__name__])}:")
|
|
153
|
-
named = named_color_idents()
|
|
117
|
+
print("{0.__module__}.{0.__name__}:".format(cm.ColorNamespace))
|
|
118
|
+
named = cm.color.palette.named_color_idents()
|
|
154
119
|
whites = [0]
|
|
155
120
|
for idx, n in enumerate(named):
|
|
156
|
-
hsv = rgb2hsv(n.fg.rgb)
|
|
121
|
+
hsv = cm.color.rgb2hsv(n.fg.rgb)
|
|
157
122
|
if all(
|
|
158
123
|
map(lambda i, x: math.isclose(hsv[i], x, abs_tol=0.16), (-1, 1), (1, 0))
|
|
159
124
|
):
|
|
@@ -161,33 +126,33 @@ def named_colors():
|
|
|
161
126
|
whites.pop()
|
|
162
127
|
whites.append(idx)
|
|
163
128
|
whites.append(-1)
|
|
164
|
-
buffer = []
|
|
165
129
|
for start, stop in zip(whites, whites[1:]):
|
|
166
130
|
xs = sorted(
|
|
167
131
|
named[start + 1 if start else None : stop + 1 if ~stop else None],
|
|
168
|
-
key=lambda x: rgb2lab(x.fg.rgb),
|
|
132
|
+
key=lambda x: cm.color.rgb2lab(x.fg.rgb),
|
|
169
133
|
)
|
|
170
|
-
|
|
171
|
-
for line in buffer:
|
|
172
|
-
print(' | '.join(line))
|
|
134
|
+
print(' | '.join(xs))
|
|
173
135
|
|
|
174
136
|
|
|
175
137
|
@DEMO_FUNCS.register
|
|
176
138
|
def color_cube():
|
|
177
139
|
"""Print the ANSI256 6x6x6 color cube"""
|
|
178
140
|
fmt_code = lambda n: f"\x1b[48;5;{n}m{n: >4}"
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
else:
|
|
141
|
+
ansi_256_codes = iter(range(0x100))
|
|
142
|
+
for i in range(0x10):
|
|
143
|
+
if i and i % 8 == 0:
|
|
183
144
|
print("\x1b[m")
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
145
|
+
print(fmt_code(next(ansi_256_codes)), end='')
|
|
146
|
+
else:
|
|
147
|
+
print("\x1b[m")
|
|
148
|
+
for i in range(6**3):
|
|
149
|
+
if i and i % 6**2 == 0:
|
|
188
150
|
print("\x1b[m")
|
|
189
|
-
|
|
190
|
-
|
|
151
|
+
print(fmt_code(next(ansi_256_codes)), end='')
|
|
152
|
+
else:
|
|
153
|
+
print("\x1b[m")
|
|
154
|
+
for x in ansi_256_codes:
|
|
155
|
+
print(fmt_code(x), end='')
|
|
191
156
|
else:
|
|
192
157
|
print("\x1b[m")
|
|
193
158
|
|
|
@@ -198,20 +163,11 @@ def color_table():
|
|
|
198
163
|
|
|
199
164
|
A handful of stylistic SGR parameters are displayed as well.
|
|
200
165
|
"""
|
|
201
|
-
from chromatic.color import (
|
|
202
|
-
ColorStr,
|
|
203
|
-
Color,
|
|
204
|
-
SgrParameter,
|
|
205
|
-
ansicolor24Bit,
|
|
206
|
-
ansicolor4Bit,
|
|
207
|
-
ansicolor8Bit,
|
|
208
|
-
ColorNamespace,
|
|
209
|
-
)
|
|
210
166
|
|
|
211
|
-
ansi_types = [ansicolor4Bit, ansicolor8Bit, ansicolor24Bit]
|
|
167
|
+
ansi_types = [cm.ansicolor4Bit, cm.ansicolor8Bit, cm.ansicolor24Bit]
|
|
212
168
|
|
|
213
|
-
colors: dict[str, Color] = {
|
|
214
|
-
name.title(): getattr(ColorNamespace, name)
|
|
169
|
+
colors: dict[str, cm.Color] = {
|
|
170
|
+
name.title(): getattr(cm.ColorNamespace, name)
|
|
215
171
|
for name in [
|
|
216
172
|
'BLACK',
|
|
217
173
|
'WHITE',
|
|
@@ -226,10 +182,10 @@ def color_table():
|
|
|
226
182
|
}
|
|
227
183
|
spacing = max(map(len, colors)) + 1
|
|
228
184
|
fg_colors = [
|
|
229
|
-
ColorStr(f"{name: ^{spacing}}", fg=color, ansi_type=ansicolor24Bit)
|
|
185
|
+
cm.ColorStr(f"{name: ^{spacing}}", fg=color, ansi_type=cm.ansicolor24Bit)
|
|
230
186
|
for name, color in colors.items()
|
|
231
187
|
]
|
|
232
|
-
bg_colors = [ColorStr().recolor(bg=None)] + [
|
|
188
|
+
bg_colors = [cm.ColorStr().recolor(bg=None)] + [
|
|
233
189
|
c.recolor(fg=None, bg=c.fg) for c in fg_colors
|
|
234
190
|
]
|
|
235
191
|
print(
|
|
@@ -244,36 +200,24 @@ def color_table():
|
|
|
244
200
|
print()
|
|
245
201
|
print('\nstyles:', end='\t')
|
|
246
202
|
style_params = [
|
|
247
|
-
SgrParameter.BOLD,
|
|
248
|
-
SgrParameter.ITALICS,
|
|
249
|
-
SgrParameter.CROSSED_OUT,
|
|
250
|
-
SgrParameter.ENCIRCLED,
|
|
251
|
-
SgrParameter.SINGLE_UNDERLINE,
|
|
252
|
-
SgrParameter.DOUBLE_UNDERLINE,
|
|
253
|
-
SgrParameter.NEGATIVE,
|
|
203
|
+
cm.SgrParameter.BOLD,
|
|
204
|
+
cm.SgrParameter.ITALICS,
|
|
205
|
+
cm.SgrParameter.CROSSED_OUT,
|
|
206
|
+
cm.SgrParameter.ENCIRCLED,
|
|
207
|
+
cm.SgrParameter.SINGLE_UNDERLINE,
|
|
208
|
+
cm.SgrParameter.DOUBLE_UNDERLINE,
|
|
209
|
+
cm.SgrParameter.NEGATIVE,
|
|
254
210
|
]
|
|
255
|
-
for style in style_params
|
|
211
|
+
for style in style_params:
|
|
256
212
|
print(
|
|
257
|
-
ColorStr(
|
|
213
|
+
cm.ColorStr(f"{cm.SgrParameter.__qualname__}.{style.name}").update_sgr(
|
|
258
214
|
style
|
|
259
215
|
),
|
|
260
|
-
end='\x1b[0m
|
|
261
|
-
)
|
|
262
|
-
else:
|
|
263
|
-
print(
|
|
264
|
-
ColorStr(f"{SgrParameter.__qualname__}.{style_params[-1].name}").update_sgr(
|
|
265
|
-
style_params[-1]
|
|
266
|
-
)
|
|
216
|
+
end=('\n' if style is style_params[-1] else "\x1b[0m".ljust(8)),
|
|
267
217
|
)
|
|
268
218
|
|
|
269
219
|
|
|
270
220
|
def glyph_comparisons(__output_dir: str | PathLike[str] = None):
|
|
271
|
-
from chromatic import get_glyph_masks
|
|
272
|
-
from chromatic.data import userfont
|
|
273
|
-
from chromatic.image import cp437_printable
|
|
274
|
-
from numpy import ndarray
|
|
275
|
-
from random import choices as get_random
|
|
276
|
-
from skimage.metrics import mean_squared_error
|
|
277
221
|
|
|
278
222
|
def _find_best_matches(
|
|
279
223
|
glyph_masks1: dict[str, ndarray], glyph_masks2: dict[str, ndarray]
|
|
@@ -292,13 +236,13 @@ def glyph_comparisons(__output_dir: str | PathLike[str] = None):
|
|
|
292
236
|
|
|
293
237
|
if __output_dir and not os.path.isdir(__output_dir):
|
|
294
238
|
raise NotADirectoryError(__output_dir)
|
|
295
|
-
user_fonts = [pair := (userfont['vga437'], userfont['consolas']), pair[::-1]]
|
|
239
|
+
user_fonts = [pair := (cm.userfont['vga437'], cm.userfont['consolas']), pair[::-1]]
|
|
296
240
|
trans_table = str.maketrans({']': None, '0': ' ', '[': ' '})
|
|
297
|
-
char_set = cp437_printable()
|
|
241
|
+
char_set = cm.cp437_printable()
|
|
298
242
|
separator = '#' * 100
|
|
299
243
|
for font1, font2 in user_fonts:
|
|
300
|
-
glyph_masks_1 = get_glyph_masks(font1, char_set, dist_transform=True)
|
|
301
|
-
glyph_masks_2 = get_glyph_masks(font2, char_set, dist_transform=True)
|
|
244
|
+
glyph_masks_1 = cm.get_glyph_masks(font1, char_set, dist_transform=True)
|
|
245
|
+
glyph_masks_2 = cm.get_glyph_masks(font2, char_set, dist_transform=True)
|
|
302
246
|
best_matches_ = _find_best_matches(glyph_masks_1, glyph_masks_2)
|
|
303
247
|
txt = ''.join(
|
|
304
248
|
'->'.center(32, ' ')
|
|
@@ -52,7 +52,7 @@ from ..color.core import (
|
|
|
52
52
|
ansicolor4Bit,
|
|
53
53
|
ansicolor8Bit,
|
|
54
54
|
get_ansi_type,
|
|
55
|
-
|
|
55
|
+
sgr_pattern,
|
|
56
56
|
)
|
|
57
57
|
from ..color.palette import rgb_dispatch
|
|
58
58
|
from ..data import UserFont, userfont
|
|
@@ -366,7 +366,7 @@ def ansi_quantize(
|
|
|
366
366
|
img: RGBArray,
|
|
367
367
|
ansi_type: type[ansicolor4Bit | ansicolor8Bit],
|
|
368
368
|
*,
|
|
369
|
-
equalize: bool | Literal['white_point'] =
|
|
369
|
+
equalize: bool | Literal['white_point'] = False,
|
|
370
370
|
):
|
|
371
371
|
"""Color-quantize an RGB array into ANSI 4-bit or 8-bit color space.
|
|
372
372
|
|
|
@@ -583,7 +583,7 @@ def img2ascii(
|
|
|
583
583
|
return ascii_str
|
|
584
584
|
|
|
585
585
|
|
|
586
|
-
@rgb_dispatch(
|
|
586
|
+
@rgb_dispatch('bg')
|
|
587
587
|
def img2ansi(
|
|
588
588
|
__img: RGBImageLike | PathLike[str] | str,
|
|
589
589
|
__font: FontArgType = userfont['vga437'],
|
|
@@ -591,7 +591,7 @@ def img2ansi(
|
|
|
591
591
|
char_set: Iterable[str] = None,
|
|
592
592
|
ansi_type: AnsiColorParam = DEFAULT_ANSI,
|
|
593
593
|
sort_glyphs: bool | type[reversed] = True,
|
|
594
|
-
equalize: bool | Literal['white_point'] =
|
|
594
|
+
equalize: bool | Literal['white_point'] = False,
|
|
595
595
|
bg: Color | Int3Tuple | str = (0, 0, 0),
|
|
596
596
|
):
|
|
597
597
|
"""Convert an image to an ANSI array.
|
|
@@ -681,7 +681,7 @@ def img2ansi(
|
|
|
681
681
|
return xs
|
|
682
682
|
|
|
683
683
|
|
|
684
|
-
@rgb_dispatch(
|
|
684
|
+
@rgb_dispatch('fg', 'bg')
|
|
685
685
|
def ascii2img(
|
|
686
686
|
__ascii: str,
|
|
687
687
|
__font: FontArgType = userfont['vga437'],
|
|
@@ -733,7 +733,7 @@ def ascii2img(
|
|
|
733
733
|
return img
|
|
734
734
|
|
|
735
735
|
|
|
736
|
-
@rgb_dispatch(
|
|
736
|
+
@rgb_dispatch('fg_default', 'bg_default')
|
|
737
737
|
def ansi2img(
|
|
738
738
|
__ansi_array: list[list[ColorStr]],
|
|
739
739
|
__font: FontArgType = userfont['vga437'],
|
|
@@ -829,7 +829,7 @@ def ansify(
|
|
|
829
829
|
char_set: Iterable[str] = None,
|
|
830
830
|
sort_glyphs: bool | type[reversed] = True,
|
|
831
831
|
ansi_type: AnsiColorParam = DEFAULT_ANSI,
|
|
832
|
-
equalize: bool | Literal['white_point'] =
|
|
832
|
+
equalize: bool | Literal['white_point'] = False,
|
|
833
833
|
fg: Int3Tuple | str = (170, 170, 170),
|
|
834
834
|
bg: Int3Tuple | str | Literal['auto'] = (0, 0, 0),
|
|
835
835
|
):
|
|
@@ -886,8 +886,8 @@ def _is_csi_param(__c: str) -> TypeGuard[Literal[';'] | LiteralDigit]:
|
|
|
886
886
|
|
|
887
887
|
|
|
888
888
|
@lru_cache(maxsize=1)
|
|
889
|
-
def
|
|
890
|
-
sgr_re =
|
|
889
|
+
def cursor_or_sgr_pattern():
|
|
890
|
+
sgr_re = sgr_pattern().pattern.removeprefix(r'\x1b\[')
|
|
891
891
|
return re.compile(
|
|
892
892
|
rf"(?:\x1b\[(?:(?P<cursor>\d*[A-G]|\d*(?:;\d*)?H)|(?P<sgr>{sgr_re})))?(?P<text>[^\x1b]*)"
|
|
893
893
|
)
|
|
@@ -951,7 +951,7 @@ def _sub_bold_colors(lines: Iterable[str]) -> Iterator[str]:
|
|
|
951
951
|
for line in lines:
|
|
952
952
|
bold_bit = False
|
|
953
953
|
prev_colors = {}
|
|
954
|
-
yield
|
|
954
|
+
yield sgr_pattern().sub(sub, line)
|
|
955
955
|
|
|
956
956
|
|
|
957
957
|
def reshape_ansi(__str: str, w: int, h: int) -> str:
|
|
@@ -982,7 +982,7 @@ def reshape_ansi(__str: str, w: int, h: int) -> str:
|
|
|
982
982
|
cur = cursor()
|
|
983
983
|
x, y = next(cur)
|
|
984
984
|
for line in _sub_bold_colors(__str.splitlines()):
|
|
985
|
-
for m in
|
|
985
|
+
for m in cursor_or_sgr_pattern().finditer(line + '\n'):
|
|
986
986
|
if cg := m['cursor']:
|
|
987
987
|
write_cell(' ')
|
|
988
988
|
param, code = cg[:-1], cg[-1]
|
|
@@ -1018,10 +1018,10 @@ def reshape_ansi(__str: str, w: int, h: int) -> str:
|
|
|
1018
1018
|
write_cell(ch, incr=True)
|
|
1019
1019
|
|
|
1020
1020
|
out_lines = []
|
|
1021
|
-
|
|
1021
|
+
any_ansi_seq = re.compile(r"\x1b\[\d*(?:;\d*)*[A-HJ-KS-Tmf]")
|
|
1022
1022
|
for row in arr:
|
|
1023
1023
|
out_row = ''.join(cell.translate({0: ' '}) for cell in row)
|
|
1024
|
-
lhs, rhs = map(' '.__mul__, divmod(w - len(
|
|
1024
|
+
lhs, rhs = map(' '.__mul__, divmod(w - len(any_ansi_seq.sub('', out_row)), 2))
|
|
1025
1025
|
out_lines.append(f"{lhs}{out_row}{rhs}")
|
|
1026
1026
|
|
|
1027
1027
|
return '\n'.join(out_lines)
|
|
@@ -1034,7 +1034,7 @@ def to_sgr_array(__str: str, ansi_type: AnsiColorParam = None):
|
|
|
1034
1034
|
xs = []
|
|
1035
1035
|
for line in _sub_bold_colors(__str.splitlines()):
|
|
1036
1036
|
x = []
|
|
1037
|
-
for m in
|
|
1037
|
+
for m in cursor_or_sgr_pattern().finditer(line):
|
|
1038
1038
|
text = m["text"]
|
|
1039
1039
|
if m["sgr"]:
|
|
1040
1040
|
sgr = SgrSequence(map(int, m["sgr"].removesuffix('m').split(';')))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{chromatic_python-0.3.3 → chromatic_python-0.3.4}/chromatic_python.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|