class Mkgraph
Example : Mkgraph#new <ruby.rb> - initialise
Mkgraph#run - process file Mkgraph#make_image - create the image file Mkgraph#show_image - display the image file
Arguments: The file to be visualised when creating a new instance
Note : A valid mgopts.yml must be in the working directory.
You could copy a template file from the gem installation directory.¶ ↑
Public Class Methods
new(pattern)
click to toggle source
Initialise
Params: The name of the file to be processed
# File lib/mkgraph.rb 34 def initialize pattern 35 36 begin 37 $yml = YAML.load_file 'mgopts.yml' 38 rescue Exception => e 39 print e.message + "\n" 40 print "You could use the default \'mgopts.yml\' file in the installation\n" 41 print "directory as a template.\n" 42 print "Example:\n" 43 44 tip = <<-EOS 45 Log Options: 46 format: brief # brief or full 47 output: stderr # stderr, stdout or file name 48 level: WARN # INFO, WARN or FATAL 49 Labels: 50 root: Entry Point 51 root comment: The Root Comment 52 Output: 53 image name: view.png 54 EOS 55 56 puts "#{tip}" 57 exit 1 58 end 59 60 # puts $yml['sectionA']['user'] + "**************\n" 61 # puts $yml['sectionB']['file'] + "**************\n" 62 log_fmt = $yml['Log Options']['format'] 63 64 log_opt = $yml['Log Options']['output'] 65 case log_opt 66 when 'stderr' 67 log_op = $stderr 68 when 'stdout' 69 log_op = $stdout 70 else 71 log_op = log_opt 72 end 73 74 loglev = $yml['Log Options']['level'] 75 case loglev 76 when 'INFO' 77 ll = Logger::INFO 78 when 'WARN' 79 ll = Logger::WARN 80 else 81 ll = Logger::FATAL 82 end 83 84 @file_pattern = pattern 85 86 $LOG = Logger.new(log_op).tap do |log| 87 log.progname = 'mkgraph' 88 log.level = ll # Logger::INFO # $yml['Log Options']['level'] 89 if log_fmt == 'brief' 90 log.formatter = proc do |severity, datetime, progname, msg| 91 "#{progname}: #{msg}\n" 92 end 93 end 94 end 95 96 $LOG.info "Pattern: " + @file_pattern 97 # Rough test for OS TODO 98 if RUBY_PLATFORM.include?("linux") == false 99 $windows = true 100 else 101 $windows = false 102 end 103 end
Public Instance Methods
make_image()
click to toggle source
Use Graphviz to create the image file
# File lib/mkgraph.rb 278 def make_image 279 g = GraphViz.new( :G, :rankdir => "TB", :type => :digraph, :bgcolor => "lightgrey", :nodesep => 0.85, :normalize => true, :concentrate => true) 280 root = $root_node 281 g = add_element g, root 282 if $windows != true 283 res = system("rm " + $iname + " > /dev/null") 284 end 285 begin 286 g.output( :png => $iname) 287 rescue Exception => e 288 $LOG.warn e.message + "\n" 289 end 290 end
run()
click to toggle source
Does the work. Params: None
# File lib/mkgraph.rb 109 def run 110 end_count = 0 111 end_expected = 0 # how many ends before class end 112 class_end_expected = 0 # how many class ends we expect (internal definitions) 113 cname = "" 114 in_class = false 115 parent_class_name = nil 116 print_parent = true 117 118 $iname = $yml['Output']['image name'] 119 120 $root_node = Tree::TreeNode.new($yml['Labels']['root'], $yml['Labels']['root comment']) 121 tnode = $root_node 122 123 # Process all file matching @file_pattern 124 Dir.glob(@file_pattern) do |file| 125 126 $LOG.info "Looking at file - " + file 127 ignore = false 128 129 next if file == '.' or file == '..' 130 131 # Process each line in the file 132 File.open(file) do |f| 133 f.each_line do |line| 134 135 # Ignore =begin/=end blocks 136 if line.match(/^=end/) != nil 137 ignore = false 138 elsif line.match(/^=begin/) != nil 139 ignore = true 140 else 141 nil 142 end 143 144 next if ignore == true 145 146 # Process the line read from file 147 case line 148 when /^\s*#/ 149 nil 150 when /\s*when.*new/ # only to avoid this situation HERE 151 nil 152 when /\'\.new/ # only to avoid the situation in line.split('.new') 153 nil 154 when /\.new/ 155 name = line.split('.new') 156 cname = name[0].split.last 157 if in_class == true 158 $LOG.debug "NEW INSTANCE OF CLASS = [" + cname + "] created in class " + parent_class_name 159 tnode = proc_node tnode, parent_class_name, cname, false, false 160 else 161 if true == print_parent 162 $LOG.debug "NEW INSTANCE OF CLASS = [" + cname + "] created outside any parent class" 163 tnode = proc_node tnode, parent_class_name, cname, true, true 164 end 165 end 166 when /^\s*elsif/ 167 nil 168 when /^\s*class[\s]+/ 169 parent_class_name = line.split(' ')[1] 170 class_end_expected += 1 171 in_class = true 172 if print_parent == true 173 $LOG.info "Start of class " + parent_class_name 174 end 175 tnode = proc_node tnode, $root_node.name, parent_class_name, true, false 176 when /^\s*begin/ 177 end_expected += 1 178 when /^.*if / 179 end_expected += 1 180 when /^\s*def / 181 end_expected += 1 182 when /^.* do/ 183 end_expected += 1 184 when /^\s*case/ 185 end_expected += 1 186 when /^\s*end[\s.]/ 187 if end_expected == 0 188 if class_end_expected > 0 189 class_end_expected -= 1 190 in_class = false 191 if print_parent == true && parent_class_name != nil 192 $LOG.info "End of class " + parent_class_name 193 end 194 parent_class_name = nil 195 end 196 else 197 end_expected -= 1 198 end 199 end # case 200 end 201 end 202 end 203 end
show_image()
click to toggle source
Display the image file
# File lib/mkgraph.rb 293 def show_image 294 begin 295 if $windows != true 296 res = system("pkill eog; " + $yml['Osdep']['viewer'] + " " + $iname + " > /dev/null 2>&1") 297 else 298 res = system("call " + $yml['Osdep']['viewer'] + " " + $iname) 299 end 300 if res == false 301 raise "Bad Command" 302 end 303 rescue Exception => e 304 $LOG.info e.message 305 end 306 end
Private Instance Methods
add_element(g, root)
click to toggle source
Recursive method to add elements from the Tree to the GraphViz Tree
# File lib/mkgraph.rb 251 def add_element g, root 252 if root.hasChildren? == true 253 root.children { |child| 254 add_element g, child 255 } 256 end 257 258 if root.isRoot? 259 g.add_node root.name, {:label => "{{" + root.name + "|" + root.content + "}|" + "Root}", :style => "filled", :fillcolor => "lightblue", :shape => "record", :color =>"black"} 260 else 261 g.add_node root.name , {:shape => "egg", :color =>"violet"} 262 end 263 264 if ! root.isRoot? 265 # Add an edge to the parent 266 if root.content == "orphan" 267 g.add_edge(root.parent.name, root.name, :label => root.parent.name + " contains " + root.name, :color => "red", :fontcolor => "red") 268 else 269 g.add_edge(root.parent.name, root.name, :label => root.parent.name + " uses " + root.name, :color => "blue", :fontcolor => "blue") 270 end 271 272 end 273 g 274 end
find_leaf(root, sname)
click to toggle source
Recursive method used to find a name (ID) in the Tree object
# File lib/mkgraph.rb 207 def find_leaf root, sname 208 209 $LOG.debug "find_leaf searching for: [" + sname + "] This Root is " + root.name 210 r = root 211 212 if root != nil && root.name != sname 213 root.children { |child| 214 r = find_leaf child, sname 215 break if r.name == sname 216 } 217 else 218 $LOG.info "NIL OR FOUND [" + root.name + "]" 219 r = root 220 end 221 $LOG.info "find_leaf returning: [" + r.name + "]" 222 r 223 end
proc_node(root, par, child, join_to_root, used)
click to toggle source
Process a line of interest i.e. when a class is being defined or instanciated etc. Called from the ‘run’ method
# File lib/mkgraph.rb 227 def proc_node root, par, child, join_to_root, used 228 begin 229 if join_to_root == true 230 if true == used 231 $root_node << Tree::TreeNode.new(child, "child") 232 else 233 $root_node << Tree::TreeNode.new(child, "orphan") 234 end 235 else 236 $LOG.info "NEED TO ATTACH " + child + " TO: " + par 237 r = find_leaf root, par 238 $LOG.info "AFTER FIND_LEAF: " + r.name 239 r << Tree::TreeNode.new(child, "used") 240 end 241 rescue Exception => e 242 $LOG.info e.message 243 $LOG.info "***** Processing node " + "None" + " --> " + child.to_s 244 end 245 # $root_node.printTree 246 247 root 248 end