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