module Text.Show.Unicode (ushow, uprint, urecover, ushowWith, uprintWith, urecoverWith) where
import Prelude ()
import Test.Hspec.Core.Compat hiding (many, (<*>), (*>), (<*))
import Data.Char (isAscii, isPrint)
import Text.ParserCombinators.ReadP
import Text.Read.Lex (lexChar)
import qualified Data.List as L
infixl 4 <*
(<*) :: Monad m => m a -> m b -> m a
<* :: m a -> m b -> m a
(<*) = (m b -> m a -> m a) -> m a -> m b -> m a
forall a b c. (a -> b -> c) -> b -> a -> c
flip m b -> m a -> m a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>)
type Replacement = (String, String)
recoverChar :: (Char -> Bool) -> ReadP Replacement
recoverChar :: (Char -> Bool) -> ReadP Replacement
recoverChar Char -> Bool
p = (String, Char) -> Replacement
represent ((String, Char) -> Replacement)
-> ReadP (String, Char) -> ReadP Replacement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadP Char -> ReadP (String, Char)
forall a. ReadP a -> ReadP (String, a)
gather ReadP Char
lexCharAndConsumeEmpties
where
represent :: (String, Char) -> Replacement
represent :: (String, Char) -> Replacement
represent (String
o,Char
lc)
| Char -> Bool
p Char
lc =
if String -> Char
forall a. [a] -> a
head String
o Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\\' Bool -> Bool -> Bool
&&
String
"\\&" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`L.isSuffixOf` String
o
then (String
o, Char
lc Char -> String -> String
forall a. a -> [a] -> [a]
: String
"\\&")
else (String
o, [Char
lc])
| Bool
otherwise = (String
o, String
o)
lexCharAndConsumeEmpties :: ReadP Char
lexCharAndConsumeEmpties :: ReadP Char
lexCharAndConsumeEmpties = ReadP Char
lexChar ReadP Char -> ReadP () -> ReadP Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m a
<* ReadP ()
consumeEmpties
where
consumeEmpties :: ReadP ()
consumeEmpties :: ReadP ()
consumeEmpties = do
String
rest <- ReadP String
look
case String
rest of
(Char
'\\':Char
'&':String
_) -> String -> ReadP String
string String
"\\&" ReadP String -> ReadP () -> ReadP ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ReadP ()
consumeEmpties
String
_ -> () -> ReadP ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
ushow :: Show a => a -> String
ushow :: a -> String
ushow = (Char -> Bool) -> a -> String
forall a. Show a => (Char -> Bool) -> a -> String
ushowWith Char -> Bool
shouldRecover
urecover :: String -> String
urecover :: String -> String
urecover = (Char -> Bool) -> String -> String
urecoverWith Char -> Bool
shouldRecover
shouldRecover :: Char -> Bool
shouldRecover :: Char -> Bool
shouldRecover Char
c = Char -> Bool
isPrint Char
c Bool -> Bool -> Bool
&& Bool -> Bool
not (Char -> Bool
isAscii Char
c)
uprint :: Show a => a -> IO ()
uprint :: a -> IO ()
uprint = String -> IO ()
putStrLn (String -> IO ()) -> (a -> String) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
ushow
ushowWith :: Show a => (Char -> Bool) -> a -> String
ushowWith :: (Char -> Bool) -> a -> String
ushowWith Char -> Bool
p = (Char -> Bool) -> String -> String
urecoverWith Char -> Bool
p (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show
urecoverWith :: (Char -> Bool) -> String -> String
urecoverWith :: (Char -> Bool) -> String -> String
urecoverWith Char -> Bool
p = Replacement -> [([Replacement], String)] -> String
go (String
"", String
"") ([([Replacement], String)] -> String)
-> (String -> [([Replacement], String)]) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReadP [Replacement] -> String -> [([Replacement], String)]
forall a. ReadP a -> ReadS a
readP_to_S (ReadP Replacement -> ReadP [Replacement]
forall a. ReadP a -> ReadP [a]
many (ReadP Replacement -> ReadP [Replacement])
-> ReadP Replacement -> ReadP [Replacement]
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> ReadP Replacement
recoverChar Char -> Bool
p)
where
go :: Replacement -> [([Replacement], String)] -> String
go :: Replacement -> [([Replacement], String)] -> String
go Replacement
_ [] = String
""
go Replacement
_ (([],String
""):[([Replacement], String)]
_) = String
""
go Replacement
_ (([Replacement]
rs,String
""):[([Replacement], String)]
_) = Replacement -> String
forall a b. (a, b) -> b
snd (Replacement -> String) -> Replacement -> String
forall a b. (a -> b) -> a -> b
$ [Replacement] -> Replacement
forall a. [a] -> a
last [Replacement]
rs
go Replacement
_ [([Replacement]
_,String
o)] = String
o
go Replacement
pr (([],String
_):[([Replacement], String)]
rest) = Replacement -> [([Replacement], String)] -> String
go Replacement
pr [([Replacement], String)]
rest
go Replacement
_ (([Replacement]
rs,String
_):[([Replacement], String)]
rest) = let r :: Replacement
r = [Replacement] -> Replacement
forall a. [a] -> a
last [Replacement]
rs in Replacement -> String
forall a b. (a, b) -> b
snd Replacement
r String -> String -> String
forall a. [a] -> [a] -> [a]
++ Replacement -> [([Replacement], String)] -> String
go Replacement
r [([Replacement], String)]
rest
uprintWith :: Show a => (Char -> Bool) -> a -> IO ()
uprintWith :: (Char -> Bool) -> a -> IO ()
uprintWith Char -> Bool
p = String -> IO ()
putStrLn (String -> IO ()) -> (a -> String) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> a -> String
forall a. Show a => (Char -> Bool) -> a -> String
ushowWith Char -> Bool
p