2424import com .github .difflib .patch .Patch ;
2525import com .github .difflib .text .DiffRow .Tag ;
2626import java .util .*;
27+ import java .util .function .BiFunction ;
2728import java .util .function .BiPredicate ;
2829import java .util .function .Function ;
2930import java .util .regex .Matcher ;
@@ -106,7 +107,7 @@ protected final static List<String> splitStringPreserveDelimiter(String str, Pat
106107 * @param tagGenerator the tag generator
107108 */
108109static void wrapInTag (List <String >sequence ,int startPosition ,
109- int endPosition ,Function < Boolean ,String >tagGenerator ,
110+ int endPosition ,Tag tag , BiFunction < Tag , Boolean ,String >tagGenerator ,
110111Function <String ,String >processDiffs ) {
111112int endPos =endPosition ;
112113
@@ -124,7 +125,7 @@ static void wrapInTag(List<String> sequence, int startPosition,
124125break ;
125126 }
126127
127- sequence .add (endPos ,tagGenerator .apply (false ));
128+ sequence .add (endPos ,tagGenerator .apply (tag , false ));
128129if (processDiffs !=null ) {
129130sequence .set (endPos -1 ,
130131processDiffs .apply (sequence .get (endPos -1 )));
@@ -143,7 +144,7 @@ static void wrapInTag(List<String> sequence, int startPosition,
143144endPos --;
144145 }
145146
146- sequence .add (endPos ,tagGenerator .apply (true ));
147+ sequence .add (endPos ,tagGenerator .apply (tag , true ));
147148endPos --;
148149 }
149150 }
@@ -153,8 +154,8 @@ static void wrapInTag(List<String> sequence, int startPosition,
153154private final boolean ignoreWhiteSpaces ;
154155private final Function <String ,List <String >>inlineDiffSplitter ;
155156private final boolean mergeOriginalRevised ;
156- private final Function < Boolean ,String >newTag ;
157- private final Function < Boolean ,String >oldTag ;
157+ private final BiFunction < Tag , Boolean ,String >newTag ;
158+ private final BiFunction < Tag , Boolean ,String >oldTag ;
158159private final boolean reportLinesUnchanged ;
159160private final Function <String ,String >lineNormalizer ;
160161private final Function <String ,String >processDiffs ;
@@ -169,7 +170,13 @@ private DiffRowGenerator(Builder builder) {
169170columnWidth =builder .columnWidth ;
170171mergeOriginalRevised =builder .mergeOriginalRevised ;
171172inlineDiffSplitter =builder .inlineDiffSplitter ;
172- equalizer =ignoreWhiteSpaces ?IGNORE_WHITESPACE_EQUALIZER :DEFAULT_EQUALIZER ;
173+
174+ if (builder .equalizer !=null ) {
175+ equalizer =builder .equalizer ;
176+ }else {
177+ equalizer =ignoreWhiteSpaces ?IGNORE_WHITESPACE_EQUALIZER :DEFAULT_EQUALIZER ;
178+ }
179+
173180reportLinesUnchanged =builder .reportLinesUnchanged ;
174181lineNormalizer =builder .lineNormalizer ;
175182processDiffs =builder .processDiffs ;
@@ -254,15 +261,15 @@ private DiffRow buildDiffRow(Tag type, String orgline, String newline) {
254261String wrapOrg =preprocessLine (orgline );
255262if (Tag .DELETE ==type ) {
256263if (mergeOriginalRevised ||showInlineDiffs ) {
257- wrapOrg =oldTag .apply (true ) +wrapOrg +oldTag .apply (false );
264+ wrapOrg =oldTag .apply (type , true ) +wrapOrg +oldTag .apply (type , false );
258265 }
259266 }
260267String wrapNew =preprocessLine (newline );
261268if (Tag .INSERT ==type ) {
262269if (mergeOriginalRevised ) {
263- wrapOrg =newTag .apply (true ) +wrapNew +newTag .apply (false );
270+ wrapOrg =newTag .apply (type , true ) +wrapNew +newTag .apply (type , false );
264271 }else if (showInlineDiffs ) {
265- wrapNew =newTag .apply (true ) +wrapNew +newTag .apply (false );
272+ wrapNew =newTag .apply (type , true ) +wrapNew +newTag .apply (type , false );
266273 }
267274 }
268275return new DiffRow (type ,wrapOrg ,wrapNew );
@@ -308,19 +315,19 @@ private List<DiffRow> generateInlineDiffs(AbstractDelta<String> delta) {
308315if (inlineDelta instanceof DeleteDelta ) {
309316wrapInTag (origList ,inlineOrig .getPosition (),inlineOrig
310317 .getPosition ()
311- +inlineOrig .size (),oldTag ,processDiffs );
318+ +inlineOrig .size (),Tag . DELETE , oldTag ,processDiffs );
312319 }else if (inlineDelta instanceof InsertDelta ) {
313320if (mergeOriginalRevised ) {
314321origList .addAll (inlineOrig .getPosition (),
315322revList .subList (inlineRev .getPosition (),
316323inlineRev .getPosition () +inlineRev .size ()));
317324wrapInTag (origList ,inlineOrig .getPosition (),
318325inlineOrig .getPosition () +inlineRev .size (),
319- newTag ,processDiffs );
326+ Tag . INSERT , newTag ,processDiffs );
320327 }else {
321328wrapInTag (revList ,inlineRev .getPosition (),
322329inlineRev .getPosition () +inlineRev .size (),
323- newTag ,processDiffs );
330+ Tag . INSERT , newTag ,processDiffs );
324331 }
325332 }else if (inlineDelta instanceof ChangeDelta ) {
326333if (mergeOriginalRevised ) {
@@ -329,15 +336,15 @@ private List<DiffRow> generateInlineDiffs(AbstractDelta<String> delta) {
329336inlineRev .getPosition () +inlineRev .size ()));
330337wrapInTag (origList ,inlineOrig .getPosition () +inlineOrig .size (),
331338inlineOrig .getPosition () +inlineOrig .size () +inlineRev .size (),
332- newTag ,processDiffs );
339+ Tag . CHANGE , newTag ,processDiffs );
333340 }else {
334341wrapInTag (revList ,inlineRev .getPosition (),
335342inlineRev .getPosition () +inlineRev .size (),
336- newTag ,processDiffs );
343+ Tag . CHANGE , newTag ,processDiffs );
337344 }
338345wrapInTag (origList ,inlineOrig .getPosition (),
339346inlineOrig .getPosition () +inlineOrig .size (),
340- oldTag ,processDiffs );
347+ Tag . CHANGE , oldTag ,processDiffs );
341348 }
342349 }
343350StringBuilder origResult =new StringBuilder ();
@@ -380,15 +387,18 @@ public static class Builder {
380387private boolean showInlineDiffs =false ;
381388private boolean ignoreWhiteSpaces =false ;
382389
383- private Function <Boolean ,String >oldTag =f ->f ?"<span class=\" editOldInline\" >" :"</span>" ;
384- private Function <Boolean ,String >newTag =f ->f ?"<span class=\" editNewInline\" >" :"</span>" ;
390+ private BiFunction <Tag ,Boolean ,String >oldTag =
391+ (tag ,f ) ->f ?"<span class=\" editOldInline\" >" :"</span>" ;
392+ private BiFunction <Tag ,Boolean ,String >newTag =
393+ (tag ,f ) ->f ?"<span class=\" editNewInline\" >" :"</span>" ;
385394
386395private int columnWidth =0 ;
387396private boolean mergeOriginalRevised =false ;
388397private boolean reportLinesUnchanged =false ;
389398private Function <String ,List <String >>inlineDiffSplitter =SPLITTER_BY_CHARACTER ;
390399private Function <String ,String >lineNormalizer =LINE_NORMALIZER_FOR_HTML ;
391400private Function <String ,String >processDiffs =null ;
401+ private BiPredicate <String ,String >equalizer =null ;
392402
393403private Builder () {
394404 }
@@ -433,21 +443,43 @@ public Builder reportLinesUnchanged(final boolean val) {
433443 * @param generator the tag generator
434444 * @return builder with configured ignoreBlankLines parameter
435445 */
436- public Builder oldTag (Function < Boolean ,String >generator ) {
446+ public Builder oldTag (BiFunction < Tag , Boolean ,String >generator ) {
437447this .oldTag =generator ;
438448return this ;
439449 }
450+
451+ /**
452+ * Generator for Old-Text-Tags.
453+ *
454+ * @param generator the tag generator
455+ * @return builder with configured ignoreBlankLines parameter
456+ */
457+ public Builder oldTag (Function <Boolean ,String >generator ) {
458+ this .oldTag = (tag ,f ) ->generator .apply (f );
459+ return this ;
460+ }
440461
441462/**
442463 * Generator for New-Text-Tags.
443464 *
444465 * @param generator
445466 * @return
446467 */
447- public Builder newTag (Function < Boolean ,String >generator ) {
468+ public Builder newTag (BiFunction < Tag , Boolean ,String >generator ) {
448469this .newTag =generator ;
449470return this ;
450471 }
472+
473+ /**
474+ * Generator for New-Text-Tags.
475+ *
476+ * @param generator
477+ * @return
478+ */
479+ public Builder newTag (Function <Boolean ,String >generator ) {
480+ this .newTag = (tag ,f ) ->generator .apply (f );
481+ return this ;
482+ }
451483
452484/**
453485 * Processor for diffed text parts. Here e.g. whitecharacters could be replaced by something
@@ -534,5 +566,16 @@ public Builder lineNormalizer(Function<String, String> lineNormalizer) {
534566this .lineNormalizer =lineNormalizer ;
535567return this ;
536568 }
569+
570+ /**
571+ * Provide an equalizer for diff processing.
572+ *
573+ * @param equalizer equalizer for diff processing.
574+ * @return builder with configured equalizer parameter
575+ */
576+ public Builder equalizer (BiPredicate <String ,String >equalizer ) {
577+ this .equalizer =equalizer ;
578+ return this ;
579+ }
537580 }
538581}