text_alignment 0.4.2 → 0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d56b44ee3cc3451b78ddb87134fefd6c043b4730f1170b07069a417bb162bad1
4
- data.tar.gz: 67318d70bee5bb82127c98e79e0b45e5e337832a2b8d23469474215168579f20
3
+ metadata.gz: dc820991f5f694f154b94c369158909ccba3760829e0d881c7fd2e6ef7ddd149
4
+ data.tar.gz: 40ae6f2e388405426a77682bd1a3fb7a3c853076eced9b7301b632081dfd0a57
5
5
  SHA512:
6
- metadata.gz: 60ae2292556d15d860e0c7377be9c1fd5aec6741b26f562fee8c0c2a9a123d0b8c656b2f7f34b8f74f83ea9ac4878b53f17454e3b25d27d00cd98ecf8175a387
7
- data.tar.gz: fe8fe545101cddb638c00ffb6f6785f8b2f5ddb109b4010739e399a2c50fe41164d791fe4a5599a76fca5553c494f78fd49630368d48e406a8211fc0516916f5
6
+ metadata.gz: 5802241b4a8394d3c570c1d4b8f5e1d7706c72852e2d6e6fb23bda2f6e2972fa09f7001695db026667144e2af982eeb91ed0b700bd8151af6df794c98e3c069b
7
+ data.tar.gz: 8d7c93acbef6ab12bb2a0291444a7bcc73b0236bb5b0d06d274e95aa30c9ffc829965653b58270686147a9ac30ccf570518b3ad266120b320dfb20cd1620f5f9
@@ -35,6 +35,10 @@ def align_mdoc(source_annotations, target_annotations)
35
35
  source_annotations.each do |annotations|
36
36
  alignment = TextAlignment::TextAlignment.new(annotations[:text], target_annotations[:text])
37
37
 
38
+ puts alignment.alignment_show
39
+ puts "-----"
40
+ puts
41
+
38
42
  # alignment.block_alignments.each do |a|
39
43
  # p {source:a[:source], target:a[:target]}
40
44
  # puts "--"
@@ -103,48 +107,39 @@ target_annotations = if source_annotations.class == Array
103
107
  else
104
108
  alignment = TextAlignment::TextAlignment.new(source_annotations[:text], target_text)
105
109
 
106
- pp alignment
110
+ # pp alignment
107
111
 
108
112
  # verification
109
- source_text = source_annotations[:text]
110
- puts "=====BEGIN"
111
- (0 ... source_text.rstrip.length).each do |p|
112
- t = alignment.transform_begin_position(p)
113
- if t.nil?
114
- print source_text[p]
115
- else
116
- print '.'
117
- end
118
- end
119
- puts
120
- puts "=====END"
121
-
122
- puts "=====BEGIN"
123
- (0 .. source_text.rstrip.length).each do |p|
124
- t = alignment.transform_end_position(p)
125
- if t.nil?
126
- print source_text[p]
127
- else
128
- print '.'
129
- end
130
- end
131
- puts
132
- puts "=====END"
133
-
134
- # alignment.block_alignments.each do |a|
135
- # if a[:alignment].nil? || a[:alignment] == :empty
136
- # # p [a[:source], a[:target]]
137
- # # p a[:alignment]
113
+ # source_text = source_annotations[:text]
114
+ # puts "=====BEGIN"
115
+ # (0 ... source_text.rstrip.length).each do |p|
116
+ # t = alignment.transform_begin_position(p)
117
+ # if t.nil?
118
+ # print source_text[p]
119
+ # else
120
+ # print '.'
121
+ # end
122
+ # end
123
+ # puts
124
+ # puts "=====END"
125
+
126
+ # puts "=====BEGIN"
127
+ # (0 .. source_text.rstrip.length).each do |p|
128
+ # t = alignment.transform_end_position(p)
129
+ # if t.nil?
130
+ # print source_text[p]
138
131
  # else
139
- # p [a[:source], a[:target]]
140
- # p a[:alignment].similarity
141
- # puts "--"
142
- # puts source_annotations[:text][a[:source][:begin] ... a[:source][:end]]
143
- # puts "--"
144
- # puts target_text[a[:target][:begin] ... a[:target][:end]]
145
- # puts "======"
132
+ # print '.'
146
133
  # end
147
134
  # end
