Skip to content

Commit 0f3b1fb

Browse files
committed
Merge pull request JuliaAttic#187 from JuliaGraphs/dot
Dot
2 parents 12ef75d + 7f05825 commit 0f3b1fb

File tree

6 files changed

+95
-4
lines changed

6 files changed

+95
-4
lines changed

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ Compat 0.4.9
33
GZip 0.2.16
44
StatsBase 0.6.15
55
LightXML 0.2.0
6-
ParserCombinator 1.6.3
6+
ParserCombinator 1.7.1
77
Docile 0.5.3

src/LightGraphs.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ using GZip
66
using StatsBase
77
using Base.Collections
88
using LightXML
9-
using ParserCombinator.Parsers.GML
9+
using ParserCombinator
10+
using ParserCombinator.Parsers
11+
1012

1113
if VERSION < v"0.4.0-dev"
1214
try
@@ -95,7 +97,7 @@ CombinatorialAdjacency,
9597
a_star,
9698

9799
# persistence
98-
readgraph, readgraphml, readgml, writegraphml, writegexf,
100+
readgraph, readgraphml, readgml, writegraphml, writegexf, readdot,
99101

100102
# flow
101103
maximum_flow,

src/persistence.jl

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# header followed by a list of (comma-delimited) edges - src,dst.
1010
# Multiple graphs may be present in one file.
1111

12+
1213
function _read_one_graph(f::IO, n_v::Integer, n_e::Integer, directed::Bool)
1314
readedges = Set{@compat Tuple{Int,Int}}()
1415
if directed
@@ -188,7 +189,7 @@ end
188189
Can optionally restrict to a single graph by specifying a name in gname."""
189190
function readgml(filename::AbstractString, gname::AbstractString="")
190191
f = open(readall,filename)
191-
p = parse_dict(f)
192+
p = Parsers.GML.parse_dict(f)
192193
graphs = @compat(Dict{AbstractString, SimpleGraph}())
193194
for gs in p[:graph]
194195

@@ -313,3 +314,42 @@ function writegexf(fname::AbstractString, g::SimpleGraph)
313314
close(f)
314315
return 1
315316
end
317+
318+
319+
function _readonedot(pg::ParserCombinator.Parsers.DOT.Graph)
320+
isdir = pg.directed
321+
nvg = length(Parsers.DOT.nodes(pg))
322+
nodedict = Dict(zip(collect(Parsers.DOT.nodes(pg)), 1:nvg))
323+
if isdir
324+
g = DiGraph(nvg)
325+
else
326+
g = Graph(nvg)
327+
end
328+
for es in Parsers.DOT.edges(pg)
329+
s = nodedict[es[1]]
330+
d = nodedict[es[2]]
331+
add_edge!(g, s, d)
332+
end
333+
return g
334+
end
335+
336+
"""Returns a dictionary (name=>graph) from file `fn` stored in
337+
[DOT](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) format.
338+
Can optionally restrict to a single graph by specifying a name in gname.
339+
"""
340+
function readdot(filename::AbstractString, gname::AbstractString="")
341+
f = open(readall,filename)
342+
p = Parsers.DOT.parse_dot(f)
343+
344+
graphs = @compat(Dict{AbstractString, SimpleGraph}())
345+
346+
for pg in p
347+
isdir = pg.directed
348+
possname = isdir? Parsers.DOT.StringID("Unnamed DiGraph") : Parsers.DOT.StringID("Unnamed Graph")
349+
name = get(pg.id, possname).id
350+
if (gname == "") || (name == gname)
351+
graphs[name] = _readonedot(pg)
352+
end
353+
end
354+
return graphs
355+
end

test/persistence.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ gml2 = gs["Unnamed DiGraph"]
4242
gs = readgraph(joinpath(testdir, "testdata", "tutte-pathdigraph.jgz"), "pathdigraph")["pathdigraph"]
4343
@test gs == p2
4444

45+
gs = readdot(joinpath(testdir, "testdata", "twographs.dot"))
46+
@test length(gs) == 2
47+
@test gs["g1"] == CompleteGraph(6)
48+
@test nv(gs["g2"]) == 4 && ne(gs["g2"]) == 6 && is_directed(gs["g2"])
49+
@test_throws KeyError readdot(joinpath(testdir, "testdata", "twographs.dot"))["badname"]
50+
4551
# test the writes
4652
# redirecting stdout per https://thenewphalls.wordpress.com/2014/03/21/capturing-output-in-julia/
4753
origSTDOUT = STDOUT

test/testdata/onegraph.dot

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
graph {
2+
a -- b;
3+
b -- c;
4+
c -- d;
5+
d -- e;
6+
e -- f;
7+
a -- f;
8+
a -- c;
9+
a -- d;
10+
a -- e;
11+
b -- d;
12+
b -- e;
13+
b -- f;
14+
c -- e;
15+
c -- f;
16+
d -- f;
17+
}

test/testdata/twographs.dot

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
graph g1 {
2+
a -- b;
3+
b -- c;
4+
c -- d;
5+
d -- e;
6+
e -- f;
7+
a -- f;
8+
a -- c;
9+
a -- d;
10+
a -- e;
11+
b -- d;
12+
b -- e;
13+
b -- f;
14+
c -- e;
15+
c -- f;
16+
d -- f;
17+
}
18+
19+
digraph g2 {
20+
a -> b;
21+
a -> c;
22+
c -> b;
23+
c -> e;
24+
e -> e;
25+
e -> b;
26+
}

0 commit comments

Comments
 (0)