#!/usr/bin/python

from pylrs.pylrs import *
from sys         import *
from optparse    import OptionParser

"""
    This program creates an lrf file from the given file.

	Features included so far.

		- Chapters delimited by "<chapter>"
		- Auto-Flow of paragraphs
		- Curly-Quotes (aka Smart Quotes)
		[- html tags <i></i>, <b></b> <center></center>, <sub></sub>]
		- html Ampersand tags - &amp;, &pound, &uumlat, etc.

	NEEDED FEATURES
		x Page Margins Fixed (flows off bottom)
		x Paragraph indentation Fixed
		x Centering Text
		x Correct Smart Quotes
		x Missing HTML Code
		Missing per-page Header
		Quoted Text / Poems (using <BR> Tags?)
		Command line flags for TITLE and AUTHOR.
			Additional Flags
				Break on CR
				Break on TAB
				Break on Space

    page = book.Page()

    This is equivalent to:

    page = Page()
    book.append(page)

    TextBlocks can be added to any page at any time, since the entire book is
    kept in memory.  Text can also be added to any paragraph at any time.

"""

#
# Globals for make_curly_quotes()
#
prev_char     = ' '
prev_was_open = False

#
# Globals - Set by Command Line Options
#
use_rdquotes    = False
preserve_spaces = False
verbose         = True


#############################################################
# def format_paragraph():									#
#															#
#############################################################
#def format_paragraph(paragraph, line):
def format_paragraph(page, ts, cs, bs, line):

	in_italic = False
	done      = False

	if len(line) <= 0 :
		return

	#
	# Text Block is either Standard or Centered
	# Both apply to WHOLE paragraph
	#
	# <CENTER>  - CENTERED TEXT
	# Otherwise - STANDARD TEXT
	#
	if line.find("<center>", 0, 8) >= 0 or \
	   line.find("<CENTER>", 0, 8) >= 0 :
		line      = line.replace("<center>","",1).replace("<CENTER>","",1)
		line      = line.replace("</center>","",1).replace("</CENTER>","",1)
		paragraph = page.TextBlock(cs, bs).Paragraph()
	else :
		paragraph = page.TextBlock(ts, bs).Paragraph()

	#
	# Split at html open
	#
	first_char = line[0]
	formatting = line.split("<")
	length     = len(formatting)
	start      = 0

	if first_char != '<' and len(formatting[0]) >= 1 :
		paragraph.append(formatting[0])
		start = 1

	#
	# Each line in split is broken at a potential html format tag
	#
	i = start
	while i < length :
		if len(formatting[i]) <= 0 :
			i += 1
			continue
		#
		# First character should tell us what kind of
		# formatting we are doing here
		#

		#
		# <I> - ITALICS
		# For some reason find range 0,1 doesn't work, but 0,2 does
		#
		if formatting[i].find("i>", 0, 2) >= 0 or \
		   formatting[i].find("I>", 0, 2) >= 0 :
			f_str = formatting[i]
			x_str = f_str.replace("i>","",1).replace("I>","",1)
			paragraph.append(Italic(x_str))
			i += 1
			if i >= length :
				continue
			r_str = formatting[i]
			x_str = r_str.replace("/i>","",1).replace("/I>","",1)
			paragraph.append(x_str)
			i += 1
			continue

		#
		# <B> - BOLD
		#
		if formatting[i].find("b>", 0, 2) >= 0 or \
		   formatting[i].find("B>", 0, 2) >= 0 :
			f_str = formatting[i]
			x_str = f_str.replace("b>","",1).replace("B>","",1)
			paragraph.append(Bold(x_str))
			i += 1
			if i >= length :
				continue
			r_str = formatting[i]
			x_str = r_str.replace("/b>","",1).replace("/B>","",1)
			paragraph.append(x_str)
			i += 1
			continue
		#
		# <SUB> - SUBSCRIPT
		#
		if formatting[i].find("sub>", 0, 4) >= 0 or \
		   formatting[i].find("SUB>", 0, 4) >= 0 :
			f_str = formatting[i]
			x_str = f_str.replace("sub>","",1).replace("SUB>","",1)
			paragraph.append(Sub(x_str))
			i += 1
			if i >= length :
				continue
			r_str = formatting[i]
			x_str = r_str.replace("/sub>","",1).replace("/SUB>","",1)
			paragraph.append(x_str)
			i += 1
			continue
		#
		# <SUP> - SUPERSCRIPT
		#
		if formatting[i].find("sup>", 0, 4) >= 0 or \
		   formatting[i].find("SUP>", 0, 4) >= 0 :
			f_str = formatting[i]
			x_str = f_str.replace("sup>","",1).replace("SUP>","",1)
			paragraph.append(Sup(x_str))
			i += 1
			if i >= length :
				continue
			r_str = formatting[i]
			x_str = r_str.replace("/sup>","",1).replace("/SUP>","",1)
			paragraph.append(x_str)
			i += 1
			continue

		paragraph.append("<")
		paragraph.append(formatting[i])

		#increment
		i += 1
	#endfor


