[blockdiag] 26/29: Import Upstream version 1.5.3+dfsg
Andreas Tille
tille at debian.org
Tue Jan 10 21:35:59 UTC 2017
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository blockdiag.
commit 1e929f702690e86af98130d35d0a843b8e17f9ae
Author: Andreas Tille <tille at debian.org>
Date: Tue Jan 10 11:08:07 2017 +0100
Import Upstream version 1.5.3+dfsg
---
.hgignore | 14 +++
.hgtags | 110 +++++++++++++++++++++
.installed.cfg | 62 ++++++++++++
CHANGES.rst | 31 ++++++
MANIFEST.in | 1 +
PKG-INFO | 2 +-
a.diag | 6 ++
b.diag | 8 ++
b.png | Bin 0 -> 7778 bytes
blockdiag.svg | 46 +++++++++
bootstrap.pyc | Bin 0 -> 4410 bytes
c.diag | 3 +
e.diag | 5 +
setup.py | 9 +-
src/blockdiag.egg-info/PKG-INFO | 2 +-
src/blockdiag.egg-info/SOURCES.txt | 18 +++-
src/blockdiag.egg-info/requires.txt | 2 +-
src/blockdiag/__init__.py | 2 +-
src/blockdiag/imagedraw/filters/linejump.py | 56 ++++++-----
src/blockdiag/imagedraw/svg.py | 7 +-
src/blockdiag/plugins/__init__.py | 25 +++--
src/blockdiag/tests/__init__.py | 1 +
src/blockdiag/tests/rst/__init__.py | 1 +
src/blockdiag/tests/rst/test_base_directives.py | 17 ++--
.../tests/rst/test_blockdiag_directives.py | 30 ++++--
src/blockdiag/tests/test_boot_params.py | 23 ++---
src/blockdiag/tests/test_command.py | 67 +++++++++++++
src/blockdiag/tests/test_generate_diagram.py | 70 ++++++++-----
src/blockdiag/tests/test_imagedraw_textfolder.py | 10 +-
src/blockdiag/tests/test_imagedraw_utils.py | 10 +-
src/blockdiag/tests/test_parser.py | 6 +-
src/blockdiag/tests/test_pep8.py | 53 ----------
src/blockdiag/tests/test_utils.py | 10 +-
src/blockdiag/tests/test_utils_fontmap.py | 41 ++++----
src/blockdiag/tests/utils.py | 12 +--
src/blockdiag/utils/__init__.py | 13 +--
src/blockdiag/utils/bootstrap.py | 31 +++++-
src/blockdiag/utils/compat.py | 2 +-
src/blockdiag/utils/fontmap.py | 16 ++-
src/blockdiag/utils/images.py | 52 +++++++---
src/blockdiag/utils/rst/directives.py | 13 ++-
src/blockdiag_sphinxhelper.py | 11 ++-
test.sh | 4 +
tox.ini | 20 +++-
44 files changed, 698 insertions(+), 224 deletions(-)
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000..d531664
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,14 @@
+.pyc
+.swp
+^.installed.cfg
+^.coverage
+^.tox
+^bin/
+^build/
+^_build/
+^develop-eggs/
+^dist/
+^eggs/
+^parts/
+^src/.*.egg-info
+^src/blockdiag/tests/truetype
diff --git a/.hgtags b/.hgtags
new file mode 100644
index 0000000..69519ff
--- /dev/null
+++ b/.hgtags
@@ -0,0 +1,110 @@
+f13b2f2d914399eae8bf7b4b5105a69eb7e657ca 0.1
+af0e42d164178abd7f849b2d5659fe01b7eed69c 0.2
+211617855c50a76c0226ecb83d659ba77323c0d9 0.2.2
+0e0308059b7d67b2d7c2bd0a3e6989dcce6c7129 0.3
+183f989ca4bb9e6ac44dacf588312f77e4b715ea 0.3.1
+c799939494fcf8adefeb4e129c111af8253519c3 0.4
+3de87d6c2c78240db3b3f800f551169e3360c16a 0.4.1
+7070f6188d7278ef26ca4e6f2fa1a1faac8853c3 0.2.1
+6dfea7499697f839240ab49ffad1000e34bcf834 0.4.2
+7a86de04a5247bc775a956e252949c04753b1449 0.5
+c86ba6300a6f00cb490f952c321c7596ba54dfaa 0.5.1
+b73c44fbe87dd5c478dbe5c861d6833381022865 0.5.2
+200c7a578e3c98db5876b4db225ec3a69cb28b5b 0.5.3
+45835d84017e5da4d7618d2eaaab98ba9d575572 0.5.4
+92e1ffe35380687329273214b2f4676a5c960ed8 0.5.5
+d6af195862867049b81021ae359668f405fdb4f5 0.6
+52ed26c213248b738ddb1b8c7f97288f087c330a 0.6.1
+52ed26c213248b738ddb1b8c7f97288f087c330a 0.6.1
+0000000000000000000000000000000000000000 0.6.1
+0000000000000000000000000000000000000000 0.6.1
+63bc462fbc487ed1f1c55c2ab9e101bd97f87d99 0.6.1
+6061c7f1706c1164cc34da48c19e543c56be007c 0.6.2
+84e23355450870f51a35e2931ef80f31f1f130fb 0.6.3
+87382e9a446bc06adbb57c52530ebcee10749738 0.6.4
+4634b17e273837c2a2d6a8effaf7fd0343e226cf 0.6.5
+f2d6cbbd62619c556afe40fa17f7da314e3d66a0 0.6.6
+663a52ef768c7725984db74fd9064fd2bca0263c 0.6.7
+01ccc2e285e57e3df3656d21eb86ea3e2c4de6e7 0.7.0
+123ed155fd4e933dfb5182af6a4bb67b776f06e3 0.7.1
+2d6ef5898a4c8c127e3ca256263597dbef0192ec 0.7.2
+93e52fb89351e2b40b2058829a41157d72a6b4fe 0.7.3
+afa7e91236bebf58d9c2081b328a8f6a209158a5 0.7.4
+dc056c5edf2fdb73c68ce55957e36442cf259bda 0.7.5
+9c9bc6e859f7e1bf2cbdf296cb98bdd43e177339 0.7.6
+f14667d477b861e146ca82974852591f343955b4 0.7.7
+6c6edf112349b3dcd525ecf805cf2d1ddce95923 0.7.8
+56d8d6c04be5c495d52479cd7273054652ea0f41 0.8.0
+5317b0bcec53c4f83badc21675255fa4f810c51b 0.8.1
+5317b0bcec53c4f83badc21675255fa4f810c51b 0.8.1
+0000000000000000000000000000000000000000 0.8.1
+0000000000000000000000000000000000000000 0.8.1
+4e291393b9818f9b744599753213b2f214418367 0.8.1
+1394f7cb6d74256841d52b65559a9181f38dc3c0 0.8.2
+1394f7cb6d74256841d52b65559a9181f38dc3c0 0.8.2
+0000000000000000000000000000000000000000 0.8.2
+0000000000000000000000000000000000000000 0.8.2
+a39c2fe87c56ecd3330fa966c16a84a719c078af 0.8.2
+dee693b247f9796ef5a71c9879e7ece81e2ca826 0.8.3
+e26b9e4dea0da3d3decaee7524add158cd8f9a89 0.8.4
+3ee05b403cb89fccf29f8225238119322d574343 0.8.5
+66503507bf9021e9373a26963380c8daefe8b732 0.8.6
+58c589bf671872eb14cb8a97572cd54f4451363d 0.8.7
+a5ae7cf75f7932c938e66df154f766d530ec9a10 0.8.8
+aeb61e8fad968a0a252e7be969e558b8058087ac 0.8.9
+9547a2a4d61e3d136913ba2fd281f568b06c26f1 0.9.0
+b8fcad4288f703ce4fe68c0f66cde6f6cfda14ea 0.9.1
+4100c1b16943477421d72dbcc47f17636cf3cd07 0.9.2
+71e676fb5eb2287ac8d864be6e3f6a1ce404e66e 0.9.3
+f0c827676fda31eec4570b901bc9a4e8094f1f6e 0.9.5
+f0c827676fda31eec4570b901bc9a4e8094f1f6e 0.9.5
+0000000000000000000000000000000000000000 0.9.5
+0000000000000000000000000000000000000000 0.9.5
+9c07fdfc24682a8a935c139113f20c60a1ded6cd 0.9.5
+9c07fdfc24682a8a935c139113f20c60a1ded6cd 0.9.5
+0000000000000000000000000000000000000000 0.9.5
+0000000000000000000000000000000000000000 0.9.5
+989c2c9e33af4c1d7033738a0e3346e2d1fe78aa 0.9.5
+a110a4a98ad14ed551539d2ce9bf022e7a65099c 0.9.6
+00957a44f847d8582b6be748ae47e613be57c5b6 0.9.7
+91f704283be06c84cfbe614be97cd43c3f342845 1.0.1
+1d6039743bd6f7056293432556cea030fbf921fc 1.0.2
+e7a0149a88f05fc2064d37f948252397a8cd945f 1.0.0
+84d6892aa674d64808d30139617550a96c50054a 1.0.3
+e180448fb931f2cc5f0c3876b7e9fe050ffdcb74 1.1.0
+bbc158edfa84fc78e694d19a7fd570127e098a82 1.1.1
+f7fc3127b629accae4b82ec69d7b13016b7093b5 1.1.2
+28eb38df230448b99bf11909f30232f9028e44c3 1.1.3
+28eb38df230448b99bf11909f30232f9028e44c3 1.1.3
+0000000000000000000000000000000000000000 1.1.3
+0000000000000000000000000000000000000000 1.1.3
+caa5f3cae7574d94efd86da6a7cba5e614ef905e 1.1.3
+dc9debc39155dad8e6bb18ead11d9af876170bc6 1.1.4
+f2faaa5683f7cf3e3ffb8927ad2a9a11ef9b62e5 1.1.5
+b57b099723600a0eb289220ffadc6b52ab3aca55 1.1.6
+ddff661e8fd9fab186382c5629032d918bfe5b48 1.1.7
+0c6e79e5491ca681ab1eb74c8b6bf84b9f7db114 1.1.8
+2a028e8248876b143d02e4113cf0e6aa45ec49da 1.2.0
+5f30defbfa6425144d9f41be9dae4e6fdd5cb1f8 1.2.1
+a58111e3769fbefea485fe78c136b1bf083566dd 1.2.2
+a58111e3769fbefea485fe78c136b1bf083566dd 1.2.2
+0000000000000000000000000000000000000000 1.2.2
+0000000000000000000000000000000000000000 1.2.2
+1e7de1d0e4656230f0b367f4a76e80e40f20747f 1.2.2
+b7204023d673853f16687412f0758d66f669fe6e 1.2.3
+924f66da959d9e6ac1f4831cf8a9fbb18a57fb8a 1.2.4
+eea92cc34dd8702eb368fb274de87b4b9bfde8c9 1.3.0
+5181da3c729559101982dee60cf2bac4098913b7 1.3.1
+eaeb1c38be3dfc0ae6e996b38437e8bdf9799ea2 1.3.2
+372e5f369ba92ed5efa40139393dea58cdf475d9 1.3.3
+4746d577dcfbe02ba535d70912236b10723a52f8 1.4.0
+41e73287a1d6e019dd1f6940d184f05adcd07b33 1.4.1
+eda0e6b41fdf9939d0d160fbdf2dfce5e7f3135e 1.4.2
+b7481dd07fe9b8f815eb6989c53b2ab7dc490f50 1.4.3
+fdf8d4f28170b81b237afdb787b81c13a0d8827a 1.4.4
+dc4a431c445e57411e8800577afa761ee4e476f0 1.4.5
+8b62ba06c865d32b6c02e185fb4ebe6478322d41 1.4.6
+bb9af150c55e8497c75f93250774d64dc7798bd9 1.4.7
+b67e529c41e7fac9796c6635e7a5b801f98a4de7 1.5.0
+1f35ac7a1e98fcdf8c74164ce721d5ab725f003a 1.5.1
+90c65044ba04b5a305980f062c83a481bf7253cf 1.5.2
diff --git a/.installed.cfg b/.installed.cfg
new file mode 100644
index 0000000..49d4d3d
--- /dev/null
+++ b/.installed.cfg
@@ -0,0 +1,62 @@
+[buildout]
+installed_develop_eggs = /Users/tkomiya/work/blockdiag/develop-eggs/blockdiag.egg-link
+parts = blockdiag test static_analysis
+
+[blockdiag]
+__buildout_installed__ = /Users/tkomiya/work/blockdiag/bin/blockdiag
+ /Users/tkomiya/work/blockdiag/bin/py
+__buildout_signature__ = zc.recipe.egg-2.0.1-py2.7.egg setuptools-e254772190d6726b0025d350d2b623f9 zc.buildout-2.3.1-py2.7.egg
+_b = /Users/tkomiya/work/blockdiag/bin
+_d = /Users/tkomiya/work/blockdiag/develop-eggs
+_e = /Users/tkomiya/.buildout/buildout-eggs
+bin-directory = /Users/tkomiya/work/blockdiag/bin
+develop-eggs-directory = /Users/tkomiya/work/blockdiag/develop-eggs
+eggs = blockdiag[rst]
+eggs-directory = /Users/tkomiya/.buildout/buildout-eggs
+interpreter = py
+recipe = zc.recipe.egg
+
+[test]
+__buildout_installed__ = /Users/tkomiya/work/blockdiag/bin/test
+__buildout_signature__ = pbp.recipe.noserunner-0.2.6-py2.7.egg zc.recipe.egg-2.0.1-py2.7.egg nose-1.3.4-py2.7.egg zc.buildout-2.3.1-py2.7.egg setuptools-e254772190d6726b0025d350d2b623f9
+_b = /Users/tkomiya/work/blockdiag/bin
+_d = /Users/tkomiya/work/blockdiag/develop-eggs
+_e = /Users/tkomiya/.buildout/buildout-eggs
+bin-directory = /Users/tkomiya/work/blockdiag/bin
+develop-eggs-directory = /Users/tkomiya/work/blockdiag/develop-eggs
+eggs = blockdiag[rst]
+ blockdiag[testing]
+ coverage
+ unittest-xml-reporting
+ nose
+eggs-directory = /Users/tkomiya/.buildout/buildout-eggs
+location = /Users/tkomiya/work/blockdiag/parts/test
+recipe = pbp.recipe.noserunner
+script = /Users/tkomiya/work/blockdiag/bin/test
+
+[static_analysis]
+__buildout_installed__ = /Users/tkomiya/work/blockdiag/bin/coverage2
+ /Users/tkomiya/work/blockdiag/bin/coverage-2.7
+ /Users/tkomiya/work/blockdiag/bin/coverage
+ /Users/tkomiya/work/blockdiag/bin/flake8
+ /Users/tkomiya/work/blockdiag/bin/pyreverse
+ /Users/tkomiya/work/blockdiag/bin/pylint
+ /Users/tkomiya/work/blockdiag/bin/epylint
+ /Users/tkomiya/work/blockdiag/bin/pylint-gui
+ /Users/tkomiya/work/blockdiag/bin/symilar
+ /Users/tkomiya/work/blockdiag/bin/epylint
+ /Users/tkomiya/work/blockdiag/bin/pylint
+ /Users/tkomiya/work/blockdiag/bin/pylint-gui
+ /Users/tkomiya/work/blockdiag/bin/pyreverse
+ /Users/tkomiya/work/blockdiag/bin/symilar
+__buildout_signature__ = zc.recipe.egg-2.0.1-py2.7.egg setuptools-e254772190d6726b0025d350d2b623f9 zc.buildout-2.3.1-py2.7.egg
+_b = /Users/tkomiya/work/blockdiag/bin
+_d = /Users/tkomiya/work/blockdiag/develop-eggs
+_e = /Users/tkomiya/.buildout/buildout-eggs
+bin-directory = /Users/tkomiya/work/blockdiag/bin
+develop-eggs-directory = /Users/tkomiya/work/blockdiag/develop-eggs
+eggs = coverage
+ flake8
+ pylint
+eggs-directory = /Users/tkomiya/.buildout/buildout-eggs
+recipe = zc.recipe.egg
diff --git a/CHANGES.rst b/CHANGES.rst
index db39cac..03e4c41 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,6 +1,37 @@
Changelog
=========
+1.5.3 (2015-07-30)
+------------------
+* Fix bug
+
+ - Fix #67 Group overlaps with nodes having href
+
+1.5.2 (2015-05-17)
+------------------
+* Fix dependency; webcolors-1.5 does not support py32
+* Fix bug
+
+ - Fix images.open() failed with PIL
+
+1.5.1 (2015-02-21)
+------------------
+* Fix bug
+
+ - Fix labels are overwrapped on antialias mode
+
+1.5.0 (2015-01-01)
+------------------
+* Refactor cleanup procedures
+* Fix bugs
+
+ - Fix get_image_size() closes Image object automatically
+ - Fix pasting Image object failed on SVG mode
+ - Fix #61 images.urlopen() got PermissionError on Windows
+ - Fix #61 images.open() raises exception if ghostscript not found
+ - Fix #62 Use "sans-serif" to font-family property on SVG output ("sansserif" is invalid)
+ - Fix #63 AttributeError on get_image_size(); Pillow (<= 2.4.x) does not have Image#close()
+
1.4.7 (2014-10-21)
------------------
* Fix bugs
diff --git a/MANIFEST.in b/MANIFEST.in
index 01212f6..73d0f29 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -5,6 +5,7 @@ include MANIFEST.in
include LICENSE
include blockdiag.1
include tox.ini
+include src/blockdiag/tests/VLGothic/*
recursive-include examples blockdiagrc *.diag *.png *.svg
recursive-include src README *.py *.diag *.gif *.png
diff --git a/PKG-INFO b/PKG-INFO
index e40f1f6..9961b0d 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: blockdiag
-Version: 1.4.7
+Version: 1.5.3
Summary: blockdiag generates block-diagram image from text
Home-page: http://blockdiag.com/
Author: Takeshi Komiya
diff --git a/a.diag b/a.diag
new file mode 100644
index 0000000..d648088
--- /dev/null
+++ b/a.diag
@@ -0,0 +1,6 @@
+{
+ A -> B;
+ C [width = 200, shape = roundedbox];
+ A [label = "hello\n\nwolrd hello world hello world"];
+ A;
+}
diff --git a/b.diag b/b.diag
new file mode 100644
index 0000000..66aa5cd
--- /dev/null
+++ b/b.diag
@@ -0,0 +1,8 @@
+{
+ A -> B -> C;
+ D -> E;
+
+ A, B [shape = circle];
+ E [shape = square];
+ pgqywz
+}
diff --git a/b.png b/b.png
new file mode 100644
index 0000000..e5fc122
Binary files /dev/null and b/b.png differ
diff --git a/blockdiag.svg b/blockdiag.svg
new file mode 100644
index 0000000..f507e66
--- /dev/null
+++ b/blockdiag.svg
@@ -0,0 +1,46 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg viewBox="0 0 448 280" xmlns="http://www.w3.org/2000/svg" xmlns:inkspace="http://www.inkscape.org/namespaces/inkscape" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs id="defs_block">
+ <filter height="1.504" id="filter_blur" inkspace:collect="always" width="1.1575" x="-0.07875" y="-0.252">
+ <feGaussianBlur id="feGaussianBlur3780" inkspace:collect="always" stdDeviation="4.2" />
+ </filter>
+ </defs>
+ <title>blockdiag</title>
+ <desc>blockdiag { default_node_color = lightyellow; default_group_color = red; default_linecolor = blue; default_textcolor = black;
+A[href="http://google.com"]; A[color = "lightgreen"]; A[numbered = 007];
+A -> B -> C; B -> D; group { A;C; } }
+</desc>
+ <rect fill="rgb(255,0,0)" height="140" style="filter:url(#filter_blur)" width="144" x="248" y="30" />
+ <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="67" y="46" />
+ <a xlink:href="http://google.com">
+ <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="259" y="46" />
+ </a>
+ <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="259" y="126" />
+ <rect fill="rgb(0,0,0)" height="40" stroke="rgb(0,0,0)" style="filter:url(#filter_blur);opacity:0.7;fill-opacity:1" width="128" x="259" y="206" />
+ <rect fill="rgb(255,255,224)" height="40" stroke="rgb(0,0,255)" width="128" x="64" y="40" />
+ <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="8" x="128" y="66">B</text>
+ <a xlink:href="http://google.com">
+ <rect fill="rgb(144,238,144)" height="40" stroke="rgb(0,0,255)" width="128" x="256" y="40" />
+ <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="9" x="320" y="65">A</text>
+ <ellipse cx="256" cy="40" fill="pink" rx="12" ry="12" stroke="rgb(0,0,255)" />
+ <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="22" x="256" y="45">007</text>
+ </a>
+ <rect fill="rgb(255,255,224)" height="40" stroke="rgb(0,0,255)" width="128" x="256" y="120" />
+ <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="9" x="320" y="145">C</text>
+ <rect fill="rgb(255,255,224)" height="40" stroke="rgb(0,0,255)" width="128" x="256" y="200" />
+ <text fill="rgb(0,0,0)" font-family="sans-serif" font-size="11" font-style="normal" font-weight="normal" text-anchor="middle" textLength="9" x="320" y="226">D</text>
+ <path d="M 192 60 L 224 60" fill="none" stroke="rgb(0,0,255)" />
+ <path d="M 224 60 L 224 140" fill="none" stroke="rgb(0,0,255)" />
+ <path d="M 224 140 L 248 140" fill="none" stroke="rgb(0,0,255)" />
+ <polygon fill="rgb(0,0,255)" points="255,140 248,136 248,144 255,140" stroke="rgb(0,0,255)" />
+ <path d="M 192 60 L 224 60" fill="none" stroke="rgb(0,0,255)" />
+ <path d="M 224 60 L 224 220" fill="none" stroke="rgb(0,0,255)" />
+ <path d="M 224 220 L 248 220" fill="none" stroke="rgb(0,0,255)" />
+ <polygon fill="rgb(0,0,255)" points="255,220 248,216 248,224 255,220" stroke="rgb(0,0,255)" />
+ <path d="M 384 60 L 400 60" fill="none" stroke="rgb(0,0,255)" />
+ <path d="M 400 60 L 400 25" fill="none" stroke="rgb(0,0,255)" />
+ <path d="M 128 25 L 400 25" fill="none" stroke="rgb(0,0,255)" />
+ <path d="M 128 25 L 128 32" fill="none" stroke="rgb(0,0,255)" />
+ <polygon fill="rgb(0,0,255)" points="128,39 124,32 132,32 128,39" stroke="rgb(0,0,255)" />
+</svg>
diff --git a/bootstrap.pyc b/bootstrap.pyc
new file mode 100644
index 0000000..1d5b6cc
Binary files /dev/null and b/bootstrap.pyc differ
diff --git a/c.diag b/c.diag
new file mode 100644
index 0000000..a6b2076
--- /dev/null
+++ b/c.diag
@@ -0,0 +1,3 @@
+{
+ A -> B -> C -> D, E -> F, G -> C;
+}
diff --git a/e.diag b/e.diag
new file mode 100644
index 0000000..2a5238d
--- /dev/null
+++ b/e.diag
@@ -0,0 +1,5 @@
+{
+ plugin autoclass;
+ default_shape = circle;
+ A -> B;
+}
diff --git a/setup.py b/setup.py
index 359b825..ec0cbb1 100644
--- a/setup.py
+++ b/setup.py
@@ -21,7 +21,6 @@ classifiers = [
requires = ['setuptools',
'funcparserlib',
- 'webcolors',
'Pillow']
pdf_requires = ['reportlab']
test_requires = ['nose',
@@ -32,11 +31,17 @@ test_requires = ['nose',
# only for Python2.6
-if sys.version_info > (2, 6) and sys.version_info < (2, 7):
+if (2, 6) < sys.version_info < (2, 7):
requires.append('OrderedDict')
pdf_requires[0] = 'reportlab < 3.0'
test_requires.append('unittest2')
+# webcolors
+if (3, 2) < sys.version_info < (3, 3):
+ requires.append('webcolors < 1.5') # webcolors-1.5 does not support py32
+else:
+ requires.append('webcolors')
+
setup(
name='blockdiag',
diff --git a/src/blockdiag.egg-info/PKG-INFO b/src/blockdiag.egg-info/PKG-INFO
index e40f1f6..9961b0d 100644
--- a/src/blockdiag.egg-info/PKG-INFO
+++ b/src/blockdiag.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: blockdiag
-Version: 1.4.7
+Version: 1.5.3
Summary: blockdiag generates block-diagram image from text
Home-page: http://blockdiag.com/
Author: Takeshi Komiya
diff --git a/src/blockdiag.egg-info/SOURCES.txt b/src/blockdiag.egg-info/SOURCES.txt
index 436e95e..3cd88c4 100644
--- a/src/blockdiag.egg-info/SOURCES.txt
+++ b/src/blockdiag.egg-info/SOURCES.txt
@@ -1,12 +1,23 @@
+.hgignore
+.hgtags
+.installed.cfg
CHANGES.rst
LICENSE
MANIFEST.in
README.rst
+a.diag
+b.diag
+b.png
blockdiag.1
+blockdiag.svg
bootstrap.py
+bootstrap.pyc
buildout.cfg
+c.diag
+e.diag
setup.cfg
setup.py
+test.sh
tox.ini
examples/blockdiagrc
examples/group.diag
@@ -85,14 +96,19 @@ src/blockdiag/tests/test_builder_errors.py
src/blockdiag/tests/test_builder_group.py
src/blockdiag/tests/test_builder_node.py
src/blockdiag/tests/test_builder_separate.py
+src/blockdiag/tests/test_command.py
src/blockdiag/tests/test_generate_diagram.py
src/blockdiag/tests/test_imagedraw_textfolder.py
src/blockdiag/tests/test_imagedraw_utils.py
src/blockdiag/tests/test_parser.py
-src/blockdiag/tests/test_pep8.py
src/blockdiag/tests/test_utils.py
src/blockdiag/tests/test_utils_fontmap.py
src/blockdiag/tests/utils.py
+src/blockdiag/tests/VLGothic/LICENSE
+src/blockdiag/tests/VLGothic/LICENSE.en
+src/blockdiag/tests/VLGothic/LICENSE_E.mplus
+src/blockdiag/tests/VLGothic/LICENSE_J.mplus
+src/blockdiag/tests/VLGothic/VL-Gothic-Regular.ttf
src/blockdiag/tests/diagrams/README
src/blockdiag/tests/diagrams/auto_jumping_edge.diag
src/blockdiag/tests/diagrams/background_url_image.diag
diff --git a/src/blockdiag.egg-info/requires.txt b/src/blockdiag.egg-info/requires.txt
index ff04388..bd90ed3 100644
--- a/src/blockdiag.egg-info/requires.txt
+++ b/src/blockdiag.egg-info/requires.txt
@@ -1,7 +1,7 @@
setuptools
funcparserlib
-webcolors
Pillow
+webcolors
[pdf]
reportlab
diff --git a/src/blockdiag/__init__.py b/src/blockdiag/__init__.py
index 33edc89..bcee0a6 100644
--- a/src/blockdiag/__init__.py
+++ b/src/blockdiag/__init__.py
@@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-__version__ = '1.4.7'
+__version__ = '1.5.3'
diff --git a/src/blockdiag/imagedraw/filters/linejump.py b/src/blockdiag/imagedraw/filters/linejump.py
index c3c41fe..0f40ea6 100644
--- a/src/blockdiag/imagedraw/filters/linejump.py
+++ b/src/blockdiag/imagedraw/filters/linejump.py
@@ -21,30 +21,32 @@ class LazyReceiver(object):
def __init__(self, target):
self.target = target
self.calls = []
- self.nested = []
def __getattr__(self, name):
return self.get_lazy_method(name)
def get_lazy_method(self, name):
- method = self._find_method(name)
-
- def _(*args, **kwargs):
- if name in self.target.self_generative_methods:
- ret = method(self.target, *args, **kwargs)
- receiver = LazyReceiver(ret)
- self.nested.append(receiver)
+ if name in self.target.nosideeffect_methods:
+ method = self._find_method(name)
+ return functools.partial(method, self.target)
+ elif name in self.target.self_generative_methods:
+ def _(*args, **kwargs):
+ receiver = LazySubReceiver(name, self.target, *args, **kwargs)
+ self.calls.append((receiver, args, kwargs))
return receiver
- else:
- self.calls.append((method, args, kwargs))
- return self
- if method.__name__ in self.target.nosideeffect_methods:
- return functools.partial(method, self.target)
+ return _
else:
+ def _(*args, **kwargs):
+ self.calls.append((name, args, kwargs))
+ return self
+
return _
def _find_method(self, name):
+ if isinstance(name, LazyReceiver):
+ return name
+
for p in self.target.__class__.__mro__:
if name in p.__dict__:
return p.__dict__[name]
@@ -53,13 +55,24 @@ class LazyReceiver(object):
(self.target.__class__.__name__, name))
def _run(self):
- for recv in self.nested:
- recv._run()
-
- for method, args, kwargs in self.calls:
+ for name, args, kwargs in self.calls:
+ method = self._find_method(name)
method(self.target, *args, **kwargs)
+class LazySubReceiver(LazyReceiver):
+ def __init__(self, name, target, *args, **kwargs):
+ self.name = name
+ self.args = args
+ self.kwargs = kwargs
+ super(LazySubReceiver, self).__init__(target)
+
+ def __call__(self, target, *args, **kwargs):
+ method = self._find_method(self.name)
+ self.target = method(self.target, *self.args, **self.kwargs)
+ self._run()
+
+
class LineJumpDrawFilter(LazyReceiver):
def __init__(self, target, jump_radius):
super(LineJumpDrawFilter, self).__init__(target)
@@ -81,12 +94,8 @@ class LineJumpDrawFilter(LazyReceiver):
self.jump_shift = kwargs['jump_shift']
def _run(self):
- for recv in self.nested:
- recv._run()
-
- line_method = self._find_method("line")
- for method, args, kwargs in self.calls:
- if method == line_method and kwargs.get('jump'):
+ for name, args, kwargs in self.calls:
+ if name == 'line' and kwargs.get('jump'):
((x1, y1), (x2, y2)) = args[0]
if self.forward == 'holizonal' and y1 == y2:
self._holizonal_jumpline(x1, y1, x2, y2, **kwargs)
@@ -95,6 +104,7 @@ class LineJumpDrawFilter(LazyReceiver):
self._vertical_jumpline(x1, y1, x2, y2, **kwargs)
continue
+ method = self._find_method(name)
method(self.target, *args, **kwargs)
def _holizonal_jumpline(self, x1, y1, x2, y2, **kwargs):
diff --git a/src/blockdiag/imagedraw/svg.py b/src/blockdiag/imagedraw/svg.py
index 5d8af22..bc71574 100644
--- a/src/blockdiag/imagedraw/svg.py
+++ b/src/blockdiag/imagedraw/svg.py
@@ -15,6 +15,7 @@
import os
import re
+from PIL.Image import Image
from base64 import b64encode
from blockdiag.imagedraw import base as _base
from blockdiag.imagedraw.simplesvg import (
@@ -234,7 +235,11 @@ class SVGImageDrawElement(_base.ImageDraw):
if hasattr(url, 'read'):
url = "data:;base64," + str(b64encode(url.read()))
else:
- ext = os.path.splitext(url)[1].lower()
+ if isinstance(url, Image):
+ ext = None
+ else:
+ ext = os.path.splitext(url)[1].lower()
+
if ext not in ('.jpg', '.png', '.gif'):
stream = None
try:
diff --git a/src/blockdiag/plugins/__init__.py b/src/blockdiag/plugins/__init__.py
index dd550de..df50207 100644
--- a/src/blockdiag/plugins/__init__.py
+++ b/src/blockdiag/plugins/__init__.py
@@ -38,14 +38,6 @@ def load(plugins, diagram, **kwargs):
raise AttributeError(msg)
-def unload_all():
- for name in general_handlers.keys():
- del general_handlers[name]
-
- for handler in node_handlers[:]:
- node_handlers.remove(handler)
-
-
def install_general_handler(name, handler):
if name not in general_handlers:
general_handlers[name] = []
@@ -86,3 +78,20 @@ class NodeHandler(object):
def on_build_finished(self, node):
return True
+
+
+def cleanup():
+ fire_general_event('cleanup')
+
+ for name in list(general_handlers.keys()):
+ del general_handlers[name]
+
+ for handler in node_handlers[:]:
+ node_handlers.remove(handler)
+
+ for plugin in loaded_plugins[:]:
+ loaded_plugins.remove(plugin)
+
+
+def setup(app):
+ app.register_cleanup_handler(cleanup)
diff --git a/src/blockdiag/tests/__init__.py b/src/blockdiag/tests/__init__.py
index e69de29..40a96af 100644
--- a/src/blockdiag/tests/__init__.py
+++ b/src/blockdiag/tests/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/src/blockdiag/tests/rst/__init__.py b/src/blockdiag/tests/rst/__init__.py
index e69de29..40a96af 100644
--- a/src/blockdiag/tests/rst/__init__.py
+++ b/src/blockdiag/tests/rst/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/src/blockdiag/tests/rst/test_base_directives.py b/src/blockdiag/tests/rst/test_base_directives.py
index 3baedf8..938d220 100644
--- a/src/blockdiag/tests/rst/test_base_directives.py
+++ b/src/blockdiag/tests/rst/test_base_directives.py
@@ -1,20 +1,19 @@
# -*- coding: utf-8 -*-
-import sys
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
-
-import os
import io
-from blockdiag.tests.utils import capture_stderr, TemporaryDirectory
-
+import os
+import sys
from docutils import nodes
from docutils.core import publish_doctree
from docutils.parsers.rst import directives as docutils
from blockdiag.utils.rst import directives
from blockdiag.utils.rst.nodes import blockdiag as blockdiag_node
+from blockdiag.tests.utils import capture_stderr, TemporaryDirectory
+
+if sys.version_info < (2, 7):
+ import unittest2 as unittest
+else:
+ import unittest
class TestRstDirectives(unittest.TestCase):
diff --git a/src/blockdiag/tests/rst/test_blockdiag_directives.py b/src/blockdiag/tests/rst/test_blockdiag_directives.py
index 8e1850f..33aa4ba 100644
--- a/src/blockdiag/tests/rst/test_blockdiag_directives.py
+++ b/src/blockdiag/tests/rst/test_blockdiag_directives.py
@@ -1,19 +1,19 @@
# -*- coding: utf-8 -*-
-import sys
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
-
import os
-from blockdiag.utils.compat import u
-from blockdiag.tests.utils import capture_stderr, with_pil, TemporaryDirectory
-
+import sys
from docutils import nodes
from docutils.core import publish_doctree
from docutils.parsers.rst import directives as docutils
+from blockdiag.utils.compat import u
from blockdiag.utils.rst import directives
+from blockdiag.tests.utils import capture_stderr, with_pil, TemporaryDirectory
+
+
+if sys.version_info < (2, 7):
+ import unittest2 as unittest
+else:
+ import unittest
class TestRstDirectives(unittest.TestCase):
@@ -59,6 +59,18 @@ class TestRstDirectives(unittest.TestCase):
self.assertEqual(True, options['noviewbox'])
self.assertEqual(True, options['inline_svg'])
+ @capture_stderr
+ def test_cleanup(self):
+ directives.setup(format='SVG', outputdir=self.tmpdir, noviewbox=False)
+ text = (".. blockdiag::\n"
+ "\n"
+ " plugin autoclass\n"
+ " A -> B")
+ publish_doctree(text)
+
+ from blockdiag import plugins
+ self.assertEqual([], plugins.loaded_plugins)
+
def test_setup_fontpath1(self):
with self.assertRaises(RuntimeError):
directives.setup(format='SVG', fontpath=['dummy.ttf'],
diff --git a/src/blockdiag/tests/test_boot_params.py b/src/blockdiag/tests/test_boot_params.py
index 846ee09..702b78a 100644
--- a/src/blockdiag/tests/test_boot_params.py
+++ b/src/blockdiag/tests/test_boot_params.py
@@ -1,13 +1,8 @@
# -*- coding: utf-8 -*-
-import sys
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
-
import os
import io
+import sys
import tempfile
from blockdiag.tests.utils import with_pdf
@@ -16,6 +11,11 @@ from blockdiag.command import BlockdiagOptions
from blockdiag.utils.bootstrap import detectfont
from blockdiag.utils.compat import u
+if sys.version_info < (2, 7):
+ import unittest2 as unittest
+else:
+ import unittest
+
class TestBootParams(unittest.TestCase):
def setUp(self):
@@ -124,14 +124,15 @@ class TestBootParams(unittest.TestCase):
def test_exist_font_config_option(self):
try:
- tmp = tempfile.mkstemp()
+ fd, path = tempfile.mkstemp()
+ os.close(fd)
- options = self.parser.parse(['-f', tmp[1], 'input.diag'])
- self.assertEqual(options.font, [tmp[1]])
+ options = self.parser.parse(['-f', path, 'input.diag'])
+ self.assertEqual(options.font, [path])
fontpath = detectfont(options)
- self.assertEqual(fontpath, tmp[1])
+ self.assertEqual(fontpath, path)
finally:
- os.unlink(tmp[1])
+ os.unlink(path)
def test_not_exist_font_config_option(self):
with self.assertRaises(RuntimeError):
diff --git a/src/blockdiag/tests/test_command.py b/src/blockdiag/tests/test_command.py
new file mode 100644
index 0000000..55fbfea
--- /dev/null
+++ b/src/blockdiag/tests/test_command.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+
+import os
+import sys
+from blockdiag.command import BlockdiagApp
+from blockdiag.tests.utils import TemporaryDirectory
+
+if sys.version_info < (2, 7):
+ import unittest2 as unittest
+else:
+ import unittest
+
+
+class TestBlockdiagApp(unittest.TestCase):
+ def test_app_cleans_up_images(self):
+ testdir = os.path.dirname(__file__)
+ diagpath = os.path.join(testdir,
+ 'diagrams',
+ 'background_url_image.diag')
+ urlopen_cache = {}
+
+ def cleanup():
+ from blockdiag.utils import images
+ urlopen_cache.update(images.urlopen_cache)
+
+ try:
+ tmpdir = TemporaryDirectory()
+ fd, tmpfile = tmpdir.mkstemp()
+ os.close(fd)
+
+ args = ['-T', 'SVG', '-o', tmpfile, diagpath]
+ app = BlockdiagApp()
+ app.register_cleanup_handler(cleanup) # to get internal state
+ app.run(args)
+
+ self.assertTrue(urlopen_cache) # check images were cached
+ for path in urlopen_cache.values():
+ self.assertFalse(os.path.exists(path)) # and removed finally
+ finally:
+ tmpdir.clean()
+
+ def test_app_cleans_up_plugins(self):
+ testdir = os.path.dirname(__file__)
+ diagpath = os.path.join(testdir,
+ 'diagrams',
+ 'plugin_autoclass.diag')
+ loaded_plugins = []
+
+ def cleanup():
+ from blockdiag import plugins
+ loaded_plugins.extend(plugins.loaded_plugins)
+
+ try:
+ tmpdir = TemporaryDirectory()
+ fd, tmpfile = tmpdir.mkstemp()
+ os.close(fd)
+
+ args = ['-T', 'SVG', '-o', tmpfile, diagpath]
+ app = BlockdiagApp()
+ app.register_cleanup_handler(cleanup) # to get internal state
+ app.run(args)
+
+ from blockdiag import plugins
+ self.assertTrue(loaded_plugins) # check plugins were loaded
+ self.assertFalse(plugins.loaded_plugins) # and unloaded finally
+ finally:
+ tmpdir.clean()
diff --git a/src/blockdiag/tests/test_generate_diagram.py b/src/blockdiag/tests/test_generate_diagram.py
index 2c0b458..e083711 100644
--- a/src/blockdiag/tests/test_generate_diagram.py
+++ b/src/blockdiag/tests/test_generate_diagram.py
@@ -2,24 +2,25 @@
import os
import re
+import sys
from nose.tools import nottest
+import blockdiag
+import blockdiag.command
from blockdiag.tests.utils import capture_stderr, TemporaryDirectory
from blockdiag.tests.utils import supported_pil, supported_pdf
-import sys
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
-import blockdiag
-import blockdiag.command
+TESTDIR = os.path.dirname(__file__)
+FONTPATH = os.path.join(TESTDIR, 'VLGothic', 'VL-Gothic-Regular.ttf')
-def get_fontpath(testdir=None):
- if testdir is None:
- testdir = os.path.dirname(__file__)
- return os.path.join(testdir, 'truetype', 'VL-PGothic-Regular.ttf')
+
+def get_fontpath(testdir):
+ return os.path.join(testdir, 'VLGothic', 'VL-Gothic-Regular.ttf')
def get_diagram_files(testdir):
@@ -58,23 +59,29 @@ def test_generate_with_separate():
@nottest
def testcase_generator(basepath, mainfunc, files, options):
fontpath = get_fontpath(basepath)
- if os.path.exists(fontpath):
- options = options + ['-f', fontpath]
+ options = options + ['-f', fontpath]
for source in files:
yield generate, mainfunc, 'svg', source, options
- if supported_pil() and os.path.exists(fontpath):
- yield generate, mainfunc, 'png', source, options
- yield generate, mainfunc, 'png', source, options + ['--antialias']
- else:
+ if not supported_pil():
yield unittest.skip("Pillow is not available")(generate)
yield unittest.skip("Pillow is not available")(generate)
-
- if supported_pdf() and os.path.exists(fontpath):
- yield generate, mainfunc, 'pdf', source, options
+ elif os.environ.get('ALL_TESTS') is None:
+ message = "Skipped by default. To enable it, specify $ALL_TESTS=1"
+ yield unittest.skip(message)(generate)
+ yield unittest.skip(message)(generate)
else:
+ yield generate, mainfunc, 'png', source, options
+ yield generate, mainfunc, 'png', source, options + ['--antialias']
+
+ if not supported_pdf():
yield unittest.skip("reportlab is not available")(generate)
+ elif os.environ.get('ALL_TESTS') is None:
+ message = "Skipped by default. To enable it, specify $ALL_TESTS=1"
+ yield unittest.skip(message)(generate)
+ else:
+ yield generate, mainfunc, 'pdf', source, options
@capture_stderr
@@ -91,13 +98,11 @@ def generate(mainfunc, filetype, source, options):
def not_exist_font_config_option_test():
- fontpath = get_fontpath()
- if os.path.exists(fontpath):
- args = ['-f', '/font_is_not_exist', '-f', fontpath, 'input.diag']
- options = blockdiag.command.BlockdiagOptions(blockdiag).parse(args)
+ args = ['-f', '/font_is_not_exist', '-f', FONTPATH, 'input.diag']
+ options = blockdiag.command.BlockdiagOptions(blockdiag).parse(args)
- from blockdiag.utils.bootstrap import detectfont
- detectfont(options)
+ from blockdiag.utils.bootstrap import detectfont
+ detectfont(options)
def stdin_test():
@@ -121,6 +126,27 @@ def stdin_test():
@capture_stderr
+def ghostscript_not_found_test():
+ testdir = os.path.dirname(__file__)
+ diagpath = os.path.join(testdir, 'diagrams', 'background_url_image.diag')
+
+ try:
+ old_path = os.environ['PATH']
+ os.environ['PATH'] = ''
+ tmpdir = TemporaryDirectory()
+ fd, tmpfile = tmpdir.mkstemp()
+ os.close(fd)
+
+ args = ['-T', 'SVG', '-o', tmpfile, diagpath]
+ ret = blockdiag.command.main(args)
+ assert 'Could not convert image:' in sys.stderr.getvalue()
+ assert ret == 0
+ finally:
+ tmpdir.clean()
+ os.environ['PATH'] = old_path
+
+
+ at capture_stderr
def svg_includes_source_code_tag_test():
from xml.etree import ElementTree
diff --git a/src/blockdiag/tests/test_imagedraw_textfolder.py b/src/blockdiag/tests/test_imagedraw_textfolder.py
index 4d1fa2d..a4d244b 100644
--- a/src/blockdiag/tests/test_imagedraw_textfolder.py
+++ b/src/blockdiag/tests/test_imagedraw_textfolder.py
@@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
import sys
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
-
from blockdiag.imagedraw.textfolder import splitlabel
from blockdiag.imagedraw.textfolder import splittext
from blockdiag.imagedraw.textfolder import truncate_text
from blockdiag.utils import Size
from blockdiag.utils.compat import u
+if sys.version_info < (2, 7):
+ import unittest2 as unittest
+else:
+ import unittest
+
CHAR_WIDTH = 14
CHAR_HEIGHT = 10
diff --git a/src/blockdiag/tests/test_imagedraw_utils.py b/src/blockdiag/tests/test_imagedraw_utils.py
index c2e26d9..7439e2f 100644
--- a/src/blockdiag/tests/test_imagedraw_utils.py
+++ b/src/blockdiag/tests/test_imagedraw_utils.py
@@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
import sys
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
-
from blockdiag.imagedraw.utils import (
is_zenkaku, zenkaku_len, hankaku_len,
string_width, textsize
)
from blockdiag.utils.compat import u
+if sys.version_info < (2, 7):
+ import unittest2 as unittest
+else:
+ import unittest
+
class TestUtils(unittest.TestCase):
def test_is_zenkaku(self):
diff --git a/src/blockdiag/tests/test_parser.py b/src/blockdiag/tests/test_parser.py
index cde0d6f..d225147 100644
--- a/src/blockdiag/tests/test_parser.py
+++ b/src/blockdiag/tests/test_parser.py
@@ -2,14 +2,14 @@
from __future__ import print_function
import sys
+from blockdiag.parser import parse_string, ParseException
+from blockdiag.parser import Diagram, Group, Statements, Node, Edge
+
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
-from blockdiag.parser import parse_string, ParseException
-from blockdiag.parser import Diagram, Group, Statements, Node, Edge
-
class TestParser(unittest.TestCase):
def test_basic(self):
diff --git a/src/blockdiag/tests/test_pep8.py b/src/blockdiag/tests/test_pep8.py
deleted file mode 100644
index 3d74cbf..0000000
--- a/src/blockdiag/tests/test_pep8.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from __future__ import print_function
-import os
-import sys
-import pep8
-
-CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
-BASE_DIR = os.path.dirname(CURRENT_DIR)
-
-
-def test_pep8():
- arglist = [['statistics', True],
- ['show-source', True],
- ['repeat', True],
- ['paths', [BASE_DIR]]]
-
- pep8style = pep8.StyleGuide(arglist, parse_argv=False, config_file=True)
- options = pep8style.options
- if options.doctest:
- import doctest
- fail_d, done_d = doctest.testmod(report=False, verbose=options.verbose)
- fail_s, done_s = pep8.selftest(options)
- count_failed = fail_s + fail_d
- if not options.quiet:
- count_passed = done_d + done_s - count_failed
- print("%d passed and %d failed." % (count_passed, count_failed))
- if count_failed:
- print("Test failed.")
- else:
- print("Test passed.")
- if count_failed:
- sys.exit(1)
- if options.testsuite:
- pep8.init_tests(pep8style)
- report = pep8style.check_files()
- if options.statistics:
- report.print_statistics()
- if options.benchmark:
- report.print_benchmark()
- if options.testsuite and not options.quiet:
- report.print_results()
- if report.total_errors:
- if options.count:
- sys.stderr.write(str(report.total_errors) + '\n')
- # sys.exit(1)
-
- # reporting errors (additional summary)
- errors = report.get_count('E')
- warnings = report.get_count('W')
- message = 'pep8: %d errors / %d warnings' % (errors, warnings)
- print(message)
- assert report.total_errors == 0, message
diff --git a/src/blockdiag/tests/test_utils.py b/src/blockdiag/tests/test_utils.py
index 97ed133..e701f91 100644
--- a/src/blockdiag/tests/test_utils.py
+++ b/src/blockdiag/tests/test_utils.py
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
import sys
+from blockdiag.utils import Size, unquote
+
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest
-from blockdiag.utils import Size
-
class TestUtils(unittest.TestCase):
def test_size_resize(self):
@@ -38,3 +38,9 @@ class TestUtils(unittest.TestCase):
size = Size(1.5, 2.5)
self.assertEqual((1, 2), size.to_integer_point())
+
+ def test_unquote(self):
+ self.assertEqual('test', unquote('"test"'))
+ self.assertEqual('test', unquote("'test'"))
+ self.assertEqual("'half quoted", unquote("'half quoted"))
+ self.assertEqual('"half quoted', unquote('"half quoted'))
diff --git a/src/blockdiag/tests/test_utils_fontmap.py b/src/blockdiag/tests/test_utils_fontmap.py
index 5c79da3..7ab87cf 100644
--- a/src/blockdiag/tests/test_utils_fontmap.py
+++ b/src/blockdiag/tests/test_utils_fontmap.py
@@ -1,19 +1,18 @@
# -*- coding: utf-8 -*-
-import sys
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
-
import os
+import sys
import tempfile
-from blockdiag.utils.compat import u
-from blockdiag.tests.utils import capture_stderr
-
from io import StringIO
from collections import namedtuple
+from blockdiag.utils.compat import u
from blockdiag.utils.fontmap import FontInfo, FontMap
+from blockdiag.tests.utils import capture_stderr
+
+if sys.version_info < (2, 7):
+ import unittest2 as unittest
+else:
+ import unittest
FontElement = namedtuple('FontElement', 'fontfamily fontsize')
@@ -75,7 +74,7 @@ class TestUtilsFontmap(unittest.TestCase):
font = FontInfo("sansserif-bold", None, 11)
self.assertEqual('', font.name)
- self.assertEqual('sansserif', font.generic_family)
+ self.assertEqual('sans-serif', font.generic_family)
self.assertEqual('bold', font.weight)
self.assertEqual('normal', font.style)
@@ -132,7 +131,7 @@ class TestUtilsFontmap(unittest.TestCase):
font1 = fmap.find()
self.assertTrue(font1)
- self.assertEqual('sansserif', font1.generic_family)
+ self.assertEqual('sans-serif', font1.generic_family)
self.assertEqual(None, font1.path)
self.assertEqual(11, font1.size)
@@ -161,7 +160,7 @@ class TestUtilsFontmap(unittest.TestCase):
font1 = fmap.find()
self.assertTrue(font1)
- self.assertEqual('sansserif', font1.generic_family)
+ self.assertEqual('sans-serif', font1.generic_family)
self.assertEqual(None, font1.path)
self.assertEqual(11, font1.size)
@@ -173,7 +172,7 @@ class TestUtilsFontmap(unittest.TestCase):
font1 = fmap.find()
self.assertTrue(font1)
- self.assertEqual('sansserif', font1.generic_family)
+ self.assertEqual('sans-serif', font1.generic_family)
self.assertEqual(self.fontpath[0], font1.path)
self.assertEqual(11, font1.size)
@@ -215,7 +214,7 @@ class TestUtilsFontmap(unittest.TestCase):
fmap = FontMap(config)
font1 = fmap.find()
- self.assertEqual('sansserif', font1.generic_family)
+ self.assertEqual('sans-serif', font1.generic_family)
self.assertEqual(self.fontpath[1], font1.path)
self.assertEqual(11, font1.size)
else:
@@ -232,7 +231,7 @@ class TestUtilsFontmap(unittest.TestCase):
fmap = FontMap(config)
font1 = fmap.find()
- self.assertEqual('sansserif', font1.generic_family)
+ self.assertEqual('sans-serif', font1.generic_family)
self.assertEqual(self.fontpath[1], font1.path)
self.assertEqual(11, font1.size)
@@ -244,7 +243,7 @@ class TestUtilsFontmap(unittest.TestCase):
element = FontElement('CapitalCase-sansserif', 11)
font1 = fmap.find(element)
- self.assertEqual('sansserif', font1.generic_family)
+ self.assertEqual('sans-serif', font1.generic_family)
self.assertEqual('capitalcase-sansserif-normal', font1.familyname)
self.assertEqual(self.fontpath[0], font1.path)
self.assertEqual(11, font1.size)
@@ -256,7 +255,7 @@ class TestUtilsFontmap(unittest.TestCase):
fmap = FontMap(config)
font1 = fmap.find()
- self.assertEqual('sansserif', font1.generic_family)
+ self.assertEqual('sans-serif', font1.generic_family)
self.assertEqual(None, font1.path)
self.assertEqual(11, font1.size)
@@ -268,7 +267,7 @@ class TestUtilsFontmap(unittest.TestCase):
element = FontElement('fantasy', 20)
font3 = fmap.find(element)
- self.assertEqual('sansserif', font3.generic_family)
+ self.assertEqual('sans-serif', font3.generic_family)
self.assertEqual(None, font3.path)
self.assertEqual(20, font3.size)
@@ -279,7 +278,7 @@ class TestUtilsFontmap(unittest.TestCase):
fmap = FontMap(config)
font1 = fmap.find()
- self.assertEqual('sansserif', font1.generic_family)
+ self.assertEqual('sans-serif', font1.generic_family)
self.assertEqual(None, font1.path)
self.assertEqual(11, font1.size)
@@ -336,7 +335,7 @@ class TestUtilsFontmap(unittest.TestCase):
font1 = fmap.find()
self.assertTrue(font1)
- self.assertEqual('sansserif', font1.generic_family)
+ self.assertEqual('sans-serif', font1.generic_family)
self.assertEqual(self.fontpath[0], font1.path)
self.assertEqual(11, font1.size)
@@ -357,7 +356,7 @@ class TestUtilsFontmap(unittest.TestCase):
font1 = fmap.find()
self.assertTrue(font1)
- self.assertEqual('sansserif', font1.generic_family)
+ self.assertEqual('sans-serif', font1.generic_family)
self.assertEqual(self.fontpath[0], font1.path)
self.assertEqual(11, font1.size)
finally:
diff --git a/src/blockdiag/tests/utils.py b/src/blockdiag/tests/utils.py
index 87d4aef..a651a30 100644
--- a/src/blockdiag/tests/utils.py
+++ b/src/blockdiag/tests/utils.py
@@ -1,20 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
-import sys
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
-
import os
import re
+import sys
import functools
from shutil import rmtree
from tempfile import mkdtemp, mkstemp
from blockdiag.builder import ScreenNodeBuilder
from blockdiag.parser import parse_file
+if sys.version_info < (2, 7):
+ import unittest2 as unittest
+else:
+ import unittest
+
try:
# sys.stderr in py2.x allows mixture of str and unicode
from cStringIO import StringIO
diff --git a/src/blockdiag/utils/__init__.py b/src/blockdiag/utils/__init__.py
index 231aa72..df84ac9 100644
--- a/src/blockdiag/utils/__init__.py
+++ b/src/blockdiag/utils/__init__.py
@@ -167,18 +167,7 @@ class Box(list):
def unquote(string):
- """
- Remove quotas from string
-
- >>> unquote('"test"')
- 'test'
- >>> unquote("'test'")
- 'test'
- >>> unquote("'half quoted")
- "'half quoted"
- >>> unquote('"half quoted')
- '"half quoted'
- """
+ """ Remove quotas from string """
if string:
m = re.match('\A(?P<quote>"|\')((.|\s)*)(?P=quote)\Z', string, re.M)
if m:
diff --git a/src/blockdiag/utils/bootstrap.py b/src/blockdiag/utils/bootstrap.py
index 47dc42f..b0b6cbf 100644
--- a/src/blockdiag/utils/bootstrap.py
+++ b/src/blockdiag/utils/bootstrap.py
@@ -20,6 +20,7 @@ import traceback
from optparse import OptionParser, SUPPRESS_HELP
from blockdiag import imagedraw
from blockdiag import plugins
+from blockdiag.utils import images
from blockdiag.utils.compat import codecs
from blockdiag.utils.config import ConfigParser
from blockdiag.utils.fontmap import parse_fontpath, FontMap
@@ -30,10 +31,24 @@ class Application(object):
module = None
options = None
+ def __init__(self):
+ self.cleanup_handlers = []
+
+ def __enter__(self):
+ self.setup()
+ return self
+
+ def __exit__(self, *args):
+ self.cleanup()
+
+ def register_cleanup_handler(self, handler):
+ self.cleanup_handlers.append(handler)
+
def run(self, args):
try:
self.parse_options(args)
self.create_fontmap()
+ self.setup()
parsed = self.parse_diagram()
return self.build_diagram(parsed)
@@ -49,8 +64,7 @@ class Application(object):
error("%s" % e)
return -1
finally:
- plugins.fire_general_event('cleanup')
- plugins.unload_all()
+ self.cleanup()
def parse_options(self, args):
self.options = Options(self.module).parse(args)
@@ -58,6 +72,10 @@ class Application(object):
def create_fontmap(self):
self.fontmap = create_fontmap(self.options)
+ def setup(self):
+ images.setup(self)
+ plugins.setup(self)
+
def parse_diagram(self):
if self.options.input == '-':
stream = codecs.getreader('utf-8-sig')(sys.stdin)
@@ -90,6 +108,15 @@ class Application(object):
return 0
+ def cleanup(self):
+ for handler in self.cleanup_handlers[:]:
+ try:
+ handler()
+ except Exception as exc:
+ error("%s" % exc)
+ finally:
+ self.cleanup_handlers.remove(handler)
+
class Options(object):
def __init__(self, module):
diff --git a/src/blockdiag/utils/compat.py b/src/blockdiag/utils/compat.py
index fb1a83a..df902b5 100644
--- a/src/blockdiag/utils/compat.py
+++ b/src/blockdiag/utils/compat.py
@@ -14,6 +14,7 @@
# limitations under the License.
import sys
+import codecs
if sys.version_info[0] == 2:
string_types = (str, unicode) # NOQA: pyflakes complains to unicode in py3
@@ -31,7 +32,6 @@ def u(string):
# replace codecs.getreader
-import codecs
if sys.version_info[0] == 3:
getreader = codecs.getreader
diff --git a/src/blockdiag/utils/fontmap.py b/src/blockdiag/utils/fontmap.py
index 05c0236..3a21eb6 100644
--- a/src/blockdiag/utils/fontmap.py
+++ b/src/blockdiag/utils/fontmap.py
@@ -43,6 +43,10 @@ class FontInfo(object):
self.weight = family[2]
self.style = family[3]
+ def __repr__(self):
+ return ("<FontInfo familyname=%r size=%r>" %
+ (self.familyname, self.size))
+
@property
def familyname(self):
if self.name:
@@ -50,10 +54,15 @@ class FontInfo(object):
else:
name = ''
+ if self.generic_family == 'sans-serif':
+ generic_family = 'sansserif'
+ else:
+ generic_family = self.generic_family
+
if self.weight == 'bold':
- return "%s%s-%s" % (name, self.generic_family, self.weight)
+ return "%s%s-%s" % (name, generic_family, self.weight)
else:
- return "%s%s-%s" % (name, self.generic_family, self.style)
+ return "%s%s-%s" % (name, generic_family, self.style)
def _parse(self, familyname):
pattern = '^(?:(.*)-)?' + \
@@ -69,6 +78,9 @@ class FontInfo(object):
generic_family = match.group(2)
style = match.group(3) or ''
+ if generic_family == 'sansserif':
+ generic_family = 'sans-serif'
+
if style == 'bold':
weight = 'bold'
style = 'normal'
diff --git a/src/blockdiag/utils/images.py b/src/blockdiag/utils/images.py
index 7859a9a..5fa94e1 100644
--- a/src/blockdiag/utils/images.py
+++ b/src/blockdiag/utils/images.py
@@ -15,6 +15,7 @@
from __future__ import division
import io
+import os
import re
from PIL import Image
from tempfile import NamedTemporaryFile
@@ -30,22 +31,25 @@ def urlopen(url, *args, **kwargs):
from blockdiag.utils.compat import urlopen as orig_urlopen
if url not in urlopen_cache:
- tmpfile = NamedTemporaryFile()
- tmpfile.write(orig_urlopen(url, *args, **kwargs).read())
- tmpfile.flush()
- urlopen_cache[url] = tmpfile
+ with NamedTemporaryFile(delete=False) as tmpfile:
+ tmpfile.write(orig_urlopen(url, *args, **kwargs).read())
+ tmpfile.flush()
+ urlopen_cache[url] = tmpfile.name
- return io.open(urlopen_cache[url].name, 'rb')
+ return io.open(urlopen_cache[url], 'rb')
-def get_image_size(filename):
- image = None
- try:
- image = open(filename)
+def get_image_size(image):
+ if isinstance(image, Image.Image):
return image.size
- finally:
- if image:
- image.close()
+ else:
+ stream = None
+ try:
+ stream = open(image)
+ return stream.size
+ finally:
+ if stream and hasattr(stream, 'close'):
+ stream.close()
def calc_image_size(size, bounded):
@@ -120,9 +124,27 @@ def open(url, mode='Pillow'):
# stream will be closed by GC
return image
else: # mode == 'png'
- png_image = io.BytesIO()
- image.save(png_image, 'PNG')
- stream.close()
+ try:
+ png_image = io.BytesIO()
+ image.save(png_image, 'PNG')
+ if hasattr(stream, 'close'): # close() is implemented on Pillow
+ stream.close()
+ except:
+ warning(u("Could not convert image: %s"), url)
+ raise IOError
png_image.seek(0)
return png_image
+
+
+def cleanup():
+ for url in list(urlopen_cache.keys()):
+ path = urlopen_cache.pop(url)
+ try:
+ os.remove(path)
+ except:
+ pass
+
+
+def setup(app):
+ app.register_cleanup_handler(cleanup)
diff --git a/src/blockdiag/utils/rst/directives.py b/src/blockdiag/utils/rst/directives.py
index fa5e218..7846280 100644
--- a/src/blockdiag/utils/rst/directives.py
+++ b/src/blockdiag/utils/rst/directives.py
@@ -16,13 +16,14 @@
import os
import io
from hashlib import sha1
+from functools import wraps
from collections import namedtuple
from docutils import nodes
from docutils.parsers import rst
from docutils.parsers.rst.roles import set_classes
from docutils.statemachine import ViewList
-from blockdiag.utils.bootstrap import create_fontmap
+from blockdiag.utils.bootstrap import create_fontmap, Application
from blockdiag.utils.compat import string_types
from blockdiag.utils.rst.nodes import blockdiag as blockdiag_node
@@ -46,6 +47,15 @@ def relfn2path(env, filename):
return relfn, os.path.join(env.srcdir, relfn)
+def with_blockdiag(fn):
+ @wraps(fn)
+ def decorator(*args):
+ with Application():
+ return fn(*args)
+
+ return decorator
+
+
def align(argument):
align_values = ('left', 'center', 'right')
return rst.directives.choice(argument, align_values)
@@ -142,6 +152,7 @@ class BlockdiagDirectiveBase(rst.Directive):
class BlockdiagDirective(BlockdiagDirectiveBase):
processor = None # backward compatibility for 1.4.0
+ @with_blockdiag
def run(self):
figwidth = self.options.pop('figwidth', None)
figclasses = self.options.pop('figclass', None)
diff --git a/src/blockdiag_sphinxhelper.py b/src/blockdiag_sphinxhelper.py
index cb250d3..87cc8ca 100644
--- a/src/blockdiag_sphinxhelper.py
+++ b/src/blockdiag_sphinxhelper.py
@@ -13,18 +13,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-__all__ = [
- 'core', 'utils'
-]
-
import blockdiag.parser
import blockdiag.builder
import blockdiag.drawer
-core = blockdiag
import blockdiag.utils.bootstrap
import blockdiag.utils.compat
import blockdiag.utils.fontmap
import blockdiag.utils.rst.nodes
import blockdiag.utils.rst.directives
+
+__all__ = [
+ 'core', 'utils'
+]
+
+core = blockdiag
utils = blockdiag.utils
diff --git a/test.sh b/test.sh
new file mode 100755
index 0000000..0fb6c95
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+bin/blockdiag --debug -Tsvg -o blockdiag.svg $1 $2 $3 $4 $5
+#bin/blockdiag --debug -Tpng -o blockdiag.png $1 $2 $3 $4 $5
diff --git a/tox.ini b/tox.ini
index 3b0b529..4e7339b 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,14 +1,17 @@
[tox]
-envlist=py26,py27,py32,py33,py34
+envlist=py26,py27,py32,py33,py34,pillow2.0,pillow2.2,pillow2.4
[testenv]
deps=
nose
mock
flake8
+ flake8-coding
docutils
reportlab
wand
+passenv=
+ ALL_TESTS
commands=
nosetests
flake8 src
@@ -22,3 +25,18 @@ deps=
unittest2
reportlab
wand
+
+[testenv:pillow2.0]
+deps=
+ {[testenv]deps}
+ Pillow<=2.0.9999
+
+[testenv:pillow2.2]
+deps=
+ {[testenv]deps}
+ Pillow<=2.2.9999
+
+[testenv:pillow2.4]
+deps=
+ {[testenv]deps}
+ Pillow<=2.4.9999
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/blockdiag.git
More information about the debian-science-commits
mailing list