#!/usr/bin/ruby =begin = manued diff * copyright (c) 2002 Kazuhiro NISHIYAMA. = about manued * see (()) or (()) =end begin require 'diff' rescue LoadError STDERR.puts "get from http://www.ruby-lang.org/en/raa-list.rhtml?name=diff.rb" raise end class Manuediff def initialize(a, b, options=Hash.new) @a = a @b = b @options = options options[:left_paren] ||= '[' options[:right_paren] ||= ']' options[:delete] ||= '/' options[:swap] ||= '|' options[:comment] ||= ';' options[:escape] ||= '~' @need_quote_in_text = Regexp.new([ options[:left_paren], options[:escape], ].collect{|x| Regexp.quote x}.join('|')) @need_quote_in_paren = Regexp.new([ options[:left_paren], options[:right_paren], options[:delete], options[:swap], options[:comment], options[:escape], ].collect{|x| Regexp.quote x}.join('|')) @diffs = nil end def compactdiffs @diffs ||= Diff.new(@a,@b).compactdiffs end private :compactdiffs def manued_header result = "defparentheses #{@options[:left_paren]} #{@options[:right_paren]}\n" result << "defdelete #{@options[:delete]}\n" result << "defswap #{@options[:swap]}\n" result << "defcomment #{@options[:comment]}\n" result << "defescape #{@options[:escape]}\n" result << "deforder newer-last\n" result << "defversion 0.9.3\n" end def manued(header=nil) result = header || manued_header ai = bi = 0 compactdiffs.each do |chunk| left_paren_inserted = false delete_inserted = false chunk.each do |sign, index, text| text = text.collect{|s|s.chr}.join('') case sign when '-' len = index - ai result << @a[ai,len].gsub(@need_quote_in_text, "#{@options[:escape]}\\&") ai += len bi += len unless left_paren_inserted left_paren_inserted = true result << @options[:left_paren] end result << text.gsub(@need_quote_in_paren, "#{@options[:escape]}\\&") ai += text.length when '+' len = index - bi result << @a[ai, len].gsub(@need_quote_in_paren, "#{@options[:escape]}\\&") ai += len bi += len unless left_paren_inserted left_paren_inserted = true result << @options[:left_paren] end unless delete_inserted delete_inserted = true result << @options[:delete] end result << text.gsub(@need_quote_in_paren, "#{@options[:escape]}\\&") bi += text.length else raise "Unknown diff action" end end result << @options[:delete] unless delete_inserted result << @options[:right_paren] end result << @a[ai..-1].gsub(@need_quote_in_text, "#{@options[:escape]}\\&") end end if __FILE__ == $0 if ARGV.size != 2 STDERR.puts "usage: #{File.basename $0} old new" end a = File.readlines(ARGV[0]).join('') b = File.readlines(ARGV[1]).join('') md = Manuediff.new(a,b) puts md.manued end