#    p3.append(Italic("This is in italics,"))

# enddef format_paragraph()



#############################################################
# def make_curly_quotes():									#
#															#
#############################################################
def make_curly_quotes(line):
	global prev_char
	global prev_was_open
	global use_rdquotes

	do_open   = True
	next_char = '\n'

	#
	# Replace any HTML quotes with he actual quote
	# This allows the curly-quote algorithm to function
	# on quotes only.
	#
	# The global use_rdquotes means we want to ignore
	# html-explicit curly quotes and use our own algorith
	# to figure them out
	#
	line = line.replace("&quot;", "\"")
	if not use_rdquotes :
		line = line.replace("&ldquo;", "\"")
		line = line.replace("&rdquo;", "\"")
		line = line.replace("&#8220;", "\"")
		line = line.replace("&#8221;", "\"")

	for i in range(len(line)) :
		if i+1 < len(line) :
			next_char = line[i+1]
		else :
			next_char = '\n';

		#
		# DOUBLE QUOTE
		#
		if line[i] == '"' :
			do_open = True

			# Prev IS Whtespace
			if prev_char.isspace() or prev_char == '\n' :
				# Open by default
				do_open = True

				# Special case if it is a dangling quote
				if next_char.isspace() or next_char == '\n' :
					do_open = False
					if not prev_was_open :
						do_open = True
				#endif

			# Prev is NOT Whitespace
			else :
				do_open = False
				if prev_char == '-' and next_char.isalnum() :
					do_open = True
				if prev_char == '>' :
					do_open = not prev_was_open

			if do_open :
				line     = line.replace("\"",u"\u201C",1)
				prev_was_open = True
			else :
				line     = line.replace("\"",u"\u201D",1)
				prev_was_open = False
		#endif

		#
		# SINGLE QUOTE
		#
		if line[i] == '\'' :
			do_open = False

			# Prev IS Whtespace
			if prev_char.isspace() or prev_char == '\n' :
				# Open by default
				do_open = True
				#
				# Find next ' and see if it is a close quote vs
				# just an apostrophe
				#
				index = line.find("'",i+1)
				if index > -1 :
					if line[index-1].isalnum() and line[index+1].isspace() :
						do_open = True
					else :
						do_open = False
					# endif
				# endif
			#endif

			if do_open :
				line = line.replace("\'",u"\u2018",1)
			else :
				line = line.replace("\'",u"\u2019",1)
		#endif

		prev_char = line[i]

	prev_char = '\n'
	return line

# enddef make_curl_quotes()

#############################################################
# def convert_misc():										#
#															#
#############################################################
def convert_misc(line):
	global preserve_spaces

	#
	# Compresses multiple spaces into single-space
	# The Reader DOES NOT justify text correclty when
	# multiple spaces between words are involved (it seems to
	# interpret the first space encountered as "flowable" and
	# the rest are treated as non-breaking spaces).
	#
	if not preserve_spaces :
		spaceline = line.replace("  ", " ")
		while spaceline != line :
			line      = spaceline
			spaceline = line.replace("  ", " ")

	#
	# Em-Dash Replacement
	#
	# Do triple dash first, then double-dash if any are left
	#
	line = line.replace("---",   u"\u2013")
	line = line.replace("--",    u"\u2013")

	return line

