class RDoc::Parser::PerlPOD

def scan

def scan
  @top_level.comment ||= ""
  state=:code_blank
  line_number = 0
  line = nil
  # This started out as a really long nested case statement,
  # which also led to repetitive code.  I'd like to avoid that
  # so I'm using a "table" instead.
  # Firstly we need some procs to do the transition and processing
  # work.  Because these are procs they are closures, and they can
  # use variables in the local scope.
  #
  # First, the "nothing to see here" stuff.
  code_noop = lambda do
    if line =~ /^\s+$/
tate = :code_blank
    end
  end
  pod_noop = lambda do
    if line =~ /^\s+$/
tate = :pod_blank
    end
    @top_level.comment += filter(line)
  end
  begin_noop = lambda do
    if line =~ /^\s+$/
tate = :begin_blank
    end
    @top_level.comment += filter(line)
  end
  # Now for the blocks that process code and comments...
  transit_to_pod = lambda do
    case line
    when /^=(?:pod|head\d+)/
tate = :pod_no_blank
top_level.comment += filter(line)
    when /^=over/
tate = :over_no_blank
top_level.comment += filter(line)
    when /^=(?:begin|for)/
tate = :begin_no_blank
    end
  end
  process_pod = lambda do
    case line
    when  /^\s*$/
tate = :pod_blank
top_level.comment += filter(line)
    when /^=cut/
tate = :code_no_blank
    when /^=end/
stderr.puts "'=end' unexpected at #{line_number} in #{@file_name}"
    else
top_level.comment += filter(line)
    end
  end
  process_begin = lambda do
    case line
    when  /^\s*$/
tate = :begin_blank
top_level.comment += filter(line)
    when /^=end/
tate = :code_no_blank
    when /^=cut/
stderr.puts "'=cut' unexpected at #{line_number} in #{@file_name}"
    else
top_level.comment += filter(line)
    end
  end
  transitions = { :code_no_blank => code_noop,
                  :code_blank => transit_to_pod,
    :pod_no_blank => pod_noop,
    :pod_blank => process_pod,
    :begin_no_blank => begin_noop,
    :begin_blank => process_begin}
  @content.each_line do |l|
    line = l
    line_number += 1
    transitions[state].call
  end # each line
  @top_level
end