Skip to content

Commit 8494638

Browse files
committed
Fix graphviz: workaround for wrong map ID which graphviz generates
1 parent 2312a0a commit 8494638

File tree

3 files changed

+28
-18
lines changed

3 files changed

+28
-18
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Bugs fixed
2525
* #4449: apidoc: include "empty" packages that contain modules
2626
* #3917: citation labels are tranformed to ellipsis
2727
* #4501: graphviz: epub3 validation error caused if graph is not clickable
28+
* #4514: graphviz: workaround for wrong map ID which graphviz generates
2829

2930
Testing
3031
--------

sphinx/ext/graphviz.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,29 @@ class ClickableMapDefinition(object):
4747
maptag_re = re.compile('<map id="(.*?)"')
4848
href_re = re.compile('href=".*?"')
4949

50-
def __init__(self, filename, content):
51-
# type: (unicode, unicode) -> None
50+
def __init__(self, filename, content, dot=''):
51+
# type: (unicode, unicode, unicode) -> None
5252
self.id = None
5353
self.filename = filename
5454
self.content = content.splitlines()
5555
self.clickable = [] # type: List[unicode]
5656

57-
self.parse()
57+
self.parse(dot=dot)
5858

59-
def parse(self):
60-
# type: () -> None
59+
def parse(self, dot=None):
60+
# type: (None) -> None
6161
matched = self.maptag_re.match(self.content[0]) # type: ignore
6262
if not matched:
6363
raise GraphvizError('Invalid clickable map file found: %s' % self.filename)
6464

6565
self.id = matched.group(1)
66+
if self.id == '%3':
67+
# graphviz generates wrong ID if graph name not specified
68+
# https://gitlab.com/graphviz/graphviz/issues/1327
69+
hashed = sha1(dot.encode('utf-8')).hexdigest()
70+
self.id = 'grapviz%s' % hashed[-10:]
71+
self.content[0] = self.content[0].replace('%3', self.id)
72+
6673
for line in self.content:
6774
if self.href_re.search(line):
6875
self.clickable.append(line)
@@ -289,7 +296,7 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
289296
self.body.append(svgtag)
290297
else:
291298
with codecs.open(outfn + '.map', 'r', encoding='utf-8') as mapfile:
292-
imgmap = ClickableMapDefinition(outfn + '.map', mapfile.read())
299+
imgmap = ClickableMapDefinition(outfn + '.map', mapfile.read(), dot=code)
293300
if imgmap.clickable:
294301
# has a map
295302
self.body.append('<img src="%s" alt="%s" usemap="#%s" %s/>\n' %

tests/test_ext_graphviz.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,30 +118,32 @@ def test_graphviz_i18n(app, status, warning):
118118

119119

120120
def test_graphviz_parse_mapfile():
121-
# digraph {
122-
# }
121+
# empty graph
122+
code = ('# digraph {\n'
123+
'# }\n')
123124
content = ('<map id="%3" name="%3">\n'
124125
'</map>')
125-
cmap = ClickableMapDefinition('dummy.map', content)
126+
cmap = ClickableMapDefinition('dummy.map', content, code)
126127
assert cmap.filename == 'dummy.map'
127-
assert cmap.id == '%3'
128+
assert cmap.id == 'grapvizb08107169e'
128129
assert len(cmap.clickable) == 0
129130
assert cmap.generate_clickable_map() == ''
130131

131-
# digraph {
132-
# foo [href="http://www.google.com/"];
133-
# foo -> bar;
134-
# }
132+
# normal graph
133+
code = ('digraph {\n'
134+
' foo [href="http://www.google.com/"];\n'
135+
' foo -> bar;\n'
136+
'}\n')
135137
content = ('<map id="%3" name="%3">\n'
136138
'<area shape="poly" id="node1" href="http://www.google.com/" title="foo" alt=""'
137139
' coords="77,29,76,22,70,15,62,10,52,7,41,5,30,7,20,10,12,15,7,22,5,29,7,37,12,'
138140
'43,20,49,30,52,41,53,52,52,62,49,70,43,76,37"/>\n'
139141
'</map>')
140-
cmap = ClickableMapDefinition('dummy.map', content)
142+
cmap = ClickableMapDefinition('dummy.map', content, code)
141143
assert cmap.filename == 'dummy.map'
142-
assert cmap.id == '%3'
144+
assert cmap.id == 'grapviza4ccdd48ce'
143145
assert len(cmap.clickable) == 1
144-
assert cmap.generate_clickable_map() == content
146+
assert cmap.generate_clickable_map() == content.replace('%3', cmap.id)
145147

146148
# inheritance-diagram:: sphinx.builders.html
147149
content = (
@@ -168,7 +170,7 @@ def test_graphviz_parse_mapfile():
168170
' alt="" coords="11,3,141,19"/>\n'
169171
'</map>'
170172
)
171-
cmap = ClickableMapDefinition('dummy.map', content)
173+
cmap = ClickableMapDefinition('dummy.map', content, 'dummy_code')
172174
assert cmap.filename == 'dummy.map'
173175
assert cmap.id == 'inheritance66ff5471b9'
174176
assert len(cmap.clickable) == 0

0 commit comments

Comments
 (0)