update.
[chise/ruby.git] / chise / graphviz.rb
1 # Copyright (C) 2002-2004 Kouichirou Eto, All rights reserved.
2
3 class DotElement
4   def initialize()
5     @attr = Hash.new
6   end
7
8   def method_missing(mid, *args) #\8eQ\8dl:ostruct.rb
9     mname = mid.id2name
10     return @attr[mname] if args.length == 0
11     @attr[mname.chop] = args[0] if mname =~ /=$/ #\91ã\93ü
12   end
13
14   def to_s
15     str = "  #{mainstr()} "
16     str << "[" + @attr.map {|k, v| %Q|#{k}="#{v}"| }.join(" ") + "]" if 0 < @attr.length
17     str << ";\n"
18     str
19   end
20 end
21
22 class DotPage < DotElement
23   def initialize()
24     super()
25     @nodes = []
26     @edges = []
27   end
28
29   def mainstr() @name.to_s; end
30
31   def add_node(node)
32     return unless node.is_a? DotNode
33     @nodes << node
34   end
35
36   def add_edge(edge)
37     return unless edge.is_a? DotEdge
38     @edges << edge
39   end
40
41   def to_s()
42     str = "digraph G {\n"
43 #    str << %Q|  size="6, 6"\n|
44     str << @attr.map {|k, v| %Q|  #{k}="#{v}"\n| }.join("")
45     @nodes.each {|node|
46       str << node.to_s
47     }
48     @edges.each {|edge|
49       str << edge.to_s
50     }
51     str << "}\n"
52     str
53   end
54 end
55
56 class DotNode < DotElement
57   def initialize(name)
58     @name = name
59     super()
60   end
61
62   def mainstr() @name.to_s; end
63 end
64
65 class DotEdge < DotElement
66   def initialize(from, to)
67     @from, @to = from, to
68     super()
69   end
70
71   def mainstr() "#{@from.to_s} -> #{@to.to_s}"; end
72 end
73
74 class Graphviz # abstract class
75   DOT = 0
76   TWOPI = 1
77   NEATO = 2
78
79   def initialize(type=DOT)
80     @type = type
81     @codepage = nil
82     @target = nil
83     @in = nil
84     @out = nil
85   end
86   attr_accessor :type, :codepage, :target, :in, :out
87
88   def post_process() #\93¯\82\83t\83@\83C\83\8b\82É\8fã\8f\91\82«\82É\82·\82é\81B
89     str = open(@out).read
90     str.gsub!(/&amp;#x/, "&#x")
91     #str.gsub!(/font-family:MS Gothic;/, "")
92     #str.gsub!(/font-family:MS Gothic;/, "font-family:MS-Mincho;")
93     str.gsub!(/font-family:Times New Roman;/, "")
94     open(@out, "w"){|out| out.print str}
95   end
96 end
97
98 class GraphvizCLI < Graphviz
99 # COMMAND_DIR = "c:\Program Files\ATT\Graphviz\bin"
100   COMMAND_DIR = "" #PATH\82ª\82Æ\82¨\82Á\82Ä\82È\82¢\82Æ\82¾\82ß\82Ý\82½\82¢\81B
101 # NAMES = "dot twopi neato".split
102   NAMES = %w(dot twopi neato)
103
104   def generate(debug=false)
105     ar = []
106     #ar << COMMAND_DIR + NAMES[@type] + ".exe"
107     ar << COMMAND_DIR + NAMES[@type]
108     #ar << "-V"
109     #ar << "-Gpack"
110     ar << "-T#{@target}"
111     ar << "-o #{@out}"
112     ar << @in
113     cmd = ar.join(" ")
114     print cmd,"\n"
115     system cmd
116     if @target =~ /svg/i
117       post_process
118     end
119   end
120 end
121
122 class GraphvizOLE < Graphviz
123   #NAMES = "DOT TWOPI NEATO".split
124
125   def generate(debug=false)
126     require "win32ole"
127     names = "DOT TWOPI NEATO".split
128     @ole = WIN32OLE.new("Wingraphviz." + names[@type])
129     @ole.codepage = cp if @codepage  #neato.codepage = 65001 #codepage: 65001 Unicode UTF-8 
130     @instr = open(@in).read
131
132     if @target =~ /svg/i
133       result = @ole.toSVG(@instr)
134       open(@out, "w"){|out| out.print result}
135       post_process
136     elsif @target =~ /svg/i
137       result = @ole.toPNG(@dot)
138       result.save(@out)
139     end
140   end
141
142   def nu_to_png(filename=nil)
143     return "" unless @dot.is_a?(String)
144     png = @ole.toPNG(@dot)
145     png.save(filename) unless filename.nil?
146     return png
147   end
148
149   #p neato.validate(str)
150   #ps = neato.toPS(str)
151   #open("test.ps", "w"){|out|  out.print ps  }
152 end