Skip to content

Commit 6b5947f

Browse files
Merge pull request #1 from benoitpflieger/proposal/issue-52
Customize text/DiffRowGenerator with algorithm and equalizer
2 parents 156f4f2 + 7cc8b4d commit 6b5947f

2 files changed

Lines changed: 47 additions & 29 deletions

File tree

src/main/java/com/github/difflib/text/DiffRowGenerator.java

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.github.difflib.patch.Patch;
2626
import com.github.difflib.text.DiffRow.Tag;
2727
import java.util.*;
28+
import java.util.function.BiFunction;
2829
import java.util.function.BiPredicate;
2930
import java.util.function.Function;
3031
import java.util.regex.Matcher;
@@ -106,7 +107,7 @@ protected final static List<String> splitStringPreserveDelimiter(String str, Pat
106107
* @param tagGenerator the tag generator
107108
*/
108109
static void wrapInTag(List<String> sequence, int startPosition,
109-
int endPosition, Function<Boolean, String> tagGenerator) {
110+
int endPosition, BiFunction<Tag, Boolean, String> tagGenerator) {
110111
int endPos = endPosition;
111112

112113
while (endPos >= startPosition) {
@@ -123,7 +124,7 @@ static void wrapInTag(List<String> sequence, int startPosition,
123124
break;
124125
}
125126

126-
sequence.add(endPos, tagGenerator.apply(false));
127+
sequence.add(endPos, tagGenerator.apply(null, false));
127128
endPos--;
128129

129130
//search position for end tag
@@ -134,7 +135,7 @@ static void wrapInTag(List<String> sequence, int startPosition,
134135
endPos--;
135136
}
136137

137-
sequence.add(endPos, tagGenerator.apply(true));
138+
sequence.add(endPos, tagGenerator.apply(null, true));
138139
endPos--;
139140
}
140141

@@ -146,8 +147,8 @@ static void wrapInTag(List<String> sequence, int startPosition,
146147
private final boolean ignoreWhiteSpaces;
147148
private final Function<String, List<String>> inlineDiffSplitter;
148149
private final boolean mergeOriginalRevised;
149-
private final Function<Boolean, String> newTag;
150-
private final Function<Boolean, String> oldTag;
150+
private final BiFunction<Tag, Boolean, String> newTag;
151+
private final BiFunction<Tag, Boolean, String> oldTag;
151152
private final boolean reportLinesUnchanged;
152153
private final Function<String, String> lineNormalizer;
153154

@@ -161,7 +162,11 @@ private DiffRowGenerator(Builder builder) {
161162
columnWidth = builder.columnWidth;
162163
mergeOriginalRevised = builder.mergeOriginalRevised;
163164
inlineDiffSplitter = builder.inlineDiffSplitter;
164-
equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER;
165+
if (Objects.nonNull(builder.equalizer)) {
166+
equalizer = builder.equalizer;
167+
} else {
168+
equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER;
169+
}
165170
reportLinesUnchanged = builder.reportLinesUnchanged;
166171
lineNormalizer = builder.lineNormalizer;
167172

@@ -245,15 +250,15 @@ private DiffRow buildDiffRow(Tag type, String orgline, String newline) {
245250
String wrapOrg = preprocessLine(orgline);
246251
if (Tag.DELETE == type) {
247252
if (mergeOriginalRevised || showInlineDiffs) {
248-
wrapOrg = oldTag.apply(true) + wrapOrg + oldTag.apply(false);
253+
wrapOrg = oldTag.apply(type, true) + wrapOrg + oldTag.apply(type, false);
249254
}
250255
}
251256
String wrapNew = preprocessLine(newline);
252257
if (Tag.INSERT == type) {
253258
if (mergeOriginalRevised) {
254-
wrapOrg = newTag.apply(true) + wrapNew + newTag.apply(false);
259+
wrapOrg = newTag.apply(type, true) + wrapNew + newTag.apply(type, false);
255260
} else if (showInlineDiffs) {
256-
wrapNew = newTag.apply(true) + wrapNew + newTag.apply(false);
261+
wrapNew = newTag.apply(type, true) + wrapNew + newTag.apply(type, false);
257262
}
258263
}
259264
return new DiffRow(type, wrapOrg, wrapNew);
@@ -367,15 +372,17 @@ public static class Builder {
367372
private boolean showInlineDiffs = false;
368373
private boolean ignoreWhiteSpaces = false;
369374

370-
private Function<Boolean, String> oldTag = f -> f ? "<span class=\"editOldInline\">" : "</span>";
371-
private Function<Boolean, String> newTag = f -> f ? "<span class=\"editNewInline\">" : "</span>";
375+
private BiFunction<Tag, Boolean, String> oldTag = (tag, isStart) -> isStart ? "<span class=\"editOldInline\">" : "</span>";
376+
private BiFunction<Tag, Boolean, String> newTag = (tag, isStart) -> isStart ? "<span class=\"editNewInline\">" : "</span>";
372377

373378
private int columnWidth = 0;
374379
private boolean mergeOriginalRevised = false;
375380
private boolean reportLinesUnchanged = false;
376381
private Function<String, List<String>> inlineDiffSplitter = SPLITTER_BY_CHARACTER;
377382
private Function<String, String> lineNormalizer = LINE_NORMALIZER_FOR_HTML;
378383

384+
private BiPredicate<String, String> equalizer = null;
385+
379386
private Builder() {
380387
}
381388

@@ -419,7 +426,7 @@ public Builder reportLinesUnchanged(final boolean val) {
419426
* @param generator the tag generator
420427
* @return builder with configured ignoreBlankLines parameter
421428
*/
422-
public Builder oldTag(Function<Boolean, String> generator) {
429+
public Builder oldTag(BiFunction<Tag, Boolean, String> generator) {
423430
this.oldTag = generator;
424431
return this;
425432
}
@@ -430,7 +437,7 @@ public Builder oldTag(Function<Boolean, String> generator) {
430437
* @param generator
431438
* @return
432439
*/
433-
public Builder newTag(Function<Boolean, String> generator) {
440+
public Builder newTag(BiFunction<Tag, Boolean, String> generator) {
434441
this.newTag = generator;
435442
return this;
436443
}
@@ -505,5 +512,16 @@ public Builder lineNormalizer(Function<String, String> lineNormalizer) {
505512
this.lineNormalizer = lineNormalizer;
506513
return this;
507514
}
515+
516+
/**
517+
* Provide an equalizer for diff processing.
518+
*
519+
* @param val equalizer for diff processing.
520+
* @return builder with configured equalizer parameter
521+
*/
522+
public Builder equalizer(BiPredicate<String, String> val) {
523+
equalizer = val;
524+
return this;
525+
}
508526
}
509527
}

src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ public void testGeneratorExample1() throws DiffException {
225225
.showInlineDiffs(true)
226226
.mergeOriginalRevised(true)
227227
.inlineDiffByWord(true)
228-
.oldTag(f -> "~")
229-
.newTag(f -> "**")
228+
.oldTag((tag, isStart) -> "~")
229+
.newTag((tag, isStart) -> "**")
230230
.build();
231231
List<DiffRow> rows = generator.generateDiffRows(
232232
Arrays.asList("This is a test senctence."),
@@ -243,8 +243,8 @@ public void testGeneratorExample2() throws DiffException {
243243
DiffRowGenerator generator = DiffRowGenerator.create()
244244
.showInlineDiffs(true)
245245
.inlineDiffByWord(true)
246-
.oldTag(f -> "~")
247-
.newTag(f -> "**")
246+
.oldTag((tag, isStart) -> "~")
247+
.newTag((tag, isStart) -> "**")
248248
.build();
249249
List<DiffRow> rows = generator.generateDiffRows(
250250
Arrays.asList("This is a test senctence.", "This is the second line.", "And here is the finish."),
@@ -285,8 +285,8 @@ public void testGeneratorIssue14() throws DiffException {
285285
.showInlineDiffs(true)
286286
.mergeOriginalRevised(true)
287287
.inlineDiffBySplitter(line -> DiffRowGenerator.splitStringPreserveDelimiter(line, Pattern.compile(",")))
288-
.oldTag(f -> "~")
289-
.newTag(f -> "**")
288+
.oldTag((tag, isStart) -> "~")
289+
.newTag((tag, isStart) -> "**")
290290
.build();
291291
List<DiffRow> rows = generator.generateDiffRows(
292292
Arrays.asList("J. G. Feldstein, Chair"),
@@ -304,8 +304,8 @@ public void testGeneratorIssue15() throws DiffException, IOException {
304304
.showInlineDiffs(true) //show the ~ ~ and ** ** symbols on each difference
305305
.inlineDiffByWord(true) //show the ~ ~ and ** ** around each different word instead of each letter
306306
//.reportLinesUnchanged(true) //experiment
307-
.oldTag(f -> "~")
308-
.newTag(f -> "**")
307+
.oldTag((tag, isStart) -> "~")
308+
.newTag((tag, isStart) -> "**")
309309
.build();
310310

311311
List<String> listOne = Files.lines(new File("target/test-classes/mocks/issue15_1.txt").toPath())
@@ -332,8 +332,8 @@ public void testGeneratorIssue22() throws DiffException {
332332
DiffRowGenerator generator = DiffRowGenerator.create()
333333
.showInlineDiffs(true)
334334
.inlineDiffByWord(true)
335-
.oldTag(f -> "~")
336-
.newTag(f -> "**")
335+
.oldTag((tag, isStart) -> "~")
336+
.newTag((tag, isStart) -> "**")
337337
.build();
338338
String aa = "This is a test senctence.";
339339
String bb = "This is a test for diffutils.\nThis is the second line.";
@@ -356,8 +356,8 @@ public void testGeneratorIssue22_2() throws DiffException {
356356
DiffRowGenerator generator = DiffRowGenerator.create()
357357
.showInlineDiffs(true)
358358
.inlineDiffByWord(true)
359-
.oldTag(f -> "~")
360-
.newTag(f -> "**")
359+
.oldTag((tag, isStart) -> "~")
360+
.newTag((tag, isStart) -> "**")
361361
.build();
362362
String aa = "This is a test for diffutils.\nThis is the second line.";
363363
String bb = "This is a test senctence.";
@@ -374,8 +374,8 @@ public void testGeneratorIssue22_3() throws DiffException {
374374
DiffRowGenerator generator = DiffRowGenerator.create()
375375
.showInlineDiffs(true)
376376
.inlineDiffByWord(true)
377-
.oldTag(f -> "~")
378-
.newTag(f -> "**")
377+
.oldTag((tag, isStart) -> "~")
378+
.newTag((tag, isStart) -> "**")
379379
.build();
380380
String aa = "This is a test senctence.";
381381
String bb = "This is a test for diffutils.\nThis is the second line.\nAnd one more.";
@@ -411,8 +411,8 @@ public void testGenerationIssue44reportLinesUnchangedProblem() throws DiffExcept
411411
DiffRowGenerator generator = DiffRowGenerator.create()
412412
.showInlineDiffs(true)
413413
.reportLinesUnchanged(true)
414-
.oldTag(f -> "~~")
415-
.newTag(f -> "**")
414+
.oldTag((tag, isStart) -> "~~")
415+
.newTag((tag, isStart) -> "**")
416416
.build();
417417
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("<dt>To do</dt>"), Arrays.asList("<dt>Done</dt>"));
418418
assertEquals("[[CHANGE,<dt>~~T~~o~~ do~~</dt>,<dt>**D**o**ne**</dt>]]", rows.toString());

0 commit comments

Comments
 (0)