Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #52 from markus1189/extract_dotscript

Extracted xDOTScript to DOTScript class
  • Loading branch information...
commit 363bc9d4fec5a6cf3ab6ee0db15d3d426442a2df 2 parents fd513e4 + d378784
@glejeune authored
View
11 Rakefile
@@ -29,7 +29,7 @@ RDoc::Task.new do |rdoc|
rdoc.main = "README.rdoc"
rdoc.title = "Ruby/GraphViz, the Documentation"
rdoc.rdoc_files.add ['README.rdoc', 'CHANGELOG.rdoc', 'AUTHORS.rdoc', 'COPYING.rdoc',
- 'lib/graphviz.rb',
+ 'lib/graphviz.rb',
'lib/graphviz/node.rb',
'lib/graphviz/edge.rb',
'lib/graphviz/constants.rb',
@@ -45,11 +45,10 @@ end
Rake::TestTask.new(:test) do |t|
require 'graphviz/utils'
include GVUtils
- if find_executable("dot", nil).nil?
- t.test_files = FileList['test/test_*.rb'].exclude("test/test_examples.rb")
- else
- t.test_files = FileList['test/test_*.rb']
- end
+ test_files = FileList['test/test_*.rb'].exclude('test/test_dot_script.rb')
+ test_files.unshift('test/test_dot_script.rb')
+ test_files.exclude("test/test_examples.rb") unless find_executable("dot", nil)
+ t.test_files = test_files
end
Bundler::GemHelper.install_tasks
View
115 lib/graphviz.rb
@@ -26,6 +26,7 @@
require 'graphviz/attrs'
require 'graphviz/constants'
require 'graphviz/elements'
+require 'graphviz/dot_script'
require 'graphviz/dot2ruby'
require 'graphviz/types'
@@ -423,86 +424,15 @@ def each_attribut(&b)
# * 2 = none
#
def output( hOpts = {} )
- xDOTScript = ""
- xLastType = nil
- xSeparator = ""
- xData = ""
+ xDOTScript = DOTScript.new
lNotHugly = []
- @elements_order.each { |kElement|
- if xLastType.nil? or xLastType != kElement["type"]
-
- if xData.length > 0
- case xLastType
- when "graph_attr"
- xDOTScript << " " + xData + ";\n"
-
- when "node_attr"
- xDOTScript << " node [" + xData + "];\n"
-
- when "edge_attr"
- xDOTScript << " edge [" + xData + "];\n"
- end
- end
-
- xSeparator = ""
- xData = ""
- end
-
- xLastType = kElement["type"]
-
- #Modified by
- #Brandon Coleman
- #verify value is NOT NULL
- if kElement["value"] == nil then
- raise ArgumentError, "#{kElement["name"]} has a nil value!"
- end
-
- case kElement["type"]
- when "graph_attr"
- xData << xSeparator + kElement["name"] + " = " + kElement["value"].to_gv
- xSeparator = "; "
-
- when "node_attr"
- xData << xSeparator + kElement["name"] + " = " + kElement["value"].to_gv
- xSeparator = ", "
-
- when "edge_attr"
- xData << xSeparator + kElement["name"] + " = " + kElement["value"].to_gv
- xSeparator = ", "
-
- when "node"
- xDOTScript << " " + kElement["value"].output() + "\n"
-
- when "edge"
- xDOTScript << " " + kElement["value"].output( @oGraphType ) + "\n"
-
- when "graph"
- xDOTScript << kElement["value"].output() + "\n"
-
- else
- raise ArgumentError, "Don't know what to do with element type '#{kElement['type']}'"
- end
- }
-
- if xData.length > 0
- case xLastType
- when "graph_attr"
- xDOTScript << " " + xData + ";\n"
-
- when "node_attr"
- xDOTScript << " node [" + xData + "];\n"
+ append_attributes_and_types(xDOTScript)
- when "edge_attr"
- xDOTScript << " edge [" + xData + "];\n"
- end
- end
xDOTScript << "}"
- if @oParentGraph
- xDOTScript = "subgraph #{GraphViz.escape(@name, :unquote_empty => true)} {\n" << xDOTScript
-
- return( xDOTScript )
+ if has_parent_graph?
+ xDOTScript.make_subgraph("#{GraphViz.escape(@name, :unquote_empty => true)}")
else
hOutput = {}
@@ -569,7 +499,9 @@ def output( hOpts = {} )
@output = hOutput if hOutput.size > 0
xStict = ((@strict && @oGraphType == "digraph") ? "strict " : "")
- xDOTScript = ("#{xStict}#{@oGraphType} #{GraphViz.escape(@name, :unquote_empty => true)} {\n" << xDOTScript).gsub( "\0", "" )
+ xDOTScript.prepend(
+ "#{xStict}#{@oGraphType} #{GraphViz.escape(@name, :unquote_empty => true)} {"
+ )
xOutputString = (@filename == String ||
@output.any? {|format, file| file == String })
@@ -671,9 +603,34 @@ def output( hOpts = {} )
end
end
end
-
alias :save :output
+ def append_attributes_and_types(script)
+ xLastType = nil
+ xData = DOTScriptData.new
+
+ @elements_order.each { |kElement|
+ is_new_type = xLastType != kElement["type"]
+ xData = DOTScriptData.new if is_new_type
+ xLastType = kElement["type"]
+
+ # Modified by Brandon Coleman verify value is NOT NULL
+ kElement["value"] or raise ArgumentError, "#{kElement["name"]} is nil!"
+
+ case xLastType
+ when "graph_attr", "node_attr", "edge_attr"
+ xData.add_attribute(xLastType,kElement["name"],kElement["value"].to_gv)
+ when "node", "graph"
+ script << kElement["value"].output()
+ when "edge"
+ script << " " + kElement["value"].output( @oGraphType )
+ else
+ raise ArgumentError,
+ "Don't know what to do with element type '#{kElement['type']}'"
+ end
+ }
+ end
+
def to_s
self.output(:none => String)
end
@@ -809,6 +766,10 @@ def complete!
def directed?
not (/digraph/ =~ "bla digraph bla").nil?
end
+
+ def has_parent_graph?
+ @oParentGraph
+ end
## ----------------------------------------------------------------------------
private
View
100 lib/graphviz/dot_script.rb
@@ -0,0 +1,100 @@
+require "forwardable"
+class GraphViz
+
+ class DOTScriptData
+ def initialize
+ @data = []
+ end
+
+ def append(data)
+ @data << data
+ end
+ alias :<< :append
+
+ def add_attribute(type,name,value)
+ @data << @separator << name << " = " << value
+ @separator = determine_separator(type)
+ end
+
+ def to_str
+ @data.join(" ")
+ end
+
+ def empty?
+ @data.empty?
+ end
+
+ private
+
+ def determine_separator(str)
+ case str
+ when "graph_attr" then ";"
+ when "node_attr", "edge_attr" then ","
+ else raise ArgumentError, "Unknown type: #{str}."
+ end
+ end
+
+ end
+
+ class DOTScript
+ extend Forwardable
+
+ def_delegators :@script, :end_with?
+
+ def initialize
+ @script = ''
+ end
+
+ def append(line)
+ @script << assure_ends_with(line.to_s,"\n")
+
+ self
+ end
+ alias :<< :append
+
+ def prepend(line)
+ @script = assure_ends_with(line.to_s,"\n") + @script
+
+ self
+ end
+
+ def make_subgraph(name)
+ prepend(assure_ends_with("subgraph #{name}"," {"))
+ end
+
+ def add_type(type, data)
+ return self if data.empty?
+
+ case type
+ when "graph_attr"
+ append_statement(" " + data)
+ when "node_attr"
+ append_statement(" node [" + data + "]")
+ when "edge_attr"
+ append_statement(" edge [" + data + "]")
+ else
+ raise ArgumentError,
+ "Unknown type: #{type}." <<
+ "Possible: 'graph_attr','node_attr','edge_attr'"
+ end
+
+ self
+ end
+
+ def to_str
+ @script
+ end
+ alias :to_s :to_str
+
+ private
+
+ def assure_ends_with(str,ending="\n")
+ str.to_s.end_with?("\n") ? str : str + ending
+ end
+
+ def append_statement(statement)
+ append(assure_ends_with(statement, ";\n"))
+ end
+
+ end
+end
View
43 test/test_dot_script.rb
@@ -0,0 +1,43 @@
+require "minitest/autorun"
+require_relative "../lib/graphviz/dot_script"
+
+describe GraphViz::DOTScript do
+ let(:script) { GraphViz::DOTScript.new }
+
+ it "appends a newline character if it is missing" do
+ str = "Test without newline"
+ script.append(str)
+ script.to_s.must_equal(str + "\n")
+ end
+
+ it "does not append a newline if already present" do
+ str = "Linebreak follows at my tail:\n"
+ script.append(str)
+ script.to_s.must_equal(str)
+ end
+
+ it "can prepend lines to its content" do
+ start_content = "I want to be at the top!\n"
+ additional_content = "No way!\n"
+
+ script.append(start_content)
+ script.prepend(additional_content)
+
+ script.to_s.must_equal(additional_content + start_content)
+ end
+
+ it "can add types with data" do
+ data = "some random data"
+ script.add_type("node_attr", data)
+ script.to_s.must_match(/\s*node\s*\[\s*#{data}\s*\]\s*/m)
+ end
+
+ it "does nothing if data is empty" do
+ script.add_type("anything", "")
+ script.to_s.must_be :empty?
+ end
+
+ it "raises an argument error on unknown types" do
+ -> { script.add_type("invalid", "some data") }.must_raise(ArgumentError)
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.