>> x = "hellont\l"world""
>> puts x.inspect.gsub( "\\", "\" ) "hellontl"world""
OR
>> x = 'hellontl"world"'
>> puts x.inspect.gsub( "\\", "\" ) "hellontl"world""
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Gregoire Lejeune <gregoire.lejeune@free.fr>
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Change default options (:use, :path, :errors and :output)
# File lib/graphviz.rb, line 690 def self.default( hOpts ) hOpts.each do |k, v| case k.to_s when "use" @@prog = v when "path" @@path = v.split( "," ).map{ |x| x.strip } when "errors" @@errors = v when "extlibs" @@extlibs = v.split( "," ).map{ |x| x.strip } when "output" warn ":output option is deprecated!" @@format = v else warn "Invalide option #{k}!" end end end
Create a new graph object
Options :
:output : Output format (Constants::FORMATS) (default : dot)
:file : Output file name (default : nil)
:use : Program to use (Constants::PROGRAMS) (default : dot)
:path : Program PATH
:parent : Parent graph (default : nil)
:type : Graph type (Constants::GRAPHTYPE) (default : digraph)
:errors : DOT error level (default 1)
0 = Error + Warning
1 = Error
2 = none
# File lib/graphviz.rb, line 761 def initialize( xGraphName, hOpts = {}, &block ) @filename = nil @name = xGraphName.to_s @format = @@format @prog = @@prog @path = @@path @errors = @@errors @extlibs = @@extlibs @output = {} @nothugly = false @strict = false @scale = nil @inverty = nil @no_layout = nil @reduce_graph = nil @Lg = nil @LO = nil @Ln = nil @LU = nil @LC = nil @LT = nil @elements_order = GraphViz::Elements::new() @oParentGraph = nil @oGraphType = "digraph" @hoNodes = Hash::new() @loEdges = Array::new() @hoGraphs = Hash::new() @node = GraphViz::Attrs::new( self, "node", NODESATTRS ) @edge = GraphViz::Attrs::new( self, "edge", EDGESATTRS ) @graph = GraphViz::Attrs::new( self, "graph", GRAPHSATTRS ) hOpts.each do |xKey, xValue| case xKey.to_s when "output" warn ":output option is deprecated, please use :<format> => :<file>" if FORMATS.index( xValue.to_s ).nil? == true raise ArgumentError, "output format '#{xValue}' invalid" end @format = xValue.to_s when "use" if PROGRAMS.index( xValue.to_s ).nil? == true raise ArgumentError, "can't use '#{xValue}'" end @prog = xValue.to_s when "file" warn ":file option is deprecated, please use :<format> => :<file>" @filename = xValue.to_s when "parent" @oParentGraph = xValue when "type" if GRAPHTYPE.index( xValue.to_s ).nil? == true raise ArgumentError, "graph type '#{xValue}' unknow" end @oGraphType = xValue.to_s when "path" @path = xValue.split( "," ).map{ |x| x.strip } when "strict" @strict = (xValue ? true : false) when "errors" @errors = xValue when "extlibs" @extlibs = xValue.split( "," ).map{ |x| x.strip } else self[xKey.to_s] = xValue.to_s end end yield( self ) if( block ) end
Transform to pretty up the SVG output
For more information, see www.hokstad.com/making-graphviz-output-pretty-with-xsl.html and www.hokstad.com/making-graphviz-output-pretty-with-xsl-updated.html
You can use the :nothugly option to GraphViz#output :
graph.output( :svg => "myGraph.svg", :nothugly => true )
Or directly on an SVG output graph :
GraphViz.nothugly( "myGraph.svg" )
# File lib/graphviz/nothugly.rb, line 26 def self.nothugly( file, save = true ) xslt = XML::XSLT.new() xslt.xml = file xslt.xsl = File.join( File.dirname(File.expand_path(__FILE__)), "nothugly", "nothugly.xsl" ) out = xslt.serve() if save fname = File.join( File.dirname(File.expand_path(file)), File.basename(file)) File.open( fname, "w" ) { |io| io.print out } else return out end end
# File lib/graphviz.rb, line 710 def self.options( hOpts ) GraphViz::default( hOpts ) end
Create a new graph from a GraphViz File
Options :
:output : Output format (Constants::FORMATS) (default : dot)
:file : Output file name (default : none)
:use : Program to use (Constants::PROGRAMS) (default : dot)
:path : Program PATH
# File lib/graphviz.rb, line 725 def self.parse( xFile, hOpts = {}, &block ) graph = Dot2Ruby::new( hOpts[:path], nil, nil ).eval( xFile ) yield( graph ) if( block and graph.nil? == false ) return graph end
Create an edge between the current cluster and the node or cluster oNode
# File lib/graphviz.rb, line 639 def <<( oNode ) raise( ArgumentError, "Edge between root graph and node or cluster not allowed!" ) if self.pg.nil? if( oNode.class == Array ) oNode.each do |no| self << no end else return GraphViz::commonGraph( oNode, self ).add_edge( self, oNode ) end end
Get the value of the graph attribut xAttrName
# File lib/graphviz.rb, line 330 def []( xAttrName ) if Hash === xAttrName xAttrName.each do |key, value| self[key] = value end else return( @graph[xAttrName].clone ) end end
Set value xValue to the graph attribut xAttrName
# File lib/graphviz.rb, line 322 def []=( xAttrName, xValue ) xValue = xValue.to_s if xValue.class == Symbol @graph[xAttrName] = xValue end
Create a new edge
In:
# File lib/graphviz.rb, line 163 def add_edge( oNodeOne, oNodeTwo, hOpts = {} ) if( oNodeOne.class == Array ) oNodeOne.each do |no| add_edge( no, oNodeTwo, hOpts ) end else if( oNodeTwo.class == Array ) oNodeTwo.each do |nt| add_edge( oNodeOne, nt, hOpts ) end else oEdge = GraphViz::Edge::new( oNodeOne, oNodeTwo, self ) oEdge.index = @elements_order.size_of( "edge" ) hOpts.each do |xKey, xValue| oEdge[xKey.to_s] = xValue end @elements_order.push( { "type" => "edge", "value" => oEdge } ) @loEdges.push( oEdge ) return( oEdge ) end end end
Create a new graph
In:
xGraphName : Graph name
hOpts : Graph attributs
# File lib/graphviz.rb, line 228 def add_graph( xGraphName = nil, hOpts = {}, &block ) if xGraphName.kind_of?(Hash) hOpts = xGraphName xGraphName = nil end if xGraphName.nil? xGraphID = String.random(11) xGraphName = "" else xGraphID = xGraphName end @hoGraphs[xGraphID] = GraphViz::new( xGraphName, {:parent => self, :type => @oGraphType}, &block ) hOpts.each do |xKey, xValue| @hoGraphs[xGraphID][xKey.to_s] = xValue end @elements_order.push( { "type" => "graph", "name" => xGraphName, "value" => @hoGraphs[xGraphID] } ) return( @hoGraphs[xGraphID] ) end
Create a new node
In:
xNodeName : Name of the new node
hOpts : Node attributs
Return the GraphViz::Node object created
# File lib/graphviz.rb, line 95 def add_node( xNodeName, hOpts = {} ) @hoNodes[xNodeName] = GraphViz::Node::new( xNodeName, self ) @hoNodes[xNodeName].index = @elements_order.size_of( "node" ) unless hOpts.keys.include?(:label) or hOpts.keys.include?("label") hOpts[:label] = xNodeName end hOpts.each do |xKey, xValue| @hoNodes[xNodeName][xKey.to_s] = xValue end @elements_order.push( { "type" => "node", "name" => xNodeName, "value" => @hoNodes[xNodeName] } ) return( @hoNodes[xNodeName] ) end
Calls block once for each attribut of the graph, passing the name and value to the block as a two-element array.
# File lib/graphviz.rb, line 344 def each_attribut(&b) @graph.each do |k,v| yield(k,v) end end
Allow you to traverse edges
# File lib/graphviz.rb, line 196 def each_edge( &block ) if block_given? @loEdges.each do |edge| yield(edge) end else return @loEdges end end
Allow you to traverse graphs
# File lib/graphviz.rb, line 270 def each_graph( &block ) if block_given? @hoGraphs.each do |name, graph| yield( name, graph ) end else return @hoGraphs end end
Allow you to traverse nodes
# File lib/graphviz.rb, line 138 def each_node( &block ) if block_given? @hoNodes.each do |name, node| yield( name, node ) end else return( @hoNodes ) end end
Get the number of edges
# File lib/graphviz.rb, line 209 def edge_count @loEdges.size end
Return the edge object for the given index
# File lib/graphviz.rb, line 216 def get_edge_at_index( index ) element = @elements_order[index, "edge"] (element.nil?) ? nil : element["value"] end
Return the graph object for the given name (or nil)
# File lib/graphviz.rb, line 259 def get_graph( xGraphName, &block ) graph = @hoGraphs[xGraphName] || nil yield( graph ) if( block and graph.nil? == false ) return graph end
Return the node object for the given name (or nil)
# File lib/graphviz.rb, line 119 def get_node( xNodeName, &block ) node = @hoNodes[xNodeName] || nil yield( node ) if( block and node.nil? == false ) return node end
Return the node object for the given index
# File lib/graphviz.rb, line 130 def get_node_at_index( index ) element = @elements_order[index, "node"] (element.nil?) ? nil : element["value"] end
Get the number of graphs
# File lib/graphviz.rb, line 289 def graph_count @hoGraphs.size end
Get the graph name
# File lib/graphviz.rb, line 631 def name @name.clone end
Get the number of nodes
# File lib/graphviz.rb, line 151 def node_count @hoNodes.size end
Generate the graph
Options :
:output : Output format (Constants::FORMATS)
:file : Output file name
:use : Program to use (Constants::PROGRAMS)
:path : Program PATH
:<format> => <file> : <file> can be
:errors : DOT error level (default 1)
0 = Error + Warning
1 = Error
2 = none
# File lib/graphviz.rb, line 367 def output( hOpts = {} ) xDOTScript = "" xLastType = nil xSeparator = "" xData = "" lNotHugly = [] @elements_order.each { |kElement| if xLastType.nil? == true 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" when "edge_attr" xDOTScript << " edge [" + xData + "];\n" end end xDOTScript << "}" if @oParentGraph.nil? == false xDOTScript = "subgraph #{GraphViz.escape(@name, :unquote_empty => true)} {\n" << xDOTScript return( xDOTScript ) else hOutput = {} hOpts.each do |xKey, xValue| xValue = xValue.to_s unless xValue.nil? or [Class, TrueClass, FalseClass].include?(xValue.class) case xKey.to_s when "output" warn ":output option is deprecated, please use :<format> => :<file> -- BE CAREFUL, it will be removed in the 1.0 version!" if FORMATS.index( xValue ).nil? == true raise ArgumentError, "output format '#{xValue}' invalid" end @format = xValue when "file" warn ":file option is deprecated, please use :<format> => :<file> -- BE CAREFUL, it will be removed in the 1.0 version!" @filename = xValue when "use" if PROGRAMS.index( xValue ).nil? == true raise ArgumentError, "can't use '#{xValue}'" end @prog = xValue when "path" @path = xValue.split( "," ).map{ |x| x.strip } when "errors" @errors = xValue when "extlib" @extlibs = xValue.split( "," ).map{ |x| x.strip } when "scale" # Scale input by 'v' (=72) @scale = xValue when "inverty" # Invert y coordinate in output @inverty = xValue when "no_layout" # No layout mode 'v' (=1) @no_layout = xValue when "reduce" # Reduce graph @reduce_graph = xValue when "Lg" # Don't use grid @Lg = xValue when "LO" # Use old attractive force @LO = xValue when "Ln" # Set number of iterations to i @Ln = xValue when "LU" # Set unscaled factor to i @LU = xValue when "LC" # Set overlap expansion factor to v @LC = xValue when "LT" # Set temperature (temperature factor) to v @LT = xValue when "nothugly" begin require 'graphviz/nothugly' @nothugly = true rescue warn "You must install ruby-xslt to use nothugly option!" @nothugly = false end else if FORMATS.index( xKey.to_s ).nil? == true raise ArgumentError, "output format '#{xValue}' invalid" end hOutput[xKey.to_s] = xValue end end @output = hOutput if hOutput.size > 0 xStict = ((@strict && @oGraphType == "digraph") ? "strict " : "") xDOTScript = ("#{xStict}#{@oGraphType} #{GraphViz.escape(@name, :unquote_empty => true)} {\n" << xDOTScript).gsub( "\00"", "" ) xOutputString = (@filename == String || @output.any? {|format, file| file == String }) xOutput = "" if @format.to_s == "none" or @output.any? {|fmt, fn| fmt.to_s == "none"} if xOutputString xOutput << xDOTScript else xFileName = @output["none"] || @filename open( xFileName, "w" ) do |h| h.puts xDOTScript end end end if (@format.to_s != "none" and not @format.nil?) or (@output.any? {|format, file| format != "none" } and @output.size > 0) ## Act: Save script and send it to dot t = Tempfile::open( File.basename(__FILE__) ) t.print( xDOTScript ) t.close cmd = find_executable( @prog, @path ) if cmd == nil raise StandardError, "GraphViz not installed or #{@prog} not in PATH. Install GraphViz or use the 'path' option" end cmd = escape_path_containing_blanks(cmd) if IS_JRUBY xOutputWithFile = "" xOutputWithoutFile = "" unless @format.nil? or @format == "none" lNotHugly << @filename if @format.to_s == "svg" and @nothugly if @filename.nil? or @filename == String xOutputWithoutFile = "-T#{@format} " else xOutputWithFile = "-T#{@format} -o#{@filename} " end end @output.each_except( :key => ["none"] ) do |format, file| lNotHugly << file if format.to_s == "svg" and @nothugly if file.nil? or file == String xOutputWithoutFile << "-T#{format} " else xOutputWithFile << "-T#{format} -o#{file} " end end xExternalLibraries = "" @extlibs.each do |lib| xExternalLibraries << "-l#{lib} " end xOtherOptions = "" xOtherOptions += " -s#{@scale}" unless @scale.nil? xOtherOptions += " -y" if @inverty == true unless @no_layout.nil? xOtherOptions += " -n" xOtherOptions += "2" if @no_layout.to_i == 2 end xOtherOptions += " -x" if @reduce_graph == true xOtherOptions += " -Lg" if @Lg == true xOtherOptions += " -LO" if @LO == true xOtherOptions += " -Ln#{@Ln}" unless @LN.nil? xOtherOptions += " -LU#{@LU}" unless @LU.nil? xOtherOptions += " -LC#{@LC}" unless @LC.nil? xOtherOptions += " -LT#{@LT}" unless @LT.nil? if IS_JRUBY xCmd = "#{cmd} -q#{@errors} #{xExternalLibraries} #{xOtherOptions} #{xOutputWithFile} #{xOutputWithoutFile} #{t.path}" elsif IS_CYGWIN tmpPath = t.path begin tmpPath = "'" + `cygpath -w #{t.path}`.chomp + "'" rescue warn "cygpath is not installed!" end xCmd = "\"#{cmd}\" -q#{@errors} #{xExternalLibraries} #{xOtherOptions} #{xOutputWithFile} #{xOutputWithoutFile} #{tmpPath}" else xCmd = "\"#{cmd}\" -q#{@errors} #{xExternalLibraries} #{xOtherOptions} #{xOutputWithFile} #{xOutputWithoutFile} #{t.path}" end xOutput << output_from_command( xCmd ) end # Not Hugly lNotHugly.each do |f| if f.nil? or f == String xOutput = GraphViz.nothugly( xOutput, false ) else GraphViz.nothugly( f, true ) end end if xOutputString xOutput else print xOutput end end end
Generated with the Darkfish Rdoc Generator 2.