class ArrayDiff

Constants

VERSION

Attributes

diffs[R]
difftype[R]

Public Class Methods

lcs(a, b) click to toggle source
# File lib/array_diff.rb, line 5
def ArrayDiff.lcs(a, b)
  astart = 0
  bstart = 0
  afinish = a.length-1
  bfinish = b.length-1
  mvector = []
  
  # First we prune off any common elements at the beginning
  while (astart <= afinish && bstart <= afinish && a[astart] == b[bstart])
    mvector[astart] = bstart
    astart += 1
    bstart += 1
  end
  
  # now the end
  while (astart <= afinish && bstart <= bfinish && a[afinish] == b[bfinish])
    mvector[afinish] = bfinish
    afinish -= 1
    bfinish -= 1
  end

  bmatches = b.reverse_hash(bstart..bfinish)
  thresh = []
  links = []
  
  (astart..afinish).each { |aindex|
    aelem = a[aindex]
    next unless bmatches.has_key? aelem
    k = nil
    bmatches[aelem].reverse.each { |bindex|
  if k && (thresh[k] > bindex) && (thresh[k-1] < bindex)
    thresh[k] = bindex
  else
    k = thresh.replacenextlarger(bindex, k)
  end
  links[k] = [ (k==0) ? nil : links[k-1], aindex, bindex ] if k
    }
  }

  if !thresh.empty?
    link = links[thresh.length-1]
    while link
  mvector[link[1]] = link[2]
  link = link[0]
    end
  end

  return mvector
end
new(diffs_or_a, b = nil, isstring = nil) click to toggle source
# File lib/array_diff.rb, line 109
def initialize(diffs_or_a, b = nil, isstring = nil)
  if b.nil?
    @diffs = diffs_or_a
    @isstring = isstring
  else
    @diffs = []
    @curdiffs = []
    makediff(diffs_or_a, b)
    @difftype = diffs_or_a.class
  end
end

Public Instance Methods

compact() click to toggle source
# File lib/array_diff.rb, line 134
def compact
  return Diff.new(compactdiffs)
end
compact!() click to toggle source
# File lib/array_diff.rb, line 138
def compact!
  @diffs = compactdiffs
end
compactdiffs() click to toggle source
# File lib/array_diff.rb, line 84
def compactdiffs
  diffs = []
  @diffs.each { |df|
    i = 0
    curdiff = []
    while i < df.length
  whot = df[i][0]
  s = @isstring ? df[i][2].chr : [df[i][2]]
  p = df[i][1]
  last = df[i][1]
  i += 1
  while df[i] && df[i][0] == whot && df[i][1] == last+1
    s << df[i][2]
    last  = df[i][1]
    i += 1
  end
  curdiff.push [whot, p, s]
    end
    diffs.push curdiff
  }
  return diffs
end
diffrange(a, b) click to toggle source
# File lib/array_diff.rb, line 146
def diffrange(a, b)
  if (a == b)
    "#{a}"
  else
    "#{a},#{b}"
  end
end
discarda(i, elem) click to toggle source
# File lib/array_diff.rb, line 126
def discarda(i, elem)
  @curdiffs.push ['-', i, elem]
end
discardb(i, elem) click to toggle source
# File lib/array_diff.rb, line 130
def discardb(i, elem)
  @curdiffs.push ['+', i, elem]
end
inspect() click to toggle source
# File lib/array_diff.rb, line 142
def inspect
  @diffs.inspect
end
makediff(a, b) click to toggle source
# File lib/array_diff.rb, line 55
def makediff(a, b)
  mvector = ArrayDiff.lcs(a, b)
  ai = bi = 0
  while ai < mvector.length
    bline = mvector[ai]
    if bline
  while bi < bline
    discardb(bi, b[bi])
    bi += 1
  end
  match(ai, bi)
  bi += 1
    else
  discarda(ai, a[ai])
    end
    ai += 1
  end
  while ai < a.length
    discarda(ai, a[ai])
    ai += 1
  end
  while bi < b.length
    discardb(bi, b[bi])
    bi += 1
  end
  match(ai, bi)
  1
end
match(ai, bi) click to toggle source
# File lib/array_diff.rb, line 121
def match(ai, bi)
  @diffs.push @curdiffs unless @curdiffs.empty?
  @curdiffs = []
end
to_diff() click to toggle source
# File lib/array_diff.rb, line 154
def to_diff
  offset = 0
  @diffs.each { |b|
    first = b[0][1]
    addcount = 0
    remcount = 0
    b.each { |l| 
      if l[0] == "+"
        addcount += 1
      elsif l[0] == "-"
        remcount += 1
      end
    }
    if addcount == 0
      puts "#{diffrange(first+1, first+remcount)}d#{first+offset}"
    elsif remcount == 0
      puts "#{first-offset}a#{diffrange(first+1, first+addcount)}"
    else
      puts "#{diffrange(first+1, first+remcount)}c#{diffrange(first+offset+1, first+offset+addcount)}"
    end
    lastdel = (b[0][0] == "-")
    b.each { |l|
      if l[0] == "-"
        offset -= 1
        print "< "
      elsif l[0] == "+"
        offset += 1
        if lastdel
          lastdel = false
          puts "---"
        end
        print "> "
      end
  print l[2]
  print "\n"
    }
  }
end