MoinLight

moinformat/serialisers/html/graphviz.py

104:8d437cdf2381
2018-07-30 Paul Boddie Introduced Unicode strings as the typical form of document data for processing, employing output encodings when serialising output documents. Introduced input contexts which provide details of input document encodings and document source locations. Introduced the familiar manifest and lookup mechanisms for input and output contexts. Provided support for standalone contexts, with the output context suppressing the generation of additional files. Moved common directory functionality to a separate utility module. Updated the conversion script and test framework, adding encoding-related tests.
     1 #!/usr/bin/env python     2      3 """     4 Graphviz serialiser, generating content for embedding in HTML documents.     5      6 Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>     7      8 This program is free software; you can redistribute it and/or modify it under     9 the terms of the GNU General Public License as published by the Free Software    10 Foundation; either version 3 of the License, or (at your option) any later    11 version.    12     13 This program is distributed in the hope that it will be useful, but WITHOUT    14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    15 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    16 details.    17     18 You should have received a copy of the GNU General Public License along with    19 this program.  If not, see <http://www.gnu.org/licenses/>.    20 """    21     22 from moinformat.serialisers.common import Serialiser, escape_attr, escape_text    23 from moinformat.utils.graphviz import Graphviz, GraphvizError, IMAGE_FORMATS, \    24                                       get_output_identifier    25     26 # Utility functions.    27     28 def select_keys(d, keys):    29     30     "Select from 'd' the given 'keys'."    31     32     if not d:    33         return []    34     35     out = {}    36     37     for key in keys:    38         if d.has_key(key):    39             out[key] = d[key]    40     41     return out    42     43     44     45 # The serialiser class.    46     47 class HTMLGraphvizSerialiser(Serialiser):    48     49     "Serialisation of Graphviz regions."    50     51     def init(self):    52         self.directives = {}    53     54     def start_block(self):    55         pass    56     57     def end_block(self):    58         pass    59     60     def directive(self, key, value):    61         if not self.directives.has_key(key):    62             self.directives[key] = []    63         self.directives[key].append(value)    64     65     def text(self, text):    66         self.process_graph(text)    67     68     69     70     # Special methods for graph production.    71     72     def _tag(self, tagname, attrname, filename, attributes, closing):    73         l = ["%s='%s'" % (attrname, escape_attr(filename))]    74         for key, value in attributes.items():    75             l.append("%s='%s'" % (key, value))    76         self.out("<%s %s%s>" % (tagname, " ".join(l), closing and " /"))    77     78     def image(self, filename, attributes):    79         self._tag("img", "src", filename, attributes, True)    80     81     def object(self, filename, attributes):    82         self._tag("object", "data", filename, attributes, False)    83         self.out("</object>")    84     85     def raw(self, text):    86         self.out(text)    87     88     89     90     # Graph output preparation.    91     92     def process_graph(self, text):    93     94         "Process the graph 'text' using the known directives."    95     96         filter = self.directives.get("filter", ["dot"])[0]    97         format = self.directives.get("format", ["svg"])[0]    98         transforms = self.directives.get("transform", [])    99    100         # Get an identifier and usable filename to store the output.   101    102         identifier = get_output_identifier(text)   103         filename = self.output.get_filename(identifier)   104    105         # Handle situations where no independent output is permitted.   106    107         if not filename:   108             return   109    110         # Permit imagemaps only for image formats.   111    112         if format in IMAGE_FORMATS:   113             cmapx = self.directives.has_key("cmapx")   114    115         # Configure Graphviz and invoke it.   116    117         graphviz = Graphviz(filter, text, identifier)   118         graphviz.call(format, transforms, filename)   119    120         # Obtain any metadata.   121    122         attributes = select_keys(graphviz.get_metadata(), ["width", "height"])   123    124         # For image output, create a file directly and reference it.   125    126         if format in IMAGE_FORMATS:   127    128             # Produce, embed and reference an imagemap if requested.   129    130             if cmapx:   131                 graphviz.call("cmapx")   132                 mapid = graphviz.get_metadata().get("id")   133    134                 if mapid:   135                     self.raw(graphviz.get_output())   136                     attributes["usemap"] = "#%s" % im_attributes["id"]   137    138             self.image(filename, attributes)   139    140         # For other output, create a file and embed the object.   141    142         else:   143             self.object(filename, attributes)   144    145 serialiser = HTMLGraphvizSerialiser   146    147 # vim: tabstop=4 expandtab shiftwidth=4