actdiag-3.0.0+dfsg1/0000755000175000017500000000000014153440035012607 5ustar zigozigoactdiag-3.0.0+dfsg1/README.rst0000644000175000017500000000276014153440035014303 0ustar zigozigo`actdiag` generate activity-diagram image file from spec-text file. .. image:: https://drone.io/bitbucket.org/blockdiag/actdiag/status.png :target: https://drone.io/bitbucket.org/blockdiag/actdiag :alt: drone.io CI build status .. image:: https://pypip.in/v/actdiag/badge.png :target: https://pypi.python.org/pypi/actdiag/ :alt: Latest PyPI version .. image:: https://pypip.in/d/actdiag/badge.png :target: https://pypi.python.org/pypi/actdiag/ :alt: Number of PyPI downloads Features ======== * Generate activity-diagram from dot like text (basic feature). * Multilingualization for node-label (utf-8 only). You can get some examples and generated images on `blockdiag.com `_ . Setup ===== Use easy_install or pip:: $ sudo easy_install actdiag Or $ sudo pip actdiag spec-text setting sample ======================== Few examples are available. You can get more examples at `blockdiag.com`_ . simple.diag ------------ simple.diag is simply define nodes and transitions by dot-like text format:: diagram { A -> B -> C; lane you { A; B; } lane me { C; } } Usage ===== Execute actdiag command:: $ actdiag simple.diag $ ls simple.png simple.png Requirements ============ * Python 3.7 or later * blockdiag 1.5.0 or later * funcparserlib 0.3.6 or later * reportlab (optional) * wand and imagemagick (optional) * setuptools License ======= Apache License 2.0 actdiag-3.0.0+dfsg1/setup.py0000644000175000017500000000437314153440035014330 0ustar zigozigo# -*- coding: utf-8 -*- import os from setuptools import find_packages, setup classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: System Administrators", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development", "Topic :: Software Development :: Documentation", "Topic :: Text Processing :: Markup", ] def get_version(): """Get version number of the package from version.py without importing core module.""" package_dir = os.path.abspath(os.path.dirname(__file__)) version_file = os.path.join(package_dir, 'src/actdiag/__init__.py') namespace = {} with open(version_file, 'r') as f: exec(f.read(), namespace) return namespace['__version__'] setup( name='actdiag', version=get_version(), description='actdiag generates activity-diagram image from text', long_description=open("README.rst").read(), long_description_content_type='text/x-rst', classifiers=classifiers, keywords=['diagram', 'generator'], author='Takeshi Komiya', author_email='i.tkomiya@gmail.com', url='http://blockdiag.com/', download_url='http://pypi.python.org/pypi/actdiag', project_urls={ "Code": "https://github.com/blockdiag/actdiag", "Issue tracker": "https://github.com/blockdiag/actdiag/issues", }, license='Apache License 2.0', packages=find_packages('src'), package_dir={'': 'src'}, package_data={'': ['buildout.cfg']}, include_package_data=True, python_requires=">=3.7", install_requires=['blockdiag >= 3.0.0'], extras_require=dict( rst=[ 'docutils', ], testing=[ 'nose', 'pep8 >=1.3', 'reportlab', 'docutils', 'flake8', 'flake8-coding', 'flake8-copyright', 'flake8-isort', ], ), test_suite='nose.collector', entry_points=""" [console_scripts] actdiag = actdiag.command:main [blockdiag_plugins] autolane = actdiag.plugins.autolane """, ) actdiag-3.0.0+dfsg1/setup.cfg0000644000175000017500000000031114153440035014423 0ustar zigozigo[egg_info] ;tag_build = dev [build] build-base = _build [sdist] formats = gztar [check] strict = 1 restructuredtext = 1 [flake8] ignore = W504 max-line-length = 120 copyright-check = True [isort] actdiag-3.0.0+dfsg1/tox.ini0000644000175000017500000000050614153440035014123 0ustar zigozigo[tox] envlist=py37,py38,py39,flake8,blockdiag_dev [testenv] usedevelop = True extras = testing passenv= ALL_TESTS commands= nosetests [testenv:flake8] description = Run style checks. extras = testing commands = flake8 src [testenv:blockdiag_dev] deps= git+https://github.com/blockdiag/blockdiag actdiag-3.0.0+dfsg1/LICENSE0000644000175000017500000002613614153440035013624 0ustar zigozigo Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. actdiag-3.0.0+dfsg1/MANIFEST.in0000644000175000017500000000035314153440035014346 0ustar zigozigoinclude CHANGES.rst include MANIFEST.in include README.rst include LICENSE include actdiag.1 include tox.ini include src/actdiag/tests/VLGothic/* recursive-include src *.py *.diag *.gif exclude .drone.io.sh exclude examples/update.sh actdiag-3.0.0+dfsg1/src/0000755000175000017500000000000014153440035013376 5ustar zigozigoactdiag-3.0.0+dfsg1/src/actdiag/0000755000175000017500000000000014153440035014772 5ustar zigozigoactdiag-3.0.0+dfsg1/src/actdiag/parser.py0000644000175000017500000001630514153440035016645 0ustar zigozigo# -*- coding: utf-8 -*- # Copyright (c) 2008/2009 Andrey Vlasovskikh # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. r'''A DOT language parser using funcparserlib. The parser is based on [the DOT grammar][1]. It is pretty complete with a few not supported things: * Ports and compass points * XML identifiers At the moment, the parser builds only a parse tree, not an abstract syntax tree (AST) or an API for dealing with DOT. [1]: http://www.graphviz.org/doc/info/lang.html ''' import io from collections import namedtuple from re import DOTALL, MULTILINE from blockdiag.parser import create_mapper, oneplus_to_list from funcparserlib.lexer import LexerError, Token, make_tokenizer from funcparserlib.parser import a, finished, many, maybe, skip, some Diagram = namedtuple('Diagram', 'id stmts') Lane = namedtuple('Lane', 'id stmts') Node = namedtuple('Node', 'id attrs') Attr = namedtuple('Attr', 'name value') Edge = namedtuple('Edge', 'from_nodes edge_type to_nodes attrs') Extension = namedtuple('Extension', 'type name attrs') Statements = namedtuple('Statements', 'stmts') class ParseException(Exception): pass def tokenize(string): """str -> Sequence(Token)""" # flake8: NOQA specs = [ # NOQA ('Comment', (r'/\*(.|[\r\n])*?\*/', MULTILINE)), # NOQA ('Comment', (r'(//|#).*',)), # NOQA ('NL', (r'[\r\n]+',)), # NOQA ('Space', (r'[ \t\r\n]+',)), # NOQA ('Name', ('[A-Za-z_0-9\u0080-\uffff]' + # NOQA '[A-Za-z_\\-.0-9\u0080-\uffff]*',)), # NOQA ('Op', (r'[{};,=\[\]]|(<->)|(<-)|(--)|(->)',)), # NOQA ('Number', (r'-?(\.[0-9]+)|([0-9]+(\.[0-9]*)?)',)), # NOQA ('String', (r'(?P(""")|(\'\'\')|"|\').*?(? object""" tokval = lambda x: x.value op = lambda s: a(Token('Op', s)) >> tokval op_ = lambda s: skip(op(s)) _id = some(lambda t: t.type in ['Name', 'Number', 'String']) >> tokval keyword = lambda s: a(Token('Name', s)) >> tokval def make_node_list(node_list, attrs): return Statements([Node(node, attrs) for node in node_list]) def make_edge(first, edge_type, second, followers, attrs): edges = [Edge(first, edge_type, second, attrs)] from_node = second for edge_type, to_node in followers: edges.append(Edge(from_node, edge_type, to_node, attrs)) from_node = to_node return Statements(edges) # # parts of syntax # node_list = ( _id + many(op_(',') + _id) >> create_mapper(oneplus_to_list) ) option_stmt = ( _id + maybe(op_('=') + _id) >> create_mapper(Attr) ) option_list = ( maybe(op_('[') + option_stmt + many(op_(',') + option_stmt) + op_(']')) >> create_mapper(oneplus_to_list, default_value=[]) ) # node (node list) statement:: # A; # B [attr = value, attr = value]; # C, D [attr = value, attr = value]; # node_stmt = ( node_list + option_list >> create_mapper(make_node_list) ) # edge statement:: # A -> B; # A <- B; # edge_relation = ( op('->') | op('--') | op('<-') | op('<->') ) edge_stmt = ( node_list + edge_relation + node_list + many(edge_relation + node_list) + option_list >> create_mapper(make_edge) ) # attributes statement:: # default_shape = box; # default_fontsize = 16; # attribute_stmt = ( _id + op_('=') + _id >> create_mapper(Attr) ) # extension statement (class, plugin):: # class red [color = red]; # plugin attributes [name = Name]; # extension_stmt = ( (keyword('class') | keyword('plugin')) + _id + option_list >> create_mapper(Extension) ) # lane statement:: # lane A [color = red]; # lane { # A; # } # lane_declare_stmt = ( skip(keyword('lane')) + _id + option_list >> create_mapper(Lane) ) lane_inline_stmt = ( edge_stmt | attribute_stmt | node_stmt ) lane_inline_stmt_list = ( many(lane_inline_stmt + skip(maybe(op(';')))) ) lane_stmt = ( skip(keyword('lane')) + maybe(_id) + op_('{') + lane_inline_stmt_list + op_('}') >> create_mapper(Lane) ) # # diagram statement:: # actdiag { # A; # } # diagram_id = ( (keyword('diagram') | keyword('actdiag')) + maybe(_id) >> list ) diagram_inline_stmt = ( extension_stmt | edge_stmt | lane_stmt | lane_declare_stmt | attribute_stmt | node_stmt ) diagram_inline_stmt_list = ( many(diagram_inline_stmt + skip(maybe(op(';')))) ) diagram = ( maybe(diagram_id) + op_('{') + diagram_inline_stmt_list + op_('}') >> create_mapper(Diagram) ) dotfile = diagram + skip(finished) return dotfile.parse(seq) def sort_tree(tree): def weight(node): if isinstance(node, (Attr, Extension)): return 1 else: return 2 if hasattr(tree, 'stmts'): tree.stmts.sort(key=lambda x: weight(x)) for stmt in tree.stmts: sort_tree(stmt) return tree def parse_string(string): try: tree = parse(tokenize(string)) return sort_tree(tree) except LexerError as e: message = "Got unexpected token at line %d column %d" % e.place raise ParseException(message) except Exception as e: raise ParseException(str(e)) def parse_file(path): input = io.open(path, 'r', encoding='utf-8-sig').read() return parse_string(input) actdiag-3.0.0+dfsg1/src/actdiag/utils/0000755000175000017500000000000014153440035016132 5ustar zigozigoactdiag-3.0.0+dfsg1/src/actdiag/utils/rst/0000755000175000017500000000000014153440035016742 5ustar zigozigoactdiag-3.0.0+dfsg1/src/actdiag/utils/rst/nodes.py0000644000175000017500000000143614153440035020430 0ustar zigozigo# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from blockdiag.utils.rst import nodes import actdiag.builder import actdiag.drawer import actdiag.parser class actdiag(nodes.blockdiag): name = 'actdiag' processor = actdiag actdiag-3.0.0+dfsg1/src/actdiag/utils/rst/__init__.py0000644000175000017500000000114414153440035021053 0ustar zigozigo# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. actdiag-3.0.0+dfsg1/src/actdiag/utils/rst/directives.py0000644000175000017500000000274514153440035021465 0ustar zigozigo# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from blockdiag.utils.rst import directives from docutils.parsers import rst from actdiag.utils.rst.nodes import actdiag as actdiag_node directive_options_default = dict(format='PNG', antialias=False, fontpath=None, outputdir=None, nodoctype=False, noviewbox=False, inline_svg=False) directive_options = {} class ActdiagDirective(directives.BlockdiagDirective): name = "actdiag" node_class = actdiag_node @property def global_options(self): return directive_options def setup(**kwargs): for key, value in directive_options_default.items(): directive_options[key] = kwargs.get(key, value) rst.directives.register_directive("actdiag", ActdiagDirective) actdiag-3.0.0+dfsg1/src/actdiag/utils/__init__.py0000644000175000017500000000114414153440035020243 0ustar zigozigo# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. actdiag-3.0.0+dfsg1/src/actdiag/drawer.py0000644000175000017500000000357714153440035016644 0ustar zigozigo# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import blockdiag.drawer from actdiag.metrics import DiagramMetrics class DiagramDraw(blockdiag.drawer.DiagramDraw): def create_metrics(self, *args, **kwargs): return DiagramMetrics(*args, **kwargs) def _draw_elements(self, **kwargs): m = self.metrics # render label of lanes for i, lane in enumerate(self.diagram.lanes): if lane.label: label = lane.label elif isinstance(lane.id, str): label = lane.id else: label = 'Lane %d' % (i + 1) if lane.href and self.format == 'SVG': drawer = self.drawer.anchor(lane.href) else: drawer = self.drawer headerbox = m.lane_headerbox(lane) drawer.rectangle(headerbox, fill=lane.color, outline=lane.color) textbox = m.lane_textbox(lane) drawer.textarea(textbox, label, fill=self.fill, font=self.metrics.font_for(lane)) # render frame of activity lanes frame = m.frame(self.diagram.lanes) self.drawer.rectangle(frame.outline, outline='gray') for xy in frame.separators: self.drawer.line(xy, fill='gray') super(DiagramDraw, self)._draw_elements(**kwargs) actdiag-3.0.0+dfsg1/src/actdiag/__init__.py0000644000175000017500000000117314153440035017105 0ustar zigozigo# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. __version__ = '3.0.0' actdiag-3.0.0+dfsg1/src/actdiag/plugins/0000755000175000017500000000000014153440035016453 5ustar zigozigoactdiag-3.0.0+dfsg1/src/actdiag/plugins/autolane.py0000644000175000017500000000221114153440035020631 0ustar zigozigo# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import re from blockdiag import plugins class AutoLane(plugins.NodeHandler): def on_created(self, node): if node.id is None: return for lane in self.diagram.lanes: pattern = "^%s_" % re.escape(lane.id) if re.search(pattern, node.id) and node.lane is None: node.label = re.sub(pattern, '', node.id) node.lane = lane lane.nodes.append(node) def setup(self, diagram, **kwargs): plugins.install_node_handler(AutoLane(diagram, **kwargs)) actdiag-3.0.0+dfsg1/src/actdiag/plugins/__init__.py0000644000175000017500000000114414153440035020564 0ustar zigozigo# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. actdiag-3.0.0+dfsg1/src/actdiag/tests/0000755000175000017500000000000014610157353016142 5ustar zigozigoactdiag-3.0.0+dfsg1/src/actdiag/tests/diagrams/0000755000175000017500000000000014153440035017723 5ustar zigozigoactdiag-3.0.0+dfsg1/src/actdiag/tests/diagrams/simple.diag0000644000175000017500000000007714153440035022046 0ustar zigozigo{ lane { A; C; } lane { B; } A -> B -> C; } actdiag-3.0.0+dfsg1/src/actdiag/tests/test_rst_directives.py0000644000175000017500000007356514153440035022616 0ustar zigozigo# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import sys import unittest from blockdiag.tests.utils import TemporaryDirectory, capture_stderr, with_pil from docutils import nodes from docutils.core import publish_doctree from docutils.parsers.rst import directives as docutils from actdiag.utils.rst import directives class TestRstDirectives(unittest.TestCase): def setUp(self): self._tmpdir = TemporaryDirectory() def tearDown(self): if 'actdiag' in docutils._directives: del docutils._directives['actdiag'] self._tmpdir.clean() @property def tmpdir(self): return self._tmpdir.name def test_setup(self): directives.setup() options = directives.directive_options self.assertIn('actdiag', docutils._directives) self.assertEqual(directives.ActdiagDirective, docutils._directives['actdiag']) self.assertEqual('PNG', options['format']) self.assertEqual(False, options['antialias']) self.assertEqual(None, options['fontpath']) self.assertEqual(False, options['nodoctype']) self.assertEqual(False, options['noviewbox']) self.assertEqual(False, options['inline_svg']) def test_setup_with_args(self): directives.setup(format='SVG', antialias=True, fontpath='/dev/null', nodoctype=True, noviewbox=True, inline_svg=True) options = directives.directive_options self.assertIn('actdiag', docutils._directives) self.assertEqual(directives.ActdiagDirective, docutils._directives['actdiag']) self.assertEqual('SVG', options['format']) self.assertEqual(True, options['antialias']) self.assertEqual('/dev/null', options['fontpath']) self.assertEqual(True, options['nodoctype']) 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 = (".. actdiag::\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'], outputdir=self.tmpdir) text = (".. actdiag::\n" "\n" " A -> B") publish_doctree(text) def test_setup_fontpath2(self): with self.assertRaises(RuntimeError): directives.setup(format='SVG', fontpath='dummy.ttf', outputdir=self.tmpdir) text = (".. actdiag::\n" "\n" " A -> B") publish_doctree(text) def test_setup_nodoctype_is_true(self): directives.setup(format='SVG', outputdir=self.tmpdir, nodoctype=True) text = (".. actdiag::\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[-1])) svg = open(doctree[0]['uri']).read() self.assertNotEqual("\n" " B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) svg = open(doctree[0]['uri']).read() self.assertEqual("\n" " B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) svg = open(doctree[0]['uri']).read() self.assertRegexpMatches(svg, r' B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) svg = open(doctree[0]['uri']).read() self.assertRegexpMatches(svg, r' B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.raw, type(doctree[0])) self.assertEqual('html', doctree[0]['format']) self.assertEqual(nodes.Text, type(doctree[0][0])) self.assertEqual("\n" " B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(1, len(os.listdir(self.tmpdir))) @with_pil def test_setup_inline_svg_is_true_but_format_isnt_svg(self): directives.setup(format='PNG', outputdir=self.tmpdir, inline_svg=True) text = (".. actdiag::\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) def test_setup_inline_svg_is_true_and_width_option1(self): directives.setup(format='SVG', outputdir=self.tmpdir, nodoctype=True, noviewbox=True, inline_svg=True) text = (".. actdiag::\n" " :width: 100\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.raw, type(doctree[0])) self.assertEqual(nodes.Text, type(doctree[0][0])) self.assertRegexpMatches(doctree[0][0], r' B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.raw, type(doctree[0])) self.assertEqual(nodes.Text, type(doctree[0][0])) self.assertRegexpMatches(doctree[0][0], r' B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.raw, type(doctree[0])) self.assertEqual(nodes.Text, type(doctree[0][0])) self.assertRegexpMatches(doctree[0][0], r' B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.raw, type(doctree[0])) self.assertEqual(nodes.Text, type(doctree[0][0])) self.assertRegexpMatches(doctree[0][0], r' B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.raw, type(doctree[0])) self.assertEqual(nodes.Text, type(doctree[0][0])) self.assertRegexpMatches(doctree[0][0], ' B" " }") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) def test_call_without_braces(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) def test_alt_option(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :alt: hello world\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual('hello world', doctree[0]['alt']) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) def test_align_option1(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :align: left\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual('left', doctree[0]['align']) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) def test_align_option2(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :align: center\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual('center', doctree[0]['align']) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) def test_align_option3(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :align: right\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual('right', doctree[0]['align']) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) @capture_stderr def test_align_option4(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :align: unknown\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.system_message, type(doctree[0])) # clear stderr outputs (ignore ERROR) from io import StringIO sys.stderr = StringIO() def test_caption_option(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :caption: hello world\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.figure, type(doctree[0])) self.assertEqual(2, len(doctree[0])) self.assertEqual(nodes.image, type(doctree[0][0])) self.assertEqual(nodes.caption, type(doctree[0][1])) self.assertEqual(1, len(doctree[0][1])) self.assertEqual(nodes.Text, type(doctree[0][1][0])) self.assertEqual('hello world', doctree[0][1][0]) def test_caption_option_and_align_option(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :align: left\n" " :caption: hello world\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.figure, type(doctree[0])) self.assertEqual('left', doctree[0]['align']) self.assertEqual(2, len(doctree[0])) self.assertEqual(nodes.image, type(doctree[0][0])) self.assertNotIn('align', doctree[0][0]) self.assertEqual(nodes.caption, type(doctree[0][1])) self.assertEqual(1, len(doctree[0][1])) self.assertEqual(nodes.Text, type(doctree[0][1][0])) self.assertEqual('hello world', doctree[0][1][0]) @capture_stderr def test_maxwidth_option(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :maxwidth: 100\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(2, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) self.assertEqual(nodes.system_message, type(doctree[1])) def test_width_option(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :width: 100\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual('100', doctree[0]['width']) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) def test_height_option(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :height: 100\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual('100', doctree[0]['height']) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) def test_scale_option(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :scale: 50%\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(50, doctree[0]['scale']) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) def test_name_option(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :name: foo%\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(['foo%'], doctree[0]['names']) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) def test_class_option(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :class: bar%\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(['bar'], doctree[0]['classes']) self.assertEqual(0, doctree[0]['uri'].index(self.tmpdir)) def test_figwidth_option1(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :caption: hello world\n" " :figwidth: 100\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.figure, type(doctree[0])) self.assertEqual('100px', doctree[0]['width']) def test_figwidth_option2(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :caption: hello world\n" " :figwidth: image\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.figure, type(doctree[0])) self.assertEqual('256px', doctree[0]['width']) def test_figclass_option(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :caption: hello world\n" " :figclass: baz\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.figure, type(doctree[0])) self.assertEqual(['baz'], doctree[0]['classes']) def test_desctable(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :desctable:\n" "\n" " A [description = foo]" " B [description = bar]") doctree = publish_doctree(text) self.assertEqual(2, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(nodes.table, type(doctree[1])) # tgroup self.assertEqual(4, len(doctree[1][0])) self.assertEqual(nodes.colspec, type(doctree[1][0][0])) self.assertEqual(nodes.colspec, type(doctree[1][0][1])) self.assertEqual(nodes.thead, type(doctree[1][0][2])) self.assertEqual(nodes.tbody, type(doctree[1][0][3])) # colspec self.assertEqual(50, doctree[1][0][0]['colwidth']) self.assertEqual(50, doctree[1][0][1]['colwidth']) # thead thead = doctree[1][0][2] self.assertEqual(2, len(thead[0])) self.assertEqual('Name', thead[0][0][0][0]) self.assertEqual('Description', thead[0][1][0][0]) # tbody tbody = doctree[1][0][3] self.assertEqual(2, len(tbody)) self.assertEqual('A', tbody[0][0][0][0]) self.assertEqual('foo', tbody[0][1][0][0]) self.assertEqual('B', tbody[1][0][0][0]) self.assertEqual('bar', tbody[1][1][0][0]) def test_desctable_option_without_description(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :desctable:\n" "\n" " A -> B") doctree = publish_doctree(text) self.assertEqual(1, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) def test_desctable_option_with_rest_markups(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :desctable:\n" "\n" " A [description = \"foo *bar* **baz**\"]" " B [description = \"**foo** *bar* baz\"]") doctree = publish_doctree(text) self.assertEqual(2, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(nodes.table, type(doctree[1])) # tgroup self.assertEqual(4, len(doctree[1][0])) self.assertEqual(nodes.colspec, type(doctree[1][0][0])) self.assertEqual(nodes.colspec, type(doctree[1][0][1])) self.assertEqual(nodes.thead, type(doctree[1][0][2])) self.assertEqual(nodes.tbody, type(doctree[1][0][3])) # colspec self.assertEqual(50, doctree[1][0][0]['colwidth']) self.assertEqual(50, doctree[1][0][1]['colwidth']) # thead thead = doctree[1][0][2] self.assertEqual(2, len(thead[0])) self.assertEqual('Name', thead[0][0][0][0]) self.assertEqual('Description', thead[0][1][0][0]) # tbody tbody = doctree[1][0][3] self.assertEqual(2, len(tbody)) self.assertEqual('A', tbody[0][0][0][0]) self.assertEqual(4, len(tbody[0][1][0])) self.assertEqual(nodes.Text, type(tbody[0][1][0][0])) self.assertEqual('foo ', str(tbody[0][1][0][0])) self.assertEqual(nodes.emphasis, type(tbody[0][1][0][1])) self.assertEqual(nodes.Text, type(tbody[0][1][0][1][0])) self.assertEqual('bar', tbody[0][1][0][1][0]) self.assertEqual(nodes.Text, type(tbody[0][1][0][2])) self.assertEqual(' ', str(tbody[0][1][0][2])) self.assertEqual(nodes.strong, type(tbody[0][1][0][3])) self.assertEqual(nodes.Text, type(tbody[0][1][0][3][0])) self.assertEqual('baz', str(tbody[0][1][0][3][0])) self.assertEqual('B', tbody[1][0][0][0]) self.assertEqual(4, len(tbody[1][1][0])) self.assertEqual(nodes.strong, type(tbody[1][1][0][0])) self.assertEqual(nodes.Text, type(tbody[1][1][0][0][0])) self.assertEqual('foo', str(tbody[1][1][0][0][0])) self.assertEqual(nodes.Text, type(tbody[1][1][0][1])) self.assertEqual(' ', str(tbody[1][1][0][1])) self.assertEqual(nodes.emphasis, type(tbody[1][1][0][2])) self.assertEqual(nodes.Text, type(tbody[1][1][0][2][0])) self.assertEqual('bar', str(tbody[1][1][0][2][0])) self.assertEqual(nodes.Text, type(tbody[1][1][0][3])) self.assertEqual(' baz', str(tbody[1][1][0][3])) def test_desctable_option_with_numbered(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :desctable:\n" "\n" " A [numbered = 2]" " B [numbered = 1]") doctree = publish_doctree(text) self.assertEqual(2, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(nodes.table, type(doctree[1])) # tgroup self.assertEqual(4, len(doctree[1][0])) self.assertEqual(nodes.colspec, type(doctree[1][0][0])) self.assertEqual(nodes.colspec, type(doctree[1][0][1])) self.assertEqual(nodes.thead, type(doctree[1][0][2])) self.assertEqual(nodes.tbody, type(doctree[1][0][3])) # colspec self.assertEqual(25, doctree[1][0][0]['colwidth']) self.assertEqual(50, doctree[1][0][1]['colwidth']) # thead thead = doctree[1][0][2] self.assertEqual(2, len(thead[0])) self.assertEqual('No', thead[0][0][0][0]) self.assertEqual('Name', thead[0][1][0][0]) # tbody tbody = doctree[1][0][3] self.assertEqual(2, len(tbody)) self.assertEqual('1', tbody[0][0][0][0]) self.assertEqual('B', tbody[0][1][0][0]) self.assertEqual('2', tbody[1][0][0][0]) self.assertEqual('A', tbody[1][1][0][0]) def test_desctable_option_with_numbered_and_description(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :desctable:\n" "\n" " A [description = foo, numbered = 2]" " B [description = bar, numbered = 1]") doctree = publish_doctree(text) self.assertEqual(2, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(nodes.table, type(doctree[1])) # tgroup self.assertEqual(5, len(doctree[1][0])) self.assertEqual(nodes.colspec, type(doctree[1][0][0])) self.assertEqual(nodes.colspec, type(doctree[1][0][1])) self.assertEqual(nodes.colspec, type(doctree[1][0][2])) self.assertEqual(nodes.thead, type(doctree[1][0][3])) self.assertEqual(nodes.tbody, type(doctree[1][0][4])) # colspec self.assertEqual(25, doctree[1][0][0]['colwidth']) self.assertEqual(50, doctree[1][0][1]['colwidth']) self.assertEqual(50, doctree[1][0][2]['colwidth']) # thead thead = doctree[1][0][3] self.assertEqual(3, len(thead[0])) self.assertEqual('No', thead[0][0][0][0]) self.assertEqual('Name', thead[0][1][0][0]) self.assertEqual('Description', thead[0][2][0][0]) # tbody tbody = doctree[1][0][4] self.assertEqual(2, len(tbody)) self.assertEqual('1', tbody[0][0][0][0]) self.assertEqual('B', tbody[0][1][0][0]) self.assertEqual(1, len(tbody[0][2])) self.assertEqual('bar', tbody[0][2][0][0]) self.assertEqual('2', tbody[1][0][0][0]) self.assertEqual('A', tbody[1][1][0][0]) self.assertEqual('foo', tbody[1][2][0][0]) def test_desctable_option_for_edges(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :desctable:\n" "\n" " A -> B [description = \"foo\"]" " C -> D [description = \"bar\"]" " C [label = \"label_C\"]" " D [label = \"label_D\"]") doctree = publish_doctree(text) self.assertEqual(2, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(nodes.table, type(doctree[1])) # tgroup self.assertEqual(4, len(doctree[1][0])) self.assertEqual(nodes.colspec, type(doctree[1][0][0])) self.assertEqual(nodes.colspec, type(doctree[1][0][1])) self.assertEqual(nodes.thead, type(doctree[1][0][2])) self.assertEqual(nodes.tbody, type(doctree[1][0][3])) # colspec self.assertEqual(25, doctree[1][0][0]['colwidth']) self.assertEqual(50, doctree[1][0][1]['colwidth']) # thead thead = doctree[1][0][2] self.assertEqual(2, len(thead[0])) self.assertEqual('Name', thead[0][0][0][0]) self.assertEqual('Description', thead[0][1][0][0]) # tbody tbody = doctree[1][0][3] self.assertEqual(2, len(tbody)) self.assertEqual('A -> B', tbody[0][0][0][0]) self.assertEqual(1, len(tbody[0][1][0])) self.assertEqual(nodes.Text, type(tbody[0][1][0][0])) self.assertEqual('foo', str(tbody[0][1][0][0])) self.assertEqual('label_C -> label_D', tbody[1][0][0][0]) self.assertEqual(1, len(tbody[1][1][0])) self.assertEqual(nodes.Text, type(tbody[1][1][0][0])) self.assertEqual('bar', str(tbody[1][1][0][0])) def test_desctable_option_for_nodes_and_edges(self): directives.setup(format='SVG', outputdir=self.tmpdir) text = (".. actdiag::\n" " :desctable:\n" "\n" " A -> B [description = \"foo\"]" " C -> D [description = \"bar\"]" " C [label = \"label_C\", description = foo]" " D [label = \"label_D\"]") doctree = publish_doctree(text) self.assertEqual(3, len(doctree)) self.assertEqual(nodes.image, type(doctree[0])) self.assertEqual(nodes.table, type(doctree[1])) self.assertEqual(nodes.table, type(doctree[2])) # tgroup self.assertEqual(4, len(doctree[2][0])) self.assertEqual(nodes.colspec, type(doctree[2][0][0])) self.assertEqual(nodes.colspec, type(doctree[2][0][1])) self.assertEqual(nodes.thead, type(doctree[2][0][2])) self.assertEqual(nodes.tbody, type(doctree[2][0][3])) # colspec self.assertEqual(25, doctree[2][0][0]['colwidth']) self.assertEqual(50, doctree[2][0][1]['colwidth']) # thead thead = doctree[2][0][2] self.assertEqual(2, len(thead[0])) self.assertEqual('Name', thead[0][0][0][0]) self.assertEqual('Description', thead[0][1][0][0]) # tbody tbody = doctree[2][0][3] self.assertEqual(2, len(tbody)) self.assertEqual('A -> B', tbody[0][0][0][0]) self.assertEqual(1, len(tbody[0][1][0])) self.assertEqual(nodes.Text, type(tbody[0][1][0][0])) self.assertEqual('foo', str(tbody[0][1][0][0])) self.assertEqual('label_C -> label_D', tbody[1][0][0][0]) self.assertEqual(1, len(tbody[1][1][0])) self.assertEqual(nodes.Text, type(tbody[1][1][0][0])) self.assertEqual('bar', str(tbody[1][1][0][0])) �������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/src/actdiag/tests/test_generate_diagram.py��������������������������������������0000644�0001750�0001750�00000002026�14153440035�023023� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os from blockdiag.tests.test_generate_diagram import (get_diagram_files, testcase_generator) import actdiag.command def test_generate(): mainfunc = actdiag.command.main basepath = os.path.dirname(__file__) files = get_diagram_files(basepath) options = [] for testcase in testcase_generator(basepath, mainfunc, files, options): yield testcase ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/src/actdiag/command.py����������������������������������������������������������0000644�0001750�0001750�00000001555�14153440035�016770� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import sys from blockdiag.utils.bootstrap import Application import actdiag import actdiag.builder import actdiag.drawer import actdiag.parser class ActdiagApp(Application): module = actdiag def main(args=sys.argv[1:]): return ActdiagApp().run(args) ���������������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/src/actdiag/elements.py���������������������������������������������������������0000644�0001750�0001750�00000002204�14153440035�017156� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import blockdiag.elements class DiagramNode(blockdiag.elements.DiagramNode): lane = None class DiagramEdge(blockdiag.elements.DiagramEdge): pass class NodeGroup(blockdiag.elements.NodeGroup): def __init__(self, _id): super(NodeGroup, self).__init__(_id) self.color = '#ffff99' class Diagram(blockdiag.elements.Diagram): _DiagramNode = DiagramNode _NodeGroup = NodeGroup def __init__(self): super(Diagram, self).__init__() self.orientation = 'portrait' self.lanes = [] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/src/actdiag/metrics.py����������������������������������������������������������0000644�0001750�0001750�00000006436�14153440035�017023� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import division from collections import namedtuple import blockdiag.metrics from blockdiag.utils import XY, Box from actdiag import elements class DiagramMetrics(blockdiag.metrics.DiagramMetrics): def __init__(self, diagram, **kwargs): super(DiagramMetrics, self).__init__(diagram, **kwargs) if diagram.page_padding is None: if diagram.orientation == 'landscape': padding = self.node_width + self.span_width self.page_padding = [0, 0, 0, padding] else: padding = self.node_height + self.span_height self.page_padding = [padding, 0, 0, 0] def pagesize(self, width=None, height=None): if width: self.colwidth = width else: width = self.colwidth if height: self.colheight = height else: height = self.colheight return super(DiagramMetrics, self).pagesize(width, height) def frame(self, lanes): dummy = elements.DiagramNode(None) dummy.xy = XY(0, 0) dummy.colwidth = self.colwidth dummy.colheight = self.colheight cell = self.cell(dummy, use_padding=False) headerbox = Box(cell.topleft.x - self.span_width // 2, (cell.topleft.y - self.node_height - self.span_height - 2), cell.topright.x + self.span_width // 2, cell.topright.y - self.span_height // 2) outline = Box(headerbox[0], headerbox[1], headerbox[2], cell.bottom.y + self.span_height // 2) separators = [(XY(headerbox[0], headerbox[3]), XY(headerbox[2], headerbox[3]))] for lane in lanes[:-1]: x = lane.xy.x + lane.colwidth + 1 m = self.cell(lane, use_padding=False) span_width = self.spreadsheet.span_width[x] // 2 x1 = m.right.x + span_width xy = (XY(x1, outline[1]), XY(x1, outline[3])) separators.append(xy) Frame = namedtuple('Frame', 'headerbox outline separators') return Frame(headerbox, outline, separators) def lane_textbox(self, lane): headerbox = self.frame([]).headerbox m = self.cell(lane, use_padding=False) x1 = m.left.x x2 = m.right.x return Box(x1, headerbox[1], x2, headerbox[3]) def lane_headerbox(self, lane): headerbox = self.frame([]).headerbox m = self.cell(lane) x1 = m.left.x - self.spreadsheet.span_width[lane.xy.x] // 2 x2 = m.right.x + self.spreadsheet.span_width[lane.xy.x + 1] // 2 return Box(x1, headerbox[1], x2, headerbox[3]) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/src/actdiag/builder.py����������������������������������������������������������0000644�0001750�0001750�00000031071�14153440035�016774� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # Copyright 2011 Takeshi KOMIYA # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function from blockdiag.utils import XY, unquote from blockdiag.utils.compat import cmp_to_key from actdiag import parser from actdiag.elements import Diagram, DiagramEdge, DiagramNode, NodeGroup class DiagramTreeBuilder(object): def build(self, tree): self.diagram = Diagram() diagram = self.instantiate(self.diagram, tree) self.bind_edges(diagram) if len(self.diagram.lanes) == 0: self.diagram.lanes.append(NodeGroup.get(None)) for node in self.diagram.nodes: if node.lane is None: edges = DiagramEdge.find(None, node) parents = [e.node1 for e in edges if e.node1.lane] parents.sort(key=lambda x: x.order) if parents: node.lane = parents[0].lane node.lane.nodes.append(node) else: node.lane = self.diagram.lanes[0] node.lane.nodes.append(node) for lane in diagram.lanes: if len(lane.nodes) == 0: diagram.lanes.remove(lane) return diagram def belong_to(self, node, lane): if lane and node.lane and node.lane != lane: print(node, node.lane, lane) msg = "DiagramNode could not belong to two lanes" raise RuntimeError(msg) node.group = self.diagram if lane: node.lane = lane lane.nodes.append(node) if node not in self.diagram.nodes: self.diagram.nodes.append(node) def instantiate(self, group, tree, lane=None): for stmt in tree.stmts: if isinstance(stmt, parser.Node): node = DiagramNode.get(stmt.id) node.set_attributes(stmt.attrs) self.belong_to(node, lane) elif isinstance(stmt, parser.Edge): from_nodes = [DiagramNode.get(n) for n in stmt.from_nodes] to_nodes = [DiagramNode.get(n) for n in stmt.to_nodes] for node in from_nodes + to_nodes: self.belong_to(node, lane) for node1 in from_nodes: for node2 in to_nodes: edge = DiagramEdge.get(node1, node2) edge.set_dir(stmt.edge_type) edge.set_attributes(stmt.attrs) elif isinstance(stmt, parser.Lane): _lane = NodeGroup.get(stmt.id) if _lane not in self.diagram.lanes: self.diagram.lanes.append(_lane) self.instantiate(group, stmt, _lane) elif isinstance(stmt, parser.Attr): if lane: lane.set_attribute(stmt) else: self.diagram.set_attribute(stmt) elif isinstance(stmt, parser.Extension): if stmt.type == 'class': name = unquote(stmt.name) Diagram.classes[name] = stmt if stmt.type == 'plugin': self.diagram.set_plugin(stmt.name, stmt.attrs) elif isinstance(stmt, parser.Statements): self.instantiate(group, stmt, lane) group.update_order() return group def bind_edges(self, group): for node in group.nodes: if isinstance(node, DiagramNode): group.edges += DiagramEdge.find(node) else: self.bind_edges(node) class DiagramLayoutManager: def __init__(self, diagram): self.diagram = diagram self.circulars = [] self.heightRefs = [] def run(self): self.edges = [e for e in DiagramEdge.find_all()] self.do_layout() self.diagram.fixiate() self.fixiate_lanes() def fixiate_lanes(self): height = 0 for lane in self.diagram.lanes: if self.coordinates[lane]: for node in self.diagram.nodes: if node.lane == lane: node.xy = XY(node.xy.x, node.xy.y + height) height += max(xy.y for xy in self.coordinates[lane]) + 1 nodes = [n for n in self.diagram.nodes if n.lane == lane] x = min(n.xy.x for n in nodes) y = min(n.xy.y for n in nodes) lane.xy = XY(x, y) lane.colwidth = max(n.xy.x + n.colwidth for n in nodes) - x lane.colheight = max(n.xy.y + n.colheight for n in nodes) - y def do_layout(self): self.detect_circulars() self.set_node_width() self.adjust_node_order() height = 0 self.initialize_markers() for node in self.diagram.traverse_nodes(): if node.xy.x == 0: lane = node.lane if self.coordinates[lane]: height = max(xy.y for xy in self.coordinates[lane]) + 1 else: height = 0 self.set_node_height(node, height) def get_related_nodes(self, node, parent=False, child=False): uniq = {} for edge in self.edges: if edge.folded: continue if parent and edge.node2 == node: uniq[edge.node1] = 1 elif child and edge.node1 == node: uniq[edge.node2] = 1 related = [] for uniq_node in uniq.keys(): if uniq_node == node: pass else: related.append(uniq_node) related.sort(key=lambda x: x.order) return related def get_parent_nodes(self, node): return self.get_related_nodes(node, parent=True) def get_child_nodes(self, node): return self.get_related_nodes(node, child=True) def detect_circulars(self): for node in self.diagram.nodes: if not [x for x in self.circulars if node in x]: self.detect_circulars_sub(node, [node]) # remove part of other circular for c1 in self.circulars: for c2 in self.circulars: intersect = set(c1) & set(c2) if c1 != c2 and set(c1) == intersect: self.circulars.remove(c1) break def detect_circulars_sub(self, node, parents): for child in self.get_child_nodes(node): if child in parents: i = parents.index(child) self.circulars.append(parents[i:]) else: self.detect_circulars_sub(child, parents + [child]) def is_circular_ref(self, node1, node2): for circular in self.circulars: if node1 in circular and node2 in circular: parents = [] for node in circular: for parent in self.get_parent_nodes(node): if parent not in circular: parents.append(parent) parents.sort(key=lambda x: x.order) for parent in parents: children = self.get_child_nodes(parent) if node1 in children and node2 in children: if circular.index(node1) > circular.index(node2): return True elif node2 in children: return True elif node1 in children: return False else: if circular.index(node1) > circular.index(node2): return True return False def set_node_width(self, depth=0): for node in self.diagram.traverse_nodes(): if node.xy.x != depth: continue for child in self.get_child_nodes(node): if self.is_circular_ref(node, child): pass elif node == child: pass elif child.xy.x > node.xy.x + node.colwidth: pass else: child.xy = XY(node.xy.x + node.colwidth, 0) nodes_iter = self.diagram.traverse_nodes() depther_node = [x for x in nodes_iter if x.xy.x > depth] if len(depther_node) > 0: self.set_node_width(depth + 1) def adjust_node_order(self): for node in self.diagram.traverse_nodes(): parents = self.get_parent_nodes(node) if len(set(parents)) > 1: for i in range(1, len(parents)): idx1 = self.diagram.nodes.index(parents[i - 1]) idx2 = self.diagram.nodes.index(parents[i]) if idx1 < idx2: self.diagram.nodes.remove(parents[i]) self.diagram.nodes.insert(idx1 + 1, parents[i]) else: self.diagram.nodes.remove(parents[i - 1]) self.diagram.nodes.insert(idx2 + 1, parents[i - 1]) if isinstance(node, NodeGroup): nodes = [n for n in node.nodes if n in self.diagram.nodes] if nodes: idx = min(self.diagram.nodes.index(n) for n in nodes) if idx < self.diagram.nodes.index(node): self.diagram.nodes.remove(node) self.diagram.nodes.insert(idx + 1, node) self.diagram.update_order() def initialize_markers(self): self.coordinates = {} for lane in self.diagram.lanes: self.coordinates[lane] = [] def mark_xy(self, node): xy = node.xy for w in range(node.colwidth): for h in range(node.colheight): self.coordinates[node.lane].append(XY(xy.x + w, xy.y + h)) def is_marked(self, lane, xy): return xy in self.coordinates[lane] def set_node_height(self, node, height=0): xy = XY(node.xy.x, height) if self.is_marked(node.lane, xy): return False node.xy = xy self.mark_xy(node) def cmp(x, y): if x.xy.x < y.xy.y: return -1 elif x.xy.x == y.xy.y: return 0 else: return 1 count = 0 children = self.get_child_nodes(node) children.sort(key=cmp_to_key(cmp)) for child in children: if child.id in self.heightRefs: pass elif node is not None and node.xy.x >= child.xy.x: pass else: if node.lane == child.lane: h = height else: h = 0 while True: if self.set_node_height(child, h): child.xy = XY(child.xy.x, h) self.mark_xy(child) self.heightRefs.append(child.id) count += 1 break elif node.lane != child.lane: h += 1 else: if count == 0: return False h += 1 if node.lane == child.lane: height = h + 1 return True class ScreenNodeBuilder(object): @classmethod def build(cls, tree, separate=False): DiagramNode.clear() DiagramEdge.clear() NodeGroup.clear() diagram = DiagramTreeBuilder().build(tree) DiagramLayoutManager(diagram).run() diagram.fixiate(True) if diagram.orientation == 'portrait': cls.rotate_diagram(diagram) return diagram @classmethod def rotate_diagram(cls, diagram): for node in diagram.traverse_nodes(): node.xy = XY(node.xy.y, node.xy.x) node.colwidth, node.colheight = (node.colheight, node.colwidth) for lane in diagram.lanes: lane.xy = XY(lane.xy.y, lane.xy.x) lane.colwidth, lane.colheight = (lane.colheight, lane.colwidth) size = (diagram.colheight, diagram.colwidth) diagram.colwidth, diagram.colheight = size �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/.github/������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14153440035�014147� 5����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/.github/workflows/��������������������������������������������������������������0000755�0001750�0001750�00000000000�14153440035�016204� 5����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/.github/workflows/release.yml���������������������������������������������������0000644�0001750�0001750�00000001213�14153440035�020344� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������name: Release a new package on: push: tags: - '*' jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: '3.x' - name: Install dependencies run: pip install docutils setuptools wheel - name: Build package run: python setup.py sdist bdist_wheel - name: Upload package to PyPI uses: pypa/gh-action-pypi-publish@master if: startsWith(github.ref, 'refs/tags/') with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/.github/workflows/lint.yml������������������������������������������������������0000644�0001750�0001750�00000000760�14153440035�017700� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������name: Lint on: [push, pull_request] jobs: lint: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 with: fetch-depth: 1 - name: Setup python uses: actions/setup-python@v2 with: python-version: 3.7 - name: Install tox and any other packages for test run: | python -m pip install --upgrade pip pip install tox - name: Run tox run: tox -e flake8 ����������������actdiag-3.0.0+dfsg1/.github/workflows/test.yml������������������������������������������������������0000644�0001750�0001750�00000001635�14153440035�017713� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������name: Test on: [push, pull_request] env: PYTHONFAULTHANDLER: x ALL_TESTS: 1 jobs: test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - python-version: '3.7' toxenv: py37 - python-version: '3.8' toxenv: py38 - python-version: '3.9' toxenv: py39 - python-version: '3.9' toxenv: blockdiag_dev steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | sudo apt-get install fonts-ipafont-gothic ghostscript libjpeg8-dev libfreetype6-dev pip install -U docutils tox - name: Run tox env: TOXENV: ${{ matrix.toxenv }} run: tox -- -v ���������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/.gitignore����������������������������������������������������������������������0000644�0001750�0001750�00000000200�14153440035�014567� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������*.pyc *.egg *.egg-info *.so *.swp .cache/ .mypy_cache/ .pytest_cache/ TAGS .tags .tox/ .coverage .DS_Store env/ _build/ dist/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/CHANGES.rst���������������������������������������������������������������������0000644�0001750�0001750�00000005144�14153440035�014415� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Changelog ========= 3.0.0 (2021-12-06) ------------------ * Drop python3.6 support * Use funcparserlib-1.0.0a0 or newer to support new python versions * Allow to write multiline string via triple quotes (""" ... """) 2.0.0 (2020-01-26) ------------------ * Drop python2 and python3.4 support 0.5.4 (2015-01-01) ------------------ * Follow blockdiag-1.5.0 interface 0.5.3 (2014-07-02) ------------------ * Change interface of docutils node (for sphinxcontrib module) 0.5.2 (2014-06-24) ------------------ * Add options to blockdiag directive (docutils extension) - :width: - :height: - :scale: - :align: - :name: - :class: - :figwidth: - :figclass: 0.5.1 (2013-10-22) ------------------ * Fix bugs 0.5.0 (2013-10-05) ------------------ * Support python 3.2 and 3.3 (thanks to @masayuko) * Drop supports for python 2.4 and 2.5 * Replace dependency: PIL -> Pillow 0.4.3 (2013-02-10) ------------------ * Fix bugs 0.4.2 (2013-02-10) ------------------ * Fix bugs 0.4.1 (2012-10-28) ------------------ * Fix bugs 0.4.0 (2012-10-22) ------------------ * Optimize algorithm for rendering shadow * Add options to docutils directive * Fix bugs 0.3.4 (2012-09-29) ------------------ * Fix bugs 0.3.3 (2012-04-23) ------------------ * Set hyperlinks to header of lanes on SVG image * Fill background of lane header with lane.color attribute 0.3.2 (2012-03-15) ------------------ * Fix bugs 0.3.1 (2012-02-15) ------------------ * Add autolane plugin * Update to new package structure (blockdiag >= 1.1.2) 0.3.0 (2011-11-19) ------------------ * Add fontfamily attribute for switching fontface * Fix bugs 0.2.4 (2011-11-10) ------------------ * Fix dependencies (do not depend PIL directly for pillow users) 0.2.3 (2011-11-06) ------------------ * Add docutils exetension * Fix bugs 0.2.2 (2011-11-01) ------------------ * Add class feature (experimental) 0.2.1 (2011-11-01) ------------------ * Follow blockdiag-0.9.7 interface 0.2.0 (2011-10-19) ------------------ * Follow blockdiag-0.9.5 interface 0.1.9 (2011-10-11) ------------------ * Fix bugs 0.1.8 (2011-09-30) ------------------ * Add diagram attribute: default_text_color 0.1.7 (2011-07-05) ------------------ * Fix bugs 0.1.6 (2011-07-03) ------------------ * Support input from stdin 0.1.5 (2011-05-15) ------------------ * Fix bugs 0.1.4 (2011-05-14) ------------------ * Change license to Apache License 2.0 * Support blockdiag 0.8.1 core interface 0.1.3 (2011-04-19) ------------------ * Fix bugs 0.1.2 (2011-04-11) ------------------ * Fix bugs 0.1.1 (2011-04-10) ------------------ * Fix bugs 0.1.0 (2011-04-09) ------------------ * First release ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������actdiag-3.0.0+dfsg1/actdiag.1�����������������������������������������������������������������������0000644�0001750�0001750�00000004020�14153440035�014261� 0����������������������������������������������������������������������������������������������������ustar �zigo����������������������������zigo�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH ACTDIAG 1 "June 5, 2011" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME actdiag \- generate activity-diagram image file from spec-text file. .SH SYNOPSIS .B actdiag .RI [ options ] " files" .SH DESCRIPTION This manual page documents briefly the .B actdiag commands. .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invode bold face and italics, .\" respectively. \fBactdiag\fP is a program that generate activity-diagram image file from spec-text file. .SH OPTIONS These programs follow the usual GNU command line syntax, with long options starting with two dashes (`-'). A summary of options is included below. For a complete description, see the Info files. .TP .B \-h, \-\-help show this help message and exit .TP .B \-a, \-\-antialias Pass diagram image to anti-alias filter .TP .B \-c FILE, \-\-config=FILE read configurations from FILE .TP .B \-o FILE write diagram to FILE .TP .B \-f FONT, \-\-font=FONT use FONT to draw diagram .TP .B \-s, \-\---separate Separate diagram images for each group (SVG only) .TP .B \-T TYPE Output diagram as TYPE format .SH SEE ALSO The programs are documented fully by .br .BR http://tk0miya.bitbucket.org/actdiag/build/html/index.html .br .SH AUTHOR actdiag was written by Takeshi Komiya .PP This manual page was written by Kouhei Maeda , for the Debian project (and may be used by others). ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������