135
+ # puts
136
+ # puts "=====END"
137
+
138
+ source_text = source_annotations[:text]
139
+
140
+ puts "[block alignment]"
141
+ puts alignment.alignment_show
142
+ puts "====="
148
143
  # exit
149
144
 
150
145
  # verification of source denotations
@@ -4,4 +4,4 @@ TextAlignment::SIZE_NGRAM = 8 unless defined? TextAlignment::SIZE_NGRAM
4
4
  TextAlignment::SIZE_WINDOW = 60 unless defined? TextAlignment::SIZE_WINDOW
5
5
  TextAlignment::BUFFER_RATE = 0.1 unless defined? TextAlignment::BUFFER_RATE
6
6
  TextAlignment::BUFFER_MIN = 20 unless defined? TextAlignment::BUFFER_MIN
7
- TextAlignment::TEXT_SIMILARITY_THRESHOLD = 0.87 unless defined? TextAlignment::TEXT_SIMILARITY_THRESHOLD
7
+ TextAlignment::TEXT_SIMILARITY_THRESHOLD = 0.9 unless defined? TextAlignment::TEXT_SIMILARITY_THRESHOLD
@@ -33,7 +33,9 @@ class TextAlignment::LCSComparison
33
33
  @str2_match_initial = sdiff[match_initial].new_position
34
34
  @str1_match_final = sdiff[match_final].old_position
35
35
  @str2_match_final = sdiff[match_final].new_position
36
- @similarity = 2 * lcs / ((@str1_match_final - @str1_match_initial + 1) + (@str2_match_final - @str2_match_initial + 1)).to_f
36
+ mlcs = sdiff.count{|d| d.action == '=' && d.old_element =~ /\S/ && d.new_element =~ /\S/}
37
+ @similarity = 2 * mlcs / (str1[@str1_match_initial .. @str1_match_final].scan(/\S/).count + str2[@str2_match_initial .. @str2_match_final].scan(/\S/).count).to_f
38
+ # @similarity = 2 * lcs / (str1[@str1_match_initial .. @str1_match_final].length + str2[@str2_match_initial .. @str2_match_final].length).to_f
37
39
  else
38
40
  @str1_match_initial = 0
39
41
  @str2_match_initial = 0
@@ -10,8 +10,6 @@ require 'text_alignment/mappings'
10
10
 
11
11
  module TextAlignment; end unless defined? TextAlignment
12
12
 
13
- TextAlignment::NOMATCH_CHARS = "@^|#$%&_" unless defined? TextAlignment::NOMATCH_CHARS
14
-
15
13
  class TextAlignment::MixedAlignment
16
14
  attr_reader :sdiff
17
15
  attr_reader :position_map_begin, :position_map_end
@@ -21,58 +19,7 @@ class TextAlignment::MixedAlignment
21
19
 
22
20
  def initialize(str1, str2, mappings = [])
23
21
  raise ArgumentError, "nil string" if str1.nil? || str2.nil?
24
- raise ArgumentError, "nil mappings" if mappings.nil?
25
-
26
- ## preprocessing
27
- str1 = str1.dup
28
- str2 = str2.dup
29
- mappings = mappings.dup
30
-
31
- ## find the first nomatch character
32
- TextAlignment::NOMATCH_CHARS.each_char do |c|
33
- if str2.index(c).nil?
34
- @nomatch_char1 = c
35
- break
36
- end
37
- end
38
- raise RuntimeError, "Cannot find nomatch character" if @nomatch_char1.nil?
39
-
40
- ## find the first nomatch character
41
- TextAlignment::NOMATCH_CHARS.each_char do |c|
42
- if c != @nomatch_char1 && str1.index(c).nil?
43
- @nomatch_char2 = c
44
- break
45
- end
46
- end
47
- raise RuntimeError, "Cannot find nomatch character" if @nomatch_char2.nil?
48
-
49
- # single character mappings
50
- character_mappings = mappings.select{|m| m[0].length == 1 && m[1].length == 1}
51
- characters_from = character_mappings.collect{|m| m[0]}.join
52
- characters_to = character_mappings.collect{|m| m[1]}.join
53
- characters_to.gsub!(/-/, '\-')
54
-
55
- str1.tr!(characters_from, characters_to)
56
- str2.tr!(characters_from, characters_to)
57
-
58
- mappings.delete_if{|m| m[0].length == 1 && m[1].length == 1}
59
-
60
- # ASCII foldings
61
- ascii_foldings = mappings.select{|m| m[0].length == 1 && m[1].length > 1}
62
- ascii_foldings.each do |f|
63
- from = f[1]
64
-
65
- if str2.index(f[0])
66
- to = f[0] + (@nomatch_char1 * (f[1].length - 1))
67
- str1.gsub!(from, to)
68
- end
69
-
70
- if str1.index(f[0])
71
- to = f[0] + (@nomatch_char2 * (f[1].length - 1))
72
- str2.gsub!(from, to)
73
- end
74
- end
75
- mappings.delete_if{|m| m[0].length == 1 && m[1].length > 1}
22
+ mappings ||= []
76
23
 
