]> git.lyx.org Git - lyx.git/blob - lib/scripts/csv2lyx.py
Remove profiling.py
[lyx.git] / lib / scripts / csv2lyx.py
1 # file csv2lyx.py
2 # This file is part of LyX, the document processor.
3 # Licence details can be found in the file COPYING.
4
5 # author Hartmut Haase
6 # author José Matos
7 # Full author contact details are available in file CREDITS
8
9 # This script reads a csv-table (file name.csv) and converts it into
10 # a LyX-table for versions 1.5.0 and higher (LyX table format 276).
11 # It uses Python's csv module for parsing.
12 # The original csv2lyx was witten by Antonio Gulino <antonio.gulino@tin.it>
13 # in Perl for LyX 1.x and modified for LyX table format 276 by the author.
14 #
15 import csv, unicodedata
16 import os, sys
17 import optparse
18
19 def error(message):
20     sys.stderr.write(message + '\n')
21     sys.exit(1)
22
23 header = """#csv2lyx created this file. For more info see http://www.lyx.org/
24 \\lyxformat 413
25 \\begin_document
26 \\begin_header
27 \\textclass article
28 \\use_default_options true
29 \\maintain_unincluded_children false
30 \\language english
31 \\language_package default
32 \\inputencoding auto
33 \\fontencoding global
34 \\font_roman default
35 \\font_sans default
36 \\font_typewriter default
37 \\font_default_family default
38 \\use_non_tex_fonts false
39 \\font_sc false
40 \\font_osf false
41 \\font_sf_scale 100
42 \\font_tt_scale 100
43
44 \\graphics default
45 \\default_output_format default
46 \\output_sync 0
47 \\bibtex_command default
48 \\index_command default
49 \\paperfontsize default
50 \\use_hyperref false
51 \\papersize default
52 \\use_geometry false
53 \\use_amsmath 1
54 \\use_esint 1
55 \\use_mhchem 1
56 \\use_mathdots 1
57 \\cite_engine basic
58 \\use_bibtopic false
59 \\use_indices false
60 \\paperorientation portrait
61 \\suppress_date false
62 \\use_refstyle 1
63 \\index Index
64 \\shortcut idx
65 \\color #008000
66 \\end_index
67 \\secnumdepth 3
68 \\tocdepth 3
69 \\paragraph_separation indent
70 \\paragraph_indentation default
71 \\quotes_language english
72 \\papercolumns 1
73 \\papersides 1
74 \\paperpagestyle default
75 \\tracking_changes false
76 \\output_changes false
77 \\html_math_output 0
78 \\html_css_as_file 0
79 \\html_be_strict false
80 \\end_header
81
82 \\begin_body
83
84 \\begin_layout Standard
85 \\begin_inset Tabular
86 <lyxtabular version="3" rows="%d" columns="%d">
87 <features tabularvalignment="middle">
88 """
89
90 cell = """<cell alignment="left" valignment="top" usebox="none">
91 \\begin_inset Text
92
93 \\begin_layout Plain Layout
94 %s
95 \\end_layout
96
97 \\end_inset
98 </cell>"""
99
100 footer = """</lyxtabular>
101
102 \\end_inset
103
104
105 \\end_layout
106
107 \\end_body
108 \\end_document
109 """
110
111 # processing command line options
112 # delegate this to standard module optparse
113 args = {}
114 args["usage"] = "Usage: csv2lyx [options] csvfile [file.lyx]"
115
116 args["description"] = """This script creates a LyX document containing a table created from a
117 comma-separated-value (CSV) file. The resulting LyX file can be opened
118 with LyX 1.5.0 or any later version.
119 If no options are given csv2lyx will try to infer the CSV type of the csvfile,
120 """
121 parser = optparse.OptionParser(**args)
122
123 parser.set_defaults(excel ='', column_sep = '')
124 parser.add_option("-e", "--excel", metavar ="CHAR",
125                   help = """CHAR corresponds to a CSV type:
126                        'e': Excel-generated CSV file
127                        't': Excel-generated TAB-delimited CSV file""")
128 parser.add_option("-s", "--separator", dest = "column_sep",
129                   help = """column separator
130                                        't' means Tab""")
131
132 group = optparse.OptionGroup(parser, "Remarks", """If your CSV file contains special characters (e. g. umlauts,
133    accented letters, etc.) make sure it is coded in UTF-8 (unicode).
134    Else LyX will loose some cell contents. If your CSV file was not written according to the "Common Format and MIME Type for Comma-Separated Values (CSV) Files" (http://tools.ietf.org/html/rfc4180) there may be unexpected results.""")
135 parser.add_option_group(group)
136
137 (options, args) = parser.parse_args()
138
139 # validate input
140 if len(args) == 1:
141     infile = args[0]
142     fout = sys.stdout
143 elif len(args) == 2:
144     infile = args[0]
145     fout = open(args[1], 'w')
146 else:
147     parser.print_help()
148     sys.exit(1)
149
150 if not os.path.exists(infile):
151         error('File "%s" not found.' % infile)
152
153 dialects = {'' : None, 'e' : 'excel', 't' : 'excel-tab'}
154 if options.excel not in dialects:
155     parser.print_help()
156     sys.exit(1)
157 dialect = dialects[options.excel]
158
159 # Set Tab, if necessary
160 if options.column_sep == 't':
161         options.column_sep = "\t"
162
163 # when no special column separator is given, try to detect it:
164 if options.column_sep and dialect :
165     reader = csv.reader(open(infile), dialect = dialect, delimiter = options.column_sep)
166 else:
167     guesser = csv.Sniffer()
168     input_file = "".join(open(infile).readlines())
169     try:
170         dialect = guesser.sniff(input_file)
171         reader = csv.reader(open(infile), dialect = dialect)
172     except:
173         # older versions (python < 2.5) of csv have problems (bugs)
174         # that is why we try harder to get a result, this should work on most cases
175         # as it assumes that the separator is a comma (the c in csv :-) )
176         try:
177             reader = csv.reader(open(infile), dialect = dialect, delimiter = ',')
178         except:
179             reader = csv.reader(open(infile), delimiter = ',')
180
181 # read input
182 num_cols = 1 # max columns
183 rows = []
184
185 for row in reader:
186     num_cols = max(num_cols, len(row))
187     rows.append(row)
188
189 num_rows = len(rows) # number of lines
190
191 # create a LyX file
192 #####################
193 # write first part
194 ####################
195 fout.write(header % (num_rows, num_cols))
196
197 #####################
198 # write table
199 ####################
200 for i in range(num_cols):
201         fout.write('<column alignment="left" valignment="top" width="0pt">\n')
202
203 for j in range(num_rows):
204     row = ['<row>']
205
206     ############################
207     # write contents of one line
208     ############################
209     for i in range(len(rows[j])):
210         row.append( cell % rows[j][i].replace('\\','\\backslash\n'))
211
212     # If row has less columns than num_cols fill with blank entries
213     for i in range(len(rows[j]), num_cols):
214         row.append(cell % " ")
215
216     fout.write("\n".join(row) + '\n</row>\n')
217
218 #####################
219 # write last part
220 ####################
221 fout.write(footer)
222 # close the LyX file
223 fout.close()