diff --git a/Diff.cabal b/Diff.cabal index 74bb759..b0c5f82 100644 --- a/Diff.cabal +++ b/Diff.cabal @@ -1,8 +1,12 @@ name: Diff version: 0.5 -synopsis: O(ND) diff algorithm in haskell. -description: Implementation of the standard diff algorithm, and utilities for pretty printing. +synopsis: Diff algorithm in pure Haskell +description: Implementation of the standard diff algorithm in Haskell. + . + Time complexity is O(ND) (input length * number of differences). + Space complexity is O(D^2). Includes utilities for pretty printing. category: Algorithms +homepage: https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 license: BSD3 license-file: LICENSE author: Sterling Clover diff --git a/src/Data/Algorithm/Diff.hs b/src/Data/Algorithm/Diff.hs index e025166..22eb1b3 100644 --- a/src/Data/Algorithm/Diff.hs +++ b/src/Data/Algorithm/Diff.hs @@ -8,7 +8,7 @@ -- Portability : portable -- -- This is an implementation of the diff algorithm as described in --- \"An \( O(ND) \) Difference Algorithm and Its Variations (1986)\" +-- /An \( O(ND) \) Difference Algorithm and Its Variations (1986)/ -- . -- For inputs of size \( O(N) \) with the number of differences \( D \) -- it has \( O(ND) \) time and \( O(D^2) \) space complexity. @@ -92,11 +92,19 @@ lcs eq as bs = path . head . dropWhile (\dl -> poi dl /= lena || poj dl /= lenb) -- | Takes two lists and returns a list of differences between them. This is -- 'getDiffBy' with '==' used as predicate. +-- +-- > > getDiff ["a","b","c","d","e"] ["a","c","d","f"] +-- > [Both "a" "a",First "b",Both "c" "c",Both "d" "d",First "e",Second "f"] +-- > > getDiff "abcde" "acdf" +-- > [Both 'a' 'a',First 'b',Both 'c' 'c',Both 'd' 'd',First 'e',Second 'f'] getDiff :: (Eq a) => [a] -> [a] -> [Diff a] getDiff = getDiffBy (==) -- | Takes two lists and returns a list of differences between them, grouped -- into chunks. This is 'getGroupedDiffBy' with '==' used as predicate. +-- +-- > > getGroupedDiff "abcde" "acdf" +-- > [Both "a" "a",First "b",Both "cd" "cd",First "e",Second "f"] getGroupedDiff :: (Eq a) => [a] -> [a] -> [Diff [a]] getGroupedDiff = getGroupedDiffBy (==) diff --git a/src/Data/Algorithm/DiffContext.hs b/src/Data/Algorithm/DiffContext.hs index 9458dc5..4a670a1 100644 --- a/src/Data/Algorithm/DiffContext.hs +++ b/src/Data/Algorithm/DiffContext.hs @@ -38,34 +38,36 @@ groupBy' eq (x : xs) = go [x] xs -- This new one corrects the issue. Here is the example from the test -- suite: -- --- > prettyContextDiff (text "file1") (text "file2") text (getContextDiffOld 2 (lines textA) (lines textB)) --- --- file1 --- +++ file2 --- @@ --- a --- b --- -c --- @@ --- d --- e --- @@ --- i --- j --- -k --- --- > prettyContextDiff (text "file1") (text "file2") text (getContextDiff 2 (lines textA) (lines textB)) --- --- file1 --- +++ file2 --- @@ --- a --- b --- -c --- d --- e --- @@ --- i --- j --- -k +-- > > let textA = unlines ["a","b","c","d","e","f","g","h","i","j","k"] +-- > > let textB = unlines ["a","b","d","e","f","g","h","i","j"] +-- > > prettyContextDiff (text "file1") (text "file2") text (getContextDiffOld 2 (lines textA) (lines textB)) +-- > --- file1 +-- > +++ file2 +-- > @@ +-- > a +-- > b +-- > -c +-- > @@ +-- > d +-- > e +-- > @@ +-- > i +-- > j +-- > -k +-- > +-- > > prettyContextDiff (text "file1") (text "file2") text (getContextDiff 2 (lines textA) (lines textB)) +-- > --- file1 +-- > +++ file2 +-- > @@ +-- > a +-- > b +-- > -c +-- > d +-- > e +-- > @@ +-- > i +-- > j +-- > -k getContextDiffNew :: Eq a => Maybe Int -- ^ Number of context elements, Nothing means infinite diff --git a/src/Data/Algorithm/DiffOutput.hs b/src/Data/Algorithm/DiffOutput.hs index b9d39c9..b10834a 100644 --- a/src/Data/Algorithm/DiffOutput.hs +++ b/src/Data/Algorithm/DiffOutput.hs @@ -45,6 +45,14 @@ diffToLineRanges = toLineRange 1 1 : toLineRange (leftLine+linesF) (rightLine+linesS) rs -- | pretty print the differences. The output is similar to the output of the diff utility +-- +-- > > putStr (ppDiff (getGroupedDiff ["a","b","c","d","e"] ["a","c","d","f"])) +-- > 2d1 +-- > < b +-- > 5c4 +-- > < e +-- > --- +-- > > f ppDiff :: [Diff [String]] -> String ppDiff gdiff = let diffLineRanges = diffToLineRanges gdiff