47
47
* </code>
48
48
*/
49
49
public class DiffRowGenerator {
50
+
50
51
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern .compile ("\\ s+|[,.\\ [\\ ](){}/\\ \\ *+\\ -#]" );
51
-
52
+
52
53
public static final BiPredicate <String , String > IGNORE_WHITESPACE_EQUALIZER = (original , revised )
53
54
-> original .trim ().replaceAll ("\\ s+" , " " ).equals (revised .trim ().replaceAll ("\\ s+" , " " ));
54
-
55
+
55
56
public static final BiPredicate <String , String > DEFAULT_EQUALIZER = Object ::equals ;
56
-
57
+
57
58
/**
58
59
* Splitting lines by word to achieve word by word diff checking.
59
60
*/
@@ -69,7 +70,7 @@ public class DiffRowGenerator {
69
70
}
70
71
return list ;
71
72
};
72
-
73
+
73
74
private final boolean showInlineDiffs ;
74
75
private final boolean ignoreWhiteSpaces ;
75
76
private final Function <Boolean , String > oldTag ;
@@ -195,11 +196,10 @@ public Builder mergeOriginalRevised(boolean mergeOriginalRevised) {
195
196
* deliver no in word changes.
196
197
*/
197
198
public Builder inlineDiffByWord (boolean inlineDiffByWord ) {
198
- inlineDiffSplitter = inlineDiffByWord ? SPLITTER_BY_WORD : SPLITTER_BY_CHARACTER ;
199
+ inlineDiffSplitter = inlineDiffByWord ? SPLITTER_BY_WORD : SPLITTER_BY_CHARACTER ;
199
200
return this ;
200
201
}
201
-
202
-
202
+
203
203
public Builder inlineDiffBySplitter (Function <String , List <String >> inlineDiffSplitter ) {
204
204
this .inlineDiffSplitter = inlineDiffSplitter ;
205
205
return this ;
@@ -220,7 +220,7 @@ private DiffRowGenerator(Builder builder) {
220
220
inlineDiffSplitter = builder .inlineDiffSplitter ;
221
221
equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER ;
222
222
reportLinesUnchanged = builder .reportLinesUnchanged ;
223
-
223
+
224
224
Objects .requireNonNull (inlineDiffSplitter );
225
225
}
226
226
@@ -356,32 +356,32 @@ private List<DiffRow> generateInlineDiffs(AbstractDelta<String> delta) throws Di
356
356
if (inlineDelta instanceof DeleteDelta ) {
357
357
wrapInTag (origList , inlineOrig .getPosition (), inlineOrig
358
358
.getPosition ()
359
- + inlineOrig .size () + 1 , oldTag );
359
+ + inlineOrig .size (), oldTag );
360
360
} else if (inlineDelta instanceof InsertDelta ) {
361
361
if (mergeOriginalRevised ) {
362
362
origList .addAll (inlineOrig .getPosition (),
363
363
revList .subList (inlineRev .getPosition (), inlineRev .getPosition ()
364
364
+ inlineRev .size ()));
365
365
wrapInTag (origList , inlineOrig .getPosition (), inlineOrig .getPosition ()
366
- + inlineRev .size () + 1 , newTag );
366
+ + inlineRev .size (), newTag );
367
367
} else {
368
368
wrapInTag (revList , inlineRev .getPosition (), inlineRev .getPosition ()
369
- + inlineRev .size () + 1 , newTag );
369
+ + inlineRev .size (), newTag );
370
370
}
371
371
} else if (inlineDelta instanceof ChangeDelta ) {
372
372
if (mergeOriginalRevised ) {
373
373
origList .addAll (inlineOrig .getPosition () + inlineOrig .size (),
374
374
revList .subList (inlineRev .getPosition (), inlineRev .getPosition ()
375
375
+ inlineRev .size ()));
376
376
wrapInTag (origList , inlineOrig .getPosition () + inlineOrig .size (), inlineOrig .getPosition () + inlineOrig .size ()
377
- + inlineRev .size () + 1 , newTag );
377
+ + inlineRev .size (), newTag );
378
378
} else {
379
379
wrapInTag (revList , inlineRev .getPosition (), inlineRev .getPosition ()
380
- + inlineRev .size () + 1 , newTag );
380
+ + inlineRev .size (), newTag );
381
381
}
382
382
wrapInTag (origList , inlineOrig .getPosition (), inlineOrig
383
383
.getPosition ()
384
- + inlineOrig .size () + 1 , oldTag );
384
+ + inlineOrig .size (), oldTag );
385
385
}
386
386
}
387
387
StringBuilder origResult = new StringBuilder ();
@@ -413,10 +413,41 @@ private List<DiffRow> generateInlineDiffs(AbstractDelta<String> delta) throws Di
413
413
* @param tag the tag name without angle brackets, just a word
414
414
* @param cssClass the optional css class
415
415
*/
416
- private static void wrapInTag (List <String > sequence , int startPosition ,
417
- int endPosition , Function <Boolean , String > generator ) {
418
- sequence .add (startPosition , generator .apply (true ));
419
- sequence .add (endPosition , generator .apply (false ));
416
+ static void wrapInTag (List <String > sequence , int startPosition ,
417
+ int endPosition , Function <Boolean , String > tagGenerator ) {
418
+ int endPos = endPosition ;
419
+
420
+ while (endPos >= startPosition ) {
421
+
422
+ //search position for end tag
423
+ while (endPos > startPosition ) {
424
+ if (!"\n " .equals (sequence .get (endPos - 1 ))) {
425
+ break ;
426
+ }
427
+ endPos --;
428
+ }
429
+
430
+ if (endPos == startPosition ) {
431
+ break ;
432
+ }
433
+
434
+ sequence .add (endPos , tagGenerator .apply (false ));
435
+ endPos --;
436
+
437
+ //search position for end tag
438
+ while (endPos > startPosition ) {
439
+ if ("\n " .equals (sequence .get (endPos - 1 ))) {
440
+ break ;
441
+ }
442
+ endPos --;
443
+ }
444
+
445
+ sequence .add (endPos , tagGenerator .apply (true ));
446
+ endPos --;
447
+ }
448
+
449
+ // sequence.add(endPosition, tagGenerator.apply(false));
450
+ // sequence.add(startPosition, tagGenerator.apply(true));
420
451
}
421
452
422
453
protected final static List <String > splitStringPreserveDelimiter (String str , Pattern SPLIT_PATTERN ) {
0 commit comments