<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -268,4 +268,65 @@ module Workflow
       end
     end
   end
+
+  # Generates a `dot` graph of the workflow.
+  # Prerequisite: the `dot` binary.
+  # You can use it in your own Rakefile like this:
+  #
+  #     namespace :doc do
+  #       desc &quot;Generate a graph of the workflow.&quot;
+  #       task :workflow do
+  #         Workflow::create_workflow_diagram(Order.new)
+  #       end
+  #     end
+  #
+  # You can influence the placement of nodes by specifying 
+  # additional meta information in your states and transition descriptions.
+  # You can assign higher `doc_weight` value to the typical transitions
+  # in your workflow. All other states and transitions will be arranged
+  # around that main line. See also `weight` in the graphviz documentation.
+  # Example:
+  #
+  #     state :new do
+  #       event :approve, :transitions_to =&gt; :approved, :meta =&gt; {:doc_weight =&gt; 8}
+  #     end
+  #
+  #
+  # @param klass A class with the Workflow mixin, for which you wish the graphical workflow representation
+  # @param [String] target_dir Directory, where to save the dot and the pdf files
+  # @param [String] graph_options You can change graph orientation, size etc. See graphviz documentation
+  def self.create_workflow_diagram(klass, target_dir, graph_options='rankdir=&quot;LR&quot;, size=&quot;7,11.6&quot;, ratio=&quot;fill&quot;')
+    workflow_name = &quot;#{klass.name.tableize}_workflow&quot;
+    fname = File.join(target_dir, &quot;generated_#{workflow_name}&quot;)
+    File.open(&quot;#{fname}.dot&quot;, 'w') do |file|
+      file.puts %Q|
+digraph #{workflow_name} {
+  graph [#{graph_options}];
+  node [shape=box];
+  edge [len=1];
+      |
+
+      klass.workflow_spec.states.each do |state_name, state|
+        file.puts %Q{  #{state.name} [label=&quot;#{state.name}&quot;];}
+        state.events.each do |event_name, event|
+          meta_info = event.meta
+          if meta_info[:doc_weight]
+            weight_prop = &quot;, weight=#{meta_info[:doc_weight]}&quot;             
+          else
+            weight_prop = ''
+          end
+          file.puts %Q{  #{state.name} -&gt; #{event.transitions_to} [label=&quot;#{event_name.to_s.humanize}&quot; #{weight_prop}];}
+        end
+      end
+      file.puts &quot;}&quot;
+      file.puts
+    end
+    `dot -Tpdf -o#{fname}.pdf #{fname}.dot`
+    puts &quot;
+Please run the following to open the generated file:
+
+open #{fname}.pdf
+
+&quot;
+  end
 end</diff>
      <filename>lib/workflow.rb</filename>
    </modified>
    <modified>
      <diff>@@ -300,5 +300,9 @@ class MainTest &lt; Test::Unit::TestCase
     assert_equal ['on_new_exit next -&gt; next_state', 'on_next_state_entry next new -&gt;'], o.history
 
   end 
+
+  test 'diagram generation' do
+    Workflow::create_workflow_diagram(Order, 'doc')
+  end
 end
 </diff>
      <filename>test/main_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>18329275ccbf9818b85efb0d1d7b0649b23dc142</id>
    </parent>
  </parents>
  <author>
    <name>Vladimir Dobriakov</name>
    <email>vladimir@geekq.net</email>
  </author>
  <url>http://github.com/geekq/workflow/commit/7800e0fe69f5638713f5f76386d7db3594d759b3</url>
  <id>7800e0fe69f5638713f5f76386d7db3594d759b3</id>
  <committed-date>2009-10-30T05:46:40-07:00</committed-date>
  <authored-date>2009-10-30T05:46:40-07:00</authored-date>
  <message>Workflow graph generation with `dot`</message>
  <tree>2a2dac1f2718102f0fc056feedb08641e673ba88</tree>
  <committer>
    <name>Vladimir Dobriakov</name>
    <email>vladimir@geekq.net</email>
  </committer>
</commit>
