aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/Automat/py3/automat/_visualize.py
diff options
context:
space:
mode:
authorshmel1k <shmel1k@ydb.tech>2023-11-26 18:16:14 +0300
committershmel1k <shmel1k@ydb.tech>2023-11-26 18:43:30 +0300
commitb8cf9e88f4c5c64d9406af533d8948deb050d695 (patch)
tree218eb61fb3c3b96ec08b4d8cdfef383104a87d63 /contrib/python/Automat/py3/automat/_visualize.py
parent523f645a83a0ec97a0332dbc3863bb354c92a328 (diff)
downloadydb-b8cf9e88f4c5c64d9406af533d8948deb050d695.tar.gz
add kikimr_configure
Diffstat (limited to 'contrib/python/Automat/py3/automat/_visualize.py')
-rw-r--r--contrib/python/Automat/py3/automat/_visualize.py182
1 files changed, 182 insertions, 0 deletions
diff --git a/contrib/python/Automat/py3/automat/_visualize.py b/contrib/python/Automat/py3/automat/_visualize.py
new file mode 100644
index 0000000000..7a9c8c6eb5
--- /dev/null
+++ b/contrib/python/Automat/py3/automat/_visualize.py
@@ -0,0 +1,182 @@
+from __future__ import print_function
+import argparse
+import sys
+
+import graphviz
+
+from ._discover import findMachines
+
+
+def _gvquote(s):
+ return '"{}"'.format(s.replace('"', r'\"'))
+
+
+def _gvhtml(s):
+ return '<{}>'.format(s)
+
+
+def elementMaker(name, *children, **attrs):
+ """
+ Construct a string from the HTML element description.
+ """
+ formattedAttrs = ' '.join('{}={}'.format(key, _gvquote(str(value)))
+ for key, value in sorted(attrs.items()))
+ formattedChildren = ''.join(children)
+ return u'<{name} {attrs}>{children}</{name}>'.format(
+ name=name,
+ attrs=formattedAttrs,
+ children=formattedChildren)
+
+
+def tableMaker(inputLabel, outputLabels, port, _E=elementMaker):
+ """
+ Construct an HTML table to label a state transition.
+ """
+ colspan = {}
+ if outputLabels:
+ colspan['colspan'] = str(len(outputLabels))
+
+ inputLabelCell = _E("td",
+ _E("font",
+ inputLabel,
+ face="menlo-italic"),
+ color="purple",
+ port=port,
+ **colspan)
+
+ pointSize = {"point-size": "9"}
+ outputLabelCells = [_E("td",
+ _E("font",
+ outputLabel,
+ **pointSize),
+ color="pink")
+ for outputLabel in outputLabels]
+
+ rows = [_E("tr", inputLabelCell)]
+
+ if outputLabels:
+ rows.append(_E("tr", *outputLabelCells))
+
+ return _E("table", *rows)
+
+
+def makeDigraph(automaton, inputAsString=repr,
+ outputAsString=repr,
+ stateAsString=repr):
+ """
+ Produce a L{graphviz.Digraph} object from an automaton.
+ """
+ digraph = graphviz.Digraph(graph_attr={'pack': 'true',
+ 'dpi': '100'},
+ node_attr={'fontname': 'Menlo'},
+ edge_attr={'fontname': 'Menlo'})
+
+ for state in automaton.states():
+ if state is automaton.initialState:
+ stateShape = "bold"
+ fontName = "Menlo-Bold"
+ else:
+ stateShape = ""
+ fontName = "Menlo"
+ digraph.node(stateAsString(state),
+ fontame=fontName,
+ shape="ellipse",
+ style=stateShape,
+ color="blue")
+ for n, eachTransition in enumerate(automaton.allTransitions()):
+ inState, inputSymbol, outState, outputSymbols = eachTransition
+ thisTransition = "t{}".format(n)
+ inputLabel = inputAsString(inputSymbol)
+
+ port = "tableport"
+ table = tableMaker(inputLabel, [outputAsString(outputSymbol)
+ for outputSymbol in outputSymbols],
+ port=port)
+
+ digraph.node(thisTransition,
+ label=_gvhtml(table), margin="0.2", shape="none")
+
+ digraph.edge(stateAsString(inState),
+ '{}:{}:w'.format(thisTransition, port),
+ arrowhead="none")
+ digraph.edge('{}:{}:e'.format(thisTransition, port),
+ stateAsString(outState))
+
+ return digraph
+
+
+def tool(_progname=sys.argv[0],
+ _argv=sys.argv[1:],
+ _syspath=sys.path,
+ _findMachines=findMachines,
+ _print=print):
+ """
+ Entry point for command line utility.
+ """
+
+ DESCRIPTION = """
+ Visualize automat.MethodicalMachines as graphviz graphs.
+ """
+ EPILOG = """
+ You must have the graphviz tool suite installed. Please visit
+ http://www.graphviz.org for more information.
+ """
+ if _syspath[0]:
+ _syspath.insert(0, '')
+ argumentParser = argparse.ArgumentParser(
+ prog=_progname,
+ description=DESCRIPTION,
+ epilog=EPILOG)
+ argumentParser.add_argument('fqpn',
+ help="A Fully Qualified Path name"
+ " representing where to find machines.")
+ argumentParser.add_argument('--quiet', '-q',
+ help="suppress output",
+ default=False,
+ action="store_true")
+ argumentParser.add_argument('--dot-directory', '-d',
+ help="Where to write out .dot files.",
+ default=".automat_visualize")
+ argumentParser.add_argument('--image-directory', '-i',
+ help="Where to write out image files.",
+ default=".automat_visualize")
+ argumentParser.add_argument('--image-type', '-t',
+ help="The image format.",
+ choices=graphviz.FORMATS,
+ default='png')
+ argumentParser.add_argument('--view', '-v',
+ help="View rendered graphs with"
+ " default image viewer",
+ default=False,
+ action="store_true")
+ args = argumentParser.parse_args(_argv)
+
+ explicitlySaveDot = (args.dot_directory
+ and (not args.image_directory
+ or args.image_directory != args.dot_directory))
+ if args.quiet:
+ def _print(*args):
+ pass
+
+ for fqpn, machine in _findMachines(args.fqpn):
+ _print(fqpn, '...discovered')
+
+ digraph = machine.asDigraph()
+
+ if explicitlySaveDot:
+ digraph.save(filename="{}.dot".format(fqpn),
+ directory=args.dot_directory)
+ _print(fqpn, "...wrote dot into", args.dot_directory)
+
+ if args.image_directory:
+ deleteDot = not args.dot_directory or explicitlySaveDot
+ digraph.format = args.image_type
+ digraph.render(filename="{}.dot".format(fqpn),
+ directory=args.image_directory,
+ view=args.view,
+ cleanup=deleteDot)
+ if deleteDot:
+ msg = "...wrote image into"
+ else:
+ msg = "...wrote image and dot into"
+ _print(fqpn, msg, args.image_directory)