@@ -107,7 +107,8 @@ protected final static List<String> splitStringPreserveDelimiter(String str, Pat
107107 * @param tagGenerator the tag generator
108108 */
109109static void wrapInTag (List <String >sequence ,int startPosition ,
110- int endPosition ,Function <Boolean ,String >tagGenerator ) {
110+ int endPosition ,Function <Boolean ,String >tagGenerator ,
111+ Function <String ,String >processDiffs ) {
111112int endPos =endPosition ;
112113
113114while (endPos >=startPosition ) {
@@ -125,23 +126,30 @@ static void wrapInTag(List<String> sequence, int startPosition,
125126 }
126127
127128sequence .add (endPos ,tagGenerator .apply (false ));
129+ if (processDiffs !=null ) {
130+ sequence .set (endPos -1 ,
131+ processDiffs .apply (sequence .get (endPos -1 )));
132+ }
128133endPos --;
129134
130135//search position for end tag
131136while (endPos >startPosition ) {
132137if ("\n " .equals (sequence .get (endPos -1 ))) {
133138break ;
134139 }
140+ if (processDiffs !=null ) {
141+ sequence .set (endPos -1 ,
142+ processDiffs .apply (sequence .get (endPos -1 )));
143+ }
135144endPos --;
136145 }
137146
138147sequence .add (endPos ,tagGenerator .apply (true ));
139148endPos --;
140149 }
141-
142- // sequence.add(endPosition, tagGenerator.apply(false));
143- // sequence.add(startPosition, tagGenerator.apply(true));
144150 }
151+
152+
145153private final int columnWidth ;
146154private final BiPredicate <String ,String >equalizer ;
147155private final boolean ignoreWhiteSpaces ;
@@ -151,6 +159,7 @@ static void wrapInTag(List<String> sequence, int startPosition,
151159private final Function <Boolean ,String >oldTag ;
152160private final boolean reportLinesUnchanged ;
153161private final Function <String ,String >lineNormalizer ;
162+ private final Function <String ,String >processDiffs ;
154163
155164private final boolean showInlineDiffs ;
156165
@@ -165,6 +174,7 @@ private DiffRowGenerator(Builder builder) {
165174equalizer =ignoreWhiteSpaces ?IGNORE_WHITESPACE_EQUALIZER :DEFAULT_EQUALIZER ;
166175reportLinesUnchanged =builder .reportLinesUnchanged ;
167176lineNormalizer =builder .lineNormalizer ;
177+ processDiffs =builder .processDiffs ;
168178
169179Objects .requireNonNull (inlineDiffSplitter );
170180Objects .requireNonNull (lineNormalizer );
@@ -178,7 +188,8 @@ private DiffRowGenerator(Builder builder) {
178188 * @param revised the revised text
179189 * @return the DiffRows between original and revised texts
180190 */
181- public List <DiffRow >generateDiffRows (List <String >original ,List <String >revised )throws DiffException {
191+ public List <DiffRow >generateDiffRows (List <String >original ,List <String >revised )
192+ throws DiffException {
182193return generateDiffRows (original ,DiffUtils .diff (original ,revised ,equalizer ));
183194 }
184195
@@ -190,7 +201,8 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
190201 * @param patch the given patch
191202 * @return the DiffRows between original and revised texts
192203 */
193- public List <DiffRow >generateDiffRows (final List <String >original ,Patch <String >patch )throws DiffException {
204+ public List <DiffRow >generateDiffRows (final List <String >original ,Patch <String >patch )
205+ throws DiffException {
194206List <DiffRow >diffRows =new ArrayList <>();
195207int endPos =0 ;
196208final List <AbstractDelta <String >>deltaList =patch .getDeltas ();
@@ -280,7 +292,8 @@ List<String> normalizeLines(List<String> list) {
280292 *
281293 * @param delta the given delta
282294 */
283- private List <DiffRow >generateInlineDiffs (AbstractDelta <String >delta )throws DiffException {
295+ private List <DiffRow >generateInlineDiffs (AbstractDelta <String >delta )
296+ throws DiffException {
284297List <String >orig =normalizeLines (delta .getSource ().getLines ());
285298List <String >rev =normalizeLines (delta .getTarget ().getLines ());
286299List <String >origList ;
@@ -300,32 +313,36 @@ private List<DiffRow> generateInlineDiffs(AbstractDelta<String> delta) throws Di
300313if (inlineDelta instanceof DeleteDelta ) {
301314wrapInTag (origList ,inlineOrig .getPosition (),inlineOrig
302315 .getPosition ()
303- +inlineOrig .size (),oldTag );
316+ +inlineOrig .size (),oldTag , processDiffs );
304317 }else if (inlineDelta instanceof InsertDelta ) {
305318if (mergeOriginalRevised ) {
306319origList .addAll (inlineOrig .getPosition (),
307- revList .subList (inlineRev .getPosition (),inlineRev .getPosition ()
308- +inlineRev .size ()));
309- wrapInTag (origList ,inlineOrig .getPosition (),inlineOrig .getPosition ()
310- +inlineRev .size (),newTag );
320+ revList .subList (inlineRev .getPosition (),
321+ inlineRev .getPosition () +inlineRev .size ()));
322+ wrapInTag (origList ,inlineOrig .getPosition (),
323+ inlineOrig .getPosition () +inlineRev .size (),
324+ newTag ,processDiffs );
311325 }else {
312- wrapInTag (revList ,inlineRev .getPosition (),inlineRev .getPosition ()
313- +inlineRev .size (),newTag );
326+ wrapInTag (revList ,inlineRev .getPosition (),
327+ inlineRev .getPosition () +inlineRev .size (),
328+ newTag ,processDiffs );
314329 }
315330 }else if (inlineDelta instanceof ChangeDelta ) {
316331if (mergeOriginalRevised ) {
317332origList .addAll (inlineOrig .getPosition () +inlineOrig .size (),
318- revList .subList (inlineRev .getPosition (),inlineRev .getPosition ()
319- +inlineRev .size ()));
320- wrapInTag (origList ,inlineOrig .getPosition () +inlineOrig .size (),inlineOrig .getPosition () +inlineOrig .size ()
321- +inlineRev .size (),newTag );
333+ revList .subList (inlineRev .getPosition (),
334+ inlineRev .getPosition () +inlineRev .size ()));
335+ wrapInTag (origList ,inlineOrig .getPosition () +inlineOrig .size (),
336+ inlineOrig .getPosition () +inlineOrig .size () +inlineRev .size (),
337+ newTag ,processDiffs );
322338 }else {
323- wrapInTag (revList ,inlineRev .getPosition (),inlineRev .getPosition ()
324- +inlineRev .size (),newTag );
339+ wrapInTag (revList ,inlineRev .getPosition (),
340+ inlineRev .getPosition () +inlineRev .size (),
341+ newTag ,processDiffs );
325342 }
326- wrapInTag (origList ,inlineOrig .getPosition (),inlineOrig
327- .getPosition ()
328- + inlineOrig . size (), oldTag );
343+ wrapInTag (origList ,inlineOrig .getPosition (),
344+ inlineOrig .getPosition () + inlineOrig . size (),
345+ oldTag , processDiffs );
329346 }
330347 }
331348StringBuilder origResult =new StringBuilder ();
@@ -376,6 +393,7 @@ public static class Builder {
376393private boolean reportLinesUnchanged =false ;
377394private Function <String ,List <String >>inlineDiffSplitter =SPLITTER_BY_CHARACTER ;
378395private Function <String ,String >lineNormalizer =LINE_NORMALIZER_FOR_HTML ;
396+ private Function <String ,String >processDiffs =null ;
379397
380398private Builder () {
381399 }
@@ -436,6 +454,18 @@ public Builder newTag(Function<Boolean, String> generator) {
436454return this ;
437455 }
438456
457+ /**
458+ * Processor for diffed text parts. Here e.g. whitecharacters could be replaced by something
459+ * visible.
460+ *
461+ * @param processDiffs
462+ * @return
463+ */
464+ public Builder processDiffs (Function <String ,String >processDiffs ) {
465+ this .processDiffs =processDiffs ;
466+ return this ;
467+ }
468+
439469/**
440470 * Set the column width of generated lines of original and revised texts.
441471 *