2 # This file is part of LyX, the document processor.
3 # Licence details can be found in the file COPYING.
7 # Full author contact details are available in file CREDITS
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.
15 import csv, unicodedata
20 sys.stderr.write(message + '\n')
23 header = """#csv2lyx created this file. For more info see http://www.lyx.org/
28 \\use_default_options true
29 \\maintain_unincluded_children false
31 \\language_package default
36 \\font_typewriter default
37 \\font_default_family default
38 \\use_non_tex_fonts false
45 \\default_output_format default
47 \\bibtex_command default
48 \\index_command default
49 \\paperfontsize default
60 \\paperorientation portrait
69 \\paragraph_separation indent
70 \\paragraph_indentation default
71 \\quotes_language english
74 \\paperpagestyle default
75 \\tracking_changes false
76 \\output_changes false
79 \\html_be_strict false
84 \\begin_layout Standard
86 <lyxtabular version="3" rows="%d" columns="%d">
87 <features tabularvalignment="middle">
90 cell = """<cell alignment="left" valignment="top" usebox="none">
93 \\begin_layout Plain Layout
100 footer = """</lyxtabular>
111 # processing command line options
112 # delegate this to standard module optparse
114 args["usage"] = "Usage: csv2lyx [options] csvfile [file.lyx]"
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,
121 parser = optparse.OptionParser(**args)
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
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)
137 (options, args) = parser.parse_args()
145 fout = open(args[1], 'w')
150 if not os.path.exists(infile):
151 error('File "%s" not found.' % infile)
153 dialects = {'' : None, 'e' : 'excel', 't' : 'excel-tab'}
154 if options.excel not in dialects:
157 dialect = dialects[options.excel]
159 # Set Tab, if necessary
160 if options.column_sep == 't':
161 options.column_sep = "\t"
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)
167 guesser = csv.Sniffer()
168 input_file = "".join(open(infile).readlines())
170 dialect = guesser.sniff(input_file)
171 reader = csv.reader(open(infile), dialect = dialect)
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 :-) )
177 reader = csv.reader(open(infile), dialect = dialect, delimiter = ',')
179 reader = csv.reader(open(infile), delimiter = ',')
182 num_cols = 1 # max columns
186 num_cols = max(num_cols, len(row))
189 num_rows = len(rows) # number of lines
192 #####################
195 fout.write(header % (num_rows, num_cols))
197 #####################
200 for i in range(num_cols):
201 fout.write('<column alignment="left" valignment="top" width="0pt">\n')
203 for j in range(num_rows):
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'))
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 % " ")
216 fout.write("\n".join(row) + '\n</row>\n')
218 #####################