From 3767c1d1e432ea37811a881ef4d6b22854ae2d24 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Fri, 10 Feb 2012 14:53:58 +0000 Subject: [PATCH] 5326: Add Alphabetical Index and Table of Contents generation for pdf reports svn: r18842 --- po/POTFILES.in | 1 + po/POTFILES.skip | 1 + src/cli/plug/__init__.py | 23 +++- src/gen/plug/_docgenplugin.py | 18 ++- src/gen/plug/_manager.py | 1 + src/gen/plug/_pluginreg.py | 17 ++- src/gen/plug/docgen/Makefile.am | 1 + src/gen/plug/docgen/__init__.py | 1 + src/gen/plug/docgen/basedoc.py | 7 +- src/gen/plug/docgen/graphdoc.py | 4 +- src/gen/plug/docgen/indexoptions.py | 45 +++++++ src/gen/plug/report/Makefile.am | 3 +- src/gen/plug/report/_options.py | 110 ++++++++++++++++- src/gen/plug/report/toc_index.py | 151 ++++++++++++++++++++++++ src/gui/plug/report/_docreportdialog.py | 73 ++++++++++-- src/gui/plug/report/_reportdialog.py | 2 + src/plugins/BookReport.py | 14 ++- src/plugins/docgen/AsciiDoc.py | 4 +- src/plugins/docgen/HtmlDoc.py | 4 +- src/plugins/docgen/ODFDoc.py | 4 +- src/plugins/docgen/PSDrawDoc.py | 4 +- src/plugins/docgen/PdfDoc.py | 74 +++++++++++- src/plugins/docgen/SvgDrawDoc.py | 4 +- src/plugins/docgen/docgen.gpr.py | 9 ++ src/plugins/lib/libcairodoc.py | 64 +++++++++- 25 files changed, 598 insertions(+), 41 deletions(-) create mode 100644 src/gen/plug/docgen/indexoptions.py create mode 100644 src/gen/plug/report/toc_index.py diff --git a/po/POTFILES.in b/po/POTFILES.in index cdd04f708..98a07d216 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -75,6 +75,7 @@ src/gen/plug/docgen/graphdoc.py src/gen/plug/report/_constants.py src/gen/plug/report/_paper.py src/gen/plug/report/endnotes.py +src/gen/plug/report/toc_index.py src/gen/plug/report/utils.py # gen proxy API diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 6ecaf3d44..8d1e957f2 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -187,6 +187,7 @@ src/gen/plug/docgen/fontscale.py src/gen/plug/docgen/fontstyle.py src/gen/plug/docgen/graphdoc.py src/gen/plug/docgen/graphicstyle.py +src/gen/plug/docgen/indexoptions.py src/gen/plug/docgen/paperstyle.py src/gen/plug/docgen/paragraphstyle.py src/gen/plug/docgen/stylesheet.py diff --git a/src/cli/plug/__init__.py b/src/cli/plug/__init__.py index 715446d04..a25ce301f 100644 --- a/src/cli/plug/__init__.py +++ b/src/cli/plug/__init__.py @@ -48,8 +48,9 @@ log = logging.getLogger(".") #------------------------------------------------------------------------- import Utils from gen.plug import BasePluginManager -from gen.plug.docgen import (StyleSheet, StyleSheetList, PaperStyle, - PAPER_PORTRAIT, PAPER_LANDSCAPE, graphdoc) +from gen.plug.docgen import (StyleSheet, StyleSheetList, PaperStyle, + PAPER_PORTRAIT, PAPER_LANDSCAPE, graphdoc, + IndexOptions) from gen.plug.menu import (FamilyOption, PersonOption, NoteOption, MediaOption, PersonListOption, NumberOption, BooleanOption, DestinationOption, StringOption, @@ -59,6 +60,7 @@ from Errors import ReportError from gen.plug.report import (CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_BOOK, CATEGORY_GRAPHVIZ, CATEGORY_CODE) from gen.plug.report._paper import paper_sizes +from gen.plug.report.toc_index import add_toc_index_styles import const import DbState from cli.grampscli import CLIManager @@ -256,6 +258,8 @@ class CommandLineReport(object): 'papermt' : self.option_class.handler.get_margins()[2], 'papermb' : self.option_class.handler.get_margins()[3], 'css' : self.option_class.handler.get_css_filename(), + 'toc' : self.option_class.handler.get_toc(), + 'index' : self.option_class.handler.get_index(), } self.options_help = { @@ -270,6 +274,10 @@ class CommandLineReport(object): 'papermb' : ["=num", "Bottom paper margin", "Size in cm"], 'css' : ["=css filename", "CSS filename to use, html format" " only", ""], + 'toc' : ["=bool", "Include table of contents.", + ["False", "True"]], + 'index' : ["=bool", "Include alphabetical index.", + ["False", "True"]], } if noopt: @@ -311,6 +319,7 @@ class CommandLineReport(object): if self.category in (CATEGORY_TEXT, CATEGORY_DRAW): default_style = StyleSheet() self.option_class.make_default_style(default_style) + add_toc_index_styles(default_style) # Read all style sheets available for this item style_file = self.option_class.handler.get_stylesheet_savefile() @@ -498,9 +507,13 @@ class CommandLineReport(object): self.margint = self.options_dict['papermt'] self.marginb = self.options_dict['papermb'] + self.toc = self.options_dict['toc'] + self.index = self.options_dict['index'] + if self.category in (CATEGORY_TEXT, CATEGORY_DRAW): default_style = StyleSheet() self.option_class.make_default_style(default_style) + add_toc_index_styles(default_style) # Read all style sheets available for this item style_file = self.option_class.handler.get_stylesheet_savefile() @@ -573,12 +586,14 @@ def cl_report(database, name, category, report_class, options_class, clr.option_class.handler.doc = clr.format( clr.selected_style, PaperStyle(clr.paper,clr.orien,clr.marginl, - clr.marginr,clr.margint,clr.marginb)) + clr.marginr,clr.margint,clr.marginb), + IndexOptions(clr.toc, clr.index)) elif category == CATEGORY_GRAPHVIZ: clr.option_class.handler.doc = clr.format( clr.option_class, PaperStyle(clr.paper,clr.orien,clr.marginl, - clr.marginr,clr.margint,clr.marginb)) + clr.marginr,clr.margint,clr.marginb), + IndexOptions(clr.toc, clr.index)) if clr.css_filename is not None and \ hasattr(clr.option_class.handler.doc, 'set_css_filename'): clr.option_class.handler.doc.set_css_filename(clr.css_filename) diff --git a/src/gen/plug/_docgenplugin.py b/src/gen/plug/_docgenplugin.py index 5a2dc4a04..e4e3b47b8 100644 --- a/src/gen/plug/_docgenplugin.py +++ b/src/gen/plug/_docgenplugin.py @@ -30,7 +30,8 @@ class DocGenPlugin(Plugin): """ This class represents a plugin for generating documents from Gramps """ - def __init__(self, name, description, basedoc, paper, style, extension): + def __init__(self, name, description, basedoc, paper, style, index, + extension): """ @param name: A friendly name to call this plugin. Example: "Plain Text" @@ -47,6 +48,10 @@ class DocGenPlugin(Plugin): @param style: Indicates whether the plugin uses styles or not. True = use styles; False = do not use styles @type style: bool + @param index: Indicates whether the plugin supports an Alphabetical + Index and Table of Contents or not. + True = supports indexing; False = does not support indexing + @type index: bool @param extension: The extension for the output file. Example: "txt" @type extension: str @@ -56,6 +61,7 @@ class DocGenPlugin(Plugin): self.__basedoc = basedoc self.__paper = paper self.__style = style + self.__index = index self.__extension = extension def get_basedoc(self): @@ -82,6 +88,14 @@ class DocGenPlugin(Plugin): """ return self.__style + def get_index_support(self): + """ + Get the index flag for this plugin. + + @return: bool - True = index support; False = no index support + """ + return self.__index + def get_extension(self): """ Get the file extension for the output file. @@ -106,4 +120,4 @@ class DocGenPlugin(Plugin): @return: bool: True if DrawDoc is supported; False if DrawDoc is not supported. """ - return bool(issubclass(self.__basedoc, DrawDoc)) \ No newline at end of file + return bool(issubclass(self.__basedoc, DrawDoc)) diff --git a/src/gen/plug/_manager.py b/src/gen/plug/_manager.py index b3f35fbc3..cad69e67e 100644 --- a/src/gen/plug/_manager.py +++ b/src/gen/plug/_manager.py @@ -533,6 +533,7 @@ class BasePluginManager(object): basedoc = getattr(mod, pdata.basedocclass), paper = pdata.paper, style = pdata.style, + index = pdata.index, extension = pdata.extension ) self.__docgen_plugins.append(dgp) diff --git a/src/gen/plug/_pluginreg.py b/src/gen/plug/_pluginreg.py index ac62a58ac..a99184fc5 100644 --- a/src/gen/plug/_pluginreg.py +++ b/src/gen/plug/_pluginreg.py @@ -268,6 +268,9 @@ class PluginData(object): bool, Indicates whether the plugin uses paper or not, default=True .. attribute :: style bool, Indicates whether the plugin uses styles or not, default=True + .. attribute :: index + bool, Indicates whether the plugin supports an Alphabetical Index and + Table of Contents or not, default=False Attribute for DOCGEN, EXPORT plugins .. attribute :: extension @@ -376,6 +379,7 @@ class PluginData(object): self._basedocclass = None self._paper = True self._style = True + self._index = False self._extension = '' #QUICKREPORT attr self._runfunc = None @@ -703,6 +707,16 @@ class PluginData(object): def _get_style(self): return self._style + def _set_index(self, index): + if not self._ptype == DOCGEN: + raise ValueError, 'index may only be set for DOCGEN plugins' + if not isinstance(index, bool): + raise ValueError, 'Plugin must have index=True or False' + self._index = index + + def _get_index(self): + return self._index + def _set_extension(self, extension): if not (self._ptype == DOCGEN or self._ptype == EXPORT or self._ptype == IMPORT): @@ -715,7 +729,8 @@ class PluginData(object): basedocclass = property(_get_basedocclass, _set_basedocclass) paper = property(_get_paper, _set_paper) - style = property(_get_style, _set_style) + style = property(_get_style, _set_style) + index = property(_get_index, _set_index) extension = property(_get_extension, _set_extension) #QUICKREPORT attributes diff --git a/src/gen/plug/docgen/Makefile.am b/src/gen/plug/docgen/Makefile.am index ba0360b52..a7def374b 100644 --- a/src/gen/plug/docgen/Makefile.am +++ b/src/gen/plug/docgen/Makefile.am @@ -14,6 +14,7 @@ pkgdata_PYTHON = \ fontstyle.py \ graphdoc.py \ graphicstyle.py \ + indexoptions.py \ paperstyle.py \ paragraphstyle.py \ stylesheet.py \ diff --git a/src/gen/plug/docgen/__init__.py b/src/gen/plug/docgen/__init__.py index b1f99467a..985493979 100644 --- a/src/gen/plug/docgen/__init__.py +++ b/src/gen/plug/docgen/__init__.py @@ -29,6 +29,7 @@ A docgen plugin should fully implement this api for TextDoc or DrawDoc from basedoc import BaseDoc from paperstyle import PaperSize, PaperStyle, PAPER_PORTRAIT, PAPER_LANDSCAPE +from indexoptions import IndexOptions from fontstyle import FontStyle, FONT_SANS_SERIF, FONT_SERIF, FONT_MONOSPACE from paragraphstyle import ParagraphStyle, PARA_ALIGN_CENTER, PARA_ALIGN_LEFT,\ PARA_ALIGN_RIGHT, PARA_ALIGN_JUSTIFY diff --git a/src/gen/plug/docgen/basedoc.py b/src/gen/plug/docgen/basedoc.py index eecb8f85e..5eef72b73 100644 --- a/src/gen/plug/docgen/basedoc.py +++ b/src/gen/plug/docgen/basedoc.py @@ -61,7 +61,7 @@ class BaseDoc(object): such as OpenOffice, AbiWord, and LaTeX are derived from this base class, providing a common interface to all document generators. """ - def __init__(self, styles, paper_style): + def __init__(self, styles, paper_style, index_options): """ Create a BaseDoc instance, which provides a document generation interface. This class should never be instantiated directly, but @@ -71,8 +71,13 @@ class BaseDoc(object): @param paper_style: PaperStyle instance containing information about the paper. If set to None, then the document is not a page oriented document (e.g. HTML) + @param index_options: IndexOptions instance containing information + about how an alphabetical index and table of contents should be + generated. If set to None, then the document is does not support + indexing (e.g. HTML) """ self.paper = paper_style + self.index_options = index_options self._style_sheet = styles self._creator = "" self.init_called = False diff --git a/src/gen/plug/docgen/graphdoc.py b/src/gen/plug/docgen/graphdoc.py index 16d1a6f00..d4ed6ec3c 100644 --- a/src/gen/plug/docgen/graphdoc.py +++ b/src/gen/plug/docgen/graphdoc.py @@ -358,8 +358,8 @@ class GVDocBase(BaseDoc, GVDoc): inherit from this class will only need to implement the close function. The close function will generate the actual file of the appropriate type. """ - def __init__(self, options, paper_style): - BaseDoc.__init__(self, None, paper_style) + def __init__(self, options, paper_style, index_opts): + BaseDoc.__init__(self, None, paper_style, index_opts) self._filename = None self._dot = StringIO() diff --git a/src/gen/plug/docgen/indexoptions.py b/src/gen/plug/docgen/indexoptions.py new file mode 100644 index 000000000..ee0f7fe6b --- /dev/null +++ b/src/gen/plug/docgen/indexoptions.py @@ -0,0 +1,45 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2012 Nick Hall +# +# 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 +# +# $Id$ + +#------------------------------------------------------------------------ +# +# IndexOptions +# +#------------------------------------------------------------------------ +class IndexOptions(object): + """ + Define the options for the alphabetical index and table of contents. + """ + def __init__(self, include_toc, include_index): + self.__include_toc = include_toc + self.__include_index = include_index + + def get_include_toc(self): + """ + Return a boolean indicating if a table of contents should be included. + """ + return self.__include_toc + + def get_include_index(self): + """ + Return a boolean indicating if an alphabetical index should be included. + """ + return self.__include_index diff --git a/src/gen/plug/report/Makefile.am b/src/gen/plug/report/Makefile.am index a02064a40..d99064490 100644 --- a/src/gen/plug/report/Makefile.am +++ b/src/gen/plug/report/Makefile.am @@ -7,10 +7,11 @@ pkgdata_PYTHON = \ __init__.py\ _bibliography.py\ _constants.py\ - _options.py\ + _options.py\ _paper.py\ _reportbase.py\ endnotes.py\ + toc_index.py\ utils.py pkgpyexecdir = @pkgpyexecdir@/gen/plug/report diff --git a/src/gen/plug/report/_options.py b/src/gen/plug/report/_options.py index ef70769ae..60132a260 100644 --- a/src/gen/plug/report/_options.py +++ b/src/gen/plug/report/_options.py @@ -83,6 +83,8 @@ class OptionList(_options.OptionList): self.margins = [2.54, 2.54, 2.54, 2.54] self.format_name = None self.css_filename = None + self.toc = None + self.index = None def set_style_name(self, style_name): """ @@ -234,6 +236,38 @@ class OptionList(_options.OptionList): """ return self.format_name + def set_toc(self, toc): + """ + Set the template name for the OptionList. + @param template_name: name of the template to set. + @type template_name: str + """ + self.toc = toc + + def get_toc(self): + """ + Return the template name of the OptionList. + @returns: template name + @rtype: str + """ + return self.toc + + def set_index(self, index): + """ + Set the template name for the OptionList. + @param template_name: name of the template to set. + @type template_name: str + """ + self.index = index + + def get_index(self): + """ + Return the template name of the OptionList. + @returns: template name + @rtype: str + """ + return self.index + #------------------------------------------------------------------------- # # Collection of option lists @@ -256,6 +290,8 @@ class OptionListCollection(_options.OptionListCollection): self.default_custom_paper_size = [29.7, 21.0] self.default_margins = [2.54, 2.54, 2.54, 2.54] self.default_format_name = 'print' + self.default_toc = False + self.default_index = False self.last_paper_metric = self.default_paper_metric self.last_paper_name = self.default_paper_name @@ -264,6 +300,8 @@ class OptionListCollection(_options.OptionListCollection): self.last_margins = copy.copy(self.default_margins) self.last_css_filename = self.default_css_filename self.last_format_name = self.default_format_name + self.last_toc = self.default_toc + self.last_index = self.default_index self.option_list_map = {} def set_last_paper_metric(self, paper_metric): @@ -398,6 +436,34 @@ class OptionListCollection(_options.OptionListCollection): """ return self.last_format_name + def set_last_toc(self, toc): + """ + Set the last format used for the any report in this collection. + + format_name: name of the format to set. + """ + self.last_toc = toc + + def get_last_toc(self): + """ + Return the last format used for the any report in this collection. + """ + return self.last_toc + + def set_last_index(self, index): + """ + Set the last format used for the any report in this collection. + + format_name: name of the format to set. + """ + self.last_index = index + + def get_last_index(self): + """ + Return the last format used for the any report in this collection. + """ + return self.last_index + def write_common(self, f): f.write('\n') if self.get_last_paper_metric() != self.default_paper_metric: @@ -413,6 +479,10 @@ class OptionListCollection(_options.OptionListCollection): f.write(' \n' % escxml(self.get_last_format_name()) ) if self.get_last_orientation() != self.default_orientation: f.write(' \n' % self.get_last_orientation() ) + if self.get_last_toc() != self.default_toc: + f.write(' \n' % self.get_last_toc()) + if self.get_last_index() != self.default_index: + f.write(' \n' % self.get_last_index()) f.write('\n') def write_module_common(self, f, option_list): @@ -441,6 +511,13 @@ class OptionListCollection(_options.OptionListCollection): for pos in range(len(margins)): f.write(' \n' % (pos, margins[pos])) + if option_list.get_format_name() == 'pdf': + if option_list.get_toc(): + f.write(' \n' % + 'True' if option_list.get_toc() else False) + if option_list.get_index(): + f.write(' \n' % + 'True' if option_list.get_index() else False) if option_list.get_style_name(): f.write('