Convert document generators to use abstract base classes

This commit is contained in:
Nick Hall 2016-06-23 22:01:20 +01:00
parent f0210825de
commit e4c2f5fe77
4 changed files with 76 additions and 53 deletions

View File

@ -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.
"""

View File

@ -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.
"""

View File

@ -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
#-------------------------------------------------------------------------------
#

View File

@ -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):
"""