Module: DiffLCS

Included in:
String
Defined in:
lib/diff_l_c_s.rb,
lib/diff_l_c_s/version.rb

Defined Under Namespace

Classes: Counter, WordSplitArray

Constant Summary collapse

VERSION =
'0.6.9'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.diff(old_arr, new_arr, options = {}) ⇒ Object

Diffs the current logi_version and the logi’s body_text with the logi_versions body_text given and returns a hash containing:

:matched_old = the position_ranges in the old text for

the places where the new matches the old.

:remaining_new = the position-ranges for the part of

the new text that remains unmatched in the old

Valid options are:

  • :minimum_lcs_size = the minimum size of LCS-es to allow



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/diff_l_c_s.rb', line 25

def diff(old_arr, new_arr, options = {})
  minimum_lcs_size = options[:minimum_lcs_size] || 0
  diff_hash = DiffLCS.longest_common_sub_strings(old_arr, new_arr,
      :minimum_lcs_size => minimum_lcs_size)
  original_matched_old = diff_hash[:matched_old]
  matched_old = PositionRange::List.new
  original_matched_new = diff_hash[:matched_new]
  matched_new = original_matched_new.sort
  i = 0
  while i < original_matched_old.size
    matched_old[matched_new.index(original_matched_new[i])] =
        original_matched_old[i]
    i += 1
  end

  return {:matched_old => matched_old,
          :matched_new => matched_new}
end

.longest_common_sub_strings(old_arr, new_arr, options = {}) ⇒ Object

Returns a PositionRange::List containing pointers to the Longest Common Substrings (not Subsequences) of the Arrays or an empty PositionRange::List if none was found.

Valid options are:

  • :minimum_lcs_size = the minimum size of LCS-es to allow

The returned List is sorted by LCS-size.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/diff_l_c_s.rb', line 64

def longest_common_sub_strings(old_arr, new_arr, options = {})
  minimum_lcs_size = options[:minimum_lcs_size] || 0

  counter_hash = Hash.new
  counter_array = Array.new
  old_arr.each_with_index do |old_el, old_i|
    counter_hash[old_i] = Hash.new
    new_arr.each_with_index do |new_el, new_i|
      if old_el == new_el
        if new_i > 0 and old_i > 0 and counter_hash[old_i - 1][new_i - 1]
          counter_hash[old_i][new_i] = counter_hash[old_i - 1][new_i - 1]
          counter_hash[old_i][new_i].step_up
        else
          counter = Counter.new(old_i, new_i)
          counter_hash[old_i][new_i] = counter
          counter_array.push(counter)
        end
      end
    end
  end

  in_old_p_r_list = PositionRange::List.new
  in_new_p_r_list = PositionRange::List.new

  counter_array = counter_array.select {|co| co.step_size > minimum_lcs_size}

  while counter = counter_array.sort!.pop
    i = 0
    while i < counter_array.size
      if counter_array[i].in_old === counter.in_old
        counter_array[i].in_old = counter_array[i].in_old - counter.in_old
      end
      if counter_array[i].in_new === counter.in_new
        counter_array[i].in_new = counter_array[i].in_new - counter.in_new
      end
      if counter_array[i].size <= minimum_lcs_size
        counter_array.delete_at(i)
      else
        i += 1
      end
    end
    in_old_p_r_list.push(counter.in_old)
    in_new_p_r_list.push(counter.in_new)
  end
  return {:matched_old => in_old_p_r_list,
      :matched_new => in_new_p_r_list}
end

.word_diff(old_string, new_string, options = {}) ⇒ Object

Words are non-spaces or groups of spaces delimited by either spaces or the beginning or the end of the string.



47
48
49
50
51
52
53
# File 'lib/diff_l_c_s.rb', line 47

def word_diff(old_string, new_string, options = {})
  old_w_s_arr = DiffLCS::WordSplitArray.new(old_string)
  new_w_s_arr = DiffLCS::WordSplitArray.new(new_string)
  diff = DiffLCS.diff(old_w_s_arr, new_w_s_arr, options)
  return {:matched_old => old_w_s_arr.translate_to_pos(diff[:matched_old]),
          :matched_new => new_w_s_arr.translate_to_pos(diff[:matched_new])}
end

Instance Method Details

#diff(other, options = {}) ⇒ Object

Diffs self with other, see DiffLCS#diff



115
116
117
# File 'lib/diff_l_c_s.rb', line 115

def diff(other, options = {})
  DiffLCS.diff(self.split(''), other.split(''), options)
end

#word_diff(other, options = {}) ⇒ Object

Diffs words in self with other, see DiffLCS#diff

Words are non-spaces or groups of spaces delimited by either spaces or the beginning or the end of the string.



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

def word_diff(other, options = {})
  DiffLCS.word_diff(self, other, options)
end