diff --git a/gramps/src/docgen/HtmlDoc.py b/gramps/src/docgen/HtmlDoc.py
index 48a226a73..c54e58ded 100644
--- a/gramps/src/docgen/HtmlDoc.py
+++ b/gramps/src/docgen/HtmlDoc.py
@@ -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
command in
+# write_text() to instead require an explicit call to line_break()
+# for insertion of
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"(.*)
\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('\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 = '\n' % \
+ (italic, bold, underline, family)
+ self.f.write(styleStr)
+
+ def end_listing(self):
+ self.f.write('
\n')
+
def start_paragraph(self,style_name,leader=None):
self.f.write('')
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','
')
+ #text = string.replace(text,'\n','
')
self.f.write(text)
-Plugins.register_text_doc(_("HTML"),HtmlDoc,1,0,1)
+ def start_bold(self):
+ self.f.write('')
+
+ def end_bold(self):
+ self.f.write('')
+
+ def start_italic(self):
+ self.f.write('')
+
+ def end_italic(self):
+ self.f.write('')
+
+ def line_break(self):
+ self.f.write('
\n')
+
+ def show_link(self, text, href):
+ self.write_text(' %s ' % (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
+ )
diff --git a/gramps/src/docgen/LaTeXDoc.py b/gramps/src/docgen/LaTeXDoc.py
index b810a37e1..5068c4d0e 100644
--- a/gramps/src/docgen/LaTeXDoc.py
+++ b/gramps/src/docgen/LaTeXDoc.py
@@ -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
+ )
diff --git a/gramps/src/docgen/NroffDoc.py b/gramps/src/docgen/NroffDoc.py
new file mode 100644
index 000000000..a1dcbbcae
--- /dev/null
+++ b/gramps/src/docgen/NroffDoc.py
@@ -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
+ )
diff --git a/gramps/src/docgen/PdfDoc.py b/gramps/src/docgen/PdfDoc.py
index 5329f6d90..4856846dc 100644
--- a/gramps/src/docgen/PdfDoc.py
+++ b/gramps/src/docgen/PdfDoc.py
@@ -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 + ''
+ def start_italic(self):
+ self.text = self.text + ''
+
+ def end_italic(self):
+ self.text = self.text + ''
+
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,'&','&'); # Must be first
- text = string.replace(text,'<','<');
- text = string.replace(text,'>','>');
+ if not self.in_listing:
+ text = string.replace(text,'&','&'); # Must be first
+ text = string.replace(text,'<','<');
+ text = string.replace(text,'>','>');
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
+ )
diff --git a/gramps/src/docgen/RTFDoc.py b/gramps/src/docgen/RTFDoc.py
index dc598c619..65c9f1e0c 100644
--- a/gramps/src/docgen/RTFDoc.py
+++ b/gramps/src/docgen/RTFDoc.py
@@ -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
+ )