packages feed

edits 0.1.0.1 → 0.1.1.0

raw patch · 5 files changed

+103/−61 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.Text.Difference: taggedDisplayEditOperation :: EditOperation Char -> Text
- Data.Text.Edits: taggedDisplayEditOperation :: EditOperation Char -> Text
+ Data.Text.Color: Black :: Color
+ Data.Text.Color: Blue :: Color
+ Data.Text.Color: Cyan :: Color
+ Data.Text.Color: Green :: Color
+ Data.Text.Color: Magenta :: Color
+ Data.Text.Color: Red :: Color
+ Data.Text.Color: White :: Color
+ Data.Text.Color: Yellow :: Color
+ Data.Text.Color: colorAs :: Color -> Text -> Text
+ Data.Text.Color: data Color
+ Data.Text.Color: instance GHC.Classes.Eq Data.Text.Color.Color
+ Data.Text.Color: instance GHC.Show.Show Data.Text.Color.Color
+ Data.Text.Difference: coloredDisplayEditOperation :: EditOperation Char -> Text
+ Data.Text.Edits: Black :: Color
+ Data.Text.Edits: Blue :: Color
+ Data.Text.Edits: Cyan :: Color
+ Data.Text.Edits: Green :: Color
+ Data.Text.Edits: Magenta :: Color
+ Data.Text.Edits: Red :: Color
+ Data.Text.Edits: White :: Color
+ Data.Text.Edits: Yellow :: Color
+ Data.Text.Edits: colorAs :: Color -> Text -> Text
+ Data.Text.Edits: coloredDisplayEditOperation :: EditOperation Char -> Text
+ Data.Text.Edits: data Color
+ Data.Text.Edits: levenshteinOperations :: Text -> Text -> [EditOperation Char]
+ Data.Text.Edits: showDistanceColored :: Text -> Text -> Text
+ Data.Text.Edits: showDistanceWith :: SplitSize -> DisplayOptions -> Text -> Text -> Text
- Data.Text.Edits: showDistance :: Text -> Text -> (Text, Text)
+ Data.Text.Edits: showDistance :: Text -> Text -> Text

Files

