From e4c2f5fe7707e9deeabc7b60ca26f0781625c0f7 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 23 Jun 2016 22:01:20 +0100 Subject: [PATCH] Convert document generators to use abstract base classes --- gramps/gen/plug/docgen/basedoc.py | 13 +++--- gramps/gen/plug/docgen/drawdoc.py | 33 +++++++++++----- gramps/gen/plug/docgen/graphdoc.py | 20 +++++----- gramps/gen/plug/docgen/textdoc.py | 63 ++++++++++++++++-------------- 4 files changed, 76 insertions(+), 53 deletions(-) diff --git a/gramps/gen/plug/docgen/basedoc.py b/gramps/gen/plug/docgen/basedoc.py index 885081c58..a1b4fb040 100644 --- a/gramps/gen/plug/docgen/basedoc.py +++ b/gramps/gen/plug/docgen/basedoc.py @@ -29,9 +29,10 @@ interfaces should be derived from the core classes. #------------------------------------------------------------------------- # -# standard python modules +# Standard Python modules # #------------------------------------------------------------------------- +from abc import ABCMeta, abstractmethod #------------------------------------------------------------------------- # @@ -53,7 +54,7 @@ log = logging.getLogger(".basedoc") # BaseDoc # #------------------------------------------------------------------------ -class BaseDoc: +class BaseDoc(metaclass=ABCMeta): """ Base class for document generators. Different output formats, such as OpenOffice, AbiWord, and LaTeX are derived from this base @@ -101,14 +102,16 @@ class BaseDoc: """ self._style_sheet = StyleSheet(style_sheet) + @abstractmethod def open(self, filename): """ Opens the file so that it can be generated. :param filename: path name of the file to create """ - raise NotImplementedError + @abstractmethod def close(self): - "Closes the generated file." - raise NotImplementedError + """ + Closes the generated file. + """ diff --git a/gramps/gen/plug/docgen/drawdoc.py b/gramps/gen/plug/docgen/drawdoc.py index fab8141b3..afbdb95c3 100644 --- a/gramps/gen/plug/docgen/drawdoc.py +++ b/gramps/gen/plug/docgen/drawdoc.py @@ -26,9 +26,10 @@ #------------------------------------------------------------------------- # -# standard python modules +# Standard Python modules # #------------------------------------------------------------------------- +from abc import ABCMeta, abstractmethod #------------------------------------------------------------------------- # @@ -50,18 +51,24 @@ log = logging.getLogger(".drawdoc") # DrawDoc # #------------------------------------------------------------------------ -class DrawDoc: +class DrawDoc(metaclass=ABCMeta): """ Abstract Interface for graphical document generators. Output formats for graphical reports must implement this interface to be used by the report system. """ + @abstractmethod def start_page(self): - raise NotImplementedError + """ + Start a page. + """ + @abstractmethod def end_page(self): - raise NotImplementedError + """ + End a page. + """ def get_usable_width(self): """ @@ -91,32 +98,38 @@ class DrawDoc: "Determine the width need for multiline text in given font" return fontscale.string_multiline_width(fontstyle, text) + @abstractmethod def draw_path(self, style, path): - raise NotImplementedError + """ + Draw a path. + """ + @abstractmethod def draw_box(self, style, text, x, y, w, h, mark=None): """ :param mark: :class:`.IndexMark` to use for indexing (if supported) """ - raise NotImplementedError + @abstractmethod def draw_text(self, style, text, x1, y1, mark=None): """ :param mark: :class:`.IndexMark` to use for indexing (if supported) """ - raise NotImplementedError + @abstractmethod def center_text(self, style, text, x1, y1, mark=None): """ :param mark: :class:`.IndexMark` to use for indexing (if supported) """ - raise NotImplementedError + @abstractmethod def rotate_text(self, style, text, x, y, angle, mark=None): """ :param mark: :class:`.IndexMark` to use for indexing (if supported) """ - raise NotImplementedError + @abstractmethod def draw_line(self, style, x1, y1, x2, y2): - raise NotImplementedError + """ + Draw a line. + """ diff --git a/gramps/gen/plug/docgen/graphdoc.py b/gramps/gen/plug/docgen/graphdoc.py index 1be45f0e2..e5b57b715 100644 --- a/gramps/gen/plug/docgen/graphdoc.py +++ b/gramps/gen/plug/docgen/graphdoc.py @@ -24,11 +24,12 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -#------------------------------------------------------------------------ +#------------------------------------------------------------------------- # -# python modules +# Standard Python modules # -#------------------------------------------------------------------------ +#------------------------------------------------------------------------- +from abc import ABCMeta, abstractmethod import os from io import BytesIO import tempfile @@ -278,12 +279,14 @@ class GVOptions: # GVDoc # #------------------------------------------------------------------------------- -class GVDoc: +class GVDoc(metaclass=ABCMeta): """ Abstract Interface for Graphviz document generators. Output formats for Graphviz reports must implement this interface to be used by the report system. """ + + @abstractmethod def add_node(self, node_id, label, shape="", color="", style="", fillcolor="", url="", htmloutput=False): """ @@ -313,8 +316,8 @@ class GVDoc: :type htmloutput: boolean :return: nothing """ - raise NotImplementedError + @abstractmethod def add_link(self, id1, id2, style="", head="", tail="", comment=""): """ Add a link between two nodes. @@ -330,8 +333,8 @@ class GVDoc: :type comment: string :return: nothing """ - raise NotImplementedError + @abstractmethod def add_comment(self, comment): """ Add a comment to the source file. @@ -341,8 +344,8 @@ class GVDoc: :type comment: string :return: nothing """ - raise NotImplementedError + @abstractmethod def start_subgraph(self, graph_id): """ Start a subgraph in this graph. @@ -352,15 +355,14 @@ class GVDoc: :type id1: string :return: nothing """ - raise NotImplementedError + @abstractmethod def end_subgraph(self): """ End a subgraph that was previously started in this graph. :return: nothing """ - raise NotImplementedError #------------------------------------------------------------------------------- # diff --git a/gramps/gen/plug/docgen/textdoc.py b/gramps/gen/plug/docgen/textdoc.py index 186349ea0..cd26ffd6d 100644 --- a/gramps/gen/plug/docgen/textdoc.py +++ b/gramps/gen/plug/docgen/textdoc.py @@ -28,9 +28,10 @@ #------------------------------------------------------------------------- # -# standard python modules +# Standard Python modules # #------------------------------------------------------------------------- +from abc import ABCMeta, abstractmethod #------------------------------------------------------------------------- # @@ -87,30 +88,44 @@ class IndexMark: # #------------------------------------------------------------------------ -class TextDoc: +class TextDoc(metaclass=ABCMeta): """ Abstract Interface for text document generators. Output formats for text reports must implement this interface to be used by the report system. """ + + @abstractmethod def page_break(self): """ Forces a page break, creating a new page. """ - raise NotImplementedError + @abstractmethod def start_bold(self): - raise NotImplementedError + """ + Start a section of bold text. + """ + @abstractmethod def end_bold(self): - raise NotImplementedError + """ + End a section of bold text. + """ + @abstractmethod def start_superscript(self): - raise NotImplementedError + """ + Start a section of superscript text. + """ + @abstractmethod def end_superscript(self): - raise NotImplementedError + """ + End a section of superscript text. + """ + @abstractmethod def start_paragraph(self, style_name, leader=None): """ Starts a new paragraph, using the specified style name. @@ -120,14 +135,14 @@ class TextDoc: :param leader: Leading text for a paragraph. Typically used for numbering. """ - raise NotImplementedError + @abstractmethod def end_paragraph(self): """ Ends the current paragraph. """ - raise NotImplementedError + @abstractmethod def start_table(self, name, style_name): """ Starts a new table. @@ -135,24 +150,26 @@ class TextDoc: :param name: Unique name of the table. :param style_name: :class:`.TableStyle` to use for the new table """ - raise NotImplementedError + @abstractmethod def end_table(self): - "Ends the current table" - raise NotImplementedError + """ + Ends the current table. + """ + @abstractmethod def start_row(self): """ Starts a new row on the current table. """ - raise NotImplementedError + @abstractmethod def end_row(self): """ Ends the current row on the current table. """ - raise NotImplementedError + @abstractmethod def start_cell(self, style_name, span=1): """ Starts a new table cell, using the paragraph style specified. @@ -160,14 +177,14 @@ class TextDoc: :param style_name: :class:`.TableCellStyle` to use for the cell :param span: number of columns to span """ - raise NotImplementedError + @abstractmethod def end_cell(self): """ Ends the current table cell. """ - raise NotImplementedError + @abstractmethod def write_text(self, text, mark=None, links=False): """ Writes the text in the current paragraph. Should only be used after a @@ -177,7 +194,6 @@ class TextDoc: :param mark: :class:`.IndexMark` to use for indexing (if supported) :param links: make URLs in the text clickable (if supported) """ - raise NotImplementedError def write_markup(self, text, s_tags, mark=None): """ @@ -193,17 +209,6 @@ class TextDoc: """ self.write_text(text, mark=mark) - def write_note(self, text, format, style_name): - """ - Writes the note's text and take care of paragraphs, - depending on the format. - - :param text: text to write. - :param format: format to use for writing. True for flowed text, - 1 for preformatted text. - """ - raise NotImplementedError - def write_styled_note(self, styledtext, format, style_name, contains_html=False, links=False): """ @@ -256,6 +261,7 @@ class TextDoc: else: self.write_text(piece, links=links) + @abstractmethod def add_media(self, name, align, w_cm, h_cm, alt='', style_name=None, crop=None): """ Add a photo of the specified width (in centimeters). @@ -269,7 +275,6 @@ class TextDoc: :param style_name: style to use for captions :param crop: image cropping parameters """ - raise NotImplementedError def start_link(self, link): """