{-# OPTIONS_HADDOCK hide #-} -- | Defines Typo data structure and related utilities. Typo data carries the -- information of a typo. module Language.Hanspell.Typo ( Typo(..) , fixTyposWithStyle , typoToStringWithStyle , rmdupTypos ) where import Data.Ord import Data.List import Data.List.Split -- | Carries the information of a typo. data Typo = Typo { errorType :: String , token :: String , suggestions :: [String] , context :: String , info :: String } deriving (Show, Eq, Ord) -- If given @True@, makes console text style reversed. reversed :: Bool -> String -> String reversed isTTY text = if isTTY then "\x1b[7m" ++ text ++ "\x1b[0m" else text -- If given @True@, makes console text style grey. grey :: Bool -> String -> String grey isTTY text = if isTTY then "\x1b[90m" ++ text ++ "\x1b[0m" else text -- | Fixes typos of given sentences. If given @True@, the colors of fixed -- words are inverted. fixTyposWithStyle :: Bool -> String -> [Typo] -> String fixTyposWithStyle isTTY = foldl' (fixTypo isTTY) where replace from to = intercalate to . splitOn from fixTypo :: Bool -> String -> Typo -> String fixTypo isTTY text aTypo = let aSuggestion = head (suggestions aTypo) in if aSuggestion == token aTypo then text else replace (token aTypo) (reversed isTTY aSuggestion) text -- | Converts a 'Typo' to string. If given @True@, 'info' of the 'Typo' is -- greyed out. typoToStringWithStyle :: Bool -> Typo -> String typoToStringWithStyle isTTY typo = token typo ++ grey isTTY " -> " ++ intercalate (grey isTTY ", ") (suggestions typo) ++ "\n" ++ grey isTTY (info typo) -- | Removes the 'Typo's whose 'token's are duplicated. Order preserving and -- O(nlogn). rmdupTypos :: [Typo] -> [Typo] rmdupTypos = map snd . sortBy compareOrder . map head . groupBy sameToken . sortBy compareToken . zip [1..] where sameToken (_, t) (_, t') = token t == token t' compareToken (_, t) (_, t') = compare (token t) (token t') compareOrder (n, _) (n', _) = compare n n'