joaopedrosa / yahoo.com (Joao Pedrosa) wrote in message news:<d518d51a.0306140458.42b21a5b / posting.google.com>...
> Hello,
> 
> I have some source code that is terribly formatted. It needs some good
> indentation at least. But I am too lazy to do it all by hand.
> 
> Does anyone know a tool to do the job ?
> 
> Thanks in advance,
> Joao

Hi Joao,

You could try a small program I wrote to do that: it's by no means
complete, and will only handle a subset off all possible ruby programs
correctly. If I remember correctly it only handles programs that use
do...end instead of {...}, but maybe you can adapt it.

Cheers,

Han Holl

#!/usr/bin/ruby


class Pprint
  attr_reader :arr
  def initialize(s)
    if ! build(s)
      puts "Pretty print problem"
      build(s, true)
      exit
    end
  end
  
  def build(s, debug = false)
    indent = 0;
    @arr = []
    comment = false
    waitforeof = false
    wf = nil
    s.each do |line|
      next if line =~ /^\s*$/
      if line =~ /^=begin/
        comment = true
      end
      if comment || line =~ /^\s*#[^{]/  
        @arr << line
        if line =~ /^=end/
          comment = false
        end
        next
      end
      if wf && line =~ wf
        arr << $1
        wf = nil
        next
      end
      if line =~ /<<([A-Z0-9_]*)$/
        waitforeof = true
        wf = /^\s*(#{$1})\s*$/
      end
      ft = line.split
#      puts line
#      puts "HHH: #{ft[0]} #{ft[-1]}"
      if ft[0] =~ /^(?:def|module|class)$/ && ft[-1] == "end"
        @arr << "#{"  " * indent}#{line.strip}"
        next
      end        
#      @arr << "" if ft[0] == "def"
      indent -= 1 if ft[0] =~ /^(else|end|when|rescue|ensure)$/
      if indent < 0
        break
      end
      @arr << "#{"  " * indent}#{line.strip}"
      puts "#{indent}: #{line}" if debug
     
      case ft[0]
      when /^(class|module|case|def|if|while|for|else|when|unless|begin|rescue|ensure)$/
        indent += 1
      else
        
        if ft.find { |w| w == "do" } && ! ft.find { |w| w == "end" }
          indent += 1
        end
      end
    end
    indent == 0
  end
  
end

if __FILE__ == $0
  ARGV.each do |file|
    if FileTest.exists? file
      f = nil
      pp = Pprint.new((f = File.open(file)).readlines)
      f.close
      puts pp.arr
    end
  end
end