77
24
  _compute_mixed_alignment(str1, str2, mappings)
78
25
  end
@@ -5,28 +5,35 @@ require 'text_alignment/mixed_alignment'
5
5
 
6
6
  module TextAlignment; end unless defined? TextAlignment
7
7
 
8
+ TextAlignment::PADDING_LETTERS = ['@', '^', '|', '#', '$', '%', '&', '_'] unless defined? TextAlignment::PADDING_LETTERS
9
+
8
10
  class TextAlignment::TextAlignment
9
- attr_reader :block_alignments
11
+ attr_reader :block_alignment
10
12
  attr_reader :similarity
11
13
  attr_reader :lost_annotations
12
14
 
13
- def initialize(str1, str2, _size_ngram = nil, _size_window = nil, _text_similiarity_threshold = nil)
14
- raise ArgumentError, "nil string" if str1.nil? || str2.nil?
15
+ def initialize(_str1, _str2, _size_ngram = nil, _size_window = nil, _text_similiarity_threshold = nil)
16
+ raise ArgumentError, "nil string" if _str1.nil? || _str2.nil?
15
17
 
16
- size_ngram = _size_ngram || TextAlignment::SIZE_NGRAM
17
- size_window = _size_window || TextAlignment::SIZE_WINDOW
18
- sim_threshold = _text_similiarity_threshold || TextAlignment::TEXT_SIMILARITY_THRESHOLD
18
+ @block_alignment = {source_text:_str1, target_text:_str2}
19
19
 
20
- mappings ||= TextAlignment::MAPPINGS
20
+ str1, str2, mappings = string_preprocessing(_str1, _str2)
21
21
 
22
22
  # try exact match
23
23
  block_begin = str2.index(str1)
24
24
  unless block_begin.nil?
25
- @block_alignments = [{source:{begin:0, end:str1.length}, target:{begin:block_begin, end:block_begin + str1.length}, delta:block_begin}]
26
- return @block_alignments
25
+ @block_alignment[:blocks] = [{source:{begin:0, end:str1.length}, target:{begin:block_begin, end:block_begin + str1.length}, delta:block_begin, alignment: :block}]
26
+ return @block_alignment
27
+ end
28
+
29
+ # try exact match
30
+ block_begin = str2.downcase.index(str1.downcase)
31
+ unless block_begin.nil?
32
+ @block_alignment[:blocks] = [{source:{begin:0, end:str1.length}, target:{begin:block_begin, end:block_begin + str1.length}, delta:block_begin, alignment: :block}]
33
+ return @block_alignment
27
34
  end
28
35
 
29
- anchor_finder = TextAlignment::AnchorFinder.new(str1, str2, size_ngram, size_window, sim_threshold)
36
+ anchor_finder = TextAlignment::AnchorFinder.new(str1, str2, _size_ngram, _size_window, _text_similiarity_threshold)
30
37
 
31
38
  # To collect matched blocks
32
39
  mblocks = []
@@ -56,7 +63,7 @@ class TextAlignment::TextAlignment
56
63
  # puts
57
64
 
58
65
  ## To find block alignments
59
- @block_alignments = []
66
+ @block_alignment[:blocks] = []
60
67
  return if mblocks.empty?
61
68
 
62
69
  # Initial step
@@ -65,35 +72,35 @@ class TextAlignment::TextAlignment
65
72
  e2 = mblocks[0][:target][:begin]
66
73
 
67
74
  if mblocks[0][:target][:begin] == 0
68
- @block_alignments << {source:{begin:0, end:e1}, target:{begin:0, end:0}, alignment: :empty}
75
+ @block_alignment[:blocks] << {source:{begin:0, end:e1}, target:{begin:0, end:0}, alignment: :empty}
69
76
  else
70
77
  _str1 = str1[0 ... e1]
