Commits

Takeshi Komiya committed 73e0e52

* Apply blockdiag_html_image_format patch by @r_rudi
- Enable blockdiag_html_image_format = "SVG"
- Support PNG image using clickable map on HTML

Comments (0)

Files changed (1)

blockdiag/sphinxcontrib/blockdiag.py

     """
     Get path of output file.
     """
-    if format not in ('PNG', 'PDF'):
+    if format not in ('PNG', 'PDF', 'SVG'):
         raise BlockdiagError('blockdiag error:\nunknown format: %s\n' % format)
 
     if format == 'PDF':
         antialias = self.builder.config.blockdiag_antialias
         draw = DiagramDraw.DiagramDraw(format, screen, filename, fontmap=fontmap,
                                        antialias=antialias)
+
     except Exception, e:
         raise BlockdiagError('blockdiag error:\n%s\n' % e)
 
     return draw
 
 
+def make_svgtag(self, image, relfn, trelfn, outfn,
+                alt, thumb_size, image_size):
+    svgtag_format = """<svg xmlns="http://www.w3.org/2000/svg"
+    xmlns:xlink="http://www.w3.org/1999/xlink"
+    alt="%s" width="%s" height="%s">%s
+    </svg>"""
+
+    code = open(outfn, 'r').read().decode('utf-8')
+
+    return (svgtag_format %
+            (alt, image_size[0], image_size[1], code))
+
+
+def make_imgtag(self, image, relfn, trelfn, outfn,
+                alt, thumb_size, image_size):
+    result = ""
+
+    clickable_map = []
+    for n in image.nodes:
+        if n.href:
+            cell = image.metrics.cell(n)
+            clickable_map.append((cell, n.href))
+
+    if clickable_map:
+        imgtag_format = '<img src="%s" alt="%s" width="%s" '
+        imgtag_format += 'usemap="#map_1" height="%s" />\n'  # TODO:mapname
+    else:
+        imgtag_format = '<img src="%s" alt="%s" width="%s" height="%s" />\n'
+
+    if trelfn:
+        result += ('<a href="%s">' % relfn)
+        result += (imgtag_format %
+                   (trelfn, alt, thumb_size[0], thumb_size[1]))
+        result += ('</a>')
+    else:
+        result += (imgtag_format %
+                   (relfn, alt, image_size[0], image_size[1]))
+
+    if clickable_map:
+        result += ('<map name="map_1">')
+        rect_format = '<area shape="rect" coords="%s,%s,%s,%s" href="%s">'
+        for m in clickable_map:
+            x1 = m[0].x1
+            y1 = m[0].y1
+            x2 = m[0].x2
+            y2 = m[0].y2
+            result += (rect_format % (x1, y1, x2, y2, m[1]))
+
+        result += ('</map>')
+
+    return result
+
+
 def render_dot_html(self, node, code, options, prefix='blockdiag',
                     imgcls=None, alt=None):
-    has_thumbnail = False
+    trelfn = None
+    thumb_size = None
     try:
         format = self.builder.config.blockdiag_html_image_format
         relfn, outfn = get_image_filename(self, code, format, options, prefix)
 
         image = create_blockdiag(self, code, format, outfn, options, prefix)
+
         if not os.path.isfile(outfn):
             image.draw()
             image.save()
         # generate thumbnails
         image_size = image.pagesize()
         if 'maxwidth' in options and options['maxwidth'] < image_size[0]:
-            has_thumbnail = True
             thumb_prefix = prefix + '_thumb'
             trelfn, toutfn = get_image_filename(self, code, format,
                                                 options, thumb_prefix)
         if alt is None:
             alt = node.get('alt', self.encode(code).strip())
 
-        imgtag_format = '<img src="%s" alt="%s" width="%s" height="%s" />\n'
-        if has_thumbnail:
-            self.body.append('<a href="%s">' % relfn)
-            self.body.append(imgtag_format %
-                             (trelfn, alt, thumb_size[0], thumb_size[1]))
-            self.body.append('</a>')
+        if format == 'SVG':
+            tagfunc = make_svgtag
         else:
-            self.body.append(imgtag_format %
-                             (relfn, alt, image_size[0], image_size[1]))
+            tagfunc = make_imgtag
+
+        self.body.append(tagfunc(self, image, relfn, trelfn, outfn, alt,
+                                 thumb_size, image_size))
 
     self.body.append('</p>\n')
     raise nodes.SkipNode
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.