Related Entries

India PyCon 2009
Quick wallpaper changer
Load testing with Grinder
Adding namespace to XML
Opera RSS to OPML

« Using Leo for reST
» Weblogs for PM

CSV to ASCII Grid

Silly script to fill a void that kept bothering me for a while.

I’m really beginning to enjoy reST now that I’ve Leo. Today, I had to make a research report. The report had a pretty big - around 8x100 - Excel sheet. Instead of referring to it as the Excel attachment I thought of adding it as an appendix to the document.

Here’s is today’s example of wasting time now to save time later :-) This little script converts a CSV file into a nice grid table that I can add to my reST document.


#!/usr/bin/env python

"""
Makes an ascii table out of a CSV file. Requires CSV module from 
http://object-craft.com.au/projects/csv/

This is very useful for adding Excel sheets into reST documents.

Usage: %s csv_file <first_line_is_header>

csv_file can be -; in which case standard input is used.
first_line_is_header is just an additional parameter. If specified (any
value you choose), it prints a different separator line after the first
row.

Caution: This process records in memory. If you have very big CSV documents,
this is probably not what you want to use.
"""
__author__ = "V S Babu <vsbabu_at_vsbabu_dot_org>"

__date__   = "$Date: 2003/06/03 10:00:00 $"
__version__ = "$Revision: 1.1 $"

import csv
import sys

p = csv.parser()

#determine the input file
try:
    if sys.argv[1] != '-':

        f = open(sys.argv[1], "r")

    else:
        f = sys.stdin
except:
    print __doc__ % sys.argv[0]

    sys.exit(1)

if len(sys.argv) > 2:

    first_line_is_header = 1
else:
    first_line_is_header = 0

records = []

field_lengths = []
#read the input file
while 1:
    line = f.readline()

    if not line:
        break
    rec =  p.parse(line)

    #trim the fields of lead/trail spaces
    rec = [r.strip() for r in rec]

    #adjust the maximum field width’s
    for i in range(len(rec)):

        if i >= len(field_lengths):
            field_lengths.append(len(rec[i]))

        if len(rec[i]) > field_lengths[i]: 
            field_lengths[i] = len(rec[i])

    records.append(rec)
f.close()

#make record separator

rec_sep = "+"
rec_fmt = "|"
for i in field_lengths:

    rec_sep = rec_sep + ((i+2) * "-") + "+"

    rec_fmt = rec_fmt + "%-" +  str(i+2) +  "s|"

#print the records
print rec_sep
count = 0
for r in records:

    try:
        print rec_fmt % tuple(r)
    except:

        print len(r),
    if count == 0 and first_line_is_header:

        print rec_sep.replace("-","=")
    else:
        print rec_sep
    count = count + 1

sys.exit(0)

For updated versions - if at all any updates happen, get it from CVS. This works for me now. If you want this to do more, you are welcome to extend it :-)

Note: It might be better to get the code from CVS anyway. I think there is some issue with entering the HTML generated by GNU source-highlight into MovableType’s textarea through MozillaFirebird. The code doesn’t have so many blank lines as above...

//-->