Updates from Gary Shao

svn: r1136
This commit is contained in:
Don Allingham 2002-09-12 03:58:47 +00:00
parent a61f2fa931
commit c9d04c8311
5 changed files with 1728 additions and 310 deletions

View File

@ -3,6 +3,51 @@
#
# Copyright (C) 2000 Donald N. Allingham
#
# Modified August 2002 by Gary Shao
#
# Removed Gramps dependencies.
#
# Removed dependencies on Gnome UI.
#
# Moved call to build_style_declaration() out of __init__ method and
# into open method to allow cell table styles to get emitted in HTML.
#
# Added style entry for underlined text in HTML output
#
# Changed statements which constructed paths using "%s/%s" string
# formatting into ones using the os.path.join function to give better
# cross-platform compatibility.
#
# Allowed table width to default to 0, which causes output table
# to have column widths that are automatically sized to the length
# of their contents.
#
# Added support for start_bold() and end_bold() methods of TextDoc
# class for inline bolding of text.
#
# Modified open() and close() methods to allow the filename parameter
# passed to open() to be either a string containing a file name, or
# a Python file object. This allows the document generator to be more
# easily used with its output directed to stdout, as may be called for
# in a CGI script.
#
# Modified September 2002 by Gary Shao
#
# Changed implicit conversion of '\n' character to <br> command in
# write_text() to instead require an explicit call to line_break()
# for insertion of <br> into text. This makes the paragraph behavior
# a better match for that of other document generators.
#
# Added start_listing() and end_listing() methods to allow displaying
# text blocks without automatic filling and justification. Intended
# for printing things like source code and plain text graphics.
#
# Added support for start_italic() and end_italic() methods of TextDoc
# class for inline italicizing of text.
#
# Added method show_link() to display a link as an anchor.
# This method really only has an active role in the HTML generator.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@ -23,20 +68,27 @@ import string
import re
import time
import gnome.ui
import Plugins
import ImgManip
import TarFile
import const
from TextDoc import *
from intl import gettext
_ = gettext
try:
import gnome.ui
import Plugins
import const
from intl import gettext
_ = gettext
except:
withGramps = 0
Version = "1.0"
else:
withGramps = 1
t_header_line_re = re.compile(r"(.*)<TITLE>(.*)</TITLE>(.*)",
re.DOTALL|re.IGNORECASE|re.MULTILINE)
#------------------------------------------------------------------------
#
# Default template
@ -85,10 +137,9 @@ class HtmlDoc(TextDoc):
self.filename = None
self.top = []
self.bottom = []
self.base = ""
self.base = "."
self.load_template()
self.build_header()
self.build_style_declaration()
self.image_dir = "images"
else:
self.owner = source.owner
@ -146,7 +197,11 @@ class HtmlDoc(TextDoc):
if top_add == 1:
mymsg = _("The marker '<!-- START -->' was not in the template")
gnome.ui.GnomeErrorDialog(mymsg)
if withGramps:
gnome.ui.GnomeErrorDialog(mymsg)
else:
print mymsg
raise "TemplateError: No START marker"
def load_html(self):
start = re.compile(r"<!--\s*START\s*-->")
@ -171,7 +226,11 @@ class HtmlDoc(TextDoc):
if top_add == 1:
mymsg = _("The marker '<!-- START -->' was not in the template")
gnome.ui.GnomeErrorDialog(mymsg)
if withGramps:
gnome.ui.GnomeErrorDialog(mymsg)
else:
print mymsg
raise "TemplateError: No START marker"
def load_template(self):
if self.template:
@ -184,13 +243,19 @@ class HtmlDoc(TextDoc):
mymsg = _("Could not open %s\nUsing the default template") % \
self.template
mymsg = "%s\n%s" % (mymsg,msg)
gnome.ui.GnomeWarningDialog(mymsg)
if withGramps:
gnome.ui.GnomeWarningDialog(mymsg)
else:
print mymsg
self.bottom = _bottom
self.top = _top
except:
mymsg = _("Could not open %s\nUsing the default template") % \
self.template
gnome.ui.GnomeWarningDialog(mymsg)
if withGramps:
gnome.ui.GnomeWarningDialog(mymsg)
else:
print mymsg
self.bottom = _bottom
self.top = _top
else:
@ -198,20 +263,29 @@ class HtmlDoc(TextDoc):
self.top = _top
def process_line(self,line):
l = string.replace(line,'$VERSION',const.version)
if withGramps:
l = string.replace(line,'$VERSION',const.version)
else:
l = string.replace(line,'$VERSION',Version)
return string.replace(l,'$COPYRIGHT',self.copyright)
def open(self,filename):
(r,e) = os.path.splitext(filename)
if e == self.ext:
self.filename = filename
else:
self.filename = filename + self.ext
if type(filename) == type(""):
(r,e) = os.path.splitext(filename)
if e == self.ext:
self.filename = filename
else:
self.filename = filename + self.ext
self.base = os.path.dirname(self.filename)
self.base = os.path.dirname(self.filename)
self.f = open(self.filename,"w")
self.f = open(self.filename,"w")
self.alreadyOpen = 0
elif hasattr(filename, "write"):
self.f = filename
self.alreadyOpen = 1
self.f.write(self.file_header)
self.build_style_declaration()
self.f.write(self.style_declaration)
def build_header(self):
@ -265,11 +339,13 @@ class HtmlDoc(TextDoc):
if style.get_right_border():
right = 'thin solid #000000'
italic = bold = ''
italic = bold = underline = ''
if font.get_italic():
italic = 'font-style:italic; '
if font.get_bold():
bold = 'font-weight:bold; '
if font.get_underline():
underline = 'text-decoration:underline; '
if font.get_type_face() == FONT_SANS_SERIF:
family = '"Helvetica","Arial","sans-serif"'
else:
@ -281,12 +357,12 @@ class HtmlDoc(TextDoc):
'\tmargin-right: %scm; margin-left: %scm;\n'
'\tborder-top:%s; border-bottom:%s;\n'
'\tborder-left:%s; border-right:%s;\n'
'\t%s%sfont-family:%s;\n}'
'\t%s%s%sfont-family:%s;\n}'
% (key, font_size, font_color,
align, text_indent,
right_margin, left_margin,
top, bottom, left, right,
italic, bold, family))
italic, bold, underline, family))
text.append('-->\n</style>')
self.style_declaration = string.join(text,'\n')
@ -294,14 +370,15 @@ class HtmlDoc(TextDoc):
def close(self):
for line in self.bottom:
self.f.write(self.process_line(line))
self.f.close()
if not self.alreadyOpen:
self.f.close()
def write_support_files(self):
if self.map:
for name in self.map.keys():
if name == 'template.html':
continue
fname = '%s/%s' % (self.base,name)
fname = '%s' % (os.path.join(self.base,name))
f = open(fname, 'wb')
f.write(self.map[name].read())
f.close()
@ -312,7 +389,10 @@ class HtmlDoc(TextDoc):
refname = "is%s" % os.path.basename(name)
if self.image_dir:
imdir = "%s/%s" % (self.base,self.image_dir)
if self.base:
imdir = "%s" % (os.path.join(self.base,self.image_dir))
else:
imdir = "%s" % (self.image_dir)
else:
imdir = self.base
@ -324,7 +404,7 @@ class HtmlDoc(TextDoc):
try:
img = ImgManip.ImgManip(name)
img.jpg_thumbnail("%s/%s" % (imdir,refname),size,size)
img.jpg_thumbnail("%s" % (os.path.join(imdir,refname)),size,size)
except:
return
@ -335,15 +415,23 @@ class HtmlDoc(TextDoc):
else:
xtra = ''
if pos == "center":
self.f.write('<center>')
if self.image_dir:
self.f.write('<img src="%s/%s" border="0""%s>\n' % \
(self.image_dir,refname,xtra))
self.f.write('<img src="%s" border="0"%s>' % \
(os.path.join(self.image_dir,refname),xtra))
else:
self.f.write('<img src="%s" border="0""%s>\n' % (refname,xtra))
self.f.write('<img src="%s" border="0"%s>' % (refname,xtra))
if pos == "center":
self.f.write('</center>')
self.f.write('\n')
def start_table(self,name,style):
self.tbl = self.table_styles[style]
self.f.write('<table width="%d%%" ' % self.tbl.get_width())
if self.tbl.get_width() == 0:
self.f.write('<table ')
else:
self.f.write('<table width="%d%%" ' % self.tbl.get_width())
self.f.write('cellspacing="0">\n')
def end_table(self):
@ -362,7 +450,7 @@ class HtmlDoc(TextDoc):
if span > 1:
self.f.write(' colspan="' + str(span) + '"')
self.col = self.col + 1
else:
elif self.tbl.get_column_width(self.col) > 0:
self.f.write(' width="')
self.f.write(str(self.tbl.get_column_width(self.col)))
self.f.write('%"')
@ -374,6 +462,55 @@ class HtmlDoc(TextDoc):
def end_cell(self):
self.f.write('</td>\n')
def start_listing(self,style_name):
style = self.style_list[style_name]
font = style.get_font()
font_size = font.get_size()
font_color = '#%02x%02x%02x' % font.get_color()
right_margin = "%.2f" % style.get_right_margin()
left_margin = "%.2f" % style.get_left_margin()
top = bottom = left = right = 'none'
pad = "%.3fcm" % style.get_padding()
if style.get_top_border():
top = 'thin solid #000000'
if style.get_bottom_border():
bottom = 'thin solid #000000'
if style.get_left_border():
left = 'thin solid #000000'
if style.get_right_border():
right = 'thin solid #000000'
italic = bold = underline = ''
if font.get_italic():
italic = 'font-style:italic; '
if font.get_bold():
bold = 'font-weight:bold; '
if font.get_underline():
underline = 'text-decoration:underline; '
if font.get_type_face() == FONT_MONOSPACE:
family = 'Courier,monospace'
elif font.get_type_face() == FONT_SANS_SERIF:
family = 'Helvetica,Arial,sans-serif'
else:
family = 'Times New Roman,Times,serif'
styleStr = '<pre style="font-size: %dpt; color: %s;\n' % \
(font_size, font_color)
styleStr = styleStr + '\tpadding: %s %s %s %s;\n' % \
(pad, pad, pad, pad)
styleStr = styleStr + '\tmargin-right: %scm; margin-left: %scm;\n' % \
(right_margin, left_margin)
styleStr = styleStr + '\tborder-top:%s; border-bottom:%s;\n' % \
(top, bottom)
styleStr = styleStr + '\tborder-left:%s; border-right:%s;\n' % \
(left, right)
styleStr = styleStr + '\t%s%s%sfont-family:%s">\n' % \
(italic, bold, underline, family)
self.f.write(styleStr)
def end_listing(self):
self.f.write('</pre>\n')
def start_paragraph(self,style_name,leader=None):
self.f.write('<p class="' + style_name + '">')
if leader != None:
@ -389,7 +526,37 @@ class HtmlDoc(TextDoc):
def write_text(self,text):
if text != "":
self.empty = 0
text = string.replace(text,'\n','<br>')
#text = string.replace(text,'\n','<br>')
self.f.write(text)
Plugins.register_text_doc(_("HTML"),HtmlDoc,1,0,1)
def start_bold(self):
self.f.write('<b>')
def end_bold(self):
self.f.write('</b>')
def start_italic(self):
self.f.write('<i>')
def end_italic(self):
self.f.write('</i>')
def line_break(self):
self.f.write('<br>\n')
def show_link(self, text, href):
self.write_text(' <a href="%s">%s</a> ' % (href, text))
#------------------------------------------------------------------------
#
# Register the document generator with the system if in Gramps
#
#------------------------------------------------------------------------
if withGramps:
Plugins.register_text_doc(
name=_("HTML"),
classref=HtmlDoc,
table=1,
paper=0,
style=1
)