71
78
  _str2 = str2[0 ... e2]
72
79
 
73
80
  unless _str1.strip.empty?
74
81
  if _str2.strip.empty?
75
- @block_alignments << {source:{begin:0, end:e1}, target:{begin:0, end:e2}, alignment: :empty}
82
+ @block_alignment[:blocks] << {source:{begin:0, end:e1}, target:{begin:0, end:e2}, alignment: :empty}
76
83
  else
77
84
  len_min = [_str1.length, _str2.length].min
78
85
  len_buffer = (len_min * (1 + TextAlignment::BUFFER_RATE)).to_i + TextAlignment::BUFFER_MIN
79
86
  b1 = _str1.length < len_buffer ? 0 : e1 - len_buffer
80
87
  b2 = _str2.length < len_buffer ? 0 : e2 - len_buffer
81
88
 
82
- @block_alignments << {source:{begin:0, end:b1}, target:{begin:0, end:b2}, alignment: :empty} if b1 > 0
89
+ @block_alignment[:blocks] << {source:{begin:0, end:b1}, target:{begin:0, end:b2}, alignment: :empty} if b1 > 0
83
90
 
84
91
  _str1 = str1[b1 ... e1]
85
92
  _str2 = str2[b2 ... e2]
86
93
  alignment = TextAlignment::MixedAlignment.new(_str1.downcase, _str2.downcase, mappings)
87
94
  if alignment.similarity < 0.6
88
- @block_alignments << {source:{begin:b1, end:e1}, target:{begin:0, end:e2}, alignment: :empty}
95
+ @block_alignment[:blocks] << {source:{begin:b1, end:e1}, target:{begin:0, end:e2}, alignment: :empty}
89
96
  else
90
- @block_alignments << {source:{begin:b1, end:e1}, target:{begin:0, end:e2}, alignment:alignment}
97
+ @block_alignment[:blocks] << {source:{begin:b1, end:e1}, target:{begin:0, end:e2}, alignment:alignment}
91
98
  end
92
99
  end
93
100
  end
94
101
  end
95
102
  end
96
- @block_alignments << mblocks[0]
103
+ @block_alignment[:blocks] << mblocks[0].merge(alignment: :block)
97
104
 
98
105
  (1 ... mblocks.length).each do |i|
99
106
  b1 = mblocks[i - 1][:source][:end]
@@ -104,17 +111,17 @@ class TextAlignment::TextAlignment
104
111
  _str2 = str2[b2 ... e2]
105
112
  unless _str1.strip.empty?
106
113
  if _str2.strip.empty?
107
- @block_alignments << {source:{begin:b1, end:e1}, target:{begin:b2, end:e2}, alignment: :empty}
114
+ @block_alignment[:blocks] << {source:{begin:b1, end:e1}, target:{begin:b2, end:e2}, alignment: :empty}
108
115
  else
109
116
  alignment = TextAlignment::MixedAlignment.new(_str1.downcase, _str2.downcase, mappings)
110
117
  if alignment.similarity < 0.6
111
- @block_alignments << {source:{begin:b1, end:e1}, target:{begin:b2, end:e2}, alignment: :empty}
118
+ @block_alignment[:blocks] << {source:{begin:b1, end:e1}, target:{begin:b2, end:e2}, alignment: :empty}
112
119
  else
113
- @block_alignments << {source:{begin:b1, end:e1}, target:{begin:b2, end:e2}, alignment:alignment}
120
+ @block_alignment[:blocks] << {source:{begin:b1, end:e1}, target:{begin:b2, end:e2}, alignment:alignment}
114
121
  end
115
122
  end
116
123
  end
117
- @block_alignments << mblocks[i]
124
+ @block_alignment[:blocks] << mblocks[i].merge(alignment: :block)
118
125
  end
119
126
 
120
127
  # Final step
@@ -126,7 +133,7 @@ class TextAlignment::TextAlignment
126
133
 
127
134
  unless _str1.strip.empty?
128
135
  if _str2.strip.empty?
129
- @block_alignments << {source:{begin:b1, end:str1.length}, target:{begin:b2, end:str2.length}, alignment: :empty}
136
+ @block_alignment[:blocks] << {source:{begin:b1, end:str1.length}, target:{begin:b2, end:str2.length}, alignment: :empty}
130
137
  else
131
138
  len_min = [_str1.length, _str2.length].min
