();
+ for (String line : list) {
+ result.add(wrapText(line, columnWidth));
+ }
+ return result;
+ }
+
+ /**
+ * Wrap the text with the given column width
+ * @param line the text
+ * @param columnWidth the given column
+ * @return the wrapped text
+ */
+ public static String wrapText(String line, int columnWidth) {
+ int lenght = line.length();
+ int delimiter = "
".length();
+ int widthIndex = columnWidth;
+
+ for (int count = 0; lenght > widthIndex; count++) {
+ line = line.subSequence(0, widthIndex + delimiter * count) + "
"
+ + line.substring(widthIndex + delimiter * count);
+ widthIndex += columnWidth;
+ }
+
+ return line;
+ }
}
diff --git a/src/difflib/myers/DiffException.java b/src/difflib/myers/DiffException.java
index 7c78adf..d3802ff 100644
--- a/src/difflib/myers/DiffException.java
+++ b/src/difflib/myers/DiffException.java
@@ -64,18 +64,14 @@
*
* @author Juanco Anez
*/
-public class DiffException extends Exception
-{
-
- private static final long serialVersionUID = 1L;
-
- public DiffException()
- {
+public class DiffException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public DiffException() {
}
-
- public DiffException(String msg)
- {
+
+ public DiffException(String msg) {
super(msg);
}
}
-
diff --git a/src/difflib/myers/DiffNode.java b/src/difflib/myers/DiffNode.java
index 92c3330..a2fb071 100644
--- a/src/difflib/myers/DiffNode.java
+++ b/src/difflib/myers/DiffNode.java
@@ -25,9 +25,7 @@
* @author Juanco Anez
*
*/
-public final class DiffNode
- extends PathNode
-{
+public final class DiffNode extends PathNode {
/**
* Constructs a DiffNode.
*
@@ -40,18 +38,16 @@ public final class DiffNode
* @param the position in the revised sequence
* @param prev the previous node in the path.
*/
- public DiffNode(int i, int j, PathNode prev)
- {
- super(i, j, (prev == null ? null : prev.previousSnake()) );
+ public DiffNode(int i, int j, PathNode prev) {
+ super(i, j, (prev == null ? null : prev.previousSnake()));
}
-
+
/**
* {@inheritDoc}
* @return false, always
*/
- public boolean isSnake()
- {
+ public boolean isSnake() {
return false;
}
-
+
}
\ No newline at end of file
diff --git a/src/difflib/myers/DifferentiationFailedException.java b/src/difflib/myers/DifferentiationFailedException.java
index 131a075..a1cdc16 100644
--- a/src/difflib/myers/DifferentiationFailedException.java
+++ b/src/difflib/myers/DifferentiationFailedException.java
@@ -67,17 +67,13 @@
* @see Diff
* @see DiffAlgorithm
*/
-public class DifferentiationFailedException extends DiffException
-{
- private static final long serialVersionUID = 1L;
-
- public DifferentiationFailedException()
- {
+public class DifferentiationFailedException extends DiffException {
+ private static final long serialVersionUID = 1L;
+
+ public DifferentiationFailedException() {
}
-
- public DifferentiationFailedException(String msg)
- {
+
+ public DifferentiationFailedException(String msg) {
super(msg);
}
}
-
diff --git a/src/difflib/myers/MyersDiff.java b/src/difflib/myers/MyersDiff.java
index 4130814..31605ed 100644
--- a/src/difflib/myers/MyersDiff.java
+++ b/src/difflib/myers/MyersDiff.java
@@ -57,10 +57,16 @@
package difflib.myers;
-import java.util.Arrays;
+import java.lang.reflect.Array;
import java.util.List;
-import difflib.*;
+import difflib.ChangeDelta;
+import difflib.Chunk;
+import difflib.DeleteDelta;
+import difflib.Delta;
+import difflib.DiffAlgorithm;
+import difflib.InsertDelta;
+import difflib.Patch;
/**
* A clean-room implementation of
@@ -71,25 +77,22 @@
*
* @author Juanco Anez
*/
-public class MyersDiff
- implements DiffAlgorithm
-{
+public class MyersDiff implements DiffAlgorithm {
/**
* Constructs an instance of the Myers differencing algorithm.
*/
- public MyersDiff()
- {
+ public MyersDiff() {
}
-
+
/**
* {@inheritDoc}
*
* Return empty diff if get the error while procession the difference.
*/
- @Override
- public Patch diff(List> original, List> revised) {
- return diff(original.toArray(), revised.toArray());
- }
+ @Override
+ public Patch diff(List> original, List> revised) {
+ return diff(original.toArray(), revised.toArray());
+ }
/**
* {@inheritDoc}
@@ -97,18 +100,17 @@ public Patch diff(List> original, List> revised) {
* Return empty diff if get the error while procession the difference.
*/
@Override
- public Patch diff(Object[] orig, Object[] rev)
- {
+ public Patch diff(Object[] orig, Object[] rev) {
PathNode path;
- try {
- path = buildPath(orig, rev);
- return buildRevision(path, orig, rev);
- } catch (DifferentiationFailedException e) {
- e.printStackTrace();
- }
+ try {
+ path = buildPath(orig, rev);
+ return buildRevision(path, orig, rev);
+ } catch (DifferentiationFailedException e) {
+ e.printStackTrace();
+ }
return new Patch();
}
-
+
/**
* Computes the minimum diffpath that expresses de differences
* between the original and revised sequences, according
@@ -120,76 +122,67 @@ public Patch diff(Object[] orig, Object[] rev)
* @throws DifferentiationFailedException if a diff path could not be found.
*/
public static PathNode buildPath(Object[] orig, Object[] rev)
- throws DifferentiationFailedException
- {
+ throws DifferentiationFailedException {
if (orig == null)
throw new IllegalArgumentException("original sequence is null");
if (rev == null)
throw new IllegalArgumentException("revised sequence is null");
-
+
// these are local constants
final int N = orig.length;
final int M = rev.length;
-
+
final int MAX = N + M + 1;
final int size = 1 + 2 * MAX;
final int middle = (size + 1) / 2;
final PathNode diagonal[] = new PathNode[size];
-
+
diagonal[middle + 1] = new Snake(0, -1, null);
- for (int d = 0; d < MAX; d++)
- {
- for (int k = -d; k <= d; k += 2)
- {
+ for (int d = 0; d < MAX; d++) {
+ for (int k = -d; k <= d; k += 2) {
final int kmiddle = middle + k;
final int kplus = kmiddle + 1;
final int kminus = kmiddle - 1;
PathNode prev = null;
-
+
int i;
- if ( (k == -d) ||
- (k != d && diagonal[kminus].i < diagonal[kplus].i))
- {
+ if ((k == -d) || (k != d && diagonal[kminus].i < diagonal[kplus].i)) {
i = diagonal[kplus].i;
prev = diagonal[kplus];
- }
- else
- {
+ } else {
i = diagonal[kminus].i + 1;
prev = diagonal[kminus];
}
-
+
diagonal[kminus] = null; // no longer used
-
+
int j = i - k;
-
+
PathNode node = new DiffNode(i, j, prev);
-
+
// orig and rev are zero-based
// but the algorithm is one-based
// that's why there's no +1 when indexing the sequences
- while (i < N && j < M && orig[i].equals(rev[j]))
- {
+ while (i < N && j < M && orig[i].equals(rev[j])) {
i++;
j++;
}
if (i > node.i)
node = new Snake(i, j, node);
-
+
diagonal[kmiddle] = node;
-
- if (i >= N && j >= M)
- {
+
+ if (i >= N && j >= M) {
return diagonal[kmiddle];
}
}
- diagonal[middle+d-1] = null;
-
+ diagonal[middle + d - 1] = null;
+
}
// According to Myers, this cannot happen
throw new DifferentiationFailedException("could not find a diff path");
}
-
+
/**
* Constructs a {@link Revision} from a difference path.
*
@@ -200,46 +193,67 @@ public static PathNode buildPath(Object[] orig, Object[] rev)
* @throws DifferentiationFailedException if a {@link Revision} could
* not be built from the given path.
*/
- public static Patch buildRevision(PathNode path, Object[] orig, Object[] rev)
- {
+ public static Patch buildRevision(PathNode path, Object[] orig, Object[] rev) {
if (path == null)
throw new IllegalArgumentException("path is null");
if (orig == null)
throw new IllegalArgumentException("original sequence is null");
if (rev == null)
throw new IllegalArgumentException("revised sequence is null");
-
+
Patch patch = new Patch();
if (path.isSnake())
path = path.prev;
- while (path != null && path.prev != null && path.prev.j >= 0)
- {
- if(path.isSnake())
- throw new IllegalStateException("bad diffpath: found snake when looking for diff");
+ while (path != null && path.prev != null && path.prev.j >= 0) {
+ if (path.isSnake())
+ throw new IllegalStateException("bad diffpath: found snake when looking for diff");
int i = path.i;
int j = path.j;
-
+
path = path.prev;
int ianchor = path.i;
int janchor = path.j;
- Chunk original = new Chunk(ianchor, i - ianchor, Arrays.copyOfRange(orig, ianchor, i));
- Chunk revised = new Chunk(janchor, j - janchor, Arrays.copyOfRange(rev, janchor, j));
+ Chunk original = new Chunk(ianchor, i - ianchor, copyOfRange(orig, ianchor, i));
+ Chunk revised = new Chunk(janchor, j - janchor, copyOfRange(rev, janchor, j));
Delta delta = null;
if (original.getSize() == 0 && revised.getSize() != 0) {
- delta = new InsertDelta(original, revised);
+ delta = new InsertDelta(original, revised);
} else if (original.getSize() > 0 && revised.getSize() == 0) {
- delta = new DeleteDelta(original, revised);
+ delta = new DeleteDelta(original, revised);
} else {
- delta = new ChangeDelta(original, revised);
+ delta = new ChangeDelta(original, revised);
}
-
patch.addDelta(delta);
if (path.isSnake())
path = path.prev;
}
return patch;
}
-
+
+ /**
+ * Copied here from JDK 1.6
+ */
+
+ @SuppressWarnings("unchecked")
+ public static T[] copyOfRange(T[] original, int from, int to) {
+ return copyOfRange(original, from, to, (Class) original.getClass());
+ }
+
+ /**
+ * Copied here from JDK 1.6
+ */
+ @SuppressWarnings("unchecked")
+ public static T[] copyOfRange(U[] original, int from, int to,
+ Class extends T[]> newType) {
+ int newLength = to - from;
+ if (newLength < 0)
+ throw new IllegalArgumentException(from + " > " + to);
+ T[] copy = ((Object) newType == (Object) Object[].class) ? (T[]) new Object[newLength]
+ : (T[]) Array.newInstance(newType.getComponentType(), newLength);
+ System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
+ return copy;
+ }
+
}
diff --git a/src/difflib/myers/PathNode.java b/src/difflib/myers/PathNode.java
index 4e98082..4ead5f2 100644
--- a/src/difflib/myers/PathNode.java
+++ b/src/difflib/myers/PathNode.java
@@ -67,34 +67,32 @@
* @see Snake
*
*/
-public abstract class PathNode
-{
+public abstract class PathNode {
/** Position in the original sequence. */
public final int i;
/** Position in the revised sequence. */
public final int j;
/** The previous node in the path. */
public final PathNode prev;
-
+
/**
* Concatenates a new path node with an existing diffpath.
* @param i The position in the original sequence for the new node.
* @param j The position in the revised sequence for the new node.
* @param prev The previous node in the path.
*/
- public PathNode(int i, int j, PathNode prev)
- {
+ public PathNode(int i, int j, PathNode prev) {
this.i = i;
this.j = j;
this.prev = prev;
}
-
+
/**
* Is this node a {@link Snake Snake node}?
* @return true if this is a {@link Snake Snake node}
*/
public abstract boolean isSnake();
-
+
/**
* Is this a bootstrap node?
*
@@ -102,11 +100,10 @@ public PathNode(int i, int j, PathNode prev)
* less than zero.
* @return tru if this is a bootstrap node.
*/
- public boolean isBootstrap()
- {
+ public boolean isBootstrap() {
return i < 0 || j < 0;
}
-
+
/**
* Skips sequences of {@link DiffNode DiffNodes} until a
* {@link Snake} or bootstrap node is found, or the end
@@ -115,24 +112,21 @@ public boolean isBootstrap()
* null
* if none found.
*/
- public final PathNode previousSnake()
- {
+ public final PathNode previousSnake() {
if (isBootstrap())
return null;
if (!isSnake() && prev != null)
return prev.previousSnake();
return this;
}
-
+
/**
* {@inheritDoc}
*/
- public String toString()
- {
+ public String toString() {
StringBuffer buf = new StringBuffer("[");
PathNode node = this;
- while (node != null)
- {
+ while (node != null) {
buf.append("(");
buf.append(Integer.toString(node.i));
buf.append(",");
diff --git a/src/difflib/myers/Snake.java b/src/difflib/myers/Snake.java
index b19b17e..452829b 100644
--- a/src/difflib/myers/Snake.java
+++ b/src/difflib/myers/Snake.java
@@ -70,9 +70,7 @@
* @author Juanco Anez
*
*/
-public final class Snake
- extends PathNode
-{
+public final class Snake extends PathNode {
/**
* Constructs a snake node.
*
@@ -80,18 +78,16 @@ public final class Snake
* @param the position in the revised sequence
* @param prev the previous node in the path.
*/
- public Snake(int i, int j, PathNode prev)
- {
+ public Snake(int i, int j, PathNode prev) {
super(i, j, prev);
}
-
+
/**
* {@inheritDoc}
* @return true always
*/
- public boolean isSnake()
- {
+ public boolean isSnake() {
return true;
}
-
+
}
\ No newline at end of file
diff --git a/test/mocks/one_delta_test_original.txt b/test/mocks/one_delta_test_original.txt
new file mode 100644
index 0000000..5d54330
--- /dev/null
+++ b/test/mocks/one_delta_test_original.txt
@@ -0,0 +1,54 @@
+
Esta é uma obra Online.
+
+Este texto é negrito
+Este texto é itálico
+Este texto está sublinhado
+Este texto está riscado
+Este texto está centralizado
+Este texto está alinhado a direita
+
+- Este texto está em uma lista numérica
+- Este texto está identado
+
+
+Este
+aqui é um link
+
+
+
,
+
+Página 1
+
+
+
+
+
+
+
+
+
+
+
+
+Página 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Página 3
+
\ No newline at end of file
diff --git a/test/mocks/one_delta_test_revised.txt b/test/mocks/one_delta_test_revised.txt
new file mode 100644
index 0000000..9197a73
--- /dev/null
+++ b/test/mocks/one_delta_test_revised.txt
@@ -0,0 +1,11 @@
+Revisão 3
Esta é uma obra
+Online.
Este texto é
+negrit
Este texto é itálico/p>
Este texto está
+sublinhado
Este texto está riscado agora não
+está mais
p style="text-align: left;">Este texto está
+centralizado nem este
Este texto
+está alinhado a direita
- Este texto está em uma
+lista numérica
Este aqui é um
+link
\ No newline at end of file
diff --git a/test/mocks/original.txt b/test/mocks/original.txt
new file mode 100644
index 0000000..479dca0
--- /dev/null
+++ b/test/mocks/original.txt
@@ -0,0 +1,174 @@
+/*
+ Copyright 2009 Dmitry Naumenko (dm.naumenko@gmail.com)
+
+ This file is part of Java Diff Utills Library.
+
+ Java Diff Utills Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Java Diff Utills Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Java Diff Utills Library. If not, see .
+*/
+package difflib;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import difflib.myers.*;
+
+/**
+ * Implements the difference and patching engine
+ *
+ * @author Dmitry Naumenko
+ * @version 0.4.1
+ */
+public class DiffUtils {
+ private static DiffAlgorithm defaultDiffAlgorithm = new MyersDiff();
+ private static Pattern unifiedDiffChunkRe =
+ Pattern.compile("@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@");
+
+ /**
+ * Compute the difference between the original and revised texts with default diff algorithm
+ *
+ * @param original the original text
+ * @param revised the revised text
+ * @return the patch describing the difference between the original and revised texts
+ */
+ public static Patch diff(List> original, List> revised) {
+ return DiffUtils.diff(original, revised, defaultDiffAlgorithm);
+ }
+
+ /**
+ * Compute the difference between the original and revised texts with given diff algorithm
+ *
+ * @param original the original text
+ * @param revised the revised text
+ * @param algorithm the given algorithm
+ * @return the patch describing the difference between the original and revised texts
+ */
+ public static Patch diff(List> original, List> revised, DiffAlgorithm algorithm) {
+ return algorithm.diff(original, revised);
+ }
+
+ /**
+ * Patch the original text with given patch
+ *
+ * @param original the original text
+ * @param patch the given patch
+ * @return the revised text
+ * @throws PatchFailedException if can't apply patch
+ */
+ public static List> patch(List> original, Patch patch) throws PatchFailedException {
+ return patch.applyTo(original);
+ }
+
+ /**
+ * Unpatch the revised text for a given patch
+ *
+ * @param revised the revised text
+ * @param patch the given patch
+ * @return the original text
+ */
+ public static List> unpatch(List> revised, Patch patch) {
+ return patch.restore(revised);
+ }
+
+ /**
+ * Parse the given text in unified format and creates the list of deltas for it.
+ *
+ * @param diff the text in unified format
+ * @return the patch with deltas.
+ */
+ public static Patch parseUnifiedDiff(List diff) {
+ boolean inPrelude = true;
+ List