From 835e16733d0a8fa3baba4386688e92ad38bd149c Mon Sep 17 00:00:00 2001 From: dave Date: Wed, 3 Dec 2003 04:20:22 +0000 Subject: [PATCH] Missing file git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5089 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/rdoc/diagram.rb | 2 +- lib/rdoc/dot/dot.rb | 255 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 lib/rdoc/dot/dot.rb diff --git a/lib/rdoc/diagram.rb b/lib/rdoc/diagram.rb index 3c7df03417..94ab17bb35 100644 --- a/lib/rdoc/diagram.rb +++ b/lib/rdoc/diagram.rb @@ -4,7 +4,7 @@ # You must have the V1.7 or later in your path # http://www.research.att.com/sw/tools/graphviz/ -require "dot/dot" +require "rdoc/dot/dot" require 'rdoc/options' module RDoc diff --git a/lib/rdoc/dot/dot.rb b/lib/rdoc/dot/dot.rb new file mode 100644 index 0000000000..3f23e5389c --- /dev/null +++ b/lib/rdoc/dot/dot.rb @@ -0,0 +1,255 @@ +module DOT + + # these glogal vars are used to make nice graph source + $tab = ' ' + $tab2 = $tab * 2 + + # if we don't like 4 spaces, we can change it any time + def change_tab( t ) + $tab = t + $tab2 = t * 2 + end + + # options for node declaration + NODE_OPTS = [ + 'bgcolor', + 'color', + 'fontcolor', + 'fontname', + 'fontsize', + 'height', + 'width', + 'label', + 'layer', + 'rank', + 'shape', + 'shapefile', + 'style', + 'URL', + ] + + # options for edge declaration + EDGE_OPTS = [ + 'color', + 'decorate', + 'dir', + 'fontcolor', + 'fontname', + 'fontsize', + 'id', + 'label', + 'layer', + 'lhead', + 'ltail', + 'minlen', + 'style', + 'weight' + ] + + # options for graph declaration + GRAPH_OPTS = [ + 'bgcolor', + 'center', + 'clusterrank', + 'color', + 'compound', + 'concentrate', + 'fillcolor', + 'fontcolor', + 'fontname', + 'fontsize', + 'label', + 'layerseq', + 'margin', + 'mclimit', + 'nodesep', + 'nslimit', + 'ordering', + 'orientation', + 'page', + 'rank', + 'rankdir', + 'ranksep', + 'ratio', + 'size', + 'style', + 'URL' + ] + + # a root class for any element in dot notation + class DOTSimpleElement + attr_accessor :name + + def initialize( params = {} ) + @label = params['name'] ? params['name'] : '' + end + + def to_s + @name + end + end + + # an element that has options ( node, edge or graph ) + class DOTElement < DOTSimpleElement + #attr_reader :parent + attr_accessor :name, :options + + def initialize( params = {}, option_list = [] ) + super( params ) + @name = params['name'] ? params['name'] : nil + @parent = params['parent'] ? params['parent'] : nil + @options = {} + option_list.each{ |i| + @options[i] = params[i] if params[i] + } + @options['label'] ||= @name if @name != 'node' + end + + def each_option + @options.each{ |i| yield i } + end + + def each_option_pair + @options.each_pair{ |key, val| yield key, val } + end + + #def parent=( thing ) + # @parent.delete( self ) if defined?( @parent ) and @parent + # @parent = thing + #end + end + + + # this is used when we build nodes that have shape=record + # ports don't have options :) + class DOTPort < DOTSimpleElement + attr_accessor :label + + def initialize( params = {} ) + super( params ) + @name = params['label'] ? params['label'] : '' + end + def to_s + ( @name && @name != "" ? "<#{@name}>" : "" ) + "#{@label}" + end + end + + # node element + class DOTNode < DOTElement + + def initialize( params = {}, option_list = NODE_OPTS ) + super( params, option_list ) + @ports = params['ports'] ? params['ports'] : [] + end + + def each_port + @ports.each{ |i| yield i } + end + + def << ( thing ) + @ports << thing + end + + def push ( thing ) + @ports.push( thing ) + end + + def pop + @ports.pop + end + + def to_s( t = '' ) + + label = @options['shape'] != 'record' && @ports.length == 0 ? + @options['label'] ? + t + $tab + "label = \"#{@options['label']}\"\n" : + '' : + t + $tab + 'label = "' + " \\\n" + + t + $tab2 + "#{@options['label']}| \\\n" + + @ports.collect{ |i| + t + $tab2 + i.to_s + }.join( "| \\\n" ) + " \\\n" + + t + $tab + '"' + "\n" + + t + "#{@name} [\n" + + @options.to_a.collect{ |i| + i[1] && i[0] != 'label' ? + t + $tab + "#{i[0]} = #{i[1]}" : nil + }.compact.join( ",\n" ) + ( label != '' ? ",\n" : "\n" ) + + label + + t + "]\n" + end + end + + # subgraph element is the same to graph, but has another header in dot + # notation + class DOTSubgraph < DOTElement + + def initialize( params = {}, option_list = GRAPH_OPTS ) + super( params, option_list ) + @nodes = params['nodes'] ? params['nodes'] : [] + @dot_string = 'subgraph' + end + + def each_node + @nodes.each{ |i| yield i } + end + + def << ( thing ) + @nodes << thing + end + + def push( thing ) + @nodes.push( thing ) + end + + def pop + @nodes.pop + end + + def to_s( t = '' ) + hdr = t + "#{@dot_string} #{@name} {\n" + + options = @options.to_a.collect{ |name, val| + val && name != 'label' ? + t + $tab + "#{name} = #{val}" : + name ? t + $tab + "#{name} = \"#{val}\"" : nil + }.compact.join( "\n" ) + "\n" + + nodes = @nodes.collect{ |i| + i.to_s( t + $tab ) + }.join( "\n" ) + "\n" + hdr + options + nodes + t + "}\n" + end + end + + # this is graph + class DOTDigraph < DOTSubgraph + def initialize( params = {}, option_list = GRAPH_OPTS ) + super( params, option_list ) + @dot_string = 'digraph' + end + end + + # this is edge + class DOTEdge < DOTElement + attr_accessor :from, :to + def initialize( params = {}, option_list = EDGE_OPTS ) + super( params, option_list ) + @from = params['from'] ? params['from'] : nil + @to = params['to'] ? params['to'] : nil + end + + def to_s( t = '' ) + t + "#{@from} -> #{to} [\n" + + @options.to_a.collect{ |i| + i[1] && i[0] != 'label' ? + t + $tab + "#{i[0]} = #{i[1]}" : + i[1] ? t + $tab + "#{i[0]} = \"#{i[1]}\"" : nil + }.compact.join( "\n" ) + "\n" + t + "]\n" + end + end +end + + +