132
139
  len_buffer = (len_min * (1 + TextAlignment::BUFFER_RATE)).to_i + TextAlignment::BUFFER_MIN
@@ -137,56 +144,56 @@ class TextAlignment::TextAlignment
137
144
 
138
145
  alignment = TextAlignment::MixedAlignment.new(_str1.downcase, _str2.downcase, mappings)
139
146
  if alignment.similarity < 0.6
140
- @block_alignments << {source:{begin:b1, end:e1}, target:{begin:b2, end:e2}, alignment: :empty}
147
+ @block_alignment[:blocks] << {source:{begin:b1, end:e1}, target:{begin:b2, end:e2}, alignment: :empty}
141
148
  else
142
- @block_alignments << {source:{begin:b1, end:e1}, target:{begin:b2, end:e2}, alignment:alignment}
149
+ @block_alignment[:blocks] << {source:{begin:b1, end:e1}, target:{begin:b2, end:e2}, alignment:alignment}
143
150
  end
144
151
 
145
- @block_alignments << {source:{begin:e1, end:-1}, target:{begin:e2, end:-1}, alignment: :empty} if e1 < str1.length
152
+ @block_alignment[:blocks] << {source:{begin:e1, end:-1}, target:{begin:e2, end:-1}, alignment: :empty} if e1 < str1.length
146
153
  end
147
154
  end
148
155
  end
149
156
 
150
- @block_alignments.each do |a|
157
+ @block_alignment[:blocks].each do |a|
151
158
  a[:delta] = a[:target][:begin] - a[:source][:begin]
152
159
  end
153
160
  end
154
161
 
155
162
  def transform_begin_position(begin_position)
156
- i = @block_alignments.index{|b| b[:source][:end] > begin_position}
157
- block_alignment = @block_alignments[i]
158
-
159
- b = if block_alignment[:alignment].nil?
160
- begin_position + block_alignment[:delta]
161
- elsif block_alignment[:alignment] == :empty
162
- if begin_position == block_alignment[:source][:begin]
163
- block_alignment[:target][:begin]
163
+ i = @block_alignment[:blocks].index{|b| b[:source][:end] > begin_position}
164
+ block = @block_alignment[:blocks][i]
165
+
166
+ b = if block[:alignment] == :block
167
+ begin_position + block[:delta]
168
+ elsif block[:alignment] == :empty
169
+ if begin_position == block[:source][:begin]
170
+ block[:target][:begin]
164
171
  else
165
172
  # raise "lost annotation"
166
173
  nil
167
174
  end
168
175
  else
169
- r = block_alignment[:alignment].transform_begin_position(begin_position - block_alignment[:source][:begin])
170
- r.nil? ? nil : r + block_alignment[:target][:begin]
176
+ r = block[:alignment].transform_begin_position(begin_position - block[:source][:begin])
177
+ r.nil? ? nil : r + block[:target][:begin]
171
178
  end
172
179
  end
173
180
 
174
181
  def transform_end_position(end_position)
175
- i = @block_alignments.index{|b| b[:source][:end] >= end_position}
176
- block_alignment = @block_alignments[i]
177
-
178
- e = if block_alignment[:alignment].nil?
179
- end_position + block_alignment[:delta]
180
- elsif block_alignment[:alignment] == :empty
181
- if end_position == block_alignment[:source][:end]
182
- block_alignment[:target][:end]
182
+ i = @block_alignment[:blocks].index{|b| b[:source][:end] >= end_position}
183
+ block = @block_alignment[:blocks][i]
184
+
185
+ e = if block[:alignment] == :block
186
+ end_position + block[:delta]
187
+ elsif block[:alignment] == :empty
188
+ if end_position == block[:source][:end]
189
+ block[:target][:end]
183
190
  else
184
191
  # raise "lost annotation"
185
192
  nil
186
193
  end
187
194
  else
188
- r = block_alignment[:alignment].transform_end_position(end_position - block_alignment[:source][:begin])
189
- r.nil? ? nil : r + block_alignment[:target][:begin]
195
+ r = block[:alignment].transform_end_position(end_position - block[:source][:begin])
196
+ r.nil? ? nil : r + block[:target][:begin]
190
197
  end
191
198
  end
192
199
 
@@ -232,4 +239,114 @@ class TextAlignment::TextAlignment
232
239
  r
233
240
  end
234
241
 
