Skip to content

Commit 9c64533

Browse files
committed
Factoring run_graphviz out of mdx_graphviz.py
This is a step towards adding reStructuredText support (see issue #32).
1 parent c5b67d9 commit 9c64533

File tree

2 files changed

+99
-80
lines changed

2 files changed

+99
-80
lines changed

pelican/plugins/graphviz/mdx_graphviz.py

Lines changed: 2 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -14,48 +14,16 @@
1414
#
1515
# You should have received a copy of the GNU Affero General Public License
1616
# along with this program. If not, see http://www.gnu.org/licenses/.
17-
#
18-
#
19-
# The run_graphviz function was taken from:
20-
# https://github.com/tkf/ipython-hierarchymagic/blob/master/hierarchymagic.py
21-
# which has the following licensing terms:
22-
#
23-
# Copyright (c) 2012 Takafumi Arakaki
24-
# All rights reserved.
25-
#
26-
# Redistribution and use in source and binary forms, with or without
27-
# modification, are permitted provided that the following conditions are
28-
# met:
29-
#
30-
# Redistributions of source code must retain the above copyright notice,
31-
# this list of conditions and the following disclaimer.
32-
#
33-
# Redistributions in binary form must reproduce the above copyright
34-
# notice, this list of conditions and the following disclaimer in the
35-
# documentation and/or other materials provided with the distribution.
36-
#
37-
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
38-
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39-
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
40-
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
41-
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42-
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43-
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44-
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45-
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46-
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47-
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4817

4918
import base64
50-
import errno
51-
import os
5219
import re
53-
from subprocess import PIPE, Popen
5420
import xml.etree.ElementTree as ET
5521

5622
from markdown import Extension
5723
from markdown.blockprocessors import BlockProcessor
5824

25+
from .run_graphviz import run_graphviz
26+
5927

6028
class DotRuntimeError(RuntimeError):
6129
"""Exception for dot program."""
@@ -65,52 +33,6 @@ def __init__(self, errmsg):
6533
super().__init__(f"dot exited with error:\n[stderr]\n{errmsg}")
6634

6735

68-
def run_graphviz(program, code, options=None, format="png"):
69-
"""Run graphviz program and returns image data."""
70-
if not options:
71-
options = []
72-
73-
dot_command = [program, *options, "-T", format]
74-
75-
if os.name == "nt":
76-
# Avoid opening shell window.
77-
# * https://github.com/tkf/ipython-hierarchymagic/issues/1
78-
# * http://stackoverflow.com/a/2935727/727827
79-
p = Popen(
80-
dot_command,
81-
stdout=PIPE,
82-
stdin=PIPE,
83-
stderr=PIPE,
84-
creationflags=0x08000000,
85-
)
86-
else:
87-
p = Popen(dot_command, stdout=PIPE, stdin=PIPE, stderr=PIPE)
88-
89-
# Initialize error flag variable
90-
wentwrong = False
91-
92-
try:
93-
# Graphviz may close standard input when an error occurs,
94-
# resulting in a broken pipe on communicate()
95-
stdout, stderr = p.communicate(code.encode("utf-8"))
96-
except OSError as err:
97-
if err.errno not in (errno.EPIPE, errno.EINVAL):
98-
raise
99-
wentwrong = True
100-
101-
if wentwrong:
102-
# in this case, read the standard output and standard error streams
103-
# directly, to get the error message(s)
104-
stdout, stderr = p.stdout.read(), p.stderr.read()
105-
p.wait()
106-
107-
if p.returncode != 0:
108-
errmsg = stderr.decode("utf-8")
109-
raise DotRuntimeError(errmsg)
110-
111-
return stdout
112-
113-
11436
class GraphvizProcessor(BlockProcessor):
11537
"""Block processor for the Graphviz Markdown Extension."""
11638

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""Run Graphviz for the Pelican plugin."""
2+
3+
# Copyright (C) 2015, 2021, 2023, 2025 Rafael Laboissière
4+
#
5+
# This program is free software: you can redistribute it and/or modify it
6+
# under the terms of the GNU General Affero Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or (at
8+
# your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful, but
11+
# WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
# Affero General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Affero General Public License
16+
# along with this program. If not, see http://www.gnu.org/licenses/.
17+
#
18+
#
19+
# The run_graphviz function was taken from:
20+
# https://github.com/tkf/ipython-hierarchymagic/blob/master/hierarchymagic.py
21+
# which has the following licensing terms:
22+
#
23+
# Copyright (c) 2012 Takafumi Arakaki
24+
# All rights reserved.
25+
#
26+
# Redistribution and use in source and binary forms, with or without
27+
# modification, are permitted provided that the following conditions are
28+
# met:
29+
#
30+
# Redistributions of source code must retain the above copyright notice,
31+
# this list of conditions and the following disclaimer.
32+
#
33+
# Redistributions in binary form must reproduce the above copyright
34+
# notice, this list of conditions and the following disclaimer in the
35+
# documentation and/or other materials provided with the distribution.
36+
#
37+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
38+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
40+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
41+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48+
49+
import errno
50+
import os
51+
from subprocess import PIPE, Popen
52+
53+
54+
def run_graphviz(program, code, options=None, format="png"):
55+
"""Run graphviz program and returns image data."""
56+
if not options:
57+
options = []
58+
59+
dot_command = [program, *options, "-T", format]
60+
61+
if os.name == "nt":
62+
# Avoid opening shell window.
63+
# * https://github.com/tkf/ipython-hierarchymagic/issues/1
64+
# * http://stackoverflow.com/a/2935727/727827
65+
p = Popen(
66+
dot_command,
67+
stdout=PIPE,
68+
stdin=PIPE,
69+
stderr=PIPE,
70+
creationflags=0x08000000,
71+
)
72+
else:
73+
p = Popen(dot_command, stdout=PIPE, stdin=PIPE, stderr=PIPE)
74+
75+
# Initialize error flag variable
76+
wentwrong = False
77+
78+
try:
79+
# Graphviz may close standard input when an error occurs,
80+
# resulting in a broken pipe on communicate()
81+
stdout, stderr = p.communicate(code.encode("utf-8"))
82+
except OSError as err:
83+
if err.errno not in (errno.EPIPE, errno.EINVAL):
84+
raise
85+
wentwrong = True
86+
87+
if wentwrong:
88+
# in this case, read the standard output and standard error streams
89+
# directly, to get the error message(s)
90+
stdout, stderr = p.stdout.read(), p.stderr.read()
91+
p.wait()
92+
93+
if p.returncode != 0:
94+
errmsg = stderr.decode("utf-8")
95+
raise DotRuntimeError(errmsg)
96+
97+
return stdout

0 commit comments

Comments
 (0)