-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmarkdown_graphviz_svg.py
90 lines (73 loc) · 2.89 KB
/
markdown_graphviz_svg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import re
from markdown.extensions import Extension
from markdown.blockprocessors import BlockProcessor
from markdown import util
import xml.etree.ElementTree as etree
import subprocess
class GraphvizBlocksExtension(Extension):
def __init__(self, **kwargs):
super(GraphvizBlocksExtension, self).__init__(**kwargs)
def extendMarkdown(self, md):
""" Add GraphvizBlocks to the Markdown instance. """
md.registerExtension(self)
processor = GraphvizBlocks(md.parser)
processor.config = self.getConfigs()
processor.md = md
md.parser.blockprocessors.register(processor, 'graphvizblocks', 150)
class GraphvizBlocks(BlockProcessor):
BLOCK_RE = re.compile(
r'\{% (?P<command>\w+)\n(?P<content>.*?)%}\s*',
re.MULTILINE | re.DOTALL)
SUPPORTED_COMMAMDS = ['dot', 'neato', 'fdp', 'sfdp', 'twopi', 'circo']
IN_GRAPH = 0
ACCUM = ""
def test(self, parent, block):
if block.startswith('{%'):
self.IN_GRAPH = 1
return 1
elif block.endswith('%}'):
self.IN_GRAPH = 0
self.RUN_GRAPH = 1
return 1
elif self.IN_GRAPH == 1:
return 1
else:
return 0
def run(self, parent, blocks):
block = blocks.pop(0)
if self.IN_GRAPH == 1:
self.ACCUM += "\n" + block
elif self.RUN_GRAPH == 1:
self.ACCUM += "\n" + block
self.RUN_GRAPH = 0
# print(self.ACCUM)
m = self.BLOCK_RE.search(self.ACCUM)
# print(m)
if m:
command = m.group('command')
content = m.group('content')
try:
if command not in self.SUPPORTED_COMMAMDS:
raise Exception('Command not supported: %s' % command)
proc = subprocess.Popen(
[command, '-Tsvg'],
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
proc.stdin.write(content.encode('utf-8'))
output, err = proc.communicate()
if err:
raise Exception(err)
data_url_filetype = 'svg+xml'
encoding = 'utf-8'
img = output.decode(encoding)
div = etree.SubElement(parent, 'div')
# this trims the doctype tag, albeit poorly
start = img.index("<svg")
div.text = img[start:]
self.ACCUM = ''
except Exception as e:
div = etree.SubElement(parent, 'h3')
div.text = '<pre style="color:red">Error : ' + str(e) + '</pre>'
def makeExtension(**kwargs): # pragma: no cover
return GraphvizBlocksExtension(**kwargs)