Class: RedmineDiff::Diff

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

Constant Summary

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



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

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



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

def diffs
  @diffs
end

#difftypeObject (readonly)

Returns the value of attribute difftype



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

def difftype
  @difftype
end

Class Method Details

.lcs(a, b) ⇒ Object



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
55
# File 'lib/diff.rb', line 7

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



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

def compact
  return Diff.new(compactdiffs)
end

#compact!Object



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

def compact!
  @diffs = compactdiffs
end

#compactdiffsObject



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

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



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

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

#discardb(i, elem) ⇒ Object



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

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

#inspectObject



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

def inspect
  @diffs.inspect
end

#makediff(a, b) ⇒ Object



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
84
# File 'lib/diff.rb', line 57

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



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

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