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