File: names.py

package info (click to toggle)
python-plumbum 1.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,300 kB
  • sloc: python: 10,016; makefile: 130; sh: 8
file content (429 lines) | stat: -rw-r--r-- 8,271 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
"""
Names for the standard and extended color set.
Extended set is similar to `vim wiki <http://vim.wikia.com/wiki/Xterm256_color_names_for_console_Vim>`_, `colored <https://pypi.python.org/pypi/colored>`_, etc. Colors based on `wikipedia <https://en.wikipedia.org/wiki/ANSI_escape_code#Colors>`_.

You can access the index of the colors with names.index(name). You can access the
rgb values with ``r=int(html[n][1:3],16)``, etc.
"""

from __future__ import annotations

color_names = """\
black
red
green
yellow
blue
magenta
cyan
light_gray
dark_gray
light_red
light_green
light_yellow
light_blue
light_magenta
light_cyan
white
grey_0
navy_blue
dark_blue
blue_3
blue_3a
blue_1
dark_green
deep_sky_blue_4
deep_sky_blue_4a
deep_sky_blue_4b
dodger_blue_3
dodger_blue_2
green_4
spring_green_4
turquoise_4
deep_sky_blue_3
deep_sky_blue_3a
dodger_blue_1
green_3
spring_green_3
dark_cyan
light_sea_green
deep_sky_blue_2
deep_sky_blue_1
green_3a
spring_green_3a
spring_green_2
cyan_3
dark_turquoise
turquoise_2
green_1
spring_green_2a
spring_green_1
medium_spring_green
cyan_2
cyan_1
dark_red
deep_pink_4
purple_4
purple_4a
purple_3
blue_violet
orange_4
grey_37
medium_purple_4
slate_blue_3
slate_blue_3a
royal_blue_1
chartreuse_4
dark_sea_green_4
pale_turquoise_4
steel_blue
steel_blue_3
cornflower_blue
chartreuse_3
dark_sea_green_4a
cadet_blue
cadet_blue_a
sky_blue_3
steel_blue_1
chartreuse_3a
pale_green_3
sea_green_3
aquamarine_3
medium_turquoise
steel_blue_1a
chartreuse_2a
sea_green_2
sea_green_1
sea_green_1a
aquamarine_1
dark_slate_gray_2
dark_red_a
deep_pink_4a
dark_magenta
dark_magenta_a
dark_violet
purple
orange_4a
light_pink_4
plum_4
medium_purple_3
medium_purple_3a
slate_blue_1
yellow_4
wheat_4
grey_53
light_slate_grey
medium_purple
light_slate_blue
yellow_4_a
dark_olive_green_3
dark_sea_green
light_sky_blue_3
light_sky_blue_3a
sky_blue_2
chartreuse_2
dark_olive_green_3a
pale_green_3a
dark_sea_green_3
dark_slate_gray_3
sky_blue_1
chartreuse_1
light_green_a
light_green_b
pale_green_1
aquamarine_1a
dark_slate_gray_1
red_3
deep_pink_4b
medium_violet_red
magenta_3
dark_violet_a
purple_a
dark_orange_3
indian_red
hot_pink_3
medium_orchid_3
medium_orchid
medium_purple_2
dark_goldenrod
light_salmon_3
rosy_brown
grey_63
medium_purple_2a
medium_purple_1
gold_3
dark_khaki
navajo_white_3
grey_69
light_steel_blue_3
light_steel_blue
yellow_3
dark_olive_green_3b
dark_sea_green_3a
dark_sea_green_2
light_cyan_3
light_sky_blue_1
green_yellow
dark_olive_green_2
pale_green_1a
dark_sea_green_2a
dark_sea_green_1
pale_turquoise_1
red_3a
deep_pink_3
deep_pink_3a
magenta_3a
magenta_3b
magenta_2
dark_orange_3a
indian_red_a
hot_pink_3a
hot_pink_2
orchid
medium_orchid_1
orange_3
light_salmon_3a
light_pink_3
pink_3
plum_3
violet
gold_3a
light_goldenrod_3
tan
misty_rose_3
thistle_3
plum_2
yellow_3a
khaki_3
light_goldenrod_2
light_yellow_3
grey_84
light_steel_blue_1
yellow_2
dark_olive_green_1
dark_olive_green_1a
dark_sea_green_1a
honeydew_2
light_cyan_1
red_1
deep_pink_2
deep_pink_1
deep_pink_1a
magenta_2a
magenta_1
orange_red_1
indian_red_1
indian_red_1a
hot_pink
hot_pink_a
medium_orchid_1a
dark_orange
salmon_1
light_coral
pale_violet_red_1
orchid_2
orchid_1
orange_1
sandy_brown
light_salmon_1
light_pink_1
pink_1
plum_1
gold_1
light_goldenrod_2a
light_goldenrod_2b
navajo_white_1
misty_rose_1
thistle_1
yellow_1
light_goldenrod_1
khaki_1
wheat_1
cornsilk_1
grey_10_0
grey_3
grey_7
grey_11
grey_15
grey_19
grey_23
grey_27
grey_30
grey_35
grey_39
grey_42
grey_46
grey_50
grey_54
grey_58
grey_62
grey_66
grey_70
grey_74
grey_78
grey_82
grey_85
grey_89
grey_93""".split()

