Skip to content

Commit 057fde3

Browse files
committed
single space equals combine with replaces
If a single space equal operation is surrounded by replace operations, then it is 'absorbed' into the replace operations. i.e R,E,R becomes simply R.
1 parent 852ba95 commit 057fde3

File tree

3 files changed

+69
-3
lines changed

3 files changed

+69
-3
lines changed

src/htmldiff.coffee

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
is_end_of_tag = (char)-> char is '>'
22
is_start_of_tag = (char)-> char is '<'
3-
is_whitespace = (char)-> /\s/.test char
3+
is_whitespace = (char)-> /^\s+$/.test char
44
is_tag = (token)-> /^\s*<[^>]+>\s*$/.test token
55
isnt_tag = (token)-> not is_tag token
66

@@ -200,7 +200,23 @@ calculate_operations = (before_tokens, after_tokens)->
200200
position_in_before = match.end_in_before + 1
201201
position_in_after = match.end_in_after + 1
202202

203-
return operations
203+
post_processed = []
204+
last_op = action: 'none'
205+
is_single_whitespace = (op)->
206+
return no unless op.action is 'equal'
207+
return no unless op.end_in_before - op.start_in_before is 0
208+
return /^\s$/.test before_tokens[op.start_in_before..op.end_in_before]
209+
210+
for op in operations
211+
if ((is_single_whitespace op) and last_op.action is 'replace') or
212+
(op.action is 'replace' and last_op.action is 'replace')
213+
last_op.end_in_before = op.end_in_before
214+
last_op.end_in_after = op.end_in_after
215+
else
216+
post_processed.push op
217+
last_op = op
218+
219+
return post_processed
204220

205221
consecutive_where = (start, content, predicate)->
206222
content = content[start..content.length]

test/calculate_operations.spec.coffee

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe 'calculate_operations', ->
3232
after = 'working on it'.split ' '
3333
@res = @cut before, after
3434

35-
it 'should result in 3 operation', ->
35+
it 'should result in 3 operations', ->
3636
(expect @res.length).to.equal 3
3737

3838
it 'should show an insert for "on"', ->
@@ -196,3 +196,42 @@ describe 'calculate_operations', ->
196196
end_in_before : 5
197197
start_in_after : 4
198198
end_in_after : undefined
199+
200+
describe 'Action Combination', ->
201+
describe 'Absorb single-whitespace to make contiguous replace actions', ->
202+
beforeEach ->
203+
#There are a bunch of replaces, but, because whitespace is
204+
#tokenized, they are broken up with equals. We want to combine
205+
#them into a contiguous replace operation.
206+
before = ['I', ' ', 'am', ' ', 'awesome']
207+
after = ['You', ' ', 'are', ' ', 'great']
208+
@res = @cut before, after
209+
210+
it 'should return 1 action', ->
211+
(expect @res.length).to.equal 1
212+
213+
it 'should return the correct replace action', ->
214+
(expect @res[0]).eql
215+
action: 'replace'
216+
start_in_before: 0
217+
end_in_before: 4
218+
start_in_after: 0
219+
end_in_after: 4
220+
221+
describe 'but dont absorb non-single-whitespace tokens', ->
222+
beforeEach ->
223+
before = ['I', ' ', 'am', ' ', 'awesome']
224+
after = ['You', ' ', 'are', ' ', 'great']
225+
@res = @cut before, after
226+
227+
it 'should return 3 actions', ->
228+
(expect @res.length).to.equal 3
229+
230+
it 'should have a replace first', ->
231+
(expect @res[0].action).to.equal 'replace'
232+
233+
it 'should have an equal second', ->
234+
(expect @res[1].action).to.equal 'equal'
235+
236+
it 'should have a replace last', ->
237+
(expect @res[2].action).to.equal 'replace'

test/pain_games.spec.coffee

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
describe 'Pain Games', ->
2+
beforeEach ->
3+
@cut = require '../src/htmldiff.coffee'
4+
5+
describe 'When an entire sentence is replaced', ->
6+
beforeEach ->
7+
@res = @cut 'this is what I had', 'and now we have a new one'
8+
9+
it 'should replace the whole chunk', ->
10+
(expect @res).to.equal '<del>this is what I had</del>'\
11+
+ '<ins>and now we have a new one</ins>'

0 commit comments

Comments
 (0)