# enddef convert_misc()


#############################################################
# def convert_html_ampersands():							#
#															#
#############################################################
def convert_html_ampersands(line):

	#
	# Basically, just global replace with equivalents
	#

	#
	# The only exception is if we want to use our algorithm
	# for curly quotes, rather than trusting existing HTML
	#
	if use_rdquotes :
		line = line.replace("&ldquo;", u"\u201C")
		line = line.replace("&rdquo;", u"\u201D")
		line = line.replace("&#8220;", u"\u201C")
		line = line.replace("&#8221;", u"\u201D")

	line = line.replace("&quot;",     u"\"")
	line = line.replace("&mdash;",    u"\u2013")
	line = line.replace("&ndash;",    u"\u2013")
	line = line.replace("&amp;",      u"\u0026")
	line = line.replace("&lt;",       u"\u003C")
	line = line.replace("&gt;",       u"\u003E")
	line = line.replace("&nbsp;",     u"\u00A0")
	line = line.replace("&iexcl;",    u"\u00A1")
	line = line.replace("&cent;",     u"\u00A2")
	line = line.replace("&pound;",    u"\u00A3")
	line = line.replace("&curren;",   u"\u00A4")
	line = line.replace("&yen;",      u"\u00A5")
	line = line.replace("&brvbar;",   u"\u00A6")
	line = line.replace("&sect;",     u"\u00A7")
	line = line.replace("&die;",      u"\u00A8")
	line = line.replace("&copy;",     u"\u00A9")
	line = line.replace("&ordf;",     u"\u00AA")
	line = line.replace("&laquo;",    u"\u00AB")
	line = line.replace("&not;",      u"\u00AC")
	line = line.replace("&shy;",      u"\u00AD")
	line = line.replace("&reg;",      u"\u00AE")
	line = line.replace("&macron;",   u"\u00AF")
	line = line.replace("&degree;",   u"\u00B0")
	line = line.replace("&plusmn;",   u"\u00B1")
	line = line.replace("&sup2;",     u"\u00B2")
	line = line.replace("&sup3;",     u"\u00B3")
	line = line.replace("&acute;",    u"\u00B4")
	line = line.replace("&micro;",    u"\u00B5")
	line = line.replace("&para;",     u"\u00B6")
	line = line.replace("&middot;",   u"\u00B7")
	line = line.replace("&Cedilla;",   u"\u00B8")
	line = line.replace("&sup1;",     u"\u00B9")
	line = line.replace("&ordm;",     u"\u00BA")
	line = line.replace("&raquo;",    u"\u00BB")
	line = line.replace("&frac14;",   u"\u00BC")
	line = line.replace("&frac12;",   u"\u00BD")
	line = line.replace("&frac34;",   u"\u00BE")
	line = line.replace("&iquest;",   u"\u00BF")
	line = line.replace("&Agrave;",   u"\u00C0")
	line = line.replace("&Aacute;",   u"\u00C1")
	line = line.replace("&Acirc;",    u"\u00C2")
	line = line.replace("&Atilde;",   u"\u00C3")
	line = line.replace("&Auml;",     u"\u00C4")
	line = line.replace("&Aring;",    u"\u00C5")
	line = line.replace("&AElig;",    u"\u00C6")
	line = line.replace("&Ccedil;",   u"\u00C7")
	line = line.replace("&Egrave;",   u"\u00C8")
	line = line.replace("&Eacute;",   u"\u00C9")
	line = line.replace("&Ecirc;",    u"\u00CA")
	line = line.replace("&Euml;",     u"\u00CB")
	line = line.replace("&Igrave;",   u"\u00CC")
	line = line.replace("&Iacute;",   u"\u00CD")
	line = line.replace("&Icirc;",    u"\u00CE")
	line = line.replace("&Iuml;",     u"\u00CF")
	line = line.replace("&ETH;",      u"\u00D0")
	line = line.replace("&Ntilde;",   u"\u00D1")
	line = line.replace("&Ograve;",   u"\u00D2")
	line = line.replace("&Oacute;",   u"\u00D3")
	line = line.replace("&Ocirc;",    u"\u00D4")
	line = line.replace("&Otilde;",   u"\u00D5")
	line = line.replace("&Ouml;",     u"\u00D6")
	line = line.replace("&times;",    u"\u00D7")
	line = line.replace("&Oslash;",   u"\u00D8")
	line = line.replace("&Ugrave;",   u"\u00D9")
	line = line.replace("&Uacute;",   u"\u00DA")
	line = line.replace("&Ucirc;",    u"\u00DB")
	line = line.replace("&Uuml;",     u"\u00DC")
	line = line.replace("&Yacute;",   u"\u00DD")
	line = line.replace("&THORN;",    u"\u00DE")
	line = line.replace("&szlig;",    u"\u00DF")
	line = line.replace("&agrave;",   u"\u00E0")
	line = line.replace("&aacute;",   u"\u00E1")
	line = line.replace("&acirc;",    u"\u00E2")
	line = line.replace("&atilde;",   u"\u00E3")
	line = line.replace("&auml;",     u"\u00E4")
	line = line.replace("&aring;",    u"\u00E5")
	line = line.replace("&aelig;",    u"\u00E6")
	line = line.replace("&ccedil;",   u"\u00E7")
	line = line.replace("&egrave;",   u"\u00E8")
	line = line.replace("&eacute;",   u"\u00E9")
	line = line.replace("&ecirc;",    u"\u00EA")
	line = line.replace("&euml;",     u"\u00EB")
	line = line.replace("&igrave;",   u"\u00EC")
	line = line.replace("&iacute;",   u"\u00ED")
	line = line.replace("&icirc;",    u"\u00EE")
	line = line.replace("&iuml;",     u"\u00EF")
	line = line.replace("&eth;",      u"\u00F0")
	line = line.replace("&ntilde;",   u"\u00F1")
	line = line.replace("&ograve;",   u"\u00F2")
	line = line.replace("&oacute;",   u"\u00F3")
	line = line.replace("&ocirc;",    u"\u00F4")
	line = line.replace("&otilde;",   u"\u00F5")
	line = line.replace("&ouml;",     u"\u00F6")
	line = line.replace("&divide;",   u"\u00F7")
	line = line.replace("&oslash;",   u"\u00F8")
	line = line.replace("&ugrave;",   u"\u00F9")
	line = line.replace("&uacute;",   u"\u00FA")
	line = line.replace("&ucirc;",    u"\u00FB")
	line = line.replace("&uuml;",     u"\u00FC")
	line = line.replace("&yacute;",   u"\u00FD")
	line = line.replace("&thorn;",    u"\u00FE")
	line = line.replace("&yuml;",     u"\u00FF")
	line = line.replace("&lowast;",   u"\u2217")
	line = line.replace("&minus;",    u"\u2212")
	line = line.replace("&cong;",     u"\u2245")
	line = line.replace("&Agr;",      u"\u0391")
	line = line.replace("&Bgr;",      u"\u0392")
	line = line.replace("&KHgr;",     u"\u03A7")
	line = line.replace("&Delta;",    u"\u0394")
	line = line.replace("&Egr;",      u"\u0395")
	line = line.replace("&PHgr;",     u"\u03A6")
	line = line.replace("&Gamma;",    u"\u0393")
	line = line.replace("&EEgr;",     u"\u0397")
	line = line.replace("&Igr;",      u"\u0399")
	line = line.replace("&thetav;",   u"\u03D1")
	line = line.replace("&Kgr;",      u"\u039A")
	line = line.replace("&Lambda;",   u"\u039B")
	line = line.replace("&Mgr;",      u"\u039C")
	line = line.replace("&Ngr;",      u"\u039D")
	line = line.replace("&Ogr;",      u"\u039F")
	line = line.replace("&Pi;",       u"\u03A0")
	line = line.replace("&Theta;",    u"\u0398")
	line = line.replace("&Rgr;",      u"\u03A1")
	line = line.replace("&Sigma;",    u"\u03A3")
	line = line.replace("&Tgr;",      u"\u03A4")
	line = line.replace("&Upsi;",     u"\u03A5")
	line = line.replace("&sfgr;",     u"\u03C2")
	line = line.replace("&Omega;",    u"\u03A9")
	line = line.replace("&Xi;",       u"\u039E")
	line = line.replace("&Psi;",      u"\u03A8")
	line = line.replace("&Zgr;",      u"\u0396")
	line = line.replace("&there4;",   u"\u2234")
	line = line.replace("&perp;",     u"\u22A5")
	line = line.replace("&alpha;",    u"\u03B1")
	line = line.replace("&beta;",     u"\u03B2")
	line = line.replace("&chi;",      u"\u03C7")
	line = line.replace("&delta;",    u"\u03B4")
	line = line.replace("&epsi;",     u"\u03B5")
	line = line.replace("&phis;",     u"\u03C6")
	line = line.replace("&gamma;",    u"\u03B3")
	line = line.replace("&eta;",      u"\u03B7")
	line = line.replace("&iota;",     u"\u03B9")
	line = line.replace("&phiv;",     u"\u03D5")
	line = line.replace("&kappa;",    u"\u03BA")
	line = line.replace("&lambda;",   u"\u03BB")
	line = line.replace("&mu;",       u"\u03BC")
	line = line.replace("&nu;",       u"\u03BD")
	line = line.replace("&ogr;",      u"\u03BF")
	line = line.replace("&pi;",       u"\u03C0")
	line = line.replace("&thetas;",   u"\u03B8")
	line = line.replace("&rho;",      u"\u03C1")
	line = line.replace("&sigma;",    u"\u03C3")
	line = line.replace("&tau;",      u"\u03C4")
	line = line.replace("&upsi;",     u"\u03C5")
	line = line.replace("&piv;",      u"\u03D6")
	line = line.replace("&omega;",    u"\u03C9")
	line = line.replace("&xi;",       u"\u03BE")
	line = line.replace("&psi;",      u"\u03C8")
	line = line.replace("&zeta;",     u"\u03B6")
	line = line.replace("&sim;",      u"\u223C")
	line = line.replace("&vprime;",   u"\u2032")
	line = line.replace("&le;",       u"\u2264")
	line = line.replace("&infin;",    u"\u221E")
	line = line.replace("&fnof;",     u"\u0192")
	line = line.replace("&clubs;",    u"\u2663")
	line = line.replace("&diams;",    u"\u2666")
	line = line.replace("&hearts;",   u"\u2665")
	line = line.replace("&spades;",   u"\u2660")
	line = line.replace("&harr;",     u"\u2194")
	line = line.replace("&larr;",     u"\u2190")
	line = line.replace("&uarr;",     u"\u2191")
	line = line.replace("&rarr;",     u"\u2192")
	line = line.replace("&darr;",     u"\u2193")
	line = line.replace("&Prime;",    u"\u2033")
	line = line.replace("&ge;",       u"\u2265")
	line = line.replace("&prop;",     u"\u221D")
	line = line.replace("&part;",     u"\u2202")
	line = line.replace("&bull;",     u"\u2022")
	line = line.replace("&ne;",       u"\u2260")
	line = line.replace("&equiv;",    u"\u2261")
	line = line.replace("&ap;",       u"\u2248")
	line = line.replace("&hellip;",   u"\u2026")
	line = line.replace("&aleph;",    u"\u2135")
	line = line.replace("&image;",    u"\u2111")
	line = line.replace("&real;",     u"\u211C")
	line = line.replace("&weierp;",   u"\u2118")
	line = line.replace("&otimes;",   u"\u2297")
	line = line.replace("&oplus;",    u"\u2295")
	line = line.replace("&empty;",    u"\u2205")
	line = line.replace("&cap;",      u"\u2229")
	line = line.replace("&cup;",      u"\u222A")
	line = line.replace("&sup;",      u"\u2283")
	line = line.replace("&supe;",     u"\u2287")
	line = line.replace("&nsub;",     u"\u2284")
	line = line.replace("&sub;",      u"\u2282")
	line = line.replace("&sube;",     u"\u2286")
	line = line.replace("&isin;",     u"\u2208")
	line = line.replace("&notin;",    u"\u2209")
	line = line.replace("&ang;",      u"\u2220")
	line = line.replace("&nabla;",    u"\u2207")
	line = line.replace("&trade;",    u"\u2122")
	line = line.replace("&prod;",     u"\u220F")
	line = line.replace("&radic;",    u"\u221A")
	line = line.replace("&sdot;",     u"\u22C5")
	line = line.replace("&and;",      u"\u2227")
	line = line.replace("&or;",       u"\u2228")
	line = line.replace("&hArr;",     u"\u21D4")
	line = line.replace("&lArr;",     u"\u21D0")
	line = line.replace("&uArr;",     u"\u21D1")
	line = line.replace("&rArr;",     u"\u21D2")
	line = line.replace("&dArr;",     u"\u21D3")
	line = line.replace("&loz;",      u"\u25CA")
	line = line.replace("&lang;",     u"\u2329")
	line = line.replace("&sum;",      u"\u2211")
	line = line.replace("&lceil;",    u"\u2308")
	line = line.replace("&lfloor;",   u"\u230A")
	line = line.replace("&rang;",     u"\u232A")
	line = line.replace("&int;",      u"\u222B")

	return line

