module Test.FitSpec.PrettyPrint
( beside
, above
, showTuple
, table
, columns
, showQuantity
, showEach
, headToUpper
)
where
import Data.List (intercalate,transpose,isSuffixOf)
import Data.Char (toUpper)
showQuantity :: Int -> String -> String
showQuantity :: Int -> String -> String
showQuantity Int
1 String
what = String
"1 " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
what
showQuantity Int
n String
what = Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
pluralize String
what
showEach :: Show a => String -> [a] -> String
showEach :: String -> [a] -> String
showEach String
what [a
x] = String
what String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
x
showEach String
what [a]
xs = String
"each of " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
pluralize String
what String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ((a -> String) -> [a] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map a -> String
forall a. Show a => a -> String
show ([a] -> [String]) -> [a] -> [String]
forall a b. (a -> b) -> a -> b
$ [a] -> [a]
forall a. [a] -> [a]
init [a]
xs)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" and "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show ([a] -> a
forall a. [a] -> a
last [a]
xs)
pluralize :: String -> String
pluralize :: String -> String
pluralize String
s | String
s String -> String -> Bool
`ew` String
"se" = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"s"
| String
s String -> String -> Bool
`ew` String
"n" = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"s"
| String
s String -> String -> Bool
`ew` String
"y" = String -> String
forall a. [a] -> [a]
init String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"ies"
| Bool
otherwise = String
s
where ew :: String -> String -> Bool
ew = (String -> String -> Bool) -> String -> String -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isSuffixOf
beside :: String -> String -> String
beside :: String -> String -> String
beside String
cs String
ds = [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (String -> String -> String) -> [String] -> [String] -> [String]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith String -> String -> String
forall a. [a] -> [a] -> [a]
(++) (Char -> [String] -> [String]
forall a. a -> [[a]] -> [[a]]
normalize Char
' ' [String]
css) [String]
dss
where [[String]
css,[String]
dss] = String -> [[String]] -> [[String]]
forall a. a -> [[a]] -> [[a]]
normalize String
"" [String -> [String]
lines String
cs,String -> [String]
lines String
ds]
above :: String -> String -> String
above :: String -> String -> String
above String
cs String
ds = if String -> Char
forall a. [a] -> a
last String
cs Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' Bool -> Bool -> Bool
|| String -> Char
forall a. [a] -> a
head String
ds Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n'
then String
cs String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ds
else String
cs String -> String -> String
forall a. [a] -> [a] -> [a]
++ Char
'\n'Char -> String -> String
forall a. a -> [a] -> [a]
:String
ds
showTuple :: [String] -> String
showTuple :: [String] -> String
showTuple [] = String
""
showTuple [String
s] = String
s
showTuple (String
s:[String]
ss) =
if (String -> Bool) -> [String] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Char
'\n' Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`) (String
sString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
ss)
then String
"( " String -> String -> String
`beside` String
s
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. [a] -> [a]
init ((String -> String) -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String
", " String -> String -> String
`beside`) [String]
ss)
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" )\n"
else String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"," (String
sString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
ss) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
table :: String -> [[String]] -> String
table :: String -> [[String]] -> String
table String
s [] = String
""
table String
s [[String]]
sss = [String] -> String
unlines
([String] -> String)
-> ([[String]] -> [String]) -> [[String]] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> String -> String
forall a. Eq a => a -> [a] -> [a]
removeTrailing Char
' ')
([String] -> [String])
-> ([[String]] -> [String]) -> [[String]] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> String) -> [[String]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
s)
([[String]] -> [String])
-> ([[String]] -> [[String]]) -> [[String]] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[String]] -> [[String]]
forall a. [[a]] -> [[a]]
transpose
([[String]] -> [[String]])
-> ([[String]] -> [[String]]) -> [[String]] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> [String]) -> [[String]] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> [String] -> [String]
forall a. a -> [[a]] -> [[a]]
normalize Char
' ')
([[String]] -> [[String]])
-> ([[String]] -> [[String]]) -> [[String]] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([[String]] -> [[String]] -> [[String]])
-> [[[String]]] -> [[String]]
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (([String] -> [String] -> [String])
-> [[String]] -> [[String]] -> [[String]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
(++))
([[[String]]] -> [[String]])
-> ([[String]] -> [[[String]]]) -> [[String]] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> [[String]]) -> [[String]] -> [[[String]]]
forall a b. (a -> b) -> [a] -> [b]
map (String -> [[String]] -> [[String]]
forall a. a -> [[a]] -> [[a]]
normalize String
"" ([[String]] -> [[String]])
-> ([String] -> [[String]]) -> [String] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> [String]) -> [String] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map String -> [String]
lines)
([[String]] -> [[[String]]])
-> ([[String]] -> [[String]]) -> [[String]] -> [[[String]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [[String]] -> [[String]]
forall a. a -> [[a]] -> [[a]]
normalize String
""
([[String]] -> String) -> [[String]] -> String
forall a b. (a -> b) -> a -> b
$ [[String]]
sss
columns :: String -> [String] -> String
columns :: String -> [String] -> String
columns String
s = [String] -> String
unlines
([String] -> String)
-> ([String] -> [String]) -> [String] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> String -> String
forall a. Eq a => a -> [a] -> [a]
removeTrailing Char
' ')
([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> String) -> [[String]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
s)
([[String]] -> [String])
-> ([String] -> [[String]]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[String]] -> [[String]]
forall a. [[a]] -> [[a]]
transpose
([[String]] -> [[String]])
-> ([String] -> [[String]]) -> [String] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([String] -> [String]) -> [[String]] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> [String] -> [String]
forall a. a -> [[a]] -> [[a]]
normalize Char
' ')
([[String]] -> [[String]])
-> ([String] -> [[String]]) -> [String] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [[String]] -> [[String]]
forall a. a -> [[a]] -> [[a]]
normalize String
""
([[String]] -> [[String]])
-> ([String] -> [[String]]) -> [String] -> [[String]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> [String]) -> [String] -> [[String]]
forall a b. (a -> b) -> [a] -> [b]
map String -> [String]
lines
fit :: a -> Int -> [a] -> [a]
fit :: a -> Int -> [a] -> [a]
fit a
x Int
n [a]
xs = [a]
xs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ Int -> a -> [a]
forall a. Int -> a -> [a]
replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs) a
x
normalize :: a -> [[a]] -> [[a]]
normalize :: a -> [[a]] -> [[a]]
normalize a
x [[a]]
xs = ([a] -> [a]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map (a
x a -> Int -> [a] -> [a]
forall a. a -> Int -> [a] -> [a]
`fit` [[a]] -> Int
forall a. [[a]] -> Int
maxLength [[a]]
xs) [[a]]
xs
maxLength :: [[a]] -> Int
maxLength :: [[a]] -> Int
maxLength = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Int] -> Int) -> ([[a]] -> [Int]) -> [[a]] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int
0Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:) ([Int] -> [Int]) -> ([[a]] -> [Int]) -> [[a]] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> Int) -> [[a]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
removeTrailing :: Eq a => a -> [a] -> [a]
removeTrailing :: a -> [a] -> [a]
removeTrailing a
x = [a] -> [a]
forall a. [a] -> [a]
reverse
([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (a -> a -> Bool
forall a. Eq a => a -> a -> Bool
==a
x)
([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. [a] -> [a]
reverse
headToUpper :: [Char] -> [Char]
headToUpper :: String -> String
headToUpper [] = []
headToUpper (Char
c:String
cs) = Char -> Char
toUpper Char
c Char -> String -> String
forall a. a -> [a] -> [a]
: String
cs