edits.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           edits-version:        0.1.0.1+version:        0.1.1.0 synopsis:       show the differences between 2 pieces of Text using the Levenshtein distance description:    This library computes the minimum number of edit operations 'insert', 'delete', 'substitute' which are necessary to transform a piece of text into another. It then displays the parts which are different in brackets. category:       Data@@ -20,6 +20,7 @@  library   exposed-modules:+      Data.Text.Color       Data.Text.Costs       Data.Text.Difference       Data.Text.EditMatrix
+ src/Data/Text/Color.hs view
@@ -0,0 +1,23 @@+{-|+  This module can color some Text to be displayed in a terminal+-}+module Data.Text.Color where++import Protolude++-- | Available ASCII colors+data Color =+  Black | Red | Green | Yellow | Blue | Magenta | Cyan | White deriving (Eq, Show)++-- | Surround a piece of text with ASCII control characters to color it+colorAs :: Color -> Text -> Text+colorAs c t =  "\x1b[" <> code c <> "m" <> t <> "\x1b[0m"+  where+    code Black = "30"+    code Red = "31"+    code Green = "32"+    code Yellow = "33"+    code Blue = "34"+    code Magenta = "35"+    code Cyan = "36"+    code White = "37"
src/Data/Text/Difference.hs view
@@ -4,6 +4,7 @@ module Data.Text.Difference where  import Data.Text qualified as T+import Data.Text.Color import Data.Text.EditOperation import Data.Text.Shorten import Data.Text.Token@@ -40,19 +41,19 @@ defaultDisplayOptions :: DisplayOptions defaultDisplayOptions = DisplayOptions bracketsSeparators (ShortenOptions 20 "...") defaultDisplayEditOperations --- | Default display for edit operations+-- | Display an edit operation by prepending a symbol showing which operation is used defaultDisplayEditOperations :: EditOperation Char -> Text-defaultDisplayEditOperations (Insert c) = T.singleton c-defaultDisplayEditOperations (Delete c) = T.singleton c-defaultDisplayEditOperations (Substitute c _) = T.singleton c+defaultDisplayEditOperations (Insert c) = "+" <> T.singleton c+defaultDisplayEditOperations (Delete c) = "-" <> T.singleton c+defaultDisplayEditOperations (Substitute c1 c2) = "~" <> T.singleton c1 <> "/" <> T.singleton c2 defaultDisplayEditOperations (Keep c) = T.singleton c --- | Display an edit operation by prepending a symbol showing which operation is used-taggedDisplayEditOperation :: EditOperation Char -> Text-taggedDisplayEditOperation (Insert c) = "+" <> T.singleton c-taggedDisplayEditOperation (Delete c) = "-" <> T.singleton c-taggedDisplayEditOperation (Substitute c1 c2) = "~" <> T.singleton c1 <> "/" <> T.singleton c2-taggedDisplayEditOperation (Keep c) = T.singleton c+-- | Display an edit operation using ascii colors: green = added, red = removed, blue = substituted+coloredDisplayEditOperation :: EditOperation Char -> Text+coloredDisplayEditOperation (Insert c) = colorAs Green (T.singleton c)+coloredDisplayEditOperation (Delete c) = colorAs Red (T.singleton c)+coloredDisplayEditOperation (Substitute c _) = colorAs Cyan (T.singleton c)+coloredDisplayEditOperation (Keep c) = T.singleton c  -- | Show the differences by enclosing them in separators --   Additionally shorten the text outside the separators if it is too long@@ -65,7 +66,7 @@               --  this allows us to open a 'start' delimiter               --  then when we go back to keeping the same character, we can close with an 'end' delimiter               case operation of-                Insert {} -> (True, res <> [Delimiter start | not different])+                Insert {} -> (True, res <> [Delimiter start | not different] <> [Kept $ displayEditOperation operation])                 Delete {} -> (True, res <> [Delimiter start | not different] <> [Kept $ displayEditOperation operation])                 Substitute {} -> (True, res <> [Delimiter start | not different] <> [Kept $ displayEditOperation operation])                 Keep {} -> (False, res <> [Delimiter end | different] <> [Kept $ displayEditOperation operation])
src/Data/Text/Edits.hs view
@@ -1,50 +1,53 @@ {-# LANGUAGE OverloadedLists #-} -{- |-  This module provides a 'showDistance' function showing the differences between 2 pieces of text-   using the Levenshtein distance. That distance is defined as the minimum number of edits: insertions, deletions, substitutions-   to go from one text to another.--   Several options are available to customize this processing:-     - split size: texts are broken into new lines first. Then if the texts are too large there are split into smaller pieces-       in order to compute their difference. This is done in order to reduce the size of the edit matrix which is used to compute all the edit costs-       the default is 200--     - separators: opening and closing pieces of text (brackets by default) used to highlight a difference--     - shorten size: there is the possibly to display mostly the differences with a bit of context around if the input text is too large.-       The text gets elided around separators if it gets greater than the shorten size (the default is 20)--     - shorten text: the text to use when eliding characters in the original text (the default is "...")--     - display edit operations: edit operations, insert/delete/substitute/keep can be annotated if necessary--Here are some examples:--@-import Data.Text.Edits---- "between the e and the n the letter i was added"-showDistance "kitten" "kittein" === ("kitte[]n", "kitte[i]n")---- "at the end of the text 3 letters have been deleted"-showDistance "kitten" "kit" === ("kit[ten]", "kit[]")---- "between the t and the n 2 letters have been modified"-showDistance "kitten" "kitsin" === ("kit[te]n", "kit[si]n" )-@---}+-- |+--  This module provides a 'showDistance' function showing the differences between 2 pieces of text+--   using the Levenshtein distance. That distance is defined as the minimum number of edits: insertions, deletions, substitutions+--   to go from one text to another.+--+--   Several options are available to customize this processing:+--     - split size: texts are broken into new lines first. Then if the texts are too large there are split into smaller pieces+--       in order to compute their difference. This is done in order to reduce the size of the edit matrix which is used to compute all the edit costs+--       the default is 200+--+--     - separators: opening and closing pieces of text (brackets by default) used to highlight a difference+--+--     - shorten size: there is the possibly to display mostly the differences with a bit of context around if the input text is too large.+--       The text gets elided around separators if it gets greater than the shorten size (the default is 20)+--+--     - shorten text: the text to use when eliding characters in the original text (the default is "...")+--+--     - display edit operations: edit operations, insert/delete/substitute/keep can be annotated if necessary+--+-- Here are some examples:+--+-- @+-- import Data.Text.Edits+--+-- -- "between the e and the n the letter i was added"+-- showDistance "kitten" "kittein" === "kitte[+i]n"+--+-- -- "at the end of the text 3 letters have been deleted"+-- showDistance "kitten" "kit" === "kit[-t-e-n]"+--+-- -- "between the t and the n 2 letters have been modified"+-- showDistance "kitten" "kitsin" === "kit[~t/s~e/i]"+-- @ module Data.Text.Edits   ( SplitSize (..),     ShortenOptions (..),     Separators (..),     DisplayOptions (..),     EditOperation (..),+    Color (..),+    colorAs,     showDistance,+    showDistanceColored,+    showDistanceWith,+    levenshteinOperations,     defaultDisplayOptions,     defaultDisplayEditOperations,-    taggedDisplayEditOperation,+    coloredDisplayEditOperation,     defaultSplitSize,     parensSeparators,     bracketsSeparators,@@ -53,6 +56,7 @@ where  import Data.Text qualified as T+import Data.Text.Color import Data.Text.Costs import Data.Text.Difference import Data.Text.EditMatrix@@ -69,16 +73,26 @@ defaultSplitSize = SplitSize 200  -- | Show the distance between 2 pieces of text-showDistance :: Text -> Text -> (Text, Text)+showDistance :: Text -> Text -> Text showDistance = showDistanceWith defaultSplitSize defaultDisplayOptions +-- | Show the distance between 2 pieces of text with colors instead of symbols+showDistanceColored :: Text -> Text -> Text+showDistanceColored = showDistanceWith defaultSplitSize defaultDisplayOptions {_displayEditOperation = coloredDisplayEditOperation}+ -- | Show the distance between 2 pieces of text and specify splitting / display options-showDistanceWith :: SplitSize -> DisplayOptions -> Text -> Text -> (Text, Text)+showDistanceWith :: SplitSize -> DisplayOptions -> Text -> Text -> Text showDistanceWith splitSize displayOptions ts1 ts2 =-  foldSplitTexts splitSize ts1 ts2 ([], []) $ \ts (line1, line2) -> do-    let matrix = createEditMatrix textLevenshteinCosts (toS line1) (toS line2)-    let operations = toList $ makeEditOperations (V.fromList . toS $ line1) (V.fromList . toS $ line2) matrix-    ts <> (displayDiffs displayOptions operations, displayDiffs displayOptions $ inverse <$> operations)+  foldSplitTexts splitSize ts1 ts2 [] $ \ts (line1, line2) -> do+    let operations = levenshteinOperations (toS line1) (toS line2)+    ts <> displayDiffs displayOptions operations++-- | Return the list of operations necessary to go from one piece of text to another+--   using the Levenshtein distance+levenshteinOperations :: Text -> Text -> [EditOperation Char]+levenshteinOperations t1 t2 = do+  let matrix = createEditMatrix textLevenshteinCosts (toS t1) (toS t2)+  toList $ makeEditOperations (V.fromList . toS $ t1) (V.fromList . toS $ t2) matrix  -- | Split texts and apply the difference on each part foldSplitTexts :: SplitSize -> Text -> Text -> a -> (a -> (Text, Text) -> a) -> a
test/Test/Data/Text/EditsSpec.hs view
@@ -4,10 +4,13 @@ import Protolude import Test.Tasty.Hedgehogx -test_show_distance = test "show the distance between different strings" $ do-  showDistance "kitte" "kittei" === ("kitte[]", "kitte[i]")-  showDistance "kitten" "kittein" === ("kitte[]n", "kitte[i]n")-  showDistance "kitten" "kit" === ("kit[ten]", "kit[]")-  showDistance "kit" "kitten" === ("kit[]", "kit[ten]")-  showDistance "kitten" "kitsin" === ("kit[te]n", "kit[si]n")-  showDistance "kitte" "kitte" === ("kitte", "kitte")+test_show_distance = test "show the distance between different texts" $ do+  showDistance "kitte" "kittei" === "kitte[+i]"+  showDistance "kitten" "kittein" === "kitte[+i]n"+  showDistance "kitten" "kit" === "kit[-t-e-n]"+  showDistance "kit" "kitten" === "kit[+t+e+n]"+  showDistance "kitten" "kitsin" === "kit[~t/s~e/i]n"+  showDistance "kitte" "kitte" === "kitte"++test_edit_operations = test "list the edit operations as a difference between 2 texts" $ do+  levenshteinOperations "kitte" "kittei" === [Keep 'k', Keep 'i', Keep 't', Keep 't', Keep 'e', Insert 'i']