View File

@ -6,6 +6,57 @@
# Modifications and feature additions:
# 2002 Donald A. Peterson
#
# Modified August 2002 by Gary Shao
#
# Removed Gramps dependencies
#
# Added rightIndent, bottomBorder, and topBorder attributes to TexFont
# class in support of allowing these properties to be expressed when
# defining paragraphs.
#
# Completely changed the way paragraph margins are handled. Now use
# LaTeX \parbox command to create a paragraph region, and \hspace command
# to position it on the page. Old method ignored the right margin,
# and didn't seem to correctly handle left margins or first line
# indents.
#
# Replaced instances of \centerline command with use of \hspace*{\fill}
# to achieve centered text. This was particularly a problem inside
# tables, where LaTeX would occasionally reject the original output
# constructs.
#
# Enabled the use of underline font property.
#
# Enable the drawing of top and bottom paragraph borders using the
# LaTeX \rule command.
#
# Reworked the way table declarations were written to allow table
# width to be specified as a percentages of \textwidth and column
# widths as percentages of table width, in the spirit of how TextDoc
# intended. Table widths of 0 will result in tables that are sized
# automatically by LaTeX.
#
# Modified open() and close() methods to allow the filename parameter
# passed to open() to be either a string containing a file name, or
# a Python file object. This allows the document generator to be more
# easily used with its output directed to stdout, as may be called for
# in a CGI script.
#
# Modified August 2002 by Gary Shao
#
# Added line_break() and page_break() methods to LaTeXDoc class.
#
# Added two new methods (start_listing() and end_listing()) to
# enable writing a text block with no filling or justifying
# Implementation uses the fancyvrb package.
#
# Added new methods start_italic() and end_italic() to enable
# italicizing parts of text within a paragraph
#
# Added method show_link() to display in text the value of a link.
# This method really only has an active role in the HTML generator,
# but is provided here for interface consistency.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@ -29,10 +80,15 @@
#
#------------------------------------------------------------------------
from TextDoc import *
import Plugins
import ImgManip
import intl
_ = intl.gettext
try:
import Plugins
import intl
_ = intl.gettext
except:
withGramps = 0
else:
withGramps = 1
#------------------------------------------------------------------------
#
@ -45,12 +101,18 @@ class TexFont(TextDoc):
self.font_beg = style.font_beg
self.font_end = style.font_end
self.leftIndent = style.left_indent
self.rightIndent = style.right_indent
self.firstLineIndent = style.firstLineIndent
self.topBorder = style.topBorder
self.bottomBorder = style.bottomBorder
else:
self.font_beg = ""
self.font_end = ""
self.leftIndent = ""
self.rightIndent = ""
self.firstLineIndent = ""
self.topBorder = 0
self.bottomBorder = 0
#------------------------------------------------------------------------
#
@ -63,12 +125,16 @@ class LaTeXDoc(TextDoc):
def open(self,filename):
"""Opens the specified file, making sure that it has the
extension of .tex"""
if filename[-4:] != ".tex":
self.filename = filename + ".tex"
else:
self.filename = filename
self.f = open(self.filename,"w")
if type(filename) == type(""):
if filename[-4:] != ".tex":
self.filename = filename + ".tex"
else:
self.filename = filename
self.f = open(self.filename,"w")
self.alreadyOpen = 0
elif hasattr(filename, "write"):
self.f = filename
self.alreadyOpen = 1
# Font size control seems to be limited. For now, ignore
# any style constraints, and use 12pt has the default
@ -102,29 +168,33 @@ class LaTeXDoc(TextDoc):
self.f.write('\\usepackage{graphicx} % Extended graphics support\n')
self.f.write('\\usepackage{longtable} % For multi-page tables\n')
self.f.write('\\usepackage{calc} % For margin indents\n')
self.f.write('\\usepackage{fancyvrb} % For listing blocks\n')
self.f.write('%\n% Depending on your LaTeX installation, the')
self.f.write(' margins may be too\n% narrow. ')
self.f.write(' This can be corrected by uncommenting the following\n')
self.f.write('% two lines and adjusting the width appropriately.')
self.f.write(' The example\n% removes 0.5in from each margin.')
self.f.write(' (Adds 1 inch to the text)\n')
self.f.write('%\\addtolength{\\oddsidemargin}{-0.5in}\n')
self.f.write('%\\addtolength{\\textwidth}{1.0in}\n%\n')
self.f.write('% Create a margin-adjusting command that allows LaTeX\n')
self.f.write(' The example\n% removes 0.5in from the left margin.')
self.f.write(' (Adds 0.5 inch to the text)\n')
self.f.write('\\addtolength{\\oddsidemargin}{-0.5in}\n')
self.f.write('\\addtolength{\\textwidth}{0.5in}\n%\n')
self.f.write('\\setlength{\\parskip}{1.3ex plus0.5ex minus0.5ex}\n')
self.f.write('% Create a first indent-adjusting command that allows LaTeX\n')
self.f.write('% to behave like the other gramps-supported output formats\n')
self.f.write('\\newlength{\\leftedge}\n')
self.f.write('\\setlength{\\leftedge}{\\parindent}\n')
self.f.write('\\newlength{\\grampstext}\n')
self.f.write('\\setlength{\\grampstext}{\\textwidth}\n')
self.f.write('\\newcommand{\\grampsindent}[1]{%\n')
self.f.write(' \\setlength{\\parindent}{\\leftedge + #1}%\n')
self.f.write(' \\setlength{\\textwidth}{\\grampstext - #1}%\n')
self.f.write('\\setlength{\\parindent}{0cm}\n')
self.f.write('\\newlength{\\newwidth}\n')
self.f.write('\\newcommand{\\grampsfirst}[1]{%\n')
self.f.write(' \\setlength{\\parindent}{#1}%\n')
self.f.write('}\n\n')
self.f.write('\\begin{document}\n\n')
self.in_list = 0
self.in_table = 0
self.imagenum = 0
self.in_cell = 0
self.cell_header_written = 0
self.last_indent = 0
self.fix_first = 0
self.in_listing = 0
#Establish some local styles for the report
self.latexstyle = {}
@ -143,10 +213,11 @@ class LaTeXDoc(TextDoc):
# Is there special alignment? (default is left)
align = style.get_alignment_text()
if align == "center":
thisstyle.font_beg = thisstyle.font_beg + "\\centerline{"
thisstyle.font_end = "}" + thisstyle.font_end
thisstyle.font_beg = thisstyle.font_beg + "\\hspace*{\\fill}"
#thisstyle.font_end = "}" + thisstyle.font_end
thisstyle.font_end = "\\hspace*{\\fill}" + thisstyle.font_end
elif align == "right":
thisstyle.font_beg = thisstyle.font_beg + "\\hfill"
thisstyle.font_beg = thisstyle.font_beg + "\\hspace*{\\fill}"
# Establish font face and shape
if font.get_type_face() == FONT_SANS_SERIF:
@ -155,7 +226,7 @@ class LaTeXDoc(TextDoc):
if font.get_bold():
thisstyle.font_beg = thisstyle.font_beg + "\\bfseries"
thisstyle.font_end = "\\mdseries" + thisstyle.font_end
if font.get_italic() or font.get_underline():
if font.get_italic():
thisstyle.font_beg = thisstyle.font_beg + "\\itshape"
thisstyle.font_end = "\\upshape" + thisstyle.font_end
@ -189,15 +260,24 @@ class LaTeXDoc(TextDoc):
if sflag == 1:
thisstyle.font_end = thisstyle.font_end + "\\normalsize"
if font.get_underline():
thisstyle.font_beg = thisstyle.font_beg + "\\underline{"
thisstyle.font_end = "}" + thisstyle.font_end
thisstyle.font_beg = thisstyle.font_beg + " "
thisstyle.font_end = thisstyle.font_end + " "
left = style.get_left_margin()
right = style.get_right_margin()
first = style.get_first_indent() + left
first = style.get_first_indent()
topborder = style.get_top_border()
bottomborder = style.get_bottom_border()
thisstyle.leftIndent = left
thisstyle.rightIndent = right
thisstyle.firstLineIndent = first
thisstyle.topBorder = topborder
thisstyle.bottomBorder = bottomborder
self.latexstyle[style_name] = thisstyle
@ -208,7 +288,8 @@ class LaTeXDoc(TextDoc):
if self.in_list:
self.f.write('\\end{enumerate}\n')
self.f.write('\n\\end{document}\n')
self.f.close()
if not self.alreadyOpen:
self.f.close()
def start_page(self,orientation=None):
"""Nothing needs to be done to start a page"""
@ -218,25 +299,129 @@ class LaTeXDoc(TextDoc):
"""Issue a new page command"""
self.f.write('\\newpage')
def start_listing(self, style_name):
"""Set up parameters for Verbatim environment of fancyvrb package"""
style = self.style_list[style_name]
font = style.get_font()
size = font.get_size()
# Determine font family
if font.get_type_face() == FONT_MONOSPACE:
family = "courier"
elif font.get_type_face() == FONT_SANS_SERIF:
family = "helvetica"
else:
family = "tt"
# Now determine font size
if size >= 22:
size = "\\Huge"
elif size >= 20:
size = "\\huge"
elif size >= 18:
size = "\\LARGE"
elif size >= 16:
size = "\\Large"
elif size >= 14:
size = "\\large"
elif size < 8:
size = "\\scriptsize"
elif size < 10:
size = "\\footnotesize"
elif size < 12:
size = "\\small"
else:
size = "\\normalsize"
if font.get_bold():
series = 'b'
else:
series = 'm'
if font.get_italic():
shape = 'it'
else:
shape = 'n'
leftMargin = style.get_left_margin()
rightMargin = style.get_right_margin()
if style.get_top_border() and style.get_bottom_border():
if style.get_left_border() and style.get_right_border():
frame = "single"
else:
frame = "lines"
elif style.get_top_border():
frame = "topline"
elif style.get_bottom_border():
frame = "bottomline"
else:
frame = ""
self.f.write("\\begin{Verbatim}%\n")
self.f.write(" [fontfamily=%s,\n" % family)
self.f.write(" fontsize=%s,\n" % size)
self.f.write(" fontshape=%s,\n" % shape)
self.f.write(" fontseries=%s,\n" % series)
if frame:
self.f.write(" frame=%s,\n" % frame)
self.f.write(" xleftmargin=%.2fcm,\n" % leftMargin)
self.f.write(" xrightmargin=%.2fcm]\n" % rightMargin)
self.last_char_written = '\n'
self.in_listing = 1
def end_listing(self):
if self.last_char_written != '\n':
self.f.write('\n')
self.f.write('\\end{Verbatim}\n')
self.in_listing = 0
def start_paragraph(self,style_name,leader=None):
"""Paragraphs handling - A Gramps paragraph is any
single body of text, from a single word, to several sentences.
We assume a linebreak at the end of each paragraph."""
style = self.style_list[style_name]
# Patch to get alignment in table cells working properly
alignment = style.get_alignment()
if alignment == PARA_ALIGN_RIGHT:
self.cell_para_align = 'r'
elif alignment == PARA_ALIGN_CENTER:
self.cell_para_align = 'c'
else:
self.cell_para_align = 'l'
if self.in_cell and not self.cell_header_written:
if self.llist == 1:
cellfmt = "p{\linewidth-3cm}"
elif self.tablewidth:
width = 0.0
for i in range(self.cell_span):
width = width + self.colwidths[self.cell_cnt + i]
cellfmt = "p{%.2f\\textwidth}" % (width * 0.95)
else:
cellfmt = self.cell_para_align
# Account for vertical rules
if self.lborder == 1:
cellfmt = '|' + cellfmt
if self.rborder == 1:
cellfmt = cellfmt + '|'
if self.tborder != 0 and self.cell_cnt == 0:
self.f.write('\\hline ')
self.f.write ('\\multicolumn{%d}{%s}{' % (self.cell_span,cellfmt))
self.cell_header_written = 1
ltxstyle = self.latexstyle[style_name]
self.level = style.get_header_level()
self.fbeg = ltxstyle.font_beg
self.fend = ltxstyle.font_end
self.indent = ltxstyle.leftIndent
self.rightmargin = ltxstyle.rightIndent
self.FLindent = ltxstyle.firstLineIndent
self.TBorder = ltxstyle.topBorder
self.BBorder = ltxstyle.bottomBorder
if self.indent != None and not self.in_table:
myspace = '%scm' % str(self.indent)
self.f.write('\\grampsindent{%s}\n' % myspace)
self.fix_indent = 1
# Adjust the first line indent if needed
if self.FLindent != self.last_indent and not self.in_table:
self.last_indent = self.FLindent
myspace = '%scm' % str(self.FLindent)
self.f.write('\\grampsfirst{%s}\n' % myspace)
self.fix_first = 1
if leader != None and not self.in_list:
self.f.write('\\begin{enumerate}\n')
@ -249,11 +434,31 @@ class LaTeXDoc(TextDoc):
if leader == None and not self.in_list and not self.in_table:
self.f.write('\n')
self.f.write('%s ' % self.fbeg)
# Patch for special handling of cell contents
font_begin = self.fbeg
if self.in_cell:
if not self.tablewidth and string.find(font_begin, '\\hspace*{\\fill}') == 0:
font_begin = font_begin[15:]
# Use parbox command to simulate left and right margins if needed
# Use rule element to make top border if needed
else:
boxcmd = ""
if self.indent or self.rightmargin:
boxcmd = "\\setlength{\\newwidth}{\\textwidth - %.2fcm}" % \
float(self.indent + self.rightmargin)
boxcmd = boxcmd + "\\hspace*{%.2fcm}\n" % float(self.indent)
boxcmd = boxcmd + "\\parbox{\\newwidth}{"
if self.TBorder:
boxcmd = boxcmd + "\\vspace{0.5ex}\\rule{\\newwidth}{0.5pt}\\newline\n"
elif self.TBorder:
boxcmd = boxcmd + "\\rule{\\textwidth}{0.5pt}\\newline\n"
font_begin = boxcmd + font_begin
self.f.write('%s ' % font_begin)
def end_paragraph(self):
"""End the current paragraph"""
newline = '\ \\newline\n'
#newline = '\ \\newline\n'
newline = '\n'
if self.in_list:
self.in_list = 0
@ -263,10 +468,27 @@ class LaTeXDoc(TextDoc):
elif self.in_table:
newline = ('')
self.f.write('%s%s' % (self.fend,newline))
if self.fix_indent == 1:
self.fix_indent = 0
self.f.write('\\grampsindent{0cm}\n')
# Draw bottom border and close parbox command if needed
if not self.in_cell:
if self.BBorder:
if (self.indent or self.rightmargin):
newline = newline + "\\ \\newline\\rule[0.5\\baselineskip]{\\newwidth}{0.5pt}\n"
newline = newline + '}\n'
else:
newline = newline + "\\ \\newline\\rule[0.5\\baselineskip]{\\textwidth}{0.5pt}\n"
elif self.indent or self.rightmargin:
newline = newline + '}\n'
# Patch for special handling of cell contents
font_end = self.fend
if self.in_cell:
if not self.tablewidth and string.find(font_end, '\\hspace*{\\fill}') == 0:
font_end = font_end[15:]
self.f.write('%s%s' % (font_end,newline))
if self.fix_first == 1:
self.last_indent = 0
self.fix_first = 0
self.f.write('\\grampsfirst{0cm}\n')
def start_bold(self):
"""Bold face"""
@ -276,16 +498,35 @@ class LaTeXDoc(TextDoc):
"""End bold face"""
self.f.write('}')
def start_italic(self):
"""Italic face"""
self.f.write('\\textit{')
def end_italic(self):
"""End italic face"""
self.f.write('}')
def start_table(self,name,style_name):
"""Begin new table"""
self.in_cell = 0
self.cell_header_written = 0
self.in_table = 1
self.currow = 0
# We need to know a priori how many columns are in this table
self.tblstyle = self.table_styles[style_name]
self.numcols = self.tblstyle.get_columns()
tblfmt = '*{%d}{l}' % self.numcols
self.tablewidth = self.tblstyle.get_width()
if self.tablewidth:
self.colwidths = []
tblfmt = ""
for i in range(self.numcols):
width = self.tblstyle.get_column_width(i)
mult = float(width * self.tablewidth) / 10000.0
self.colwidths.append(mult)
tblfmt = tblfmt + "p{%.2f\\textwidth}" % (mult * 0.95)
else:
tblfmt = '*{%d}{l}' % self.numcols
self.f.write('\n\n\\begin{longtable}[l]{%s}\n' % tblfmt)
def end_table(self):
@ -297,6 +538,7 @@ class LaTeXDoc(TextDoc):
def start_row(self):
"""Begin a new row"""
# doline/skipfirst are flags for adding hor. rules
self.cell_cnt = -1
self.doline = 0
self.skipfirst = 0
self.curcol = 0
@ -317,6 +559,10 @@ class LaTeXDoc(TextDoc):
"""Add an entry to the table.
We always place our data inside braces
for safety of formatting."""
self.cell_cnt = self.cell_cnt + 1
self.in_cell = 1
self.cell_span = span
self.cell_header_written = 0
self.colspan = span
self.curcol = self.curcol + self.colspan
@ -327,16 +573,22 @@ class LaTeXDoc(TextDoc):
self.tborder = self.cstyle.get_top_border()
self.llist = self.cstyle.get_longlist()
if self.llist == 1:
cellfmt = "p{\linewidth-3cm}"
else:
cellfmt = "l"
# Patched out - functionality moved to start of paragraph
# because we have to wait until then to find out the
# alignment properties of the paragraph which is the
# contents of the cell
##if self.llist == 1:
## cellfmt = "p{\linewidth-3cm}"
##else:
## cellfmt = self.cell_para_align
##self.cellfmt = cellfmt
# Account for vertical rules
if self.lborder == 1:
cellfmt = '|' + cellfmt
if self.rborder == 1:
cellfmt = cellfmt + '|'
## Account for vertical rules
##if self.lborder == 1:
## cellfmt = '|' + cellfmt
##if self.rborder == 1:
## cellfmt = cellfmt + '|'
# and Horizontal rules
if self.bborder == 1:
@ -344,12 +596,14 @@ class LaTeXDoc(TextDoc):
elif self.curcol == 1:
self.skipfirst = 1
if self.tborder != 0:
self.f.write('\\hline\n')
self.f.write ('\\multicolumn{%d}{%s}{' % (span,cellfmt))
##if self.tborder != 0:
## self.f.write('\\hline\n')
##self.f.write ('\\multicolumn{%d}{%s}{' % (span,cellfmt))
def end_cell(self):
"""Prepares for next cell"""
self.in_cell = 0
self.cell_header_written = 0
self.f.write('} ')
if self.curcol < self.numcols:
self.f.write('& ')
@ -364,29 +618,45 @@ class LaTeXDoc(TextDoc):
# x and y will be maximum width OR height in units of cm
mysize = 'width=%dcm,height=%dcm,keepaspectratio' % (x,y)
if pos == "right":
self.f.write('\\hfill\\includegraphics[%s]{%s}\n' % (mysize,picf))
self.f.write('\\hspace*{\\fill}\\includegraphics[%s]{%s}\n' % (mysize,picf))
elif pos == "left":
self.f.write('\\includegraphics[%s]{%s}\\hfill\n' % (mysize,picf))
self.f.write('\\includegraphics[%s]{%s}\\hspace*{\\fill}\n' % (mysize,picf))
else:
self.f.write('\\centerline{\\includegraphics[%s]{%s}}\n' % (mysize,picf))
self.f.write('\\hspace*{\\fill}\\includegraphics[%s]{%s}\hspace*{\\fill}\n' % (mysize,picf))
def write_text(self,text):
"""Write the text to the file"""
if text == '\n':
text = '\\newline\n'
text = string.replace(text,'#','\#')
if not self.in_listing:
if text == '\n':
text = '\\newline\n'
text = string.replace(text,'#','\#')
self.f.write(text)
if text:
self.last_char_written = text[-1]
def line_break(self):
self.f.write('\\newline\n')
def page_break(self):
self.f.write('\\newpage\n')
def show_link(self, text, href):
self.write_text("%s (" % text)
self.start_italic()
self.write_text(href)
self.end_italic()
self.write_text(") ")
#------------------------------------------------------------------------
#
# Register the document generator with the system
# Register the document generator with the system if in Gramps
#
#------------------------------------------------------------------------
Plugins.register_text_doc(
name=_("LaTeX"),
classref=LaTeXDoc,
table=1,
paper=1,
style=0
)
if withGramps:
Plugins.register_text_doc(
name=_("LaTeX"),
classref=LaTeXDoc,
table=1,
paper=1,
style=1
)

