diff --git a/demo/elm.json b/demo/elm.json index 3d2313f..3aabd5f 100644 --- a/demo/elm.json +++ b/demo/elm.json @@ -9,7 +9,8 @@ "elm/html": "1.0.0", "elm/json": "1.0.0", "elm/regex": "1.0.0", - "elm-community/list-extra": "8.0.0" + "elm-community/list-extra": "8.0.0", + "jinjor/elm-diff": "1.0.6" }, "indirect": { "elm/time": "1.0.0", diff --git a/elm.json b/elm.json index c831ac5..1e0a563 100644 --- a/elm.json +++ b/elm.json @@ -20,7 +20,8 @@ "elm/json": "1.0.0 <= v < 2.0.0", "elm/regex": "1.0.0 <= v < 2.0.0", "elm/svg": "1.0.0 <= v < 2.0.0", - "elm-community/list-extra": "8.0.0 <= v < 9.0.0" + "elm-community/list-extra": "8.0.0 <= v < 9.0.0", + "jinjor/elm-diff": "1.0.6 <= v < 2.0.0" }, "test-dependencies": { "elm-explorations/test": "1.2.0 <= v < 2.0.0" diff --git a/src/Diff.elm b/src/Diff.elm deleted file mode 100644 index 810a091..0000000 --- a/src/Diff.elm +++ /dev/null @@ -1,290 +0,0 @@ -module Diff exposing - ( Change(..) - , diffChars, diffLines - ) - -{-| NOTES: This is a copy of with an upgrade to Elm 0.18. -I need to copy it here since it's not upgraded to Elm 0.18 yet. -Replace this with package dependency once it's upgraded to Elm 0.18. -Functions to compare strings to produce a list of changes. This is an -implementation of the [Hunt-McIlroy](http://en.wikipedia.org/wiki/Hunt%E2%80%93McIlroy_algorithm) -diff algorithm. - - -# Types and Constructors - -@docs Change - - -# Diffing strings - -@docs diffChars, diffLines - --} - -import Debug -import Dict exposing (Dict) -import List -import Maybe -import String - - -{-| -} -type Change - = NoChange String - | Changed String String - | Added String - | Removed String - - -mergeAll : Change -> List Change -> List Change -mergeAll next list = - case ( next, list ) of - ( Added a, (Added b) :: rest ) -> - Added (a ++ b) :: rest - - ( Added a, (Removed b) :: rest ) -> - Changed b a :: rest - - ( Added a, (Changed b1 b2) :: rest ) -> - Changed b1 (a ++ b2) :: rest - - ( Removed a, (Removed b) :: rest ) -> - Removed (a ++ b) :: rest - - ( Removed a, (Added b) :: rest ) -> - Changed a b :: rest - - ( Removed a, (Changed b1 b2) :: rest ) -> - Changed (a ++ b1) b2 :: rest - - ( NoChange a, (NoChange b) :: rest ) -> - NoChange (a ++ b) :: rest - - ( Changed a1 a2, (Changed b1 b2) :: rest ) -> - Changed (a1 ++ b1) (a2 ++ b2) :: rest - - _ -> - next :: list - - -type alias Cell = - ( Int, List Change ) - - -type From - = UseBoth - | UseA - | UseB - - -score : Int -> Change -> Cell -> Cell -score add c ( s, cs ) = - ( s + add, c :: cs ) - - -scores : Maybe Cell -> Maybe Cell -> Maybe Cell -> ( From, Int, Change ) -> Maybe Cell -scores tl t l ( from, add, c ) = - (case from of - UseA -> - t - - UseB -> - l - - UseBoth -> - tl - ) - |> Maybe.map (score add c) - - -bestScore : Maybe Cell -> Maybe Cell -> Maybe Cell -bestScore ma mb = - case ( ma, mb ) of - ( m, Nothing ) -> - m - - ( Nothing, m ) -> - m - - ( Just ( sa, ca ), Just ( sb, cb ) ) -> - if sb > sa then - Just ( sb, cb ) - - else - Just ( sa, ca ) - - -orNoChange : Maybe Cell -> Cell -orNoChange c = - case c of - Just a -> - a - - _ -> - ( 0, [ NoChange "" ] ) - - -best : Maybe Cell -> Maybe Cell -> Maybe Cell -> String -> String -> Cell -best tl t l a b = - choices a b - |> List.map (scores tl t l) - |> List.foldl bestScore Nothing - |> orNoChange - - - --- should only happen if the grid as initialized incorrectly - - -choices : String -> String -> List ( From, Int, Change ) -choices a b = - if a == b then - [ ( UseA, 0, Removed a ) - , ( UseB, 0, Added b ) - , ( UseBoth, 1, NoChange a ) - ] - - else - [ ( UseA, 0, Removed a ) - , ( UseB, 0, Added b ) - , ( UseBoth, 0, Changed a b ) - ] - - -type alias State = - Dict ( Int, Int ) Cell - - -val : Int -> Int -> State -> Maybe Cell -val row col s = - Dict.get ( row, col ) s - - -calcCell : ( Int, String ) -> ( Int, String ) -> State -> State -calcCell ( row, a ) ( col, b ) s = - Dict.insert ( row, col ) - (best (val (row - 1) (col - 1) s) - (val (row - 1) col s) - (val row (col - 1) s) - a - b - ) - s - - -calcRow : List String -> ( Int, String ) -> State -> State -calcRow bs ( row, a ) d = - bs - |> List.indexedMap Tuple.pair - |> List.foldl (calcCell ( row, a )) d - - -initialGrid : List String -> List String -> State -initialGrid az bs = - Dict.singleton ( -1, -1 ) ( 0, [] ) - |> calcRow bs ( -1, "" ) - |> (\d -> List.foldl (\a -> calcCell a ( -1, "" )) d (az |> List.indexedMap Tuple.pair)) - - -calcGrid : List String -> List String -> State -calcGrid az bs = - az - |> List.indexedMap Tuple.pair - |> List.foldl (calcRow bs) (initialGrid az bs) - - -diff : (String -> List String) -> String -> String -> List Change -diff tokenize a b = - let - az = - tokenize a - - bs = - tokenize b - in - if az == [] then - List.map Added bs |> List.foldr mergeAll [] - - else if bs == [] then - List.map Removed az |> List.foldr mergeAll [] - - else - calcGrid az bs - |> Dict.get ( -1 + List.length az, -1 + List.length bs ) - |> Maybe.map (\( _, changes ) -> changes) - |> Maybe.withDefault [] - |> List.foldl mergeAll [] - - - --- rediff1 : (String -> List String) -> Change -> List Change --- rediff1 tokenize change = case change of --- Changed a b -> diff tokenize a b --- _ -> [change] --- --- rediff : (String -> List String) -> List Change -> List Change --- rediff tokenize input = input |> List.map (rediff1 tokenize) |> List.concat - - -{-| Diffs two strings, comparing character by charater. - - diffChars "abc" "aBcd" - == [ NoChange "a", Changed "b" "B", NoChange "c", Added "d" ] - --} -diffChars : String -> String -> List Change -diffChars = - diff (String.split "") - - -tokenizeLines : String -> List String -tokenizeLines s_ = - let - tokens = - String.split "\n" s_ - - n = - List.length tokens - in - if s_ == "" then - [] - - else - tokens - |> List.indexedMap - (\i s -> - if i < n - 1 then - s ++ "\n" - - else - s - ) - - -{-| Diffs two strings, comparing line by line. - - original = """Brian - Sohie - Oscar - Stella - Takis - """ - - changed = """BRIAN - Stella - Frosty - Takis - """ - - diffLines original changed - == [ Changed "Brian\nSohie\nOscar\n" "BRIAN\n" - , NoChange "Stella\n" - , Added "Frosty\n" - , NoChange "Takis\n" - ] - --} -diffLines : String -> String -> List Change -diffLines = - diff tokenizeLines diff --git a/src/MaskedInput/Pattern.elm b/src/MaskedInput/Pattern.elm index 8989fbd..4e8f8b2 100644 --- a/src/MaskedInput/Pattern.elm +++ b/src/MaskedInput/Pattern.elm @@ -189,7 +189,7 @@ adjust tokens adjustment previous current = |> foldPairs adjustment -splitChanges : List Diff.Change -> List Diff.Change +splitChanges : List (Diff.Change String) -> List (Diff.Change String) splitChanges changes = let splitString change str = @@ -207,16 +207,13 @@ splitChanges changes = Diff.Removed str -> splitString Diff.Removed str - - Diff.Changed _ str -> - splitString (Diff.Changed "") str in changes |> List.map split |> List.concat -isAdd : Diff.Change -> Bool +isAdd : Diff.Change String -> Bool isAdd change = case change of Diff.Added _ -> @@ -226,7 +223,7 @@ isAdd change = False -changesPairWithToken : List Token -> String -> String -> List ( Maybe Token, Diff.Change ) +changesPairWithToken : List Token -> String -> String -> List ( Maybe Token, Diff.Change String ) changesPairWithToken tokens previous current = let getToken index change = @@ -246,7 +243,7 @@ changesPairWithToken tokens previous current = getAt tokenIndex tokens splittedChanges = - Diff.diffChars previous current + Diff.diff (String.split "" previous) (String.split "" current) |> splitChanges totalChanges = @@ -274,7 +271,7 @@ changesPairWithToken tokens previous current = |> List.take (List.length tokens) -foldPairs : Adjustment -> List ( Maybe Token, Diff.Change ) -> String +foldPairs : Adjustment -> List ( Maybe Token, Diff.Change String ) -> String foldPairs adjustment pairs = let left = @@ -302,9 +299,6 @@ foldPairs adjustment pairs = ( Just (Other _), Diff.Added _ ) -> str - ( Just (Other _), Diff.Changed _ _ ) -> - str - ( Just (Other _), Diff.NoChange _ ) -> str @@ -314,9 +308,6 @@ foldPairs adjustment pairs = ( Just Input, Diff.Added s ) -> concat isLeft s str - ( Just Input, Diff.Changed _ s ) -> - concat isLeft s str - ( Just Input, Diff.NoChange s ) -> concat isLeft s str @@ -326,9 +317,6 @@ foldPairs adjustment pairs = ( Nothing, Diff.Added s ) -> concat isLeft s str - ( Nothing, Diff.Changed _ s ) -> - concat isLeft s str - ( Nothing, Diff.NoChange s ) -> concat isLeft s str in @@ -340,7 +328,7 @@ foldPairs adjustment pairs = right -changedString : Diff.Change -> String +changedString : Diff.Change String -> String changedString change = case change of Diff.NoChange str -> @@ -352,9 +340,6 @@ changedString change = Diff.Removed str -> str - Diff.Changed _ str -> - str - -- Helpers diff --git a/tests/PatternTests.elm b/tests/PatternTests.elm index 61e713d..dfdd5ee 100644 --- a/tests/PatternTests.elm +++ b/tests/PatternTests.elm @@ -186,7 +186,7 @@ splitChangesTest = describe "Pattern.splitChanges" [ test "Changes from (123) to (123A)" <| \() -> - Pattern.splitChanges (Diff.diffChars "(123)" "(123A)") + Pattern.splitChanges (Diff.diff (String.split "" "(123)") (String.split "" "(123A)")) |> Expect.equal [ Diff.NoChange "(" , Diff.NoChange "1" @@ -197,7 +197,7 @@ splitChangesTest = ] , test "Changes from (123) to (13)" <| \() -> - Pattern.splitChanges (Diff.diffChars "(123)" "(13)") + Pattern.splitChanges (Diff.diff (String.split "" "(123)") (String.split "" "(13)")) |> Expect.equal [ Diff.NoChange "(" , Diff.NoChange "1"