Module Webby::Helpers::GraphvizHelper
In: lib/webby/helpers/graphviz_helper.rb


Public Class methods

Check the temporary error file to see if it contains any error messages from the graphviz program. If it is not empty, then read the contents and log an error message and raise an exception.


# File lib/webby/helpers/graphviz_helper.rb, line 32
  def self.error_check( file )
    if ::File.size(file.path) != 0
      msg = "\n" <<
      raise ::Webby::Error, msg

Public Instance methods

The graphviz method processes DOT scripts in a webpage and replaces them with generated image files. The page sections to be processed are given as blocks of text to the graphviz method.

Options can be passed to the Graphviz program using attributes in the graphviz method.

    <% graphviz( :path => "images", :type => "gif", cmd => "dot" ) do %>
    digraph graph_1 {
      graph [URL="default.html"]
      a [URL="a.html"]
      b [URL="b.html"]
      c [URL="c.html"]
      a -> b -> c
      a -> c
    <% end %>

If the DOT script contains URL or href attributes on any of the nodes or edges, then an image map will be generated and the image will be "clikcable" in the webpage. If URL or href attributes do not appear in the DOT script, then a regular image will be inserted into the webpage.

The image is inserted into the page using an HTML <img /> tag. A corresponding <map>…</map> element will be inserted if needed.

The supported Graphviz options are the following:

   :path     : where generated images will be stored
               [default is "/"]
   :type     : the type of image to generate (png, jpeg, gif)
               [default is png]
   :cmd      : the Graphviz command to use when generating images
               (dot, neato, twopi, circo, fdp) [default is dot]

   the following options are passed as-is to the generated <img /> tag
   :style    : CSS styles to apply to the <img />
   :class    : CSS class to apply to the <img />
   :id       : HTML identifier
   :alt      : alternate text for the <img />


# File lib/webby/helpers/graphviz_helper.rb, line 80
  def graphviz( *args, &block )
    opts = args.last.instance_of?(Hash) ? args.pop : {}

    text = capture_erb(&block)
    return if text.empty?

    # create a temporary file for holding any error messages
    # from the graphviz program
    err ='graphviz_err')

    defaults =
    path = opts.getopt(:path, defaults.path)
    cmd  = opts.getopt(:cmd, defaults.cmd)
    type = opts.getopt(:type, defaults.type)

    # pull the name of the graph|digraph out of the DOT script
    name = text.match(%r/\A\s*(?:strict\s+)?(?:di)?graph\s+([A-Za-z_][A-Za-z0-9_]*)\s+\{/o)[1]

    # see if the user includes any URL or href attributes
    # if so, then we need to create an imagemap
    usemap = text.match(%r/(?:URL|href)\s*=/o) != nil

    # generate the image filename based on the path, graph name, and type
    # of image to generate
    image_fn = path.nil? ? name.dup : ::File.join(path, name)
    image_fn = ::File.join('', image_fn) << '.' << type

    # create the HTML img tag
    out = "<img src=\"#{image_fn}\""

    %w[class style id alt].each do |atr|
      val = opts.getopt(atr)
      next if val.nil?
      out << " %s=\"%s\"" % [atr, val]

    out << " usemap=\"\##{name}\"" if usemap
    out << " />\n"

    # generate the image map if needed
    if usemap
      IO.popen("#{cmd} -Tcmapx 2> #{err.path}", 'r+') do |io|
        io.write text
        out <<

    # generate the image using graphviz -- but first ensure that the
    # path exists
    out_dir =
    out_file = ::File.join(out_dir, image_fn)
    FileUtils.mkpath(::File.join(out_dir, path)) unless path.nil?
    cmd = "#{cmd} -T#{type} -o #{out_file} 2> #{err.path}"

    IO.popen(cmd, 'w') {|io| io.write text}

    # put some guards around the output (specifically for textile)
    out = _guard(out)

    concat_erb(out, block.binding)