class Cucumber::Formatter::Pdf

def after_background(background)

def after_background(background)
  @in_background = nil
end

def after_feature(feature)

def after_feature(feature)
  flush
end

def after_feature_element(feature_element)

def after_feature_element(feature_element)
  flush
end

def after_features(features)

def after_features(features)
  @pdf.render_file(@file.path)
  puts "\ndone"
end

def announce(announcement)

def announce(announcement)
  @pdf.fill_color(@status_colors[:announced])  
  @pdf.text announcement, :size => 10
  @pdf.fill_color BLACK
end

def background_name(keyword, name, file_colon_line, source_indent)

def background_name(keyword, name, file_colon_line, source_indent)
  feature_element_name(keyword, name)
end

def before_background(background)

def before_background(background)
  @in_background = true
end

def before_multiline_arg(table)

def before_multiline_arg(table)
  return if @hide_this_step
  if(table.kind_of? Cucumber::Ast::Table)
    keep_with do
      print_table(table, ['ffffff', 'f0f0f0'])
    end
  end
end

def before_outline_table(table)

using row_color hack to highlight each row correctly
def before_outline_table(table)
  return if @hide_this_step
  row_colors = table.example_rows.map { |r| @status_colors[r.status] unless r.status == :skipped}
  keep_with do
    print_table(table, row_colors)
  end
end

def before_py_string(string)

def before_py_string(string)
  return if @hide_this_step
  s = %{"""\n#{string}\n"""}.indent(10)
  s = s.split("\n").map{|l| l =~ /^\s+$/ ? '' : l}
  s.each do |line|
    keep_with { @doc.text(line, :size => 8) }
  end
end

def colorize(text, status)

def colorize(text, status)
  keep_with do
    @doc.fill_color(@status_colors[status] || BLACK)
    @doc.text(text)
    @doc.fill_color(BLACK)
  end
end

def examples_name(keyword, name)

def examples_name(keyword, name)
  feature_element_name(keyword, name)
end

def feature_element_name(keyword, name)

def feature_element_name(keyword, name)
  names = name.empty? ? [name] : name.split("\n")
  print "."
  STDOUT.flush
  keep_with do
    @doc.move_down(20)
    @doc.fill_color GREY
    @doc.text("#{keyword}", :size => 8)
    @doc.fill_color BLACK
    @doc.text("#{names[0]}", :size => 16)
    names[1..-1].each { |s| @doc.text(s, :size => 12) }
    @doc.text("\n")
  end
end

def feature_name(keyword, name)

def feature_name(keyword, name)
  @pdf.start_new_page
  names = name.split("\n")
  @pdf.fill_color GREY
  @pdf.text(keyword, :align => :center)
  @pdf.fill_color BLACK
  names.each_with_index do |nameline, i|
    case i
    when 0
      @pdf.text(nameline.strip, :size => 30, :align => :center )
      @pdf.text("\n")
    else
      @pdf.text(nameline.strip, :size => 12)
    end
  end
  @pdf.move_down(30)
end

def flush

This obviously doesn't work if a scenario is longer than a whole page (God forbid)
if that too high for the space left on the age in the real document, we do a page break.
This method does a 'test' rendering on a blank page, to see the rendered height of the buffer
def flush
  @scrap.start_new_page
  oldy = @scrap.y
  render @scrap
  height = (oldy - @scrap.y) + 36 # whops magic number
  if ((@pdf.y - height) < @pdf.bounds.bottom)
    @pdf.start_new_page
  end
  render @pdf
  @pdf.move_down(20)
  @buffer = []
end

def initialize(step_mother, path_or_io, options)

def initialize(step_mother, path_or_io, options)
  @step_mother = step_mother
  @file = ensure_file(path_or_io, "pdf")
  if(options[:dry_run])
    @status_colors = { :passed => BLACK, :skipped => BLACK, :undefined => BLACK, :failed => BLACK, :announced => GREY}
  else
    @status_colors = { :passed => '055902', :skipped => GREY, :undefined => 'F27405', :failed => '730202', :announced => GREY}
  end
  @pdf = Prawn::Document.new
  @scrap = Prawn::Document.new
  @doc = @scrap
  @options = options
  @exceptions = []
  @indent = 0
  @buffer = []
  load_cover_page_image
  @pdf.text "\n\n\nCucumber features", :align => :center, :size => 32
  @pdf.draw_text "Generated: #{Time.now.strftime("%Y-%m-%d %H:%M")}", :size => 10, :at => [0, 24]
  @pdf.draw_text "$ cucumber #{ARGV.join(" ")}", :size => 10, :at => [0,10]
  unless options[:dry_run]
    @pdf.bounding_box [450,100] , :width => 100 do  
      @pdf.text 'Legend', :size => 10
      @status_colors.each do |k,v|
        @pdf.fill_color v
        @pdf.text k.to_s, :size => 10
        @pdf.fill_color BLACK
      end
    end
  end
end

def keep_with(&block)

def keep_with(&block)
  @buffer << block
end

def load_cover_page_image()

def load_cover_page_image()
  if (!load_image("features/support/logo.png"))
    load_image("features/support/logo.jpg")
  end
end

def load_image(image_path)

def load_image(image_path)
  begin
    @pdf.image open(image_path, "rb"), :position => :center, :width => 500
    true
  rescue Errno::ENOENT
    false
  end
end

def print_table(table, row_colors)

def print_table(table, row_colors)
  @doc.table(table.rows, :headers => table.headers, :position => :center, :row_colors => row_colors)
end

def render(doc)

def render(doc)
  @doc = doc
  @buffer.each do |proc|
    proc.call
  end
end

def scenario_name(keyword, name, file_colon_line, source_indent)

def scenario_name(keyword, name, file_colon_line, source_indent)
  feature_element_name(keyword, name)
end

def step_name(keyword, step_match, status, source_indent, background)

def step_name(keyword, step_match, status, source_indent, background)
  return if @hide_this_step
  line = "#{keyword} #{step_match.format_args("%s")}"
  colorize(line, status)
end

def step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)

def step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
  @hide_this_step = false
  if exception
    if @exceptions.include?(exception)
      @hide_this_step = true
      return
    end
    @exceptions << exception
  end
  if status != :failed && @in_background ^ background
    @hide_this_step = true
    return
  end
end

def tag_name(tag_name)

def tag_name(tag_name)
  return if @hide_this_step
  tag = format_string(tag_name, :tag).indent(@indent)
  # TODO should we render tags at all? skipped for now. difficult to place due to page breaks
end