-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcsv2tbl.py
More file actions
113 lines (95 loc) · 2.86 KB
/
csv2tbl.py
File metadata and controls
113 lines (95 loc) · 2.86 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
#!/usr/bin/env python
# file: csv2tbl.py
# vim:fileencoding=utf-8:ft=python
#
# Copyright © 2012-2018 R.F. Smith <rsmith@xs4all.nl>.
# SPDX-License-Identifier: MIT
# Created: 2012-06-17T19:25:53+02:00
# Last modified: 2019-09-16T21:54:30+0200
"""Convert a CSV file to a LaTeX table."""
from collections import Counter
from datetime import date
import os.path
import sys
__version__ = "2019.09.16"
def main(argv):
"""
Entry point for csv2tbl.
Arguments:
argv: Command line arguments.
"""
binary = os.path.basename(argv[0])
if len(argv) < 2:
print(f"{binary} ver. {__version__}")
print(f"Usage: {binary} file", file=sys.stderr)
sys.exit(0)
# Read the data into a list of lines.
lines = readlines(argv[1])
# Check which seperator is used.
sep = csvsep(lines)
# Get the filename and remove the extension.
fname = os.path.basename(argv[1])
if fname.endswith((".csv", ".CSV")):
fname = fname[:-4]
# Create a format definition for the tabular environment.
columns = len(lines[1].split(sep))
columns = "l" * columns
# Print the output.
print("% Generated from " + str(argv[1]))
print("% by csv2tbl.py on " + str(date.today()))
print(r"\begin{table}[!htbp]")
print(r" \centering")
print(r" \caption{\label{tb:" + fname + r"}" + fname + r"}")
print(r" \begin{tabular}{" + columns + r"}")
print(r" \toprule")
fmtcsv(lines[0], sep)
print(r" \midrule")
for l in lines[1:]:
fmtcsv(l, sep)
print(r" \bottomrule")
print(r" \end{tabular}")
print(r"\end{table}")
def readlines(filename):
"""
Read a file and return the contents as a list of lines.
Arguments:
filename name of the file to read
Returns:
A list of stripped lines.
"""
with open(filename) as infile:
lines = infile.readlines()
return [l.strip() for l in lines]
def csvsep(lines, separators=",\t;:"):
"""
Determine the separator used in the lines of csv data.
Arguments:
lines: CSV data as a list of strings.
separator: String of separators.
Returns:
The most occuring separator character.
"""
letters, sep = Counter(), Counter()
for ln in lines:
letters.update(ln)
for s in ",\t;:":
sep[s] = letters[s]
return sep.most_common()[0][0]
def fmtcsv(line, sep):
"""
Format a single line of CSV data as a LaTeX table cells.
Arguments:
line: The string of CSV data to convert
sep: The separator to use.
"""
# Skip empty lines.
if len(line) == line.count(sep):
return
if line.endswith(sep):
line = line[: -len(sep)]
# Escape existing ampersands.
line = line.replace(r"&", r"\&")
outs = " " + line.replace(sep, r" & ") + r"\\"
print(outs)
if __name__ == "__main__":
main(sys.argv)