1.1 --- a/moinformat/serialisers/html/graphviz.py Tue Nov 27 21:23:24 2018 +0100
1.2 +++ b/moinformat/serialisers/html/graphviz.py Tue Nov 27 22:48:12 2018 +0100
1.3 @@ -97,27 +97,36 @@
1.4 format = self.directives.get("format", ["svg"])[0]
1.5 transforms = self.directives.get("transform", [])
1.6
1.7 - # Graph output is stored for a known page only.
1.8 + inline = format == "svg"
1.9 +
1.10 + # Non-inline graph output is stored for a known page only.
1.11
1.12 pagename = self.metadata.get("pagename")
1.13 - if not pagename:
1.14 - return
1.15 +
1.16 + if not inline:
1.17 + if not pagename:
1.18 + return
1.19
1.20 - # Get an identifier and usable filename to store the output.
1.21 + # Get an identifier and usable filename to store the output.
1.22
1.23 - identifier = get_output_identifier(text)
1.24 - attachment = "%s.%s" % (identifier, format)
1.25 - filename = self.output.get_attachment_filename(pagename, attachment)
1.26 + identifier = get_output_identifier(text)
1.27 + attachment = "%s.%s" % (identifier, format)
1.28 + filename = self.output.get_attachment_filename(pagename, attachment)
1.29 +
1.30 + # Handle situations where no independent output is permitted.
1.31
1.32 - # Handle situations where no independent output is permitted.
1.33 + if not filename:
1.34 + return
1.35
1.36 - if not filename:
1.37 - return
1.38 + # Make sure that page attachments can be stored.
1.39
1.40 - # Make sure that page attachments can be stored.
1.41 + self.output.ensure_attachments(pagename)
1.42 + target, _label = self.linker.translate("attachment:%s" % attachment)
1.43
1.44 - self.output.ensure_attachments(pagename)
1.45 - target, label = self.linker.translate("attachment:%s" % attachment)
1.46 + # No filename is defined for inline output.
1.47 +
1.48 + else:
1.49 + filename = None
1.50
1.51 # Permit imagemaps only for image formats.
1.52
1.53 @@ -126,7 +135,7 @@
1.54
1.55 # Configure Graphviz and invoke it.
1.56
1.57 - graphviz = Graphviz(filter, text, identifier)
1.58 + graphviz = Graphviz(filter, text)
1.59 graphviz.call(format, transforms, filename)
1.60
1.61 # Obtain any metadata.
1.62 @@ -151,8 +160,13 @@
1.63
1.64 # For other output, create a file and embed the object.
1.65
1.66 + elif not inline:
1.67 + self.object(target, attributes)
1.68 +
1.69 + # Or for inline output, emit it in the document itself.
1.70 +
1.71 else:
1.72 - self.object(target, attributes)
1.73 + self.out(graphviz.get_inline_output())
1.74
1.75 serialiser = HTMLGraphvizSerialiser
1.76
2.1 --- a/moinformat/utils/graphviz.py Tue Nov 27 21:23:24 2018 +0100
2.2 +++ b/moinformat/utils/graphviz.py Tue Nov 27 22:48:12 2018 +0100
2.3 @@ -22,6 +22,7 @@
2.4 from os.path import exists, join
2.5 from StringIO import StringIO
2.6 from subprocess import Popen, PIPE
2.7 +from xml.sax.saxutils import XMLGenerator
2.8 import gzip
2.9 import sha
2.10 import xml.sax
2.11 @@ -63,16 +64,9 @@
2.12 else:
2.13 return s
2.14
2.15 -class MetadataParser(xml.sax.handler.ContentHandler):
2.16 -
2.17 - "Parse metadata from the svg element."
2.18 +class Parser(xml.sax.handler.ContentHandler):
2.19
2.20 - def __init__(self):
2.21 - self.attrs = {}
2.22 -
2.23 - def startElement(self, name, attrs):
2.24 - if name == self.tagname:
2.25 - self.attrs = dict(attrs)
2.26 + "Common XML parsing functionality."
2.27
2.28 def parse(self, f):
2.29
2.30 @@ -87,11 +81,9 @@
2.31 finally:
2.32 f.close()
2.33
2.34 - def get_metadata(self, data, tagname):
2.35 + def parse_data(self, data):
2.36
2.37 - "Process 'data', returning attributes from 'tagname'."
2.38 -
2.39 - self.tagname = tagname
2.40 + "Parse the given 'data'."
2.41
2.42 f = StringIO(data)
2.43 try:
2.44 @@ -99,8 +91,32 @@
2.45 finally:
2.46 f.close()
2.47
2.48 +class MetadataParser(Parser):
2.49 +
2.50 + "Parse metadata from the svg element."
2.51 +
2.52 + def __init__(self):
2.53 + self.attrs = {}
2.54 +
2.55 + def startElement(self, name, attrs):
2.56 + if name == self.tagname:
2.57 + self.attrs = dict(attrs)
2.58 +
2.59 + def get_metadata(self, data, tagname):
2.60 +
2.61 + "Process 'data', returning attributes from 'tagname'."
2.62 +
2.63 + self.tagname = tagname
2.64 + self.parse_data(data)
2.65 return self.attrs
2.66
2.67 +class DocumentSelector(XMLGenerator, Parser):
2.68 +
2.69 + "Parse a document and obtain the serialisation of the document node."
2.70 +
2.71 + def startDocument(self):
2.72 + pass
2.73 +
2.74 def get_output_identifier(text):
2.75
2.76 "Return an output identifier for the given 'text'."
2.77 @@ -179,17 +195,14 @@
2.78
2.79 "A Graphviz configuration for single or repeated invocation."
2.80
2.81 - def __init__(self, filter, text, identifier):
2.82 + def __init__(self, filter, text):
2.83
2.84 """
2.85 - Employ the given 'filter' to produce a graph from the given 'text'. The
2.86 - output 'identifier' for the text is used to provide a filename, if
2.87 - required.
2.88 + Employ the given 'filter' to produce a graph from the given 'text'.
2.89 """
2.90
2.91 self.filter = filter
2.92 self.text = text
2.93 - self.identifier = identifier
2.94
2.95 def call(self, format, transforms=None, filename=None):
2.96
2.97 @@ -264,4 +277,20 @@
2.98 def get_output(self):
2.99 return self.output
2.100
2.101 + def get_inline_output(self):
2.102 +
2.103 + """
2.104 + Return a string containing the document element, excluding XML
2.105 + boilerplate.
2.106 + """
2.107 +
2.108 + f = StringIO()
2.109 + parser = DocumentSelector(f, "utf-8")
2.110 +
2.111 + try:
2.112 + parser.parse_data(self.output)
2.113 + return f.getvalue()
2.114 + finally:
2.115 + f.close()
2.116 +
2.117 # vim: tabstop=4 expandtab shiftwidth=4