2 # -*- coding: utf-8 -*-
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
10 # Full author contact details are available in file CREDITS
12 # This script reads a csv-table (file name.csv) and converts it into
13 # a LyX-table for versions 1.5.0 and higher (LyX table format 276).
14 # It uses Python's csv module for parsing.
15 # The original csv2lyx was witten by Antonio Gulino <antonio.gulino@tin.it>
16 # in Perl for LyX 1.x and modified for LyX table format 276 by the author.
18 import csv, unicodedata
23 sys.stderr.write(message + '\n')
26 header = """#csv2lyx created this file. For more info see http://www.lyx.org/
31 \\use_default_options true
32 \\maintain_unincluded_children false
34 \\language_package default
39 \\font_typewriter default
40 \\font_default_family default
41 \\use_non_tex_fonts false
48 \\default_output_format default
50 \\bibtex_command default
51 \\index_command default
52 \\paperfontsize default
63 \\paperorientation portrait
72 \\paragraph_separation indent
73 \\paragraph_indentation default
74 \\quotes_language english
77 \\paperpagestyle default
78 \\tracking_changes false
79 \\output_changes false
82 \\html_be_strict false
87 \\begin_layout Standard
89 <lyxtabular version="3" rows="%d" columns="%d">
90 <features tabularvalignment="middle">
93 cell = """<cell alignment="left" valignment="top" usebox="none">
96 \\begin_layout Plain Layout
103 footer = """</lyxtabular>
114 # processing command line options
115 # delegate this to standard module optparse
117 args["usage"] = "Usage: csv2lyx [options] csvfile [file.lyx]"
119 args["description"] = """This script creates a LyX document containing a table created from a
120 comma-separated-value (CSV) file. The resulting LyX file can be opened
121 with LyX 1.5.0 or any later version.
122 If no options are given csv2lyx will try to infer the CSV type of the csvfile,
124 parser = optparse.OptionParser(**args)
126 parser.set_defaults(excel ='', column_sep = '')
127 parser.add_option("-e", "--excel", metavar ="CHAR",
128 help = """CHAR corresponds to a CSV type:
129 'e': Excel-generated CSV file
130 't': Excel-generated TAB-delimited CSV file""")
131 parser.add_option("-s", "--separator", dest = "column_sep",
132 help = """column separator
135 group = optparse.OptionGroup(parser, "Remarks", """If your CSV file contains special characters (e. g. umlauts,
136 accented letters, etc.) make sure it is coded in UTF-8 (unicode).
137 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.""")
138 parser.add_option_group(group)
140 (options, args) = parser.parse_args()
148 fout = open(args[1], 'w')
153 if not os.path.exists(infile):
154 error('File "%s" not found.' % infile)
156 dialects = {'' : None, 'e' : 'excel', 't' : 'excel-tab'}
157 if options.excel not in dialects:
160 dialect = dialects[options.excel]
162 # Set Tab, if necessary
163 if options.column_sep == 't':
164 options.column_sep = "\t"
166 # when no special column separator is given, try to detect it:
167 if options.column_sep and dialect :
168 reader = csv.reader(open(infile, "rb"), dialect = dialect, delimiter = options.column_sep)
170 guesser = csv.Sniffer()
171 input_file = "".join(open(infile,'rb').readlines())
173 dialect = guesser.sniff(input_file)
174 reader = csv.reader(open(infile, "rb"), dialect = dialect)
176 # older versions (python < 2.5) of csv have problems (bugs)
177 # that is why we try harder to get a result, this should work on most cases
178 # as it assumes that the separator is a comma (the c in csv :-) )
180 reader = csv.reader(open(infile, "rb"), dialect = dialect, delimiter = ',')
182 reader = csv.reader(open(infile, "rb"), delimiter = ',')
185 num_cols = 1 # max columns
189 num_cols = max(num_cols, len(row))
192 num_rows = len(rows) # number of lines
195 #####################
198 fout.write(header % (num_rows, num_cols))
200 #####################
203 for i in range(num_cols):
204 fout.write('<column alignment="left" valignment="top" width="0pt">\n')
206 for j in range(num_rows):
209 ############################
210 # write contents of one line
211 ############################
212 for i in range(len(rows[j])):
213 row.append( cell % rows[j][i].replace('\\','\\backslash\n'))
215 # If row has less columns than num_cols fill with blank entries
216 for i in range(len(rows[j]), num_cols):
217 row.append(cell % " ")
219 fout.write("\n".join(row) + '\n</row>\n')
221 #####################