#!/usr/bin/env python
# vim:sts=4:sw=4:noet
# by Walter Doekes, 2009-04-05, licensed to the public
# domain.

# Rewrites plaintext documents to RTF files
# that are perfect for the Sony PRS-505 portable
# reader.
#
# Created to read RFC files on the screen reader.
# The RFC's require a monospaced font for proper reading
# while the PRS renders TXT files with a variable
# width font.
#
# Usage: txt2prs505rtf.py inputfile.txt
# It creates (silently overwrites!) inputfile.rtf with
# proper RTF formatting.


def main(fin, fout):
    OUT_LEN = 71

    # Find appropriate encoding
    for codec in ('cp1252', 'iso-8859-1', 'ascii'):
	try: u'\u00c5'.encode(codec) ; break # swedish AO
	except (LookupError, UnicodeEncodeError): pass

    # Write prolog
    fout.write('\n'.join([
	r'{\rtf1\ansi\deflang1033\widowctrl\deff0',
	r'{\fonttbl{\f0\fmodern\fprq1\fcharset0 Courier;}}',
	r'\pard\plain\f0\fs20 ',
    ]))

    # Loop over every line of the file
    condense_newlines = True
    need_newline = False
    for line in fin:
	# Expand tabs
	line = line.expandtabs(8)
	# Is it time for a new page?
	formfeed = line.find('\f')
	# Try to reduce the length by trimming space on the right
	line = line.rstrip() # removes (CR)LF and additional space
	# Honor lone form feeds with a new page and condense linefeeds
	if line == '':
	    if formfeed != -1:
		fout.write('\\page\n')
		need_newline = False
		condense_newlines = True
		continue
	    if condense_newlines:
		continue
	    condense_newlines = True
	else:
	    condense_newlines = False
	# Try to reduce space by removing reducing multiple spaces
	# to single spaces (from the right).
	try:
	    while len(line) > OUT_LEN:
		pos = line.rindex('  ')
		line = line[0:pos] + line[pos+1:]
	except ValueError:
	    # In the future we could do better fixes,
	    # for now we'll ignore it and hope the PRS
	    # handles the excess line length.
	    pass

        # Escape RTF characters
	line = line.replace('\\', '\\\\').replace('{', '\\{').replace('}', '\\}')

	# Write line
	if need_newline:
	    fout.write('\\line\n')
	fout.write(line.encode(codec))
	need_newline = True

    # Finish document
    fout.write('par}\n')


if __name__ == '__main__':
    import sys
    assert sys.argv[1][-4:] == '.txt'
    main(open(sys.argv[1], 'r'), open('%s.rtf' % sys.argv[1][0:-4], 'w'))
