1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/moinformat/serialisers/html/graphviz.py Sun Jul 29 23:28:13 2018 +0200
1.3 @@ -0,0 +1,142 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +"""
1.7 +Graphviz serialiser, generating content for embedding in HTML documents.
1.8 +
1.9 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
1.10 +
1.11 +This program is free software; you can redistribute it and/or modify it under
1.12 +the terms of the GNU General Public License as published by the Free Software
1.13 +Foundation; either version 3 of the License, or (at your option) any later
1.14 +version.
1.15 +
1.16 +This program is distributed in the hope that it will be useful, but WITHOUT
1.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.19 +details.
1.20 +
1.21 +You should have received a copy of the GNU General Public License along with
1.22 +this program. If not, see <http://www.gnu.org/licenses/>.
1.23 +"""
1.24 +
1.25 +from moinformat.serialisers.common import Serialiser, escape_attr, escape_text
1.26 +from moinformat.utils.graphviz import Graphviz, GraphvizError, IMAGE_FORMATS, \
1.27 + get_output_identifier
1.28 +
1.29 +# Utility functions.
1.30 +
1.31 +def select_keys(d, keys):
1.32 +
1.33 + "Select from 'd' the given 'keys'."
1.34 +
1.35 + if not d:
1.36 + return []
1.37 +
1.38 + out = {}
1.39 +
1.40 + for key in keys:
1.41 + if d.has_key(key):
1.42 + out[key] = d[key]
1.43 +
1.44 + return out
1.45 +
1.46 +
1.47 +
1.48 +# The serialiser class.
1.49 +
1.50 +class HTMLGraphvizSerialiser(Serialiser):
1.51 +
1.52 + "Serialisation of Graphviz regions."
1.53 +
1.54 + def init(self):
1.55 + self.directives = {}
1.56 +
1.57 + def start_block(self):
1.58 + pass
1.59 +
1.60 + def end_block(self):
1.61 + pass
1.62 +
1.63 + def directive(self, key, value):
1.64 + if not self.directives.has_key(key):
1.65 + self.directives[key] = []
1.66 + self.directives[key].append(value)
1.67 +
1.68 + def text(self, text):
1.69 + self.process_graph(text)
1.70 +
1.71 +
1.72 +
1.73 + # Special methods for graph production.
1.74 +
1.75 + def _tag(self, tagname, attrname, filename, attributes, closing):
1.76 + l = ["%s='%s'" % (attrname, escape_attr(filename))]
1.77 + for key, value in attributes.items():
1.78 + l.append("%s='%s'" % (key, value))
1.79 + self.out("<%s %s%s>" % (tagname, " ".join(l), closing and " /"))
1.80 +
1.81 + def image(self, filename, attributes):
1.82 + self._tag("img", "src", filename, attributes, True)
1.83 +
1.84 + def object(self, filename, attributes):
1.85 + self._tag("object", "data", filename, attributes, False)
1.86 + self.out("</object>")
1.87 +
1.88 + def raw(self, text):
1.89 + self.out(text)
1.90 +
1.91 +
1.92 +
1.93 + # Graph output preparation.
1.94 +
1.95 + def process_graph(self, text):
1.96 +
1.97 + "Process the graph 'text' using the known directives."
1.98 +
1.99 + filter = self.directives.get("filter", ["dot"])[0]
1.100 + format = self.directives.get("format", ["svg"])[0]
1.101 + transforms = self.directives.get("transform", [])
1.102 +
1.103 + # Get an identifier and usable filename to store the output.
1.104 +
1.105 + identifier = get_output_identifier(text)
1.106 + filename = self.output.get_filename(identifier)
1.107 +
1.108 + # Permit imagemaps only for image formats.
1.109 +
1.110 + if format in IMAGE_FORMATS:
1.111 + cmapx = self.directives.has_key("cmapx")
1.112 +
1.113 + # Configure Graphviz and invoke it.
1.114 +
1.115 + graphviz = Graphviz(filter, text, identifier)
1.116 + graphviz.call(format, transforms, filename)
1.117 +
1.118 + # Obtain any metadata.
1.119 +
1.120 + attributes = select_keys(graphviz.get_metadata(), ["width", "height"])
1.121 +
1.122 + # For image output, create a file directly and reference it.
1.123 +
1.124 + if format in IMAGE_FORMATS:
1.125 +
1.126 + # Produce, embed and reference an imagemap if requested.
1.127 +
1.128 + if cmapx:
1.129 + graphviz.call("cmapx")
1.130 + mapid = graphviz.get_metadata().get("id")
1.131 +
1.132 + if mapid:
1.133 + self.raw(graphviz.get_output())
1.134 + attributes["usemap"] = "#%s" % im_attributes["id"]
1.135 +
1.136 + self.image(filename, attributes)
1.137 +
1.138 + # For other output, create a file and embed the object.
1.139 +
1.140 + else:
1.141 + self.object(filename, attributes)
1.142 +
1.143 +serialiser = HTMLGraphvizSerialiser
1.144 +
1.145 +# vim: tabstop=4 expandtab shiftwidth=4