EMPTY_SLICE = slice(None, None, None)

_greys = (
    3.4,
    7.4,
    11,
    15,
    19,
    23,
    26.7,
    30.49,
    34.6,
    38.6,
    42.4,
    46.4,
    50,
    54,
    58,
    62,
    66,
    69.8,
    73.8,
    77.7,
    81.6,
    85.3,
    89.3,
    93,
)
_grey_vals = [int(x / 100.0 * 16 * 16) for x in _greys]

_grey_html = ["#" + format(x, "02x") * 3 for x in _grey_vals]

_normals = [int(x, 16) for x in "0 5f 87 af d7 ff".split()]
_normal_html = [
    "#"
    + format(_normals[n // 36], "02x")
    + format(_normals[n // 6 % 6], "02x")
    + format(_normals[n % 6], "02x")
    for n in range(16 - 16, 232 - 16)
]

_base_pattern = [(n // 4, n // 2 % 2, n % 2) for n in range(8)]
_base_html = (
    [f"#{x[2] * 192:02x}{x[1] * 192:02x}{x[0] * 192:02x}" for x in _base_pattern]
    + ["#808080"]
    + [f"#{x[2] * 255:02x}{x[1] * 255:02x}{x[0] * 255:02x}" for x in _base_pattern][1:]
)
color_html = _base_html + _normal_html + _grey_html

color_codes_simple = list(range(8)) + list(range(60, 68))
"""Simple colors, remember that reset is #9, second half is non as common."""

# Attributes
attributes_ansi = {
    "bold": 1,
    "dim": 2,
    "italics": 3,
    "underline": 4,
    "reverse": 7,
    "hidden": 8,
    "strikeout": 9,
}

# Stylesheet
default_styles = {
    "warn": "fg red",
    "title": "fg cyan underline bold",
    "fatal": "fg red bold",
    "highlight": "bg yellow",
    "info": "fg blue",
    "success": "fg green",
}

# Functions to be used for color name operations


class FindNearest:
    """This is a class for finding the nearest color given rgb values.
    Different find methods are available."""

    def __init__(self, r: int, g: int, b: int) -> None:
        self.r = r
        self.b = b
        self.g = g

    def only_basic(self):
        """This will only return the first 8 colors!
        Breaks the colorspace into cubes, returns color"""
        midlevel = 0x40  # Since bright is not included

        # The colors are organised so that it is a
        # 3D cube, black at 0,0,0, white at 1,1,1
        # Compressed to linear_integers r,g,b
        # [[[0,1],[2,3]],[[4,5],[6,7]]]
        # r*1 + g*2 + b*4
        return (
            (self.r >= midlevel) * 1
            + (self.g >= midlevel) * 2
            + (self.b >= midlevel) * 4
        )

    def all_slow(self, color_slice: slice = EMPTY_SLICE) -> int:
        """This is a slow way to find the nearest color."""
        distances = [
            self._distance_to_color(color) for color in color_html[color_slice]
        ]
        return min(range(len(distances)), key=distances.__getitem__)

    def _distance_to_color(self, color: str) -> int:
        """This computes the distance to a color, should be minimized."""
        rgb = (int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16))
        return (self.r - rgb[0]) ** 2 + (self.g - rgb[1]) ** 2 + (self.b - rgb[2]) ** 2

    def _distance_to_color_number(self, n: int) -> int:
        color = color_html[n]
        return self._distance_to_color(color)

    def only_colorblock(self) -> int:
        """This finds the nearest color based on block system, only works
        for 17-232 color values."""
        rint = min(
            range(len(_normals)), key=[abs(x - self.r) for x in _normals].__getitem__
        )
        bint = min(
            range(len(_normals)), key=[abs(x - self.b) for x in _normals].__getitem__
        )
        gint = min(
            range(len(_normals)), key=[abs(x - self.g) for x in _normals].__getitem__
        )
        return 16 + 36 * rint + 6 * gint + bint

    def only_simple(self) -> int:
        """Finds the simple color-block color."""
        return self.all_slow(slice(0, 16, None))

    def only_grey(self) -> int:
        """Finds the greyscale color."""
        rawval = (self.r + self.b + self.g) / 3
        n = min(
            range(len(_grey_vals)),
            key=[abs(x - rawval) for x in _grey_vals].__getitem__,
        )
        return n + 232

    def all_fast(self) -> int:
        """Runs roughly 8 times faster than the slow version."""
        colors = [self.only_simple(), self.only_colorblock(), self.only_grey()]
        distances = [self._distance_to_color_number(n) for n in colors]
        return colors[min(range(len(distances)), key=distances.__getitem__)]


def from_html(color: str) -> tuple[int, int, int]:
    """Convert html hex code to rgb."""
    if len(color) != 7 or color[0] != "#":
        raise ValueError("Invalid length of html code")
    return (int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16))


def to_html(r, g, b):
    """Convert rgb to html hex code."""
    return f"#{r:02x}{g:02x}{b:02x}"