# enddef convert_html_ampersands()

#############################################################
# def parse_cmdline():										#
#															#
#############################################################
def parse_cmdline():

	global cmdline

	cmdline = OptionParser(usage="usage: %prog -i infile -o outfile "
						   "[-t Title -a Author ...] (-h for all options)"
						   )

	# Input / Output Files
	cmdline.add_option("-i", "--infile", dest="infile",
					   action="store",   type="string",
					   help="Input text file to convert to lrf")
	cmdline.add_option("-o", "--outfile", dest="outfile",
					   action="store",    type="string",
					   help="Output lrf file for converted text")

	# Title / Author
	cmdline.add_option("-t", "--title", dest="title",default="Unknown Title",
					   action="store",  type="string",
					   help="Specify Book Title, use quotes")
	cmdline.add_option("-a", "--author",dest="author",default="Unknown Author",
					   action="store",  type="string",
					   help="Specify Book Author, use quotes.")

	#
	# Spaces are removed to one-space, maybe we don't want to?
	#
	cmdline.add_option("--preserve-spaces", dest="preserve_spaces",
					   default=False, action="store_true",
					   help="Do not remove extra spaces between words. "
					        "DEFAULT is to remove spaces because the Reader "
					        "treats extra spaces as non-breaking, and this "
					        "interferes with proper justification"
					   )
	cmdline.add_option("--use-rdquotes", dest="use_rdquotes",
					   default=False, action="store_true",
					   help="Trust html &rdquote;|&ldquote; for curly quotes."
					        " DEFAULT is to NOT trust these tags, since many"
					        " OCRs get them wrong, and the built-in alorithmic"
					        " calculation is more accurate."
					   )
	#
	# How to calculate linebreaks
	#
	cmdline.add_option("-b", "--paragraphbreak", dest="linebreak",
					   default="auto", metavar="auto|cr|tab|space",
					   help="Specify how to break paragraphs: "
					        "'auto' (default) - best-guess algorithm. "
					        "'html' - paragraphs begin with HTML <p> tags. "
					        "'cr' - paragraphs begin after line break. "
					        "'tab' - paragraphs begin with tab-indented line. "
					        "'space' - paragraphs begin with multi-spaced "
					        " indented line."
					   )

	#
	# Font size and boldness
	#
	cmdline.add_option("--textsize", dest="textsize", default=95,
					   action="store",  type="int",
					   help="Text Font size (points) - DEFAULT: 95")
	cmdline.add_option("--textweight", dest="textweight", default=400,
					   action="store",  type="int",
					   help="Text Font weight - DEFAULT 400, Bold is 800.")
	cmdline.add_option("--headsize", dest="headsize", default=120,
					   action="store",  type="int",
					   help="Header Font size (points) - DEFAULT: 120")
	cmdline.add_option("--headweight", dest="headweight", default=800,
					   action="store",  type="int",
					   help="Header Font weight - DEFAULT 800, Roman is 400.")
	
	#verbosity
	cmdline.add_option("-q",  "--quite", dest="verbose",
					   action="store_false", default=True,
					   help="Turn of all textual output (runs quiet)"),

	(options, args) = cmdline.parse_args()

	#
	# Arg Checking is handled here.
	# Any Global Variables are set in Main Program
	#
	infile  = options.infile
	outfile = options.outfile
	linebrk = options.linebreak

	if not infile :
		cmdline.print_help()
		print "No Input File Specified"
		return False
	if not outfile :
		cmdline.print_help()
		print "No Output File Specified"
		return False

	if linebrk != "auto" and linebrk != "cr" and linebrk != "html" and \
	   linebrk != "tab"  and linebrk != "space" :
		cmdline.print_help()
		print "Incorrect line break option specified: -b ", linebrk
		return False

	if not os.path.exists(infile) :
		cmdline.print_help()
		print "Input File \"", infile, "\" does not exist"
		return False

	#
	# Return now if we are not using verbose mode
	# Everything is okay here, so returning true
	#
	if not options.verbose :
		return True

	#
	# Verbose statement of argument values
	#
	print "Infile:  ", infile
	print "Outfile: ", outfile
	print "Title:   ", options.title
	print "Author:  ", options.author

	print "Options:"
	print "\tText font size:   ", options.textsize
	print "\tText font wieght: ", options.textweight
	print "\tChapter Header font size:   ", options.headsize
	print "\tChapter Header font wieght: ", options.headweight

	if options.use_rdquotes:
		print "\tUsing explicit HTML curly-quotes (&rdquo;|&ldquo;)"
	else :
		print "\tIgnoring explicit HTML curly-quotes"

	if options.preserve_spaces :
		print "\tPreserving extra spaces between words"
	else :
		print "\tEliminating extra spaces between words"
	if linebrk == "auto" :
		print "\tParagraph Breaks will be determined automatically."
	else :
		print "\tParagraph Breaks determined by indentation with ", linebrk

	print

	return True