View File

@ -0,0 +1,620 @@
#
# Copyright (C) 2002 Gary Shao
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""nroff/groff document generator"""
#------------------------------------------------------------------------
#
# gramps modules
#
#------------------------------------------------------------------------
from TextDoc import *
try:
import Plugins
import intl
_ = intl.gettext
except:
withGramps = 0
else:
withGramps = 1
#------------------------------------------------------------------------
#
# Paragraph Handling
#
#------------------------------------------------------------------------
class RoffParastyle:
def __init__(self, style=None):
if style:
self.fontSize = style.fontSize
self.fontFamily = style.fontFamily
self.leftIndent = style.left_indent
self.rightIndent = style.right_indent
self.firstLineIndent = style.firstLineIndent
self.topBorder = style.topBorder
self.bottomBorder = style.bottomBorder
self.leftBorder = style.leftBorder
self.rightBorder = style.rightBorder
self.align = style.align
else:
self.fontSize = 12
self.fontFamily = "R"
self.leftIndent = 0.0
self.rightIndent = 0.0
self.firstLineIndent = 0.0
self.topBorder = 0
self.bottomBorder = 0
self.leftBorder = 0
self.rightBorder = 0
self.align = "left"
# Standard paper sizes, width x height (cm)
PaperSizes = {"Letter" : (21.6,27.9),
"Legal" : (21.6,35.6),
"Executive" : (19.0,25.4),
"Ledger" : (27.9,43.2),
"A" : (21.6,27.9),
"B" : (27.9,43.2),
"C" : (43.2,55.9),
"D" : (55.9,86.4),
"E" : (86.4,111.8),
"A1" : (59.4,84.1),
"A2" : (42.0,59.4),
"A3" : (29.7,42.0),
"A4" : (21.0,29.7),
"A5" : (14.8,21.0),
"A6" : (10.5,14.8),
"A7" : (7.4,10.5),
"A8" : (5.2,7.4),
"B4" : (25.0,35.3),
"B5" : (17.6,25.0),
"B6" : (12.5,17.6),
}
#------------------------------------------------------------------------
#
# NroffDoc
#
#------------------------------------------------------------------------
class NroffDoc(TextDoc):
"""Nroff document interface class. Derived from TextDoc"""
def open(self,filename):
"""Opens the specified file, making sure that it has the
extension of .rof"""
if type(filename) == type(""):
if filename[-4:] != ".rof":
self.filename = filename + ".rof"
else:
self.filename = filename
self.f = open(self.filename,"w")
self.alreadyOpen = 0
elif hasattr(filename, "write"):
self.f = filename
self.alreadyOpen = 1
if self.orientation == PAPER_LANDSCAPE:
options = options + ",landscape"
# If the user picks something not listed above, we'll just accept
# the default of American letter size.
if self.paper.name == "Terminal":
self.paperWidth = 80
self.paperHeight = 24
elif self.paper.name == "Text":
self.paperWidth, self.paperHeight = PaperSizes["Letter"]
elif self.paper.name in PaperSizes.keys():
self.paperWidth, self.paperHeight = PaperSizes[self.paper.name]
else:
self.paperWidth, self.paperHeight = PaperSizes["Letter"]
# Write any generator-supplied macros
# Macros and traps to set 1in. top and bottom page margins
self.f.write('.de hd\n')
self.f.write('\'sp 0.5i\n')
self.f.write('..\n')
self.f.write('\'bp\n')
self.f.write('..\n')
self.f.write('.wh 0 hd\n')
self.f.write('.wh -1i fo\n')
# Macros for drawing parts of paragraph border
# Top side
self.f.write('.de tb\n')
self.f.write('.nr b \\\\n(.lu-\\\\n(.iu\n')
self.f.write('.sp -1\n')
self.f.write('.nf\n')
self.f.write('\\h\'-.5n\'\\v\'|\\\\nau-1\'\\l\'\\\\nbu+1n\\(em\'\\v\'-|\\\\nau+1\'\\h\'|0u-.5n\'\n')
self.f.write('.fi\n')
self.f.write('..\n')
# Bottom side
self.f.write('.de bb\n')
self.f.write('.nr b \\\\n(.lu-\\\\n(.iu\n')
self.f.write('.nf\n')
self.f.write('\\h\'-.5n\'\\l\'\\\\nbu+1n\\(em\'\\h\'|0u-.5n\'\n')
self.f.write('.fi\n')
self.f.write('..\n')
# Macro for beginning a new paragraph
self.f.write('.de pg\n')
self.f.write('.br\n')
self.f.write('.ft \\\\$1\n')
self.f.write('.ps \\\\$2\n')
self.f.write('.vs \\\\$3\n')
self.f.write('.in \\\\$4\n')
self.f.write('.ti \\\\$5\n')
self.f.write('.ll \\\\$6\n')
self.f.write('.sp 0.9\n')
self.f.write('.ne 1+\\n(.Vu\n')
self.f.write('.ad \\\\$7\n')
self.f.write('..\n')
# Set up an initial choice of font
self.f.write('.ft R\n')
self.f.write('.ps 12\n')
# Set the page parameters
# Page length
if self.paper.name == "Terminal":
self.f.write('.pl %dv\n' % self.paperHeight)
else:
self.f.write('.pl %.2fc\n' % self.paperHeight)
# Start with a 1in. left and right margin unless targeting a terminal
self.origLineLength = self.paperWidth - 5.08
if self.paper.name == "Terminal":
self.origLineLength = self.paperWidth
self.f.write('.po 0\n')
self.f.write('.ll %dm\n' % self.origLineLength)
else:
self.page_offset = 2.54
self.right_offset = 2.54
self.origLineLength = self.paperWidth - self.page_offset - self.right_offset
self.f.write('.po %.2fc\n' % self.page_offset)
self.f.write('.ll %.2fc\n' % (self.origLineLength))
self.in_list = 0
self.in_paragraph = 0
self.in_table = 0
self.in_cell = 0
self.cell_header_written = 0
self.last_indent = 0
self.fix_first = 0
self.tabchar = '~' # separator for table cell data
#Establish some local styles for the report
self.roffstyle = {}
for style_name in self.style_list.keys():
style = self.style_list[style_name]
font = style.get_font()
size = font.get_size()
thisstyle = RoffParastyle()
# Is there special alignment? (default is left)
align = style.get_alignment_text()
if align == "center":
thisstyle.align = "center"
elif align == "right":
thisstyle.align = "right"
else:
thisstyle.align = "left"
# Establish font face and shape
if self.paper.name == "Terminal" or self.paper.name == "Text":
if font.get_bold():
if font.get_italic():
thisstyle.fontFamily = 'BI'
else:
thisstyle.fontFamily = 'B'
else:
if font.get_italic():
thisstyle.fontFamily = 'I'
else:
thisstyle.fontFamily = 'R'
elif font.get_type_face() == FONT_MONOSPACE:
if font.get_bold():
if font.get_italic():
thisstyle.fontFamily = 'CBI'
else:
thisstyle.fontFamily = 'CB'
else:
if font.get_italic():
thisstyle.fontFamily = 'CI'
else:
thisstyle.fontFamily = 'CR'
elif font.get_type_face() == FONT_SANS_SERIF:
if font.get_bold():
if font.get_italic():
thisstyle.fontFamily = 'HBI'
else:
thisstyle.fontFamily = 'HB'
else:
if font.get_italic():
thisstyle.fontFamily = 'HI'
else:
thisstyle.fontFamily = 'HR'
else:
if font.get_bold():
if font.get_italic():
thisstyle.fontFamily = 'TBI'
else:
thisstyle.fontFamily = 'TB'
else:
if font.get_italic():
thisstyle.fontFamily = 'TI'
else:
thisstyle.fontFamily = 'TR'
# Now determine font size
thisstyle.fontSize = size
# And add the other paragraph attributes
thisstyle.leftIndent = style.get_left_margin()
thisstyle.rightIndent = style.get_right_margin()
thisstyle.firstLineIndent = style.get_first_indent()
thisstyle.topBorder = style.get_top_border()
thisstyle.bottomBorder = style.get_bottom_border()
thisstyle.leftBorder = style.get_left_border()
thisstyle.rightBorder = style.get_right_border()
self.roffstyle[style_name] = thisstyle
def close(self):
"""Close the document if needed"""
if not self.alreadyOpen:
self.f.close()
def start_page(self,orientation=None):
"""Nothing needs to be done to start a page"""
pass
def end_page(self):
"""Issue a new page command"""
self.f.write('.bp\n')
def start_listing(self,style_name):
"""Listing handling"""
alignment = 'l'
self.current_style = style_name
style = self.roffstyle[style_name]
linelength = self.paperWidth - self.page_offset - self.right_offset
linelength = linelength - style.rightIndent
self.lineLength = linelength
self.f.write('.pg %s %d %d %.2fc %.2fc %.2fc %s\n' % \
(style.fontFamily, style.fontSize, style.fontSize+2,
style.leftIndent, style.leftIndent,
linelength, alignment))
if style.topBorder:
self.f.write('.sp 1\n')
self.f.write('.nf\n')
self.f.write('.na\n')
self.f.write('.mk a\n')
self.last_char_written = '\n'
def end_listing(self):
if self.last_char_written != '\n':
self.f.write('\n')
style = self.roffstyle[self.current_style]
if style.topBorder:
self.f.write('.tb\n')
if style.bottomBorder:
self.f.write('.bb\n')
def start_paragraph(self,style_name,leader=None):
"""Paragraph handling - A Gramps paragraph is any
single body of text, from a single word, to several sentences."""
self.current_style = style_name
style = self.roffstyle[style_name]
# Calculate table cell alignment and spacing
if style.align == "right":
alignment = 'r'
elif style.align == "center":
alignment = 'c'
else:
alignment = 'l'
self.cell_para_align = alignment
if self.in_cell and not self.cell_header_written:
if self.tablewidth:
width = self.colwidths[self.cell_cnt]
cellfmt = "%sw(%.2fc-1.5m)" % (self.cell_para_align, width)
else:
cellfmt = self.cell_para_align
cellfmt = cellfmt + "p%d" % style.fontSize
cellfmt = cellfmt + "f%s " % style.fontFamily
if self.cell_span > 1:
for i in range(1, self.cell_span):
cellfmt = cellfmt + " s"
# Account for vertical rules
rowformat = self.row_formatstr
end = len(rowformat) - 1
if end > -1:
lastformatchar = rowformat[end]
else:
lastformatchar = ""
if self.lborder == 1 and lastformatchar != '|':
cellfmt = '| ' + cellfmt
if self.rborder == 1:
cellfmt = cellfmt + ' |'
self.row_formatstr = self.row_formatstr + ' ' + cellfmt
self.cell_header_written = 1
if not self.in_cell:
linelength = self.paperWidth - self.page_offset - self.right_offset
linelength = linelength - style.rightIndent
self.lineLength = linelength
self.f.write('.pg %s %d %d %.2fc %.2fc %.2fc %s\n' % \
(style.fontFamily, style.fontSize, style.fontSize+2,
style.leftIndent, style.leftIndent+style.firstLineIndent,
linelength, alignment))
if style.topBorder:
self.f.write('.sp 1\n')
self.f.write('.fi\n')
self.f.write('.mk a\n')
self.last_char_written = '\n'
self.current_fontfamily = style.fontFamily
self.in_paragraph = 1
def end_paragraph(self):
if not self.in_cell and self.last_char_written != '\n':
self.f.write('\n')
if not self.in_cell:
style = self.roffstyle[self.current_style]
if style.topBorder:
self.f.write('.tb\n')
if style.bottomBorder:
self.f.write('.bb\n')
self.in_paragraph = 0
def start_italic(self):
"""Italic face inside a paragraph"""
if self.in_paragraph:
font = self.current_fontfamily
if 'I' not in font:
if font=='R':
newfont = 'I'
elif font =='B':
newfont = 'BI'
elif font[1]=='R':
newfont = font[0] + 'I'
else:
newfont = font[0] + 'BI'
if self.last_char_written != '\n':
self.f.write('\n.ft %s\n' % newfont)
else:
self.f.write('.ft %s\n' % newfont)
self.current_fontfamily = newfont
def end_italic(self):
"""End italic face inside a paragraph"""
if self.in_paragraph:
font = self.current_fontfamily
if 'I' in font:
if font=='I':
newfont = 'R'
elif font=='BI':
newfont = 'B'
elif len(font)==2 and font[1]=='I':
newfont = font[0] + 'R'
else:
newfont = font[0] + 'B'
if self.last_char_written != '\n':
self.f.write('\n.ft %s\n' % newfont)
else:
self.f.write('.ft %s\n' % newfont)
self.current_fontfamily = newfont
def start_bold(self):
"""Bold face inside a paragraph"""
if self.in_paragraph:
font = self.current_fontfamily
if 'B' not in font:
if font=='R':
newfont = 'B'
elif font =='I':
newfont = 'BI'
elif font[1]=='R':
newfont = font[0] + 'B'
else:
newfont = font[0] + 'BI'
if self.last_char_written != '\n':
self.f.write('\n.ft %s\n' % newfont)
else:
self.f.write('.ft %s\n' % newfont)
self.current_fontfamily = newfont
def end_bold(self):
"""End bold face inside a paragraph"""
if self.in_paragraph:
font = self.current_fontfamily
if 'B' in font:
if font=='B':
newfont = 'R'
elif font=='BI':
newfont = 'I'
elif len(font)==2 and font[1]=='B':
newfont = font[0] + 'R'
else:
newfont = font[0] + 'I'
if self.last_char_written != '\n':
self.f.write('\n.ft %s\n' % newfont)
else:
self.f.write('.ft %s\n' % newfont)
self.current_fontfamily = newfont
def start_table(self,name,style_name):
"""Begin new table"""
self.in_cell = 0
self.cell_header_written = 0
self.in_table = 1
self.first_row = 1
self.last_row_had_bottomborder = 0
# Reset the left indent and line length to original values
self.f.write('.in 0c\n')
self.f.write('.ll %.2fc\n' % self.origLineLength)
# Make the column separator character be the tilde when specifying
# data in each table cell
optionstr = "tab(%s)" % self.tabchar
# We need to know a priori how many columns are in this table
self.tblstyle = self.table_styles[style_name]
self.numcols = self.tblstyle.get_columns()
self.tablewidth = self.tblstyle.get_width()
if self.tablewidth:
self.colwidths = []
for i in range(self.numcols):
width = self.tblstyle.get_column_width(i)
mult = self.origLineLength * float(width * self.tablewidth) / 10000.0
self.colwidths.append(mult)
optionstr = optionstr + ";"
else:
optionstr = optionstr + ",center;"
self.f.write('.TS\n')
self.f.write('%s\n' % optionstr)
def end_table(self):
"""Close the table specification"""
self.in_table = 0
self.f.write('.TE\n')
def start_row(self):
"""Begin a new row"""
self.cell_cnt = -1
self.row_line_above = 1
self.row_line_below = 1
self.row_formatstr = ""
self.row_datastrs = []
def end_row(self):
"""End the row (new line)"""
# Write out the format string for the row if it is the first row,
# or make a continuation row specification if the format has changed
# from the last one
self.row_formatstr = self.row_formatstr + ".\n"
if self.first_row:
self.f.write(self.row_formatstr)
self.last_row_formatstr = self.row_formatstr
else:
if self.row_formatstr != self.last_row_formatstr:
self.f.write('.T&\n')
self.f.write(self.row_formatstr)
# Write a horizontal line if the row calls for a top border
# and any previous row did not already print a bottom border line
if self.row_line_above and not self.last_row_had_bottomborder:
self.f.write('_\n')
# Write out the row data
datastr = self.row_datastrs.pop(0)
self.f.write(datastr)
while len(self.row_datastrs) > 0:
self.f.write("%s%s" % (self.tabchar, self.row_datastrs.pop(0)))
self.f.write('\n')
# Write a horizontal line if the row calls for a bottom border
if self.row_line_below:
self.f.write('_\n')
self.last_row_had_bottomborder = 1
else:
self.last_row_had_bottomborder = 0
if self.first_row:
self.first_row = 0
def start_cell(self,style_name,span=1):
"""Add an entry to the table."""
self.cell_cnt = self.cell_cnt + 1
self.in_cell = 1
self.cell_span = span
self.cell_header_written = 0
self.cell_string = ""
self.cstyle = self.cell_styles[style_name]
self.lborder = self.cstyle.get_left_border()
self.rborder = self.cstyle.get_right_border()
self.bborder = self.cstyle.get_bottom_border()
if not self.bborder:
self.row_line_below = 0
self.tborder = self.cstyle.get_top_border()
if not self.tborder:
self.row_line_above = 0
# Wait until paragraph start to get paragraph attributes so
# that we can apply them to the cell format
def end_cell(self):
"""Adds the cell data string to the row data"""
self.in_cell = 0
self.cell_header_written = 0
if self.tablewidth:
width = self.colwidths[self.cell_cnt]
for i in range(1, self.cell_span):
width = width + self.colwidths[self.cell_cnt + i]
if (0.254 * len(self.cell_string)) > width:
self.cell_string = 'T{\n' + self.cell_string + '\nT}'
self.row_datastrs.append(self.cell_string)
def add_photo(self,name,pos,x,y):
pass
def write_text(self,text):
"""Write the text to the file"""
if self.in_cell:
self.cell_string = self.cell_string + text
else:
self.f.write(text)
if text:
self.last_char_written = text[-1]
def line_break(self):
if self.in_paragraph and self.last_char_written != '\n':
self.f.write('\n.br\n')
else:
self.f.write('.br\n')
self.last_char_written = '\n'
def page_break(self):
if self.in_paragraph and self.last_char_written != '\n':
self.f.write('\n.bp\n')
else:
self.f.write('.bp\n')
self.last_char_written = '\n'
def show_link(self, text, href):
self.write_text("%s (" % text)
self.start_italic()
self.write_text(href)
self.end_italic()
self.write_text(") ")
#------------------------------------------------------------------------
#
# Register the document generator with the system if in Gramps
#
#------------------------------------------------------------------------
if withGramps:
Plugins.register_text_doc(
name=_("nroff/groff"),
classref=NroffDoc,
table=1,
paper=1,
style=1
)

View File

@ -3,6 +3,45 @@
#
# Copyright (C) 2000 Donald N. Allingham
#
# Modified August 2002 by Gary Shao
#
# Removed Gramps dependencies.
#
# Finagled the import name of the TableStyle class from reportlab so
# that it doesn't conflict with TableStyle class name from TextDoc
# module. Reportlab version is now referenced as ReportlabTableStyle.
#
# Added two new derived classes (BoxedParagraphStyle, BoxedParagraph)
# to replace standard reportlab classes to allow for drawing a border
# around a Paragraph flowable.
#
# Added new derived class SpanTable to replace standard reportlab class
# Table. Allows for proper placement of text within a table cell which
# spans several columns.
#
# Modified open() and close() methods to allow the filename parameter
# passed to open() to be either a string containing a file name, or
# a Python file object. This allows the document generator to be more
# easily used with its output directed to stdout, as may be called for
# in a CGI script.
#
# Modified September 2002 by Gary Shao
#
# Added new derived class BoxedPreformatted to replace standard
# reportlab class Preformatted to allow for drawing a border around
# the flowable.
#
# Added new methods start_listing() and end_listing() for specifying
# a block of text that should be rendered without any filling or
# justification.
#
# Added new methods start_italic() and end_italic() to enable
# italicizing parts of text within a paragraph
#
# Added method show_link() to display in text the value of a link.
# This method really only has an active role in the HTML generator,
# but is provided here for interface consistency.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@ -24,10 +63,20 @@
#
#------------------------------------------------------------------------
from TextDoc import *
import Plugins
OldTableStyle = TableStyle #Make an alias for original TableStyle
#because reportlab.platypus.tables also
#has a TableStyle class whose name will
#cover up the one from the TextDoc module
import ImgManip
import intl
_ = intl.gettext
try:
import Plugins
import intl
_ = intl.gettext
except:
withGramps = 0
else:
withGramps = 1
#------------------------------------------------------------------------
#
@ -38,12 +87,165 @@ _ = intl.gettext
try:
import reportlab.platypus.tables
from reportlab.platypus import *
ReportlabTableStyle = reportlab.platypus.tables.TableStyle
TableStyle = OldTableStyle #Let TableStyle refer to the original class
from reportlab.lib.units import cm
from reportlab.lib.colors import Color
from reportlab.lib.colors import Color,black,white
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
import reportlab.lib.styles
except:
raise Plugins.MissingLibraries, _("The ReportLab modules are not installed")
if withGramps:
raise Plugins.MissingLibraries, _("The ReportLab modules are not installed")
else:
print "The ReportLab modules are not installed"
raise
#------------------------------------------------------------------------
#
# BoxedParagraphStyle
#
# Class derived from ParagraphStyle which adds four attributes
# (topBorder, bottomBorder, leftBorder, rightBorder). Allows
# for drawing border sides around a standard paragraph when using
# a BoxedParagraph flowable (see below).
#
#------------------------------------------------------------------------
class BoxedParagraphStyle(reportlab.lib.styles.ParagraphStyle):
defaults = {
'fontName':'Times-Roman',
'fontSize':10,
'leading':12,
'leftIndent':0,
'rightIndent':0,
'firstLineIndent':0,
'alignment':TA_LEFT,
'spaceBefore':0,
'spaceAfter':0,
'bulletFontName':'Times-Roman',
'bulletFontSize':10,
'bulletIndent':0,
'textColor': black,
'backColor':None,
'topBorder':0,
'bottomBorder':0,
'leftBorder':0,
'rightBorder':0
}
#------------------------------------------------------------------------
#
# BoxedParagraph
#
# Class derived from Paragraph which overrides the original drawing
# method with one which also allows for drawing the sides of a border
# around a Paragraph flowable.
#
#------------------------------------------------------------------------
class BoxedParagraph(Paragraph):
def draw(self):
self.drawPara2(self.debug)
def drawPara2(self, debug=0):
#call the original drawing method
self.drawPara(debug)
#stash some key facts locally for speed
canvas = self.canv
style = self.style
#if borders are called for, draw them
extra = 0.5 * style.leading
if style.bottomBorder:
canvas.line(style.leftIndent, 0.0-extra, self.width-style.rightIndent, 0.0-extra)
if style.topBorder:
canvas.line(style.leftIndent, self.height, self.width-style.rightIndent, self.height)
if style.leftBorder:
canvas.line(style.leftIndent, 0.0-extra, style.leftIndent, self.height)
if style.rightBorder:
canvas.line(self.width-style.rightIndent, 0.0-extra, self.width-style.rightIndent, self.height)
#------------------------------------------------------------------------
#
# BoxedPreformatted
#
# Class derived from Preformatted which overrides the original drawing
# method with one which also allows for drawing the sides of a border
# around a Preformatted flowable.
#
#------------------------------------------------------------------------
class BoxedPreformatted(Preformatted):
def draw(self):
cur_x = self.style.leftIndent
cur_y = self.height - self.style.fontSize
self.canv.addLiteral('%PreformattedPara')
if self.style.textColor:
self.canv.setFillColor(self.style.textColor)
tx = self.canv.beginText(cur_x, cur_y)
#set up the font etc.
tx.setFont( self.style.fontName,
self.style.fontSize,
self.style.leading)
for text in self.lines:
tx.textLine(text)
self.canv.drawText(tx)
#if borders are called for, draw them
style = self.style
canvas = self.canv
extra = 0.5 * style.leading
if style.bottomBorder:
canvas.line(style.leftIndent, 0.0-extra, self.width-style.rightIndent, 0.0-extra)
if style.topBorder:
canvas.line(style.leftIndent, self.height, self.width-style.rightIndent, self.height)
if style.leftBorder:
canvas.line(style.leftIndent, 0.0-extra, style.leftIndent, self.height)
if style.rightBorder:
canvas.line(self.width-style.rightIndent, 0.0-extra, self.width-style.rightIndent, self.height)
#------------------------------------------------------------------------
#
# SpanTable
#
# Class derived from Table which overrides the original __init__ method
# to allow one additional parameter (an array of integer values giving
# the span of each cell in a table), and overrides the draw method to
# adjust cell output when the cell spans several columns.
#
#------------------------------------------------------------------------
class SpanTable(reportlab.platypus.tables.Table):
def __init__(self, data, spandata, colWidths=None, rowHeights=None,
style=None, repeatRows=0, repeatCols=0, splitByRow=1,
emptyTableAction=None):
reportlab.platypus.tables.Table.__init__(self, data, colWidths,
rowHeights, style, repeatRows, repeatCols, splitByRow,
emptyTableAction)
self.span_data = spandata
def draw(self):
self._curweight = self._curcolor = self._curcellstyle = None
self._drawBkgrnd()
self._drawLines()
in_span = 0
span_cnt = 0
for row, rowstyle, rowpos, rowheight, rowspan in map(None, self._cellvalues, self._cellStyles, self._rowpositions[1:], self._rowHeights, self.span_data):
for cellval, cellstyle, colpos, colwidth, cellspan in map(None, row, rowstyle, self._colpositions[:-1], self._colWidths, rowspan):
if in_span:
span_cnt = span_cnt - 1
span_width = span_width + colwidth
if span_cnt:
continue
else:
cellval, cellstyle, colpos, rowpos, rowheight = save_data
self._drawCell(cellval, cellstyle, (colpos, rowpos), (span_width, rowheight))
in_span = 0
continue
if cellspan > 1:
in_span = 1
span_cnt = cellspan - 1
span_width = colwidth
save_data = (cellval, cellstyle, colpos, rowpos, rowheight)
continue
self._drawCell(cellval, cellstyle, (colpos, rowpos), (colwidth, rowheight))
#------------------------------------------------------------------------
#
@ -67,10 +269,13 @@ class GrampsDocTemplate(BaseDocTemplate):
class PdfDoc(TextDoc):
def open(self,filename):
if filename[-4:] != ".pdf":
self.filename = "%s.pdf" % filename
else:
self.filename = filename
if type(filename) == type(""):
if filename[-4:] != ".pdf":
self.filename = "%s.pdf" % filename
else:
self.filename = filename
elif hasattr(filename, "write"):
self.filename = filename
self.pagesize = (self.width*cm,self.height*cm)
@ -95,11 +300,23 @@ class PdfDoc(TextDoc):
style = self.style_list[style_name]
font = style.get_font()
pdf_style = reportlab.lib.styles.ParagraphStyle(name=style_name)
#pdf_style = reportlab.lib.styles.ParagraphStyle(name=style_name)
pdf_style = BoxedParagraphStyle(name=style_name)
pdf_style.fontSize = font.get_size()
pdf_style.bulletFontSize = font.get_size()
if font.get_type_face() == FONT_SERIF:
if font.get_type_face() == FONT_MONOSPACE:
if font.get_bold():
if font.get_italic():
pdf_style.fontName = "Courier-BoldOblique"
else:
pdf_style.fontName = "Courier-Bold"
else:
if font.get_italic():
pdf_style.fontName = "Courier-Oblique"
else:
pdf_style.fontName = "Courier"
elif font.get_type_face() == FONT_SERIF:
if font.get_bold():
if font.get_italic():
pdf_style.fontName = "Times-BoldItalic"
@ -126,7 +343,13 @@ class PdfDoc(TextDoc):
right = style.get_right_margin()*cm
left = style.get_left_margin()*cm
first = left + style.get_first_indent()*cm
#first = left + style.get_first_indent()*cm
first = style.get_first_indent()*cm
pdf_style.topBorder = style.get_top_border()
pdf_style.bottomBorder = style.get_bottom_border()
pdf_style.leftBorder = style.get_left_border()
pdf_style.rightBorder = style.get_right_border()
pdf_style.rightIndent = right
pdf_style.leftIndent = left
@ -149,6 +372,7 @@ class PdfDoc(TextDoc):
self.story = []
self.in_table = 0
self.in_listing = 0
def close(self):
self.doc.build(self.story)
@ -156,6 +380,28 @@ class PdfDoc(TextDoc):
def end_page(self):
self.story.append(PageBreak())
def start_listing(self,style_name):
self.text = ''
self.current_para = self.pdfstyles[style_name]
self.in_listing = 1
def end_listing(self):
text = self.text
index = string.find(text, '\n')
if index > -1:
if index > 0 and text[index-1] == '\r':
eol = '\r\n'
else:
eol = '\n'
else:
eol = ''
text = ' ' + text
if eol:
text = string.replace(text,eol,eol+' ');
self.story.append(BoxedPreformatted(text,self.current_para))
self.story.append(Spacer(1,0.5*cm))
self.in_listing = 0
def start_paragraph(self,style_name,leader=None):
self.current_para = self.pdfstyles[style_name]
self.my_para = self.style_list[style_name]
@ -167,7 +413,7 @@ class PdfDoc(TextDoc):
def end_paragraph(self):
if self.in_table == 0 and self.image == 0:
self.story.append(Paragraph(self.text,self.current_para))
self.story.append(BoxedParagraph(self.text,self.current_para))
self.story.append(Spacer(1,0.5*cm))
else:
self.image = 0
@ -178,6 +424,12 @@ class PdfDoc(TextDoc):
def end_bold(self):
self.text = self.text + '</b>'
def start_italic(self):
self.text = self.text + '<i>'
def end_italic(self):
self.text = self.text + '</i>'
def start_table(self,name,style_name):
self.in_table = 1
self.cur_table = self.table_styles[style_name]
@ -185,6 +437,7 @@ class PdfDoc(TextDoc):
self.col = 0
self.cur_row = []
self.table_data = []
self.span_data = []
self.tblstyle = []
self.cur_table_cols = []
@ -194,23 +447,29 @@ class PdfDoc(TextDoc):
self.cur_table_cols.append(int(width * percent * cm))
def end_table(self):
ts = reportlab.platypus.tables.TableStyle(self.tblstyle)
tbl = reportlab.platypus.tables.Table(data=self.table_data,
colWidths=self.cur_table_cols,
style=ts)
ts = ReportlabTableStyle(self.tblstyle)
#tbl = reportlab.platypus.tables.Table(data=self.table_data,
# colWidths=self.cur_table_cols,
# style=ts)
tbl = SpanTable(data=self.table_data, spandata=self.span_data,
colWidths=self.cur_table_cols, style=ts)
self.story.append(tbl)
self.story.append(Spacer(1,0.5*cm))
self.in_table = 0
def start_row(self):
self.row = self.row + 1
self.col = 0
self.cur_row = []
self.cur_span_row = []
def end_row(self):
self.table_data.append(self.cur_row)
self.span_data.append(self.cur_span_row)
def start_cell(self,style_name,span=1):
self.span = span
self.cur_span_row.append(span)
self.my_table_style = self.cell_styles[style_name]
pass
@ -218,7 +477,8 @@ class PdfDoc(TextDoc):
if self.span == 1:
self.cur_row.append(Paragraph(self.text,self.current_para))
else:
self.cur_row.append(self.text)
self.cur_row.append(Paragraph(self.text,self.current_para))
#self.cur_row.append(self.text)
for val in range(1,self.span):
self.cur_row.append("")
@ -278,14 +538,22 @@ class PdfDoc(TextDoc):
self.image = 1
def write_text(self,text):
text = string.replace(text,'&','&amp;'); # Must be first
text = string.replace(text,'<','&lt;');
text = string.replace(text,'>','&gt;');
if not self.in_listing:
text = string.replace(text,'&','&amp;'); # Must be first
text = string.replace(text,'<','&lt;');
text = string.replace(text,'>','&gt;');
self.text = self.text + text
def show_link(self, text, href):
self.write_text("%s (" % text)
self.start_italic()
self.write_text(href)
self.end_italic()
self.write_text(") ")
#------------------------------------------------------------------------
#
# Convert an RGB color tulple to a Color instance
# Convert an RGB color tuple to a Color instance
#
#------------------------------------------------------------------------
def make_color(color):
@ -298,10 +566,11 @@ def make_color(color):
#
#------------------------------------------------------------------------
Plugins.register_text_doc(
name=_("PDF"),
classref=PdfDoc,
table=1,
paper=1,
style=1
)
if withGramps:
Plugins.register_text_doc(
name=_("PDF"),
classref=PdfDoc,
table=1,
paper=1,
style=1
)

View File

@ -3,6 +3,52 @@
#
# Copyright (C) 2000 Donald N. Allingham
#
# Modified August 2002 by Gary Shao
#
# Removed Gramps dependencies.
#
# Made a more explicit distinction of whether paragraph properties
# were being emitted in a table or not. Changing the location of
# \qc and \qr commands in cell text enabled text alignment in table
# cells to work properly.
#
# Improved the appearance of output by adding some default spacing
# before and after paragraphs using \sa and \sb commands. This lets
# the output more closely mimic that of the other document generators
# given the same document parameters.
#
# Improved the appearance of tables by adding some default cell
# padding using the \trgaph command. This causes the output to
# more closely resemble that of the other document generators.
#
# Removed unnecessary \par command at the end of embedded image.
#
# Removed self-test function in favor of a general testing program
# that can be run for all supported document generators. Simplifies
# testing when the test program only has to be changed in one location
# instead of in each document generator.
#
# Modified open() and close() methods to allow the filename parameter
# passed to open() to be either a string containing a file name, or
# a Python file object. This allows the document generator to be more
# easily used with its output directed to stdout, as may be called for
# in a CGI script.
#
# Modified September 2002 by Gary Shao
#
# Added start_listing() and end_listing() methods to allow showing
# text blocks without filling or justifying.
#
# Added line_break() method to allow forcing a line break in a text
# block.
#
# Added new methods start_italic() and end_italic() to enable
# italicizing parts of text within a paragraph
#
# Added method show_link() to display in text the value of a link.
# This method really only has an active role in the HTML generator,
# but is provided here for interface consistency.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@ -24,11 +70,16 @@
#
#------------------------------------------------------------------------
from TextDoc import *
import Plugins
import ImgManip
import intl
_ = intl.gettext
try:
import Plugins
import intl
_ = intl.gettext
except:
withGramps = 0
else:
withGramps = 1
#------------------------------------------------------------------------
#
@ -60,16 +111,22 @@ class RTFDoc(TextDoc):
#
#--------------------------------------------------------------------
def open(self,filename):
if filename[-4:] != ".rtf":
self.filename = filename + ".rtf"
else:
self.filename = filename
if type(filename) == type(""):
if filename[-4:] != ".rtf":
self.filename = filename + ".rtf"
else:
self.filename = filename
self.f = open(self.filename,"w")
self.f = open(self.filename,"w")
self.alreadyOpen = 0
elif hasattr(filename, "write"):
self.f = filename
self.alreadyOpen = 1
self.f.write('{\\rtf1\\ansi\\ansicpg1252\\deff0\n')
self.f.write('{\\fonttbl\n')
self.f.write('{\\f0\\froman\\fcharset0\\fprq0 Times New Roman;}\n')
self.f.write('{\\f1\\fswiss\\fcharset0\\fprq0 Arial;}}\n')
self.f.write('{\\f1\\fswiss\\fcharset0\\fprq0 Arial;}\n')
self.f.write('{\\f2\\fmodern\\fcharset0\\fprq0 Courier New;}}\n')
self.f.write('{\colortbl\n')
self.color_map = {}
index = 1
@ -97,6 +154,7 @@ class RTFDoc(TextDoc):
self.f.write('\\margb%d' % twips(self.bmargin))
self.f.write('\\widowctl\n')
self.in_table = 0
self.in_listing = 0
self.text = ""
#--------------------------------------------------------------------
@ -106,7 +164,8 @@ class RTFDoc(TextDoc):
#--------------------------------------------------------------------
def close(self):
self.f.write('}\n')
self.f.close()
if not self.alreadyOpen:
self.f.close()
#--------------------------------------------------------------------
#
@ -116,6 +175,90 @@ class RTFDoc(TextDoc):
def end_page(self):
self.f.write('\\sbkpage\n')
#--------------------------------------------------------------------
#
# Starts a listing. Instead of using a style sheet, generate the
# the style for each paragraph on the fly. Not the ideal, but it
# does work.
#
#--------------------------------------------------------------------
def start_listing(self,style_name):
self.opened = 0
p = self.style_list[style_name]
# build font information
f = p.get_font()
size = f.get_size()*2
bgindex = self.color_map[p.get_background_color()]
fgindex = self.color_map[f.get_color()]
if f.get_type_face() == FONT_MONOSPACE:
self.font_type = '\\f2\\fs%d\\cf%d\\cb%d' % (size,fgindex,bgindex)
elif f.get_type_face() == FONT_SERIF:
self.font_type = '\\f0\\fs%d\\cf%d\\cb%d' % (size,fgindex,bgindex)
else:
self.font_type = '\\f1\\fs%d\\cf%d\\cb%d' % (size,fgindex,bgindex)
if f.get_bold():
self.font_type = self.font_type + "\\b"
if f.get_underline():
self.font_type = self.font_type + "\\ul"
if f.get_italic():
self.font_type = self.font_type + "\\i"
# build listing block information
self.f.write('\\pard')
self.f.write('\\ql')
self.para_align = '\\ql'
self.f.write('\\nowidctlpar')
self.f.write('\\nowwrap')
self.f.write('\\nocwrap')
self.f.write('\\ri%d' % twips(p.get_right_margin()))
self.f.write('\\li%d' % twips(p.get_left_margin()))
self.f.write('\\fi%d' % twips(p.get_first_indent()))
if p.get_padding():
self.f.write('\\sa%d' % twips((0.25 + p.get_padding())/2.0))
self.f.write('\\sb%d' % twips((0.25 + p.get_padding())/2.0))
else:
self.f.write('\\sa%d' % twips(0.125))
self.f.write('\\sb%d' % twips(0.125))
haveBorders = 0
if p.get_top_border():
self.f.write('\\brdrt\\brdrs')
haveBorders = 1
if p.get_bottom_border():
self.f.write('\\brdrb\\brdrs')
haveBorders = 1
if p.get_left_border():
self.f.write('\\brdrl\\brdrs')
haveBorders = 1
if p.get_right_border():
self.f.write('\\brdrr\\brdrs')
haveBorders = 1
if haveBorders:
if p.get_padding():
self.f.write('\\brsp%d' % twips(p.get_padding()))
else:
self.f.write('\\brsp%d' % twips(0.125))
self.in_listing = 1
#--------------------------------------------------------------------
#
# Ends a listing. Care has to be taken to make sure that the
# braces are closed properly. The self.opened flag is used to indicate
# if braces are currently open. If the last write was the end of
# a bold-faced phrase, braces may already be closed.
#
#--------------------------------------------------------------------
def end_listing(self):
self.f.write(self.text)
if self.opened:
self.f.write('}')
self.opened = 0
self.text = ""
self.f.write('\n\\par')
self.in_listing = 0
#--------------------------------------------------------------------
#
# Starts a paragraph. Instead of using a style sheet, generate the
@ -149,30 +292,54 @@ class RTFDoc(TextDoc):
if not self.in_table:
self.f.write('\\pard')
if p.get_alignment() == PARA_ALIGN_RIGHT:
self.f.write('\\qr')
if not self.in_table:
self.f.write('\\qr')
self.para_align = '\\qr'
elif p.get_alignment() == PARA_ALIGN_CENTER:
self.f.write('\\qc')
if not self.in_table:
self.f.write('\\qc')
self.para_align = '\\qc'
else:
self.para_align = '\\ql'
self.f.write('\\ri%d' % twips(p.get_right_margin()))
self.f.write('\\li%d' % twips(p.get_left_margin()))
self.f.write('\\fi%d' % twips(p.get_first_indent()))
if p.get_alignment() == PARA_ALIGN_JUSTIFY:
self.f.write('\\qj')
if p.get_padding():
self.f.write('\\sa%d' % twips(p.get_padding()/2.0))
if p.get_top_border():
self.f.write('\\brdrt\\brdrs')
if p.get_bottom_border():
self.f.write('\\brdrb\\brdrs')
if p.get_left_border():
self.f.write('\\brdrl\\brdrs')
if p.get_right_border():
self.f.write('\\brdrr\\brdrs')
if p.get_first_indent():
self.f.write('\\fi%d' % twips(p.get_first_indent()))
if p.get_left_margin():
self.f.write('\\li%d' % twips(p.get_left_margin()))
if p.get_right_margin():
self.f.write('\\ri%d' % twips(p.get_right_margin()))
if self.in_table:
self.f.write('\\trgaph80')
else:
if p.get_padding():
self.f.write('\\sa%d' % twips((0.25 + p.get_padding())/2.0))
self.f.write('\\sb%d' % twips((0.25 + p.get_padding())/2.0))
else:
self.f.write('\\sa%d' % twips(0.125))
self.f.write('\\sb%d' % twips(0.125))
haveBorders = 0
if p.get_top_border():
self.f.write('\\brdrt\\brdrs')
haveBorders = 1
if p.get_bottom_border():
self.f.write('\\brdrb\\brdrs')
haveBorders = 1
if p.get_left_border():
self.f.write('\\brdrl\\brdrs')
haveBorders = 1
if p.get_right_border():
self.f.write('\\brdrr\\brdrs')
haveBorders = 1
if haveBorders:
if p.get_padding():
self.f.write('\\brsp%d' % twips(p.get_padding()))
else:
self.f.write('\\brsp%d' % twips(0.125))
# This is redundant. Why was it here?
#if p.get_first_indent():
# self.f.write('\\fi%d' % twips(p.get_first_indent()))
#if p.get_left_margin():
# self.f.write('\\li%d' % twips(p.get_left_margin()))
#if p.get_right_margin():
# self.f.write('\\ri%d' % twips(p.get_right_margin()))
if leader:
self.opened = 1
@ -181,6 +348,9 @@ class RTFDoc(TextDoc):
self.write_text(leader)
self.f.write('\\tab}')
self.opened = 0
self.bold_on = 0
self.italic_on = 0
#--------------------------------------------------------------------
#
@ -195,23 +365,52 @@ class RTFDoc(TextDoc):
self.f.write(self.text)
if self.opened:
self.f.write('}')
self.text = ""
self.opened = 0
self.text = ""
self.f.write('\n\\par')
else:
if self.text == "":
self.write_text(" ")
self.text = self.text + '}'
#--------------------------------------------------------------------
#
# Starts italicized text, enclosed the braces
#
#--------------------------------------------------------------------
def start_italic(self):
self.italic_on = 1
emph = '\\i'
if self.bold_on:
emph = emph + '\\b'
if self.opened:
self.text = self.text + '}'
self.text = self.text + '{%s%s ' % (self.font_type, emph)
self.opened = 1
#--------------------------------------------------------------------
#
# Ends italicized text, closing the braces
#
#--------------------------------------------------------------------
def end_italic(self):
self.italic_on = 0
self.opened = 0
self.text = self.text + '}'
#--------------------------------------------------------------------
#
# Starts boldfaced text, enclosed the braces
#
#--------------------------------------------------------------------
def start_bold(self):
self.bold_on = 1
emph = '\\b'
if self.italic_on:
emph = emph + '\\i'
if self.opened:
self.f.write('}')
self.f.write('{%s\\b ' % self.font_type)
self.text = self.text + '}'
self.text = self.text + '{%s%s ' % (self.font_type, emph)
self.opened = 1
#--------------------------------------------------------------------
@ -220,8 +419,9 @@ class RTFDoc(TextDoc):
#
#--------------------------------------------------------------------
def end_bold(self):
self.bold_on = 0
self.opened = 0
self.f.write('}')
self.text = self.text + '}'
#--------------------------------------------------------------------
#
@ -342,7 +542,7 @@ class RTFDoc(TextDoc):
if index%32==0:
self.f.write('\n')
index = index+1
self.f.write('}}\\par\n')
self.f.write('}}\n')
#--------------------------------------------------------------------
#
@ -354,163 +554,55 @@ class RTFDoc(TextDoc):
#--------------------------------------------------------------------
def write_text(self,text):
if self.opened == 0:
emph = ''
if self.bold_on:
emph = emph + '\\b'
if self.italic_on:
emph = emph + '\\i'
self.opened = 1
self.text = self.text + '{%s ' % self.font_type
if self.in_table:
self.text = self.text + self.para_align
self.text = self.text + '{%s%s ' % (self.font_type, emph)
for i in text:
if ord(i) > 127:
self.text = self.text + '\\\'%2x' % ord(i)
elif i == '{' or i == '}' :
self.text = self.text + '\\%s' % i
elif self.in_listing and i == '\n':
self.text = self.text + '\\line\n'
else:
self.text = self.text + i
#--------------------------------------------------------------------
#
# Inserts a required line break into the text.
#
#--------------------------------------------------------------------
def line_break(self):
self.text = self.text + '\\line\n'
if __name__ == "__main__":
#--------------------------------------------------------------------
#
# Shows link text.
#
#--------------------------------------------------------------------
def show_link(self, text, href):
self.write_text("%s (" % text)
self.start_italic()
self.write_text(href)
self.end_italic()
self.write_text(") ")
paper = PaperStyle("Letter",27.94,21.59)
styles = StyleSheet()
foo = FontStyle()
foo.set_type_face(FONT_SANS_SERIF)
foo.set_color((255,0,0))
foo.set_size(24)
foo.set_underline(1)
foo.set_bold(1)
foo.set_italic(1)
para = ParagraphStyle()
para.set_alignment(PARA_ALIGN_RIGHT)
para.set_font(foo)
styles.add_style("Title",para)
foo = FontStyle()
foo.set_type_face(FONT_SERIF)
foo.set_size(12)
para = ParagraphStyle()
para.set_font(foo)
styles.add_style("Normal",para)
foo = FontStyle()
foo.set_type_face(FONT_SERIF)
foo.set_size(12)
para = ParagraphStyle()
para.set_font(foo)
para.set_top_border(1)
para.set_left_border(1)
para.set_right_border(1)
para.set_bottom_border(1)
styles.add_style("Box",para)
doc = RTFDoc(styles,paper,PAPER_PORTRAIT)
cell = TableCellStyle()
cell.set_padding(0.2)
cell.set_top_border(1)
cell.set_bottom_border(1)
cell.set_right_border(1)
cell.set_left_border(1)
doc.add_cell_style('ParentHead',cell)
cell = TableCellStyle()
cell.set_padding(0.1)
cell.set_bottom_border(1)
cell.set_left_border(1)
doc.add_cell_style('TextContents',cell)
cell = TableCellStyle()
cell.set_padding(0.1)
cell.set_bottom_border(0)
cell.set_left_border(1)
cell.set_padding(0.1)
doc.add_cell_style('TextChild1',cell)
cell = TableCellStyle()
cell.set_padding(0.1)
cell.set_bottom_border(1)
cell.set_left_border(1)
cell.set_padding(0.1)
doc.add_cell_style('TextChild2',cell)
cell = TableCellStyle()
cell.set_padding(0.1)
cell.set_bottom_border(1)
cell.set_right_border(1)
cell.set_left_border(1)
doc.add_cell_style('TextContentsEnd',cell)
cell = TableCellStyle()
cell.set_padding(0.2)
cell.set_bottom_border(1)
cell.set_right_border(1)
cell.set_left_border(1)
doc.add_cell_style('ChildName',cell)
table = TableStyle()
table.set_width(100)
table.set_columns(3)
table.set_column_width(0,20)
table.set_column_width(1,40)
table.set_column_width(2,40)
doc.add_table_style('ParentTable',table)
table = TableStyle()
table.set_width(100)
table.set_columns(4)
table.set_column_width(0,5)
table.set_column_width(1,15)
table.set_column_width(2,40)
table.set_column_width(3,40)
doc.add_table_style('ChildTable',table)
doc.open("test")
doc.start_paragraph("Title")
doc.write_text("My Title")
doc.end_paragraph()
doc.start_paragraph("Normal")
doc.write_text("Hello there. This is fun")
doc.end_paragraph()
doc.start_paragraph("Box")
doc.write_text("This is my box")
doc.end_paragraph()
doc.start_paragraph("Normal")
doc.add_photo("foo.png",200,200)
doc.end_paragraph()
doc.start_table(id,'ParentTable')
doc.start_row()
doc.start_cell('ParentHead',3)
doc.start_paragraph('Normal')
doc.write_text('Banana : Smith ')
doc.end_paragraph()
doc.end_cell()
doc.end_row()
doc.start_row()
doc.start_cell("TextContents")
doc.start_paragraph('Normal')
doc.write_text("some event")
doc.end_paragraph()
doc.end_cell()
doc.start_cell("TextContents")
doc.start_paragraph('Normal')
doc.write_text("someday")
doc.end_paragraph()
doc.end_cell()
doc.start_cell("TextContentsEnd")
doc.start_paragraph('Normal')
doc.write_text("somewhere")
doc.end_paragraph()
doc.end_cell()
doc.end_row()
doc.end_table()
doc.close()
Plugins.register_text_doc(_("Rich Text Format (RTF)"),RTFDoc,1,1,1)
#------------------------------------------------------------------------
#
# Register the document generator with the system if in Gramps
#
#------------------------------------------------------------------------
if withGramps:
Plugins.register_text_doc(
name=_("Rich Text Format (RTF)"),
classref=RTFDoc,
table=1,
paper=1,
style=1
)