242
+ def alignment_show
243
+ stext = @block_alignment[:source_text]
244
+ ttext = @block_alignment[:target_text]
245
+
246
+ show = ''
247
+ @block_alignment[:blocks].each do |a|
248
+ show += case a[:alignment]
249
+ when :block
250
+ "===== common =====\n" +
251
+ stext[a[:source][:begin] ... a[:source][:end]] + "\n\n"
252
+ when :empty
253
+ "<<<<< string 1\n" +
254
+ stext[a[:source][:begin] ... a[:source][:end]] + "\n\n" +
255
+ ">>>>> string 2\n" +
256
+ ttext[a[:target][:begin] ... a[:target][:end]] + "\n\n"
257
+ else
258
+ astr1 = ''
259
+ astr2 = ''
260
+
261
+ base = a[:source][:begin]
262
+ astr1 = a[:alignment].sdiff.map do |c|
263
+ case c.action
264
+ when '='
265
+ stext[c.old_position + base]
266
+ when '+'
267
+ '_'
268
+ when '-'
269
+ stext[c.old_position + base]
270
+ when '!'
271
+ stext[c.old_position + base] + '_'
272
+ end
273
+ end.join('')
274
+
275
+ base = a[:target][:begin]
276
+ astr2 = a[:alignment].sdiff.map do |c|
277
+ case c.action
278
+ when '='
279
+ ttext[c.new_position + base]
280
+ when '+'
281
+ ttext[c.new_position + base]
282
+ when '-'
283
+ '_'
284
+ when '!'
285
+ '_' + ttext[c.new_position + base]
286
+ end
287
+ end.join('')
288
+
289
+ "***** local mismatch\n" +
290
+ "[#{astr1}]\n" +
291
+ "[#{astr2}]\n\n"
292
+ end
293
+ end
294
+ show
295
+ end
296
+
297
+ private
298
+
299
+ def string_preprocessing(_str1, _str2)
300
+ str1 = _str1.dup
301
+ str2 = _str2.dup
302
+ mappings = TextAlignment::MAPPINGS.dup
303
+
304
+ ## single character mappings
305
+ character_mappings = mappings.select{|m| m[0].length == 1 && m[1].length == 1}
306
+ characters_from = character_mappings.collect{|m| m[0]}.join
307
+ characters_to = character_mappings.collect{|m| m[1]}.join
308
+ characters_to.gsub!(/-/, '\-')
309
+
310
+ str1.tr!(characters_from, characters_to)
311
+ str2.tr!(characters_from, characters_to)
312
+
313
+ mappings.delete_if{|m| m[0].length == 1 && m[1].length == 1}
314
+
315
+ ## long to one character mappings
316
+ pletters = TextAlignment::PADDING_LETTERS
317
+
318
+ # find the padding letter for str1
319
+ padding_letter1 = begin
320
+ i = pletters.index{|l| str2.index(l).nil?}
321
+ raise RuntimeError, "Could not find a padding letter for str1" if i.nil?
322
+ TextAlignment::PADDING_LETTERS[i]
323
+ end
324
+
325
+ # find the padding letter for str2
326
+ padding_letter2 = begin
327
+ i = pletters.index{|l| l != padding_letter1 && str1.index(l).nil?}
328
+ raise RuntimeError, "Could not find a padding letter for str2" if i.nil?
329
+ TextAlignment::PADDING_LETTERS[i]
330
+ end
331
+
332
+ # ASCII foldings
333
+ ascii_foldings = mappings.select{|m| m[0].length == 1 && m[1].length > 1}
334
+ ascii_foldings.each do |f|
335
+ from = f[1]
336
+
337
+ if str2.index(f[0])
338
+ to = f[0] + (padding_letter1 * (f[1].length - 1))
339
+ str1.gsub!(from, to)
340
+ end
341
+
342
+ if str1.index(f[0])
343
+ to = f[0] + (padding_letter2 * (f[1].length - 1))
344
+ str2.gsub!(from, to)
345
+ end
346
+ end
347
+ mappings.delete_if{|m| m[0].length == 1 && m[1].length > 1}
348
+
349
+ [str1, str2, mappings]
350
+ end
351
+
235
352
  end
@@ -1,3 +1,3 @@
1
1
  class TextAlignment
2
- VERSION = '0.4.2'
2
+ VERSION = '0.6'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: text_alignment
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: '0.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jin-Dong Kim
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-02 00:00:00.000000000 Z
11
+ date: 2020-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-dictionary