Class: ULG
- Inherits:
-
Object
- Object
- ULG
- Defined in:
- lib/ulg.rb
Instance Attribute Summary collapse
-
#arrow_regex ⇒ Object
Returns the value of attribute arrow_regex.
-
#destfile ⇒ Object
Returns the value of attribute destfile.
-
#edges ⇒ Object
Returns the value of attribute edges.
-
#nodes ⇒ Object
Returns the value of attribute nodes.
-
#output ⇒ Object
Returns the value of attribute output.
Instance Method Summary collapse
- #add_edge(from, to, from_arrow, open, label, color, close, to_arrow) ⇒ Object
- #add_node(open, label, color, close) ⇒ Object
- #clear(node) ⇒ Object
- #debug ⇒ Object
- #dputs(msg) ⇒ Object
- #draw(files) ⇒ Object
-
#initialize ⇒ ULG
constructor
A new instance of ULG.
- #label_to_name(label) ⇒ Object
- #parse(file) ⇒ Object
- #parse_arrow(arrow) ⇒ Object
- #parse_line(line) ⇒ Object
- #set_option(option, value) ⇒ Object
- #wputs(msg) ⇒ Object
Constructor Details
#initialize ⇒ ULG
Returns a new instance of ULG.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/ulg.rb', line 7 def initialize @debug = 0 @destfile = nil @output = "png" @read_files = [] @graphviz_options = { "type" => "digraph" } @nodes = {} @edges = {} @rex = [] @rex << '(?<from_open>[\[\<\(\{]*)' @rex << '(?<from_label>[^\]\>\)\|\}]+?)' @rex << '(?<from_color>\|[^\]\>\)\} ]+?)?' @rex << '(?<from_close>[\]\>\)\}]*)' @rex << '\s(?<from_arrow>[\<\>ox]*)' @rex << '(?<edge_open>[\=\-\.]+)' @rex << '(?<edge_label>(?:[^\=\-\|\.][^\|]*?[^\=\-\|\.])?)' @rex << '(?<edge_color>\|[^\=\-\|\.\ ]+)?' @rex << '(?<edge_close>[\=\-\.]+)' @rex << '(?<to_arrow>[\<\>ox]*)\s' @rex << '(?<to_open>[\[\<\(\{]*)' @rex << '(?<to_label>[^\]\>\)\|\}]+?)' @rex << '(?<to_color>\|[^\]\>\)\} ]+?)?' @rex << '(?<to_close>[\]\>\)\}]*)' @arrow_regex = @rex.join '\s*' end |
Instance Attribute Details
#arrow_regex ⇒ Object
Returns the value of attribute arrow_regex.
5 6 7 |
# File 'lib/ulg.rb', line 5 def arrow_regex @arrow_regex end |
#destfile ⇒ Object
Returns the value of attribute destfile.
5 6 7 |
# File 'lib/ulg.rb', line 5 def destfile @destfile end |
#edges ⇒ Object
Returns the value of attribute edges.
5 6 7 |
# File 'lib/ulg.rb', line 5 def edges @edges end |
#nodes ⇒ Object
Returns the value of attribute nodes.
5 6 7 |
# File 'lib/ulg.rb', line 5 def nodes @nodes end |
#output ⇒ Object
Returns the value of attribute output.
5 6 7 |
# File 'lib/ulg.rb', line 5 def output @output end |
Instance Method Details
#add_edge(from, to, from_arrow, open, label, color, close, to_arrow) ⇒ Object
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/ulg.rb', line 207 def add_edge(from, to, from_arrow, open, label, color, close, to_arrow) label = label.rstrip.lstrip from_name = label_to_name from to_name = label_to_name to if not label.empty? edge_name = label_to_name label else edge_name = "none" end return if @edges.has_key? from_name and @edges[from_name].has_key? to_name and @edges[from_name][to_name].has_key? edge_name dputs "Adding edge #{edge_name} for #{from_name} #{to_name}" @edges[from_name] = {} unless @edges.has_key? from_name @edges[from_name][to_name] = {} unless @edges[from_name].has_key? to_name arrowtail = parse_arrow from_arrow arrowhead = parse_arrow to_arrow case open when /^\.+$/ style = "dotted" when /^\-+$/ style = "dashed" else style = "solid" end if color color = color.gsub /\|+/, "" else color = "black" end @edges[from_name][to_name][edge_name] = { "attr" => { "style" => style, "label" => label, "arrowtail" => arrowtail, "arrowhead" => arrowhead, "fontcolor" => color } } end |
#add_node(open, label, color, close) ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/ulg.rb', line 173 def add_node(open, label, color, close) label = label.rstrip.lstrip name = label_to_name label if @nodes.has_key? name and not @nodes[name].has_key? 'cleared' dputs "Skipping node #{name} as already defined" return name end dputs "Adding node #{name}" if color color = color.gsub /\|+/, "" else color = "black" end case open when '<' shape = "diamond" when '(' shape = "oval" when '{' shape = "hexagon" else shape = "box" end @nodes[name] = { "attr" => { "shape" => shape, "label" => label, "fontcolor" => color } } return name end |
#clear(node) ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/ulg.rb', line 159 def clear(node) node.lstrip.rstrip! name = label_to_name node if @nodes.has_key? name dputs "Clearing node #{node}" @nodes[name]['cleared'] = true @nodes[name]['attr']['shape'] = 'box' @nodes[name]['attr']['fontcolor'] = 'black' else wputs "Node not found #{node}" end end |
#debug ⇒ Object
43 44 45 |
# File 'lib/ulg.rb', line 43 def debug @debug = 1 end |
#dputs(msg) ⇒ Object
47 48 49 |
# File 'lib/ulg.rb', line 47 def dputs(msg) puts "DEBUG #{msg}" if @debug == 1 end |
#draw(files) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/ulg.rb', line 55 def draw(files) dputs "Rex: #{@arrow_regex}" # Move files parsing out of here files.each do |file| parse file end if @nodes.size == 0 wputs "No nodes found so not saving any output" return end # Move this into a generate function? g = GraphViz.new :G, @graphviz_options @edges.keys.each do |from| @edges[from].keys.each do |to| from_label = @nodes[from]["attr"]["label"] from_opts = @nodes[from]["attr"].clone from_opts.delete "label" to_label = @nodes[to]["attr"]["label"] to_opts = @nodes[to]["attr"].clone to_opts.delete "label" dputs "Building from node for #{from_label} as #{from}" from_node = g.add_nodes from_label, from_opts dputs "Building to node for #{to_label} as #{to}" to_node = g.add_nodes to_label, to_opts @edges[from][to].keys.each do |edge| dputs "Building edge #{edge} for #{from} #{to}" g.add_edges from_node, to_node, @edges[from][to][edge]["attr"] end end end if not @destfile if files.size == 1 @destfile = "#{files[0]}.#{@output}" else @destfile = "graph.#{@output}" end end puts "Saving output to #{@destfile}" g.output @output => @destfile end |
#label_to_name(label) ⇒ Object
267 268 269 270 |
# File 'lib/ulg.rb', line 267 def label_to_name(label) name = label.gsub /\W+/, "" return name.downcase end |
#parse(file) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/ulg.rb', line 106 def parse(file) # Iterate over array of files if needed puts "Reading #{file}" if @read_files.include? file wputs "Skipping #{file} as I've seen it before" return end if file == "stdin" contents = STDIN.read else if File.readable? file contents = File.read(file) else wputs "Cannot read file #{file}, skipping" return end end contents.split("\n").each do |line| parse_line line end @read_files << file end |
#parse_arrow(arrow) ⇒ Object
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/ulg.rb', line 248 def parse_arrow(arrow) case arrow when '<' arrow = "normal" when '>' arrow = "normal" when 'o' arrow = "dot" when 'x' arrow = "box" when '<>' arrow = "diamond" else arrow = "none" end return arrow end |
#parse_line(line) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/ulg.rb', line 134 def parse_line(line) line.chomp! case line when /^\s*option\s+(?<option>\w+)\s+(?<value>\w+)\s*$/i set_option $~[:option], $~[:value] when /^\s*include\s+(?<file>.*)$/i parse $~[:file] when /^\s*clear\s+(?<node>.*)$/i clear $~[:node] when /^\s*#{@arrow_regex}\s*$/ from = add_node $~[:from_open], $~[:from_label], $~[:from_color], $~[:from_close] to = add_node $~[:to_open], $~[:to_label], $~[:to_color], $~[:to_close] add_edge from, to, $~[:from_arrow], $~[:edge_open], $~[:edge_label], $~[:edge_color], $~[:edge_close], $~[:to_arrow] end end |
#set_option(option, value) ⇒ Object
155 156 157 |
# File 'lib/ulg.rb', line 155 def set_option(option, value) @graphviz_options[option] = value end |
#wputs(msg) ⇒ Object
51 52 53 |
# File 'lib/ulg.rb', line 51 def wputs(msg) puts "WARN #{msg}" end |