267: def output( *hOpt )
268: xDOTScript = ""
269: xLastType = nil
270: xSeparator = ""
271: xData = ""
272:
273: @elements_order.each { |kElement|
274: if xLastType.nil? == true or xLastType != kElement["type"]
275:
276: if xData.length > 0
277: case xLastType
278: when "graph_attr"
279: xDOTScript << " " + xData + ";\n"
280:
281: when "node_attr"
282: xDOTScript << " node [" + xData + "];\n"
283:
284: when "edge_attr"
285: xDOTScript << " edge [" + xData + "];\n"
286: end
287: end
288:
289: xSeparator = ""
290: xData = ""
291: end
292:
293: xLastType = kElement["type"]
294:
295:
296:
297:
298: if kElement["value"] == nil then
299: raise ArgumentError, "#{kElement["name"]} has a nil value!"
300: end
301:
302: case kElement["type"]
303: when "graph_attr"
304: xData << xSeparator + kElement["name"] + " = " + kElement["value"].to_gv
305: xSeparator = "; "
306:
307: when "node_attr"
308: xData << xSeparator + kElement["name"] + " = " + kElement["value"].to_gv
309: xSeparator = ", "
310:
311: when "edge_attr"
312: xData << xSeparator + kElement["name"] + " = " + kElement["value"].to_gv
313: xSeparator = ", "
314:
315: when "node"
316: xDOTScript << " " + kElement["value"].output() + "\n"
317:
318: when "edge"
319: xDOTScript << " " + kElement["value"].output( @oGraphType ) + "\n"
320:
321: when "graph"
322: xDOTScript << kElement["value"].output() + "\n"
323:
324: else
325: raise ArgumentError, "Don't know what to do with element type '#{kElement['type']}'"
326: end
327: }
328:
329: if xData.length > 0
330: case xLastType
331: when "graph_attr"
332: xDOTScript << " " + xData + ";\n"
333:
334: when "node_attr"
335: xDOTScript << " node [" + xData + "];\n"
336:
337: when "edge_attr"
338: xDOTScript << " edge [" + xData + "];\n"
339: end
340: end
341: xDOTScript << "}"
342:
343: if @oParentGraph.nil? == false
344: xDOTScript = "subgraph #{@name} {\n" << xDOTScript
345:
346: return( xDOTScript )
347: else
348: if hOpt.nil? == false and hOpt[0].nil? == false
349: hOpt[0].each do |xKey, xValue|
350: xValue = xValue.to_s unless xValue.nil? or [Class, TrueClass, FalseClass].include?(xValue.class)
351: case xKey.to_s
352: when "output"
353: warn ":output option is deprecated, please use :<format> => :<file>"
354: if FORMATS.index( xValue ).nil? == true
355: raise ArgumentError, "output format '#{xValue}' invalid"
356: end
357: @format = xValue
358: when "file"
359: warn ":file option is deprecated, please use :<format> => :<file>"
360: @filename = xValue
361: when "use"
362: if PROGRAMS.index( xValue ).nil? == true
363: raise ArgumentError, "can't use '#{xValue}'"
364: end
365: @prog = xValue
366: when "path"
367: @path = xValue.split( "," ).map{ |x| x.strip }
368: when "errors"
369: @errors = xValue
370: when "extlib"
371: @extlibs = xValue.split( "," ).map{ |x| x.strip }
372: else
373: if FORMATS.index( xKey.to_s ).nil? == true
374: raise ArgumentError, "output format '#{xValue}' invalid"
375: end
376: @output[xKey.to_s] = xValue
377: end
378: end
379: end
380:
381: xDOTScript = "#{@oGraphType} #{@name} {\n" << xDOTScript
382:
383: xOutputString = (@filename == String ||
384: @output.any? {|format, file| file == String })
385:
386: xOutput =
387: if @format.to_s == "none" || @output.any? {|fmt, fn| fmt.to_s == "none" }
388: xDOTScript
389: else
390:
391: t = Tempfile::open( File.basename($0) )
392: t.print( xDOTScript )
393: t.close
394:
395: cmd = find_executable( @prog, @path )
396: if cmd == nil
397: raise StandardError, "GraphViz not installed or #{@prog} not in PATH. Install GraphViz or use the 'path' option"
398: end
399:
400: cmd = escape_path_containing_blanks(cmd) if IS_JRUBY
401:
402: xOutputWithFile = ""
403: xOutputWithoutFile = ""
404: unless @format.nil?
405: if @filename.nil? || @filename == String
406: xOutputWithoutFile = "-T#{@format} "
407: else
408: xOutputWithFile = "-T#{@format} -o#{@filename} "
409: end
410: end
411: @output.each do |format, file|
412: if file.nil? || file == String
413: xOutputWithoutFile << "-T#{format} "
414: else
415: xOutputWithFile << "-T#{format} -o#{file} "
416: end
417: end
418:
419: xExternalLibraries = ""
420: @extlibs.each do |lib|
421: xExternalLibraries << "-l#{lib} "
422: end
423:
424: if IS_JRUBY
425: xCmd = "#{cmd} -q#{@errors} #{xExternalLibraries} #{xOutputWithFile} #{xOutputWithoutFile} #{t.path}"
426: else
427: xCmd = "\"#{cmd}\" -q#{@errors} #{xExternalLibraries} #{xOutputWithFile} #{xOutputWithoutFile} #{t.path}"
428: end
429:
430: output_from_command( xCmd )
431: end
432:
433: if xOutputString
434: xOutput
435: else
436: print xOutput
437: end
438: end
439: end