Repository navigation
Expand file tree
/
Copy pathcli.py
More file actions
227 lines (198 loc) · 7.14 KB
/
Copy pathcli.py
File metadata and controls
227 lines (198 loc) · 7.14 KB
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
"""Command-line interface for tabulate."""
from functools import partial
import re
import sys
import textwrap
try:
from . import (
_DEFAULT_FLOATFMT,
_DEFAULT_INTFMT,
_is_file,
tabulate,
tabulate_formats,
)
except ImportError: # pragma: no cover
# running as a script: python tabulate/cli.py
import os as _os
import sys as _sys
_sys.path.insert(0, _os.path.dirname(_os.path.dirname(_os.path.abspath(__file__))))
from tabulate import (
_DEFAULT_FLOATFMT,
_DEFAULT_INTFMT,
_is_file,
tabulate,
tabulate_formats,
)
def _main():
"""\
Usage: tabulate [options] [FILE ...]
Pretty-print tabular data. Use Python module for more features.
FILE a filename of the file with tabular data;
if "-" or missing, read data from stdin.
Options:
-h, --help show this message
INPUT:
-r, --read FILEFORMAT parse input FILEs as:
rsv (REGEXP-separated values, default),
csv (comma-separated valued, Excel dialect),
jsonl (one JSON object per line)
-s REGEXP, --sep REGEXP column separator for rsv data (default: whitespace)
FORMAT:
--headers HEADERS HEADERS can be one of:
"firstrow" (for csv and rsv data),
"keys" (for jsonl data),
"HEADER1,HEADER2,..." (for csv and rsv data),
"KEY1:HEADER1,KEY2:HEADER2,..." (for jsonl data)
-1 use the first row of input data as a table header
(the same as --headers firstrow)
-F FPFMT, --float FPFMT floating point number format (default: g)
-I INTFMT, --int INTFMT integer point number format (default: "")
-f FMT, --format FMT set output table format (default: simple)
Supported output formats: asciidoc, colon_grid, double_grid, double_outline,
fancy_grid, fancy_outline, github, grid, heavy_grid, heavy_outline, html, jira,
latex, latex_booktabs, latex_longtable, latex_raw, mediawiki, mixed_grid, mixed_outline,
moinmoin, orgtbl, outline, pipe, plain, presto, pretty, psql, rounded_grid,
rounded_outline, rst, simple, simple_grid, simple_outline, textile, tsv, unsafehtml.
OUTPUT:
-o FILE, --output FILE print table to FILE (default: stdout)
"""
import getopt
usage = textwrap.dedent(_main.__doc__)
try:
opts, args = getopt.getopt(
sys.argv[1:],
"h1H:r:o:s:F:I:f:",
[
"help",
"header", # deprecated in CLI > 0.10
"headers=", # CLI > 0.10
"read=", # CLI > 0.10
"output=",
"sep=",
"float=",
"int=",
"colalign=",
"format=",
],
)
except getopt.GetoptError as e:
print(e, file=sys.stderr)
print(usage)
sys.exit(2)
headers = []
floatfmt = _DEFAULT_FLOATFMT
intfmt = _DEFAULT_INTFMT
colalign = None
tablefmt = "simple"
fileformat = "rsv"
sep = r"\s+"
outfile = "-"
special_headers_values = ["firstrow", "keys"]
for opt, value in opts:
if opt in ["-1", "--header"]:
# "header" option is for backwards compatibility with CLI <= 0.10
# CLI >= 0.11 should user --headers
headers = "firstrow"
if opt in ["-H", "--headers"]:
if value in special_headers_values:
headers = value
else:
headers = value # may need to be processed
elif opt in ["-o", "--output"]:
outfile = value
elif opt in ["-F", "--float"]:
floatfmt = value
elif opt in ["-I", "--int"]:
intfmt = value
elif opt in ["-C", "--colalign"]:
colalign = value.split()
elif opt in ["-r", "--read"]:
fileformat = value.lower()
elif opt in ["-f", "--format"]:
if value not in tabulate_formats:
print(f"{value} is not a supported output format", file=sys.stderr)
print(usage)
sys.exit(3)
tablefmt = value
elif opt in ["-s", "--sep"]:
sep = value
elif opt in ["-h", "--help"]:
print(usage)
sys.exit(0)
# choose a reader and parse headers option
if fileformat == "rsv":
reader = partial(_read_rsv_file, sep=sep)
if type(headers) is str and headers not in special_headers_values:
# parse as CSV values
headers = headers.split(",")
elif fileformat == "csv":
reader = _read_csv_file
if type(headers) is str and headers not in special_headers_values:
# parse as CSV values
headers = headers.split(",")
elif fileformat == "jsonl":
reader = _read_jsonl_file
if not headers:
headers = "keys" # reasonable default
if type(headers) is str and headers not in special_headers_values:
# "," and ":" in header titles are not supported in CLI
try:
headers2 = dict(tuple(hh.split(":", 2)) for hh in headers.split(","))
except Exception:
print(f"cannot parse headers parameter: {headers}", file=sys.stderr)
headers2 = []
headers = headers2
else:
print(f"{fileformat} is not a supported file format")
sys.exit(3)
# format all input files
files = [sys.stdin] if not args else args
with sys.stdout if outfile == "-" else open(outfile, "w") as out:
for f in files:
if f == "-":
f = sys.stdin
_open_and_pprint_file(
reader,
f,
headers=headers,
tablefmt=tablefmt,
floatfmt=floatfmt,
intfmt=intfmt,
file=out,
colalign=colalign,
)
def _read_rsv_file(fobject, sep):
rows = fobject.readlines()
table = [re.split(sep, r.rstrip()) for r in rows if r.strip()]
return table
def _read_jsonl_file(fobject):
import json
rows: list[str] = fobject.readlines()
table = [json.loads(row) for row in rows]
return table
def _read_csv_file(fobject):
import csv
reader = csv.reader(fobject, dialect="excel")
table = [list(row) for row in reader]
return table
def _open_and_pprint_file(reader, f, *args, **kwargs):
if _is_file(f):
_pprint_file(reader, f, *args, **kwargs)
else:
with open(f) as fobj:
_pprint_file(reader, fobj, *args, **kwargs)
def _pprint_file(reader, fobject, headers, tablefmt, floatfmt, intfmt, file, colalign):
table = reader(fobject)
print(
tabulate(
table,
headers,
tablefmt,
floatfmt=floatfmt,
intfmt=intfmt,
colalign=colalign,
),
file=file,
)
if __name__ == "__main__": # pragma: no cover
_main()