# enddef parse_cmdline()


#############################################################
# def pielrf():												#
#															#
#############################################################
def pielrf():

	global cmdline
	global preserve_spaces
	global use_rdquotes

	if not parse_cmdline() :
		return

	(cmdopts, cmdargs) = cmdline.parse_args()

	# Locals
	infile          = cmdopts.infile
	outfile         = cmdopts.outfile
	linebreak       = cmdopts.linebreak
	textweight      = cmdopts.textweight
	textsize        = cmdopts.textsize
	textweight      = cmdopts.textweight
	headsize        = cmdopts.headsize
	headweight      = cmdopts.headweight
	# Globals
	preserve_spaces = cmdopts.preserve_spaces
	use_rdquotes    = cmdopts.use_rdquotes
	verbose         = cmdopts.verbose

	#
	# Read whole file in all at once
	#
	f    = open(infile, 'rb')
	data = f.read()
	f.close()

#    hiTextStyle = TextStyle(parindent=-900, parskip=200)

	ps     = PageStyle(topmargin=50, textheight=710, textwidth=550)
	# This side margin matches Eragon from Connect Book Store
	bs     = BlockStyle(sidemargin=20)
	# 100 is default fontsize
#	ts     = TextStyle(parindent=200, fontsize=90, fontweight=500)
	# Standard Text style and a Center text style
	ts     = TextStyle(parindent=200, fontsize=textsize, fontweight=textweight)
	cs     = TextStyle(align="center",fontsize=textsize, fontweight=textweight)
	# No paragraph indent for Table of Contents
	tocTs  = TextStyle()
	# Chapter Header
	headTs = TextStyle(fontsize=headsize,fontweight=headweight,align="center")

	# create the book
	title       = cmdopts.title
	author      = cmdopts.author

	book = Book(title=title,
				author=(author, author),
				bookid="FB0123456", isbn="123-0-1234-5678-9",
				category="Fiction")

	#
	# Create Table Of contents Page.
	# This should be filled with buttons
	#
	tocPage = book.Page(ps)
	tocText = TextBlock(tocTs, bs)
	tocPage.append(tocText)
	book.addTocEntry(u"Table of Contents", tocText)
	tocText.Paragraph(Bold(u"Table of Contents"))
	tocText.Paragraph(CR())

	chapters = data.split("<chapter>")

	if verbose :
		print "Creating ", len(chapters), " Chapters..."

	#
	# For each Chapter
	# Dilineated by <chapter>
	#
	first = True
	for chapter in range(len(chapters)) :
		if len(chapters[chapter]) == 0 or chapters[chapter].isspace():
			continue

		#
		# Do not know how the paragraphs are delimited
		# Pick the one which yeilds the greatest amount of
		# total paragraphs in "auto" mode, otherwise use
		# the mode specified
		#
		list_cr    = chapters[chapter].split("\n\n")
		list_tab   = chapters[chapter].split("\n\t")
		list_spc   = chapters[chapter].split("\n  ")
		list_html  = chapters[chapter].split("<p>")
		list       = list_cr

		if   linebreak == "cr" :
			list     = list_cr
		elif linebreak == "tab" :
			list     = list_tab
		elif linebreak == "space" :
			list     = list_spc
		elif linebreak == "html" :
			list = list_html
			for i in range(len(list)):
				list[i] = list[i].replace("</p>","")
		elif linebreak == "auto" :
			list     = list_cr
			if len(list_tab) > len(list):
				list = list_tab
			if len(list_spc) > len(list):
				list = list_spc
			if len(list_html) > len(list) :
				list = list_html.replace("</p>","").replace("</P>","")

		#
		# The very first element is the name of the chapter, since
		# it had the <chapter> tag before it
		#
		if verbose :
			print "Chapter ", chapter, " has ", len(list), " paragraphs"

		#
		# Create the attributes for the page.
		# A chapter header, a separator, text for the chapter
		#
		page       = book.Page(ps)
		headBlock  = page.TextBlock(headTs, bs);
#		textBlock  = page.TextBlock(ts,     bs)

		#
		# Make a Button on the TOC Page for this chapter
		#
		buttonText = list[0].lstrip().rstrip()
		tocText.Paragraph(CharButton(JumpButton(headBlock), buttonText))

		#
		# Add TOC Entries
		#
		if first :
			book.addTocEntry("Begin Reading", headBlock)
			first = False
		book.addTocEntry(buttonText, headBlock)

		#
		# Now Parse Each Paragraph in the Chapter
		# The first Paragrah is the Chapter heading.
		#
		for i in range(len(list)):
			newstr   = make_curly_quotes(list[i].lstrip())
			newstr   = convert_misc(newstr)
			newstr   = convert_html_ampersands(newstr)
			finalstr = newstr
			if i == 0:
				headBlock.Paragraph(finalstr)
				textBlock = page.TextBlock(ts, bs)
				textBlock.Paragraph(CR())
			else :
				format_paragraph(page, ts, cs, bs, finalstr)
		# endfor

	#end for chapter in range(len(chapters)) :

	if verbose :
		print "Generating LRF..."

	# generate the lrf file
	book.renderLrf(outfile)

# enddef pielrf()


if __name__ == "__main__":
    pielrf()
