Skip to content

Commit

Permalink
Merge pull request #27 from macbre/graphviz-escaping
Browse files Browse the repository at this point in the history
Escape " in graphviz entries
  • Loading branch information
macbre authored Jan 6, 2019
2 parents 26b6d42 + e6ff14c commit 4698728
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 6 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ install:
pip install -e .[dev]

test:
py.test
py.test -vv

coverage:
rm -f .coverage*
rm -rf htmlcov/*
coverage run -p -m py.test
coverage run -p -m py.test -vv
coverage combine
coverage html -d htmlcov $(coverage_options)
coverage xml -i
Expand Down
15 changes: 14 additions & 1 deletion data_flow_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ def format_tsv_lines(lines):
return [format_tsv_line(**line) + '\n' for line in lines]


def escape_graphviz_entry(entry):
"""
:type entry str
:rtype: str
"""
return entry.replace('"', '\\"')


def format_graphviz_lines(lines):
"""
Render a .dot file with graph definition from a given set of data
Expand All @@ -59,7 +67,10 @@ def format_graphviz_lines(lines):
graph = list()

# some basic style definition
# https://graphviz.gitlab.io/_pages/doc/info/lang.html
graph.append('digraph G {')

# https://graphviz.gitlab.io/_pages/doc/info/shapes.html#record
graph.append('\tgraph [ center=true, margin=0.75, nodesep=0.5, ranksep=0.75, rankdir=LR ];')
graph.append('\tnode [ shape=box, style="rounded,filled" width=0, height=0, '
'fontname=Helvetica, fontsize=11 ];')
Expand All @@ -81,6 +92,8 @@ def format_graphviz_lines(lines):
else:
group = None

label = escape_graphviz_entry(label)

graph.append('\t{name} [label="{label}"{group}];'.format(
name=name,
label="{}\\n{}".format(group, label) if group is not None else label,
Expand All @@ -96,7 +109,7 @@ def format_graphviz_lines(lines):
graph.append('\t{source} -> {target} [{label}];'.format(
source=nodes[line['source']],
target=nodes[line['target']],
label='label="{}"'.format(label) if label != '' else ''
label='label="{}"'.format(escape_graphviz_entry(label)) if label != '' else ''
))

graph.append('}')
Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
py_modules=["data_flow_graph"],
extras_require={
'dev': [
'coverage==4.5.1',
'pylint==1.8.2',
'pytest==3.4.0',
'coverage==4.5.2',
'pylint>=1.9.2, <=2.1.1', # 2.x branch is for Python 3
'pytest==4.0.0',
]
}
)
29 changes: 29 additions & 0 deletions test/test_graphviz.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,32 @@ def test_format():

with open('examples/graph.gv') as fp:
assert graph == fp.read().strip()


def test_escaping():
line = {
'source': 'Foo "bar" test',
'metadata': '"The Edge"',
'target': 'Test "foo" 42',
}

graph = format_graphviz_lines([line])
print(graph)

assert 'n1 [label="Foo \\"bar\\" test"];' in graph, 'Nodes labels are properly escaped'
assert 'n2 [label="Test \\"foo\\" 42"];' in graph, 'Nodes labels are properly escaped'
assert 'n1 -> n2 [label="\\"The Edge\\""];' in graph, 'Edges labels are properly escaped'


def test_escaping_with_groups():
line = {
'source': 'Foo:Foo "bar" test',
'metadata': '"The Edge"',
'target': 'Bar:Test "foo" 42',
}

graph = format_graphviz_lines([line])
print(graph)

assert 'n1 [label="Bar\\nTest \\"foo\\" 42" group="Bar" colorscheme=pastel28 color=1];' in graph, 'Nodes labels are properly escaped'
assert 'n2 [label="Foo\\nFoo \\"bar\\" test" group="Foo" colorscheme=pastel28 color=2];' in graph, 'Nodes labels are properly escaped'

0 comments on commit 4698728

Please sign in to comment.