Module: DiffLCS

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

Defined Under Namespace

Modules: VERSION Classes: Counter, WordSplitArray

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



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/diff_l_c_s.rb', line 61

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.



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/diff_l_c_s.rb', line 100

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.



83
84
85
86
87
88
89
# File 'lib/diff_l_c_s.rb', line 83

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



31
32
33
# File 'lib/diff_l_c_s.rb', line 31

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.



40
41
42
# File 'lib/diff_l_c_s.rb', line 40

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