Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- version: '1'
os: ubuntu-latest
arch: x64
- version: '1.5'
- version: '1.10'
os: ubuntu-latest
arch: x64
- version: 'nightly'
Expand Down
14 changes: 10 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
name = "MetaGraphs"
uuid = "626554b9-1ddb-594c-aa3c-2596fe9399a5"
version = "0.8.1"
version = "0.9.0"

[deps]
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[weakdeps]
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"

[extensions]
MetaGraphsJLD2Ext = ["Graphs", "JLD2"]

[compat]
Graphs = "1.4"
JLD2 = "0.1.11, 0.2, 0.3, 0.4, 0.5, 0.6"
julia = "1"
julia = "1.10"

[extras]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "Base64"]
test = ["Test", "Base64", "JLD2"]
74 changes: 74 additions & 0 deletions ext/MetaGraphsJLD2Ext.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
module MetaGraphsJLD2Ext

using Graphs
using JLD2
using MetaGraphs

function MetaGraphs.loadmg(fn::AbstractString)
@load fn g
return g
end

function MetaGraphs.savemg(fn::AbstractString, g::AbstractMetaGraph)
@save fn g
return 1
end

# escaping unescaped quotation marks
# i.e. replacing `"`` with `\"` while leaving `\"` as is
escape_quotes(s::AbstractString) = replace(s, r"([^\\])\"" => s"\1\\\\\"")

# According to the DOT language specification https://graphviz.org/doc/info/lang.html
# we can quote everyhthing that's not an XML/HTML literal
function quote_prop(p::AbstractString)
if occursin(r"<+.*>+$", p)
# The label is an HTML string, no additional quotes here.
return p
else
return "\"" * escape_quotes(p) * "\""
end
end
# if the property value is _not_ a string it cannot be XML/HTML literal, so just put it in quotes
quote_prop(p::Any) = "\"" * escape_quotes(string(p)) * "\""
# NOTE: down there I only quote property _values_. DOT allows quoting property _names_ too
# I don't do that as long as names are Symbols and can't have spaces and commas and stuff.
# That will break if someone uses a DOT keyword as a property name, as they must be quoted.

function MetaGraphs.savedot(io::IO, g::AbstractMetaGraph)
if is_directed(g)
write(io, "digraph G {\n")
dash = "->"
else
write(io, "graph G {\n")
dash = "--"
end

for p in props(g)
write(io, "$(p[1])=$(quote_prop(p[2]));\n")
end

for v in vertices(g)
write(io, "$v")
if length(props(g, v)) > 0
write(io, " [ ")

for p in props(g, v)
write(io, "$(p[1])=$(quote_prop(p[2])), ")
end

write(io, "];")
end
write(io, "\n")
end

for e in edges(g)
write(io, "$(src(e)) $dash $(dst(e)) [ ")
for p in props(g,e)
write(io, "$(p[1])=$(quote_prop(p[2])), ")
end
write(io, "]\n")
end
write(io, "}\n")
end

end
17 changes: 16 additions & 1 deletion src/MetaGraphs.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module MetaGraphs
using Graphs
using JLD2

import Base:
eltype, show, ==, Pair,
Expand Down Expand Up @@ -582,4 +581,20 @@ include("metadigraph.jl")
include("metagraph.jl")
include("persistence.jl")
include("overrides.jl")

function __init__()
# Register error hint for the `loadmg`, `savemg`, and `savedot` functions
if isdefined(Base.Experimental, :register_error_hint)
Base.Experimental.register_error_hint(MethodError) do io, exc, _, _
if exc.f === loadsg
print(io, "\n\nIn order to load meta graphs from binary files, you need \
to load the JLD2.jl package.")
elseif exc.f === savesg
print(io,"\n\nIn order to save meta graphs to binary files, you need to \
load the JLD2.jl package.")
end
end
end
end

end # module
74 changes: 5 additions & 69 deletions src/persistence.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,76 +3,12 @@
struct MGFormat <: AbstractGraphFormat end
struct DOTFormat <: AbstractGraphFormat end

function loadmg(fn::AbstractString)
@load fn g
return g
end

function savemg(fn::AbstractString, g::AbstractMetaGraph)
@save fn g
return 1
end

loadgraph(fn::AbstractString, gname::String, ::MGFormat) = loadmg(fn)
savegraph(fn::AbstractString, g::AbstractMetaGraph) = savemg(fn, g)

# escaping unescaped quotation marks
# i.e. replacing `"`` with `\"` while leaving `\"` as is
escape_quotes(s::AbstractString) = replace(s, r"([^\\])\"" => s"\1\\\\\"")
function loadmg end
function savemg end
function savedot end

# According to the DOT language specification https://graphviz.org/doc/info/lang.html
# we can quote everyhthing that's not an XML/HTML literal
function quote_prop(p::AbstractString)
if occursin(r"<+.*>+$", p)
# The label is an HTML string, no additional quotes here.
return p
else
return "\"" * escape_quotes(p) * "\""
end
end
# if the property value is _not_ a string it cannot be XML/HTML literal, so just put it in quotes
quote_prop(p::Any) = "\"" * escape_quotes(string(p)) * "\""
# NOTE: down there I only quote property _values_. DOT allows quoting property _names_ too
# I don't do that as long as names are Symbols and can't have spaces and commas and stuff.
# That will break if someone uses a DOT keyword as a property name, as they must be quoted.

function savedot(io::IO, g::AbstractMetaGraph)

if is_directed(g)
write(io, "digraph G {\n")
dash = "->"
else
write(io, "graph G {\n")
dash = "--"
end

for p in props(g)
write(io, "$(p[1])=$(quote_prop(p[2]));\n")
end

for v in vertices(g)
write(io, "$v")
if length(props(g, v)) > 0
write(io, " [ ")

for p in props(g, v)
write(io, "$(p[1])=$(quote_prop(p[2])), ")
end

write(io, "];")
end
write(io, "\n")
end

for e in edges(g)
write(io, "$(src(e)) $dash $(dst(e)) [ ")
for p in props(g,e)
write(io, "$(p[1])=$(quote_prop(p[2])), ")
end
write(io, "]\n")
end
write(io, "}\n")
end
loadgraph(fn::AbstractString, ::String, ::MGFormat) = loadmg(fn)
savegraph(fn::AbstractString, g::AbstractMetaGraph) = savemg(fn, g)

function savegraph(fn::AbstractString, g::AbstractMetaGraph, ::DOTFormat)
open(fn, "w") do fp
Expand Down
2 changes: 2 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Graphs
using MetaGraphs

using JLD2
using Test

import Graphs.SimpleGraphs: SimpleGraph, SimpleDiGraph
Expand Down
Loading