#!/usr/bin/env python '''Convert a CSV table to an HTML table - with some benefits''' import sys #mport string def usage(retval): '''Output a usage message and exit''' sys.stderr.write("Convert a whitespace (or arbitrarily) delimited\n") sys.stderr.write("ASCII table, one row per line, to an HTML table.\n\n") sys.stderr.write("Usage:\n") sys.stderr.write(" -d use a delimiter of |\n") sys.stderr.write(" --delimiter ch use a delimiter of ch\n") sys.stderr.write(" --help this stuff\n") sys.stderr.write(" --suppressible Output javascript code to allow suppressing unwanted rows and columns\n") sys.stderr.write(" --tooltips Output CSS styling to allow row/column tooltips\n") sys.exit(retval) def suppression_functions(): '''Output javascript code needed for suppressing rows and columns''' return ''' ''' def tooltip_style(): '''Output enough CSS that we can bring up tooltips for table elements, describing what row and column they correspond to''' return ''' ''' def id_equals_table(suppressible): '''If needed, output the id="table" stuff''' if suppressible: return 'id="table" ' else: return '' def form_tr_start(suppressible, rowno): '''Create a well-formed whatever''' return '' % id_equals_rowno(suppressible, rowno) def form_tr_end(): '''Output a close tr tag''' return '' def id_equals_rowno(suppressible, rowno): '''Output an id for a ''' if suppressible: return ' id="row-%d"' % (rowno + 1) else: return '' def spanned(tooltips, rowno, colno, row_description, column_description, field): # pylint: disable=R0913 # R0913: We need a few arguments '''Output tooltip stuff, if needed''' if tooltips and rowno != 0 and colno != 0: return '%s' % (row_description, column_description, field) else: return field def full_td(field, row_description, column_description, rowno, colno, suppressible, tooltips): # pylint: disable=R0913 # R0913: We need a few arguments '''Form a complete whatever''' return '' % ( td_name(field, rowno, colno, suppressible), spanned(tooltips, rowno, colno, row_description, column_description, field), ) def td_name(field, rowno, colno, suppressible): '''Output a suitable ''' if field is None: field = '' if suppressible: if rowno == 0 and colno != 0: return ' name="col-%d">
' % (colno + 1, colno + 1) elif rowno != 0 and colno == 0: return ' name="row-%d">' % (rowno + 1, rowno + 1) else: return ' name="col-%d">' % (colno + 1) else: return '>' def table_start(suppressible): '''Return the beginning of table tag and attributes''' # Note that in my source material, id='table' was used, not id="table" return '' % id_equals_table(suppressible) class Options: # pylint: disable=R0903 # R0903: We're a container; we don't need a bunch of public methods '''Just a container class, to hold a few variables whose values we get from command line options''' def __init__(self, delimiter=None, suppressible=False, tooltips=False): self.delimiter = delimiter self.suppressible = suppressible self.tooltips = tooltips def parse_options(self, argv): '''Parse command line options, modifying config variable values as we go''' while argv[1:]: if argv[1] == '-d': self.delimiter = '|' elif argv[1] == '--suppressible': self.suppressible = True elif argv[1] == '--tooltips': self.tooltips = True elif argv[1] == '--delimiter' and argv[2:]: self.delimiter = argv[2] del argv[1] elif argv[1] in [ '-h', '--help' ]: usage(0) else: sys.stderr.write("%s: Illegal argument: %s\n" % (argv[0], argv[1])) usage(1) del argv[1] def form_comment(line): '''Output a comment containing the original CSV data - albeit converted to a list''' return '' % str(line) def main(): '''Main function''' options = Options() options.parse_options(sys.argv) maxfields = 0 lines = [] for line in sys.stdin: line = line.rstrip('\n') if options.delimiter == None: fields = line.split() else: fields = line.split(options.delimiter) if len(fields) > maxfields: maxfields = len(fields) lines.append(fields) if options.suppressible: print suppression_functions() if options.tooltips: print tooltip_style() print table_start(options.suppressible) top_row = lines[0] #print >> sys.stderr, "top_row is %s" % top_row for rowno, line in enumerate(lines): print '\t%s' % form_comment(line) print '\t%s' % form_tr_start(options.suppressible, rowno) for colno in range(maxfields): if line[colno:]: field = line[colno] else: field = None print '\t\t%s' % full_td(field, lines[rowno][0], top_row[colno], rowno, colno, options.suppressible, options.tooltips) print '\t%s' % form_tr_end() print '
' main()