forked from varia/varia.website
many many many Varia's websites, work in progress: https://many.vvvvvvaria.org
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
4.0 KiB
178 lines
4.0 KiB
7 years ago
|
"""
|
||
|
Blockdiag Tag
|
||
|
---------
|
||
|
This tag implements a liquid style tag for blockdiag [1]. You can use different
|
||
|
diagram types like blockdiag, seqdiag, packetdiag etc. [1]
|
||
|
|
||
|
|
||
|
[1] http://blockdiag.com/en/blockdiag/
|
||
|
|
||
|
Syntax
|
||
|
------
|
||
|
{% blockdiag {
|
||
|
<diagramm type> {
|
||
|
<CODE>
|
||
|
}
|
||
|
}
|
||
|
%}
|
||
|
|
||
|
Examples
|
||
|
--------
|
||
|
{% blockdiag {
|
||
|
blockdiag {
|
||
|
A -> B -> C;
|
||
|
B -> D;
|
||
|
}
|
||
|
}
|
||
|
%}
|
||
|
|
||
|
|
||
|
{% blockdiag {
|
||
|
actdiag {
|
||
|
A -> B -> C -> D -> E;
|
||
|
|
||
|
lane {
|
||
|
A; C; E;
|
||
|
}
|
||
|
lane {
|
||
|
B; D;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
%}
|
||
|
|
||
|
|
||
|
{% blockdiag {
|
||
|
packetdiag {
|
||
|
0-7: Source Port
|
||
|
8-15: Destination Port
|
||
|
16-31: Sequence Number
|
||
|
32-47: Acknowledgment Number
|
||
|
}
|
||
|
}
|
||
|
%}
|
||
|
|
||
|
...
|
||
|
|
||
|
|
||
|
Output
|
||
|
------
|
||
|
<span class="blockdiag" style="align: center;"><img src="data:image/png;base64,_BASE64_IMAGE DATA_/></span>
|
||
|
|
||
|
"""
|
||
|
|
||
|
import io
|
||
|
import os
|
||
|
import sys
|
||
|
|
||
|
import base64
|
||
|
import re
|
||
|
from .mdx_liquid_tags import LiquidTags
|
||
|
|
||
|
|
||
|
SYNTAX = '{% blockdiag [diagram type] [code] %}'
|
||
|
DOT_BLOCK_RE = re.compile(r'^\s*(?P<diagram>\w+).*$', re.MULTILINE | re.DOTALL)
|
||
|
|
||
|
_draw_mode = 'PNG'
|
||
|
_publish_mode = 'PNG'
|
||
|
|
||
|
|
||
|
def get_diag(code, command):
|
||
|
""" Generate diagramm and return data """
|
||
|
import tempfile
|
||
|
import shutil
|
||
|
code = code + u'\n'
|
||
|
|
||
|
try:
|
||
|
tmpdir = tempfile.mkdtemp()
|
||
|
fd, diag_name = tempfile.mkstemp(dir=tmpdir)
|
||
|
|
||
|
f = os.fdopen(fd, "w")
|
||
|
f.write(code.encode('utf-8'))
|
||
|
f.close()
|
||
|
|
||
|
format = _draw_mode.lower()
|
||
|
draw_name = diag_name + '.' + format
|
||
|
|
||
|
saved_argv = sys.argv
|
||
|
argv = [diag_name, '-T', format, '-o', draw_name]
|
||
|
|
||
|
if _draw_mode == 'SVG':
|
||
|
argv += ['--ignore-pil']
|
||
|
|
||
|
# Run command
|
||
|
command.main(argv)
|
||
|
|
||
|
# Read image data from file
|
||
|
file_name = diag_name + '.' + _publish_mode.lower()
|
||
|
|
||
|
with io.open(file_name, 'rb') as f:
|
||
|
data = f.read()
|
||
|
f.close()
|
||
|
|
||
|
finally:
|
||
|
for file in os.listdir(tmpdir):
|
||
|
os.unlink(tmpdir + "/" + file)
|
||
|
|
||
|
# os.rmdir will fail -> use shutil
|
||
|
shutil.rmtree(tmpdir)
|
||
|
|
||
|
return data
|
||
|
|
||
|
|
||
|
def diag(code, command):
|
||
|
if command == "blockdiag": # blockdiag
|
||
|
import blockdiag.command
|
||
|
return get_diag(code, blockdiag.command)
|
||
|
|
||
|
elif command == "diagram": # diagram
|
||
|
import blockdiag.command
|
||
|
return get_diag(code, blockdiag.command)
|
||
|
|
||
|
elif command == "seqdiag": # seqdiag
|
||
|
import seqdiag.command
|
||
|
return get_diag(code, seqdiag.command)
|
||
|
|
||
|
elif command == "actdiag": # actdiag
|
||
|
import actdiag.command
|
||
|
return get_diag(code, actdiag.command)
|
||
|
|
||
|
elif command == "nwdiag": # nwdiag
|
||
|
import nwdiag.command
|
||
|
return get_diag(code, nwdiag.command)
|
||
|
|
||
|
elif command == "packetdiag": # packetdiag
|
||
|
import packetdiag.command
|
||
|
return get_diag(code, packetdiag.command)
|
||
|
|
||
|
elif command == "rackdiag": # racketdiag
|
||
|
import rackdiag.command
|
||
|
return get_diag(code, rackdiag.command)
|
||
|
|
||
|
else: # not found
|
||
|
print("No such command %s" % command)
|
||
|
return None
|
||
|
|
||
|
|
||
|
@LiquidTags.register("blockdiag")
|
||
|
def blockdiag_parser(preprocessor, tag, markup):
|
||
|
""" Blockdiag parser """
|
||
|
m = DOT_BLOCK_RE.search(markup)
|
||
|
if m:
|
||
|
# Get diagram type and code
|
||
|
diagram = m.group('diagram').strip()
|
||
|
code = markup
|
||
|
|
||
|
# Run command
|
||
|
output = diag(code, diagram)
|
||
|
|
||
|
if output:
|
||
|
# Return Base64 encoded image
|
||
|
return '<span class="blockdiag" style="align: center;"><img src="data:image/png;base64,%s"></span>' % base64.b64encode(output)
|
||
|
else:
|
||
|
raise ValueError('Error processing input. '
|
||
|
'Expected syntax: {0}'.format(SYNTAX))
|
||
|
|
||
|
# This import allows image tag to be a Pelican plugin
|
||
|
from .liquid_tags import register
|