Tuesday, May 19, 2009

First 'useful' Python script

here's my first 'useful' Python script. it converts a Crosswire SWORD IMP file to the XML needed by OpenSong scripture files. if this is useful to you, please let me know. and please use, don't abuse. you can download it here. full source code available below, and you'll obviously need Python to use it. Want to try it out? Grab a SWORD module (raw ZIP only, please!, convert it to IMP by following these instructions as far as creating an IMP file is concerned, then use my script.

# imp2opensong - converts a SWORD IMP file to an OpenSong XML file
# author: lewzscruz
# date: 18-May-2009
# license: public domain, i guess. use, don't abuse
# version: 0.2 ('cause i only tested with one source file!)

def strip_markup(line):
    '''Strips ALL markup from a line'''
    temp = line

    while True:
        # get first opening angle bracket
        open_angle_pos = temp.find('<')

        # quit if there's none
        if open_angle_pos == -1:
            return temp

        # get first closing angle bracket
        close_angle_pos = temp.find('>', open_angle_pos)

        # strip out the markup
        temp = temp[:open_angle_pos] + temp[close_angle_pos + 1:]

# prompt for input and output files
sourcefile = open(raw_input('Where is the input file? '))
destfile = open(raw_input('Where should I put the output file? '), 'w')

# start writing
destfile.write('<?xml version="1.0" encoding="utf-8"?>\n')
destfile.write('<bible>\n')

old_book = current_book = ''
old_chapter = current_chapter = ''
verse = ''

while True:
    # read lines till EOF
    line = sourcefile.readline()
    if line == '':
        break

    # trim the newline
    line = line[:-1]

    # don't do empty lines,
    # empty verses will be handled below
    if line == '':
        continue

    # and 'useless' lines
    if line.startswith('$$$['):
        continue

    # if we have a 'control' line
    if line.startswith('$$$'):
        # get the colon's location in the line...
        colon_pos = line.rfind(':')

        # ...and that of the space between the book name and the
        # chapter and verse
        lastspace_pos = line.rfind(' ')

        # ...now we know what book we're in...
        current_book = line[3:lastspace_pos]

        # ...the chapter...
        current_chapter = line[lastspace_pos + 1:colon_pos]

        # ...and the verse!
        verse = line[colon_pos + 1:]

        # if we changed books on this line,
        if old_book != current_book:
            # and we didn't just start,
            if old_book != '':
                # close the old chapter and book
                destfile.write('</c>\n')
                destfile.write('</b>\n')

            # start a fresh book
            old_book = current_book
            old_chapter = current_chapter = ''
            destfile.write('<b n="%s">\n' % (current_book,))
            continue

        # if we changed chapters,
        if old_chapter != current_chapter:
            # and it's not the beginning of a book,
            if old_chapter != '':
                # close previous chapter
                destfile.write('</c>\n')

            # start a fresh chapter
            old_chapter = current_chapter
            destfile.write('<c n="%s">\n' % (current_chapter,))

        # output real verses (there are fake ones in the source file),
        # including empty ones
        if verse != '0':
            # get the next line and strip the newline
            nextline = sourcefile.readline()[:-1]
            # output it, stripping any markup and whitespace
            destfile.write('<v n="%s">%s</v>\n' % (verse, strip_markup(nextline).strip()))

# finally, close the last chapter of Revelation,
# Revelation itself, and the Bible
destfile.write('</c>\n')
destfile.write('</b>\n')
destfile.write('</bible>\n')

# thanks for all the fish!
sourcefile.close()
destfile.close()

2 comments:

Tim said...

Awesome Lewscruz! I read your blog rather consistently. Great posts.

Babatunde Adeyemi said...

I'm impressed with the myriad of tools you use for your 3D work. Very informative blog