-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathutf-8.py
executable file
·114 lines (92 loc) · 2.74 KB
/
utf-8.py
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
#!/usr/bin/env python3
# Copyright 2017 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""UTF8 dumper for testing terminal output.
You'll need to install the 'wcwidth' module on the system.
"""
import argparse
import sys
import wcwidth
def wcfilter(ch):
"""Return x/X for non-printable characters."""
width = wcwidth.wcwidth(ch)
if width == -1:
return "x"
elif width == 0:
return "X"
else:
return ch
def gen_range(start, end):
"""Return a list of the numbers between |start| and |end|.
This filters out surrogate pairs.
"""
return [x for x in range(start, end) if x < 0xD800 or x >= 0xE000]
def print_range(opts):
"""Display all the code points requests by |opts|."""
codepoints = gen_range(opts.start, opts.end)
if not codepoints:
return
start = codepoints[0]
codepoints = [wcfilter(chr(x)) for x in codepoints]
i = 0
spacer = opts.spacer or " "
while i < len(codepoints):
data = codepoints[i : i + opts.width]
print(f"{i + start:>{opts.pad}x}{spacer}", end="")
print(opts.spacer.join(data), end="")
print(opts.spacer)
i += opts.width
def print_header(opts):
"""Display the header for the codepoints."""
print(f'{"":{opts.pad}}{opts.spacer or " "}', end="")
i = 4
width = 4
if opts.spacer:
width += 4 * len(opts.spacer) - 1
while i <= opts.width:
cell = f"+{i - 1:x}"
print(f"{cell:>{width}}{opts.spacer}", end="")
i += 4
print("")
class IntAction(argparse.Action):
"""Argparse callback to parse int/hex values."""
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, int(values, 0))
def get_parser():
"""Return an argparse parser for the CLI."""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"-s",
dest="start",
default=0,
action=IntAction,
help="First codepoint to display",
)
parser.add_argument(
"-e",
dest="end",
default=0x800,
action=IntAction,
help="Last codepoint to display",
)
parser.add_argument(
"-w",
dest="width",
default=64,
action=IntAction,
help="Width of the table",
)
parser.add_argument(
"-p", dest="spacer", default="|", help="Interspace character for table"
)
return parser
def main(argv):
"""The main entry point!"""
parser = get_parser()
opts = parser.parse_args(argv)
opts.pad = len(f"{opts.end:x}")
print_header(opts)
print_range(opts)
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))