1 # -*- coding: utf-8 -*-
4 # This file is part of LyX, the document processor.
5 # Licence details can be found in the file COPYING.
9 # Full author contact details are available in file CREDITS
11 # This script reads a csv-table (file name.csv) and converts it into
12 # a LyX-table for versions 1.5.0 and higher (LyX table format 276).
13 # It uses Python's csv module for parsing.
14 # The original csv2lyx was witten by Antonio Gulino <antonio.gulino@tin.it>
15 # in Perl for LyX 1.x and modified for LyX table format 276 by the author.
17 import csv, unicodedata
22 sys.stderr.write(message + '\n')
25 header = """#csv2lyx created this file. For more info see http://www.lyx.org/
30 \\use_default_options true
31 \\maintain_unincluded_children false
33 \\language_package default
38 \\font_typewriter default
39 \\font_default_family default
40 \\use_non_tex_fonts false
47 \\default_output_format default
49 \\bibtex_command default
50 \\index_command default
51 \\paperfontsize default
62 \\paperorientation portrait
71 \\paragraph_separation indent
72 \\paragraph_indentation default
73 \\quotes_language english
76 \\paperpagestyle default
77 \\tracking_changes false
78 \\output_changes false
81 \\html_be_strict false
86 \\begin_layout Standard
88 <lyxtabular version="3" rows="%d" columns="%d">
89 <features tabularvalignment="middle">
92 cell = """<cell alignment="left" valignment="top" usebox="none">
95 \\begin_layout Plain Layout
102 footer = """</lyxtabular>
113 # processing command line options
114 # delegate this to standard module optparse
116 args["usage"] = "Usage: csv2lyx [options] csvfile [file.lyx]"
118 args["description"] = """This script creates a LyX document containing a table created from a
119 comma-separated-value (CSV) file. The resulting LyX file can be opened
120 with LyX 1.5.0 or any later version.
121 If no options are given csv2lyx will try to infer the CSV type of the csvfile,
123 parser = optparse.OptionParser(**args)
125 parser.set_defaults(excel ='', column_sep = '')
126 parser.add_option("-e", "--excel", metavar ="CHAR",
127 help = """CHAR corresponds to a CSV type:
128 'e': Excel-generated CSV file
129 't': Excel-generated TAB-delimited CSV file""")
130 parser.add_option("-s", "--separator", dest = "column_sep",
131 help = """column separator
134 group = optparse.OptionGroup(parser, "Remarks", """If your CSV file contains special characters (e. g. umlauts,
135 accented letters, etc.) make sure it is coded in UTF-8 (unicode).
136 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.""")
137 parser.add_option_group(group)
139 (options, args) = parser.parse_args()
147 fout = open(args[1], 'w')
152 if not os.path.exists(infile):
153 error('File "%s" not found.' % infile)
155 dialects = {'' : None, 'e' : 'excel', 't' : 'excel-tab'}
156 if options.excel not in dialects:
159 dialect = dialects[options.excel]
161 # Set Tab, if necessary
162 if options.column_sep == 't':
163 options.column_sep = "\t"
165 # when no special column separator is given, try to detect it:
166 if options.column_sep and dialect :
167 reader = csv.reader(open(infile, "rU"), dialect = dialect, delimiter = options.column_sep)
169 guesser = csv.Sniffer()
170 input_file = "".join(open(infile,'rU').readlines())
172 dialect = guesser.sniff(input_file)
173 reader = csv.reader(open(infile, "rU"), dialect = dialect)
175 # older versions (python < 2.5) of csv have problems (bugs)
176 # that is why we try harder to get a result, this should work on most cases
177 # as it assumes that the separator is a comma (the c in csv :-) )
179 reader = csv.reader(open(infile, "rU"), dialect = dialect, delimiter = ',')
181 reader = csv.reader(open(infile, "rU"), delimiter = ',')
184 num_cols = 1 # max columns
188 num_cols = max(num_cols, len(row))
191 num_rows = len(rows) # number of lines
194 #####################
197 fout.write(header % (num_rows, num_cols))
199 #####################
202 for i in range(num_cols):
203 fout.write('<column alignment="left" valignment="top" width="0pt">\n')
205 for j in range(num_rows):
208 ############################
209 # write contents of one line
210 ############################
211 for i in range(len(rows[j])):
212 row.append( cell % rows[j][i].replace('\\','\\backslash\n'))
214 # If row has less columns than num_cols fill with blank entries
215 for i in range(len(rows[j]), num_cols):
216 row.append(cell % " ")
218 fout.write("\n".join(row) + '\n</row>\n')
220 #####################