Skip to content

Commit 4a9332c

Browse files
committed
fix svg
1 parent 170168d commit 4a9332c

2 files changed

Lines changed: 88 additions & 12 deletions

File tree

_unittests/ut_gdot/test_gdot_extension.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,9 @@ def test_gdot2_split(self):
6868
content = rst2html(
6969
content, writer_name="rst", new_extensions=["sphinx_runpython.gdot"]
7070
)
71-
self.assertIn('digraph foo { "bar" -> "baz"; }', content)
71+
self.assertIn("svg", content)
7272
self.assertNotIn("BEGIN", content)
73+
self.assertNotIn("png", content)
7374

7475
@ignore_warnings(PendingDeprecationWarning)
7576
def test_gdot3_svg(self):
@@ -89,8 +90,8 @@ def test_gdot3_svg(self):
8990
content = rst2html(
9091
content, writer_name="html", new_extensions=["sphinx_runpython.gdot"]
9192
)
92-
self.assertIn("digraph foo {", content)
93-
print(content)
93+
self.assertIn("svg", content)
94+
self.assertNotIn("png", content)
9495

9596
@ignore_warnings(PendingDeprecationWarning)
9697
def test_gdot3_svg_process(self):

sphinx_runpython/gdot/sphinx_gdot_extension.py

Lines changed: 84 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,16 @@
22
import logging
33
from docutils import nodes
44
from docutils.parsers.rst import directives, Directive
5+
from typing import Any
56
import sphinx
6-
from sphinx.ext.graphviz import latex_visit_graphviz, text_visit_graphviz, graphviz
7+
from sphinx.ext.graphviz import (
8+
latex_visit_graphviz,
9+
text_visit_graphviz,
10+
render_dot,
11+
GraphvizError,
12+
ClickableMapDefinition,
13+
__,
14+
)
715
from ..ext_helper import get_env_state_info
816
from ..ext_io_helper import download_requirejs, get_url_content_timeout
917
from ..runpython.sphinx_runpython_extension import run_python_script
@@ -179,14 +187,13 @@ def run(self):
179187
logger.warning("[gdot] too many output lines %s", content)
180188
content = spl[-1]
181189

182-
if format == "svg":
183-
node = graphviz()
184-
node["code"] = content
185-
node["options"] = {"docname": docname}
186-
else:
187-
node = gdot_node(
188-
format=format, code=content, url=url, options={"docname": docname}
189-
)
190+
node = gdot_node(
191+
format=format,
192+
code=content,
193+
url=url,
194+
options={"docname": docname},
195+
use_sphinx_graphviz=True,
196+
)
190197
return [node]
191198

192199

@@ -209,8 +216,76 @@ def depart_gdot_node_rst(self, node):
209216
self.end_state(wrap=False)
210217

211218

219+
def render_dot_html(
220+
self,
221+
node: gdot_node,
222+
code: str,
223+
options: dict[str, Any],
224+
prefix: str = "gdot",
225+
imgcls: str | None = None,
226+
alt: str | None = None,
227+
filename: str | None = None,
228+
format: str = "svg",
229+
) -> tuple[str, str]:
230+
if format not in {"png", "svg"}:
231+
logger = logging.getLogger(__name__)
232+
logger.warning(__("format must be either 'png' or 'svg', but is %r"), format)
233+
try:
234+
fname, outfn = render_dot(self, code, options, format, prefix, filename)
235+
except GraphvizError as exc:
236+
logger.warning(__("dot code %r: %s"), code, exc)
237+
raise nodes.SkipNode from exc
238+
239+
classes = [imgcls, "graphviz", *node.get("classes", [])]
240+
imgcls = " ".join(filter(None, classes))
241+
242+
if fname is None:
243+
self.body.append(self.encode(code))
244+
else:
245+
src = fname.as_posix()
246+
if alt is None:
247+
alt = node.get("alt", self.encode(code).strip())
248+
if "align" in node:
249+
align = node["align"]
250+
self.body.append(f'<div align="{align}" class="align-{align}">')
251+
if format == "svg":
252+
self.body.append('<div class="graphviz">')
253+
self.body.append(
254+
f'<object data="{src}" type="image/svg+xml" class="{imgcls}">\n'
255+
)
256+
self.body.append(f'<p class="warning">{alt}</p>')
257+
self.body.append("</object></div>\n")
258+
else:
259+
assert outfn is not None
260+
with open(f"{outfn}.map", encoding="utf-8") as mapfile:
261+
map_content = mapfile.read()
262+
imgmap = ClickableMapDefinition(f"{outfn}.map", map_content, dot=code)
263+
if imgmap.clickable:
264+
# has a map
265+
self.body.append('<div class="graphviz">')
266+
self.body.append(
267+
f'<img src="{src}" alt="{alt}" usemap="#{imgmap.id}" class="{imgcls}" />'
268+
)
269+
self.body.append("</div>\n")
270+
self.body.append(imgmap.generate_clickable_map())
271+
else:
272+
# nothing in image map
273+
self.body.append('<div class="graphviz">')
274+
self.body.append(f'<img src="{src}" alt="{alt}" class="{imgcls}" />')
275+
self.body.append("</div>\n")
276+
if "align" in node:
277+
self.body.append("</div>\n")
278+
279+
raise nodes.SkipNode
280+
281+
212282
def visit_gdot_node_html_svg(self, node):
213283
"""visit collapse_node"""
284+
if node["use_sphinx_graphviz"]:
285+
render_dot_html(
286+
self, node, node["code"], node["options"], filename=node.get("filename")
287+
)
288+
return
214289

215290
def process(text):
216291
text = text.replace("\\", "\\\\")

0 commit comments

Comments
 (0)