Skip to content

Commit

Permalink
https://github.com/mingrammer/diagrams/issues/26
Browse files Browse the repository at this point in the history
  • Loading branch information
shagr4th committed Jul 25, 2022
1 parent ad5593e commit 78ce45b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
51 changes: 51 additions & 0 deletions diagrams/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ def __str__(self) -> str:
class Diagram(_Cluster):
__curvestyles = ("ortho", "curved")
__outformats = ("png", "jpg", "svg", "pdf", "dot")
__embedformats = ("png", "jpg")

# fmt: off
_default_graph_attrs = {
Expand Down Expand Up @@ -153,6 +154,7 @@ def __init__(
graph_attr: dict = {},
node_attr: dict = {},
edge_attr: dict = {},
embed = False
):
"""Diagram represents a global diagrams context.
Expand Down Expand Up @@ -210,6 +212,7 @@ def __init__(
self.dot.edge_attr.update(edge_attr)

self.show = show
self.embed = embed

def __enter__(self):
setdiagram(self)
Expand All @@ -233,8 +236,56 @@ def __exit__(self, *args):

self.render()
# Remove the graphviz file leaving only the image.
if self.embed:
self._embed_svg()
os.remove(self.filename)

# https://github.com/FFengIll/diagrams/commit/d6970ab8a19e8f07899565999576def77857dbd1
def _embed_svg(self):
"""
Process svg href here
<image xlink:href="..." .../>
<image xlink:href="data:image/png;base64,..." .../>
"""
if self.outformat != 'svg':
return

from lxml import etree
from base64 import b64encode
import traceback
import os

path = self.filename + '.svg'
xml = etree.parse(path)

svg = xml.getroot()

# Mention: must give svg namespace
tag_image = './/{http://www.w3.org/2000/svg}image'
tag_href = '{http://www.w3.org/1999/xlink}href'

for img in svg.findall(tag_image):
rsc = img.attrib.get(tag_href, None)

# Only process local image files
if rsc is None or not os.path.exists(rsc):
continue

# Only support some pre-define type
ext = rsc.split('.')[-1]
if ext not in self.__embedformats:
continue

# Use base64 to embed the image resource
with open(rsc, 'rb') as data:
b = data.read()
code = b64encode(b)
img.attrib[tag_href] = 'data:image/{};base64,{}'.format(
ext, code.decode())

# Write back to the svg file
etree.ElementTree(svg).write(path)

def _repr_png_(self):
return self.dot.pipe(format="png")

Expand Down
3 changes: 2 additions & 1 deletion diagrams/custom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ def __init__(self, label, icon_path, **attrs: Dict):
if icon_path.startswith('data:image/'):
with urlopen(icon_path) as response:
data = response.read()
icon_path = "/tmp/" + hashlib.md5(data).hexdigest()
imageformat = icon_path[11:icon_path.index(';')]
icon_path = "/tmp/" + hashlib.md5(data).hexdigest() + "." + imageformat
with open(icon_path, "wb") as f:
f.write(data)
f.close()
Expand Down
2 changes: 1 addition & 1 deletion docker/dev/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ WORKDIR /usr/src/diagrams
COPY . .

# install python requirements.
RUN pip install Flask black graphviz jinja2
RUN pip install Flask black graphviz jinja2 lxml

RUN wget https://github.com/material-icons/material-icons-png/archive/refs/heads/master.zip -O master.zip && \
unzip -d /tmp master.zip && rm -f master.zip && mv /tmp/material-icons-png-master/png / && \
Expand Down

0 comments on commit 78ce45b

Please sign in to comment.