Class: RedmineDiff::Diff

Inherits:
Object
  • Object
show all
Defined in:
lib/diff.rb

Constant Summary collapse

VERSION =
0.3

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(diffs_or_a, b = nil, isstring = nil) ⇒ Diff

Returns a new instance of Diff.


110
111
112
113
114
115
116
117
118
119
120
# File 'lib/diff.rb', line 110

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

Instance Attribute Details

#diffsObject (readonly)

Returns the value of attribute diffs


108
109
110
# File 'lib/diff.rb', line 108

def diffs
  @diffs
end

#difftypeObject (readonly)

Returns the value of attribute difftype


108
109
110
# File 'lib/diff.rb', line 108

def difftype
  @difftype
end

Class Method Details

.lcs(a, b) ⇒ Object


6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/diff.rb', line 6

def Diff.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

Instance Method Details

#compactObject


135
136
137
# File 'lib/diff.rb', line 135

def compact
  return Diff.new(compactdiffs)
end

#compact!Object


139
140
141
# File 'lib/diff.rb', line 139

def compact!
  @diffs = compactdiffs
end

#compactdiffsObject


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/diff.rb', line 85

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

#discarda(i, elem) ⇒ Object


127
128
129
# File 'lib/diff.rb', line 127

def discarda(i, elem)
  @curdiffs.push ['-', i, elem]
end

#discardb(i, elem) ⇒ Object


131
132
133
# File 'lib/diff.rb', line 131

def discardb(i, elem)
  @curdiffs.push ['+', i, elem]
end

#inspectObject


143
144
145
# File 'lib/diff.rb', line 143

def inspect
  @diffs.inspect
end

#makediff(a, b) ⇒ Object


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/diff.rb', line 56

def makediff(a, b)
  mvector = Diff.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) ⇒ Object


122
123
124
125
# File 'lib/diff.rb', line 122

def match(ai, bi)
  @diffs.push @curdiffs unless @curdiffs.empty?
  @curdiffs = []
end