module Text.PercentFormat
( (%)
, (-%)
, (/%)
, (%%)
, (%%%)
, (%%%%)
, (%%%%%)
, (%%%%%%)
, (-%%)
, (-%%%)
, (-%%%%)
, (-%%%%%)
, (-%%%%%%)
, (+%)
)
where
import Data.Maybe (listToMaybe, fromMaybe)
import Data.Char (isDigit, toUpper)
import Text.PercentFormat.Spec as S
import Text.PercentFormat.Utils hiding (align)
import Text.PercentFormat.Quotient (maybeReadQ, digits, Quotient, infinity, nan)
import qualified Text.PercentFormat.Quotient as Q
import qualified Text.PercentFormat.Utils as U
import Prelude hiding (showString, showChar)
(%) :: Show a => String -> a -> String
(Char
'%':String
s) % :: forall a. Show a => String -> a -> String
% a
x =
case Spec -> SpecType
ty Spec
sp of
SpecType
Percent -> Char
'%'forall a. a -> [a] -> [a]
:Char
'%'forall a. a -> [a] -> [a]
: String
s' forall a. Show a => String -> a -> String
% a
x
SpecType
ReprSpec -> (String -> String
duplicatePercents forall a b. (a -> b) -> a -> b
$ forall a. Show a => Spec -> a -> String
showRepr Spec
sp a
x) forall a. [a] -> [a] -> [a]
++ String
s'
SpecType
StringSpec -> (String -> String
duplicatePercents forall a b. (a -> b) -> a -> b
$ forall a. Show a => Spec -> a -> String
showString Spec
sp a
x) forall a. [a] -> [a] -> [a]
++ String
s'
SpecType
CharSpec -> (String -> String
duplicatePercents forall a b. (a -> b) -> a -> b
$ forall a. Show a => Spec -> a -> String
showChar Spec
sp a
x) forall a. [a] -> [a] -> [a]
++ String
s'
SpecType
NumberSpec -> (String -> String
duplicatePercents forall a b. (a -> b) -> a -> b
$ forall a. Show a => Spec -> a -> String
showDigits Spec
sp a
x) forall a. [a] -> [a] -> [a]
++ String
s'
where
(Spec
sp,String
s') = String -> (Spec, String)
parseSpec String
s
(Char
c:String
s) % a
x = Char
c forall a. a -> [a] -> [a]
: String
s forall a. Show a => String -> a -> String
% a
x
String
"" % a
x = String
""
infixl 9 %
showRepr :: Show a => Spec -> a -> String
showRepr :: forall a. Show a => Spec -> a -> String
showRepr Spec
spec = Spec -> String -> String
align Spec
spec forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
showString :: Show a => Spec -> a -> String
showString :: forall a. Show a => Spec -> a -> String
showString Spec
spec a
s =
case forall a. Read a => String -> Maybe a
maybeRead (forall a. Show a => a -> String
show a
s) of
Maybe String
Nothing -> Spec -> String -> String
align Spec
spec (forall a. Show a => a -> String
show a
s)
Just String
s -> Spec -> String -> String
align Spec
spec String
s
showChar :: Show a => Spec -> a -> String
showChar :: forall a. Show a => Spec -> a -> String
showChar Spec
spec a
c =
case forall a. Read a => String -> Maybe a
maybeRead (forall a. Show a => a -> String
show a
c) of
Maybe Char
Nothing -> Char -> Spec -> String
err Char
'!' Spec
spec
Just Char
c -> Spec -> String -> String
align Spec
spec (Char
cforall a. a -> [a] -> [a]
:String
"")
showDigits :: Show a => Spec -> a -> String
showDigits :: forall a. Show a => Spec -> a -> String
showDigits Spec
spec a
x =
case String -> Maybe Quotient
maybeReadQ (forall a. Show a => a -> String
show a
x) of
Maybe Quotient
Nothing -> Char -> Spec -> String
err Char
'!' Spec
spec
Just Quotient
q -> forall a. Bool -> (a -> a) -> a -> a
applyWhen (Spec -> Char
padWith Spec
spec forall a. Eq a => a -> a -> Bool
/= Char
' ') (forall {a}. (Ord a, Num a) => a -> String
signal Quotient
q forall a. [a] -> [a] -> [a]
++)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Quotient -> String -> String
align' Quotient
q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Bool -> (a -> a) -> a -> a
applyWhen (Spec -> Char
padWith Spec
spec forall a. Eq a => a -> a -> Bool
== Char
' ') (forall {a}. (Ord a, Num a) => a -> String
signal Quotient
q forall a. [a] -> [a] -> [a]
++)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> a
id (\([Int]
ids,[Int]
fds,[Int]
pds) -> String -> String
capitalize forall a b. (a -> b) -> a -> b
$ [Int] -> [Int] -> [Int] -> Maybe Int -> String
showds [Int]
ids [Int]
fds [Int]
pds (Spec -> Maybe Int
precision Spec
spec))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Quotient -> Either String ([Int], [Int], [Int])
digits (Spec -> Int
base Spec
spec)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Maybe Int -> Quotient -> Quotient
round' (Spec -> Int
base Spec
spec) (Spec -> Maybe Int
precision Spec
spec)
forall a b. (a -> b) -> a -> b
$ Quotient
q
where
capitalize :: String -> String
capitalize = forall a. Bool -> (a -> a) -> a -> a
applyWhen (Spec -> Bool
capitalizeDigits Spec
spec) (forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toUpper)
signal :: a -> String
signal a
q | a
q forall a. Eq a => a -> a -> Bool
/= a
q = Spec -> String
positivePrefix Spec
spec
| a
q forall a. Ord a => a -> a -> Bool
>= a
0 = Spec -> String
positivePrefix Spec
spec
| a
q forall a. Ord a => a -> a -> Bool
< a
0 = String
"-"
align' :: Quotient -> String -> String
align' :: Quotient -> String -> String
align' Quotient
q = if Spec -> Char
padWith Spec
spec forall a. Eq a => a -> a -> Bool
== Char
' '
then Spec -> String -> String
align Spec
spec
else Spec -> String -> String
align Spec
spec{width :: Int
width = Spec -> Int
width Spec
spec forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length (forall {a}. (Ord a, Num a) => a -> String
signal Quotient
q)}
round' :: Int -> Maybe Int -> Quotient -> Quotient
round' :: Int -> Maybe Int -> Quotient -> Quotient
round' Int
_ Maybe Int
_ Quotient
q | Quotient -> Bool
Q.isInfinite Quotient
q = Quotient
q
round' Int
_ Maybe Int
_ Quotient
q | Quotient -> Bool
Q.isNaN Quotient
q = Quotient
q
round' Int
_ Maybe Int
Nothing Quotient
q = Quotient
q
round' Int
b (Just Int
p) Quotient
q = forall a b. (RealFrac a, Integral b) => a -> b
round (Quotient
q forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b forall a b. (Num a, Integral b) => a -> b -> a
^ Int
p) Integer -> Integer -> Quotient
Q.% forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b forall a b. (Num a, Integral b) => a -> b -> a
^ Int
p
showds :: [Int] -> [Int] -> [Int] -> Maybe Int -> String
showds :: [Int] -> [Int] -> [Int] -> Maybe Int -> String
showds [Int]
ids [Int]
fds [] Maybe Int
Nothing | forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
fds forall a. Ord a => a -> a -> Bool
< Spec -> Int
minPrecision Spec
spec
= [Int] -> [Int] -> [Int] -> Maybe Int -> String
showds [Int]
ids ([Int]
fds forall a. [a] -> [a] -> [a]
++ forall a. Int -> a -> [a]
replicate (Spec -> Int
minPrecision Spec
spec forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
fds) Int
0) [] forall a. Maybe a
Nothing
showds [Int]
ids [] [Int]
_ Maybe Int
Nothing = [Int] -> String
intsToDigits [Int]
ids
showds [Int]
ids [Int]
fds [Int]
pds (Just Int
0) = [Int] -> String
intsToDigits [Int]
ids
showds [Int]
ids [Int]
fds [Int]
pds Maybe Int
Nothing = [Int] -> String
intsToDigits [Int]
ids forall a. [a] -> [a] -> [a]
++ String
"."
forall a. [a] -> [a] -> [a]
++ [Int] -> String
intsToDigits [Int]
fds forall a. [a] -> [a] -> [a]
++ [Int] -> String
showPeriod [Int]
pds
showds [Int]
ids [Int]
fds [Int]
pds (Just Int
pr) = [Int] -> String
intsToDigits [Int]
ids forall a. [a] -> [a] -> [a]
++ String
"."
forall a. [a] -> [a] -> [a]
++ [Int] -> String
intsToDigits (forall a. Int -> [a] -> [a]
take Int
pr ([Int]
fds forall a. [a] -> [a] -> [a]
++ forall a. [a] -> [a]
loop [Int]
pds forall a. [a] -> [a] -> [a]
++ forall a. a -> [a]
repeat Int
0))
showPeriod :: [Int] -> String
showPeriod [] = String
""
showPeriod [Int]
xs = [Int] -> String
intsToDigits [Int]
xs
forall a. [a] -> [a] -> [a]
++ [Int] -> String
intsToDigits [Int]
xs
forall a. [a] -> [a] -> [a]
++ [Int] -> String
intsToDigits [Int]
xs
forall a. [a] -> [a] -> [a]
++ String
"..."
err :: Char -> Spec -> String
err :: Char -> Spec -> String
err Char
c Spec
spec = Spec -> String -> String
align Spec
spec{padWith :: Char
padWith=Char
c} (Char
cforall a. a -> [a] -> [a]
:String
"")
(-%) :: Show a => String -> a -> String
String
s -% :: forall a. Show a => String -> a -> String
-% a
x = String
s forall a. Show a => String -> a -> String
% a
x String -> Char -> String
/% Char
'?'
infixl 9 -%
(/%) :: String -> Char -> String
String
s /% :: String -> Char -> String
/% Char
errChar = String -> String
depercent String
s
where
depercent :: String -> String
depercent (Char
'%':String
s) = let (Spec
spec,String
s') = String -> (Spec, String)
parseSpec String
s
s'' :: String
s'' = case Spec -> SpecType
ty Spec
spec of
SpecType
Percent -> String
"%"
SpecType
_ -> Char -> Spec -> String
err Char
errChar Spec
spec
in String
s'' forall a. [a] -> [a] -> [a]
++ String -> String
depercent String
s'
depercent (Char
c:String
s) = Char
c forall a. a -> [a] -> [a]
: String -> String
depercent String
s
depercent String
"" = String
""
align :: Spec -> String -> String
align :: Spec -> String -> String
align Spec
spec = Bool -> Char -> Int -> String -> String
U.align (Spec -> Bool
S.leftAlign Spec
spec) (Spec -> Char
padWith Spec
spec) (Spec -> Int
width Spec
spec)
duplicatePercents :: String -> String
duplicatePercents :: String -> String
duplicatePercents (Char
'%':String
s) = Char
'%'forall a. a -> [a] -> [a]
:Char
'%'forall a. a -> [a] -> [a]
:String -> String
duplicatePercents String
s
duplicatePercents (Char
c:String
s) = Char
cforall a. a -> [a] -> [a]
:String -> String
duplicatePercents String
s
duplicatePercents String
"" = String
""
(%%) :: (Show a, Show b) => String -> (a,b) -> String
String
s %% :: forall a b. (Show a, Show b) => String -> (a, b) -> String
%% (a
x,b
y) = String
s forall a. Show a => String -> a -> String
% a
x forall a. Show a => String -> a -> String
% b
y
(%%%) :: (Show a, Show b, Show c) => String -> (a,b,c) -> String
String
s %%% :: forall a b c.
(Show a, Show b, Show c) =>
String -> (a, b, c) -> String
%%% (a
x,b
y,c
z) = String
s forall a. Show a => String -> a -> String
% a
x forall a. Show a => String -> a -> String
% b
y forall a. Show a => String -> a -> String
% c
z
(%%%%) :: (Show a, Show b, Show c, Show d) => String -> (a,b,c,d) -> String
String
s %%%% :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
String -> (a, b, c, d) -> String
%%%% (a
x,b
y,c
z,d
w) = String
s forall a. Show a => String -> a -> String
% a
x forall a. Show a => String -> a -> String
% b
y forall a. Show a => String -> a -> String
% c
z forall a. Show a => String -> a -> String
% d
w
(%%%%%) :: (Show a, Show b, Show c, Show d, Show e)
=> String -> (a,b,c,d,e) -> String
String
s %%%%% :: forall a b c d e.
(Show a, Show b, Show c, Show d, Show e) =>
String -> (a, b, c, d, e) -> String
%%%%% (a
x,b
y,c
z,d
w,e
v) = String
s forall a. Show a => String -> a -> String
% a
x forall a. Show a => String -> a -> String
% b
y forall a. Show a => String -> a -> String
% c
z forall a. Show a => String -> a -> String
% d
w forall a. Show a => String -> a -> String
% e
v
(%%%%%%) :: (Show a, Show b, Show c, Show d, Show e, Show f)
=> String -> (a,b,c,d,e,f) -> String
String
s %%%%%% :: forall a b c d e f.
(Show a, Show b, Show c, Show d, Show e, Show f) =>
String -> (a, b, c, d, e, f) -> String
%%%%%% (a
x,b
y,c
z,d
w,e
v,f
u) = String
s forall a. Show a => String -> a -> String
% a
x forall a. Show a => String -> a -> String
% b
y forall a. Show a => String -> a -> String
% c
z forall a. Show a => String -> a -> String
% d
w forall a. Show a => String -> a -> String
% e
v forall a. Show a => String -> a -> String
% f
u
(-%%) :: (Show a, Show b) => String -> (a,b) -> String
String
s -%% :: forall a b. (Show a, Show b) => String -> (a, b) -> String
-%% (a, b)
t = String
s forall a b. (Show a, Show b) => String -> (a, b) -> String
%% (a, b)
t String -> Char -> String
/% Char
'?'
(-%%%) :: (Show a, Show b, Show c) => String -> (a,b,c) -> String
String
s -%%% :: forall a b c.
(Show a, Show b, Show c) =>
String -> (a, b, c) -> String
-%%% (a, b, c)
t = String
s forall a b c.
(Show a, Show b, Show c) =>
String -> (a, b, c) -> String
%%% (a, b, c)
t String -> Char -> String
/% Char
'?'
(-%%%%) :: (Show a, Show b, Show c, Show d) => String -> (a,b,c,d) -> String
String
s -%%%% :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
String -> (a, b, c, d) -> String
-%%%% (a, b, c, d)
t = String
s forall a b c d.
(Show a, Show b, Show c, Show d) =>
String -> (a, b, c, d) -> String
%%%% (a, b, c, d)
t String -> Char -> String
/% Char
'?'
(-%%%%%) :: (Show a, Show b, Show c, Show d, Show e)
=> String -> (a,b,c,d,e) -> String
String
s -%%%%% :: forall a b c d e.
(Show a, Show b, Show c, Show d, Show e) =>
String -> (a, b, c, d, e) -> String
-%%%%% (a, b, c, d, e)
t = String
s forall a b c d e.
(Show a, Show b, Show c, Show d, Show e) =>
String -> (a, b, c, d, e) -> String
%%%%% (a, b, c, d, e)
t String -> Char -> String
/% Char
'?'
(-%%%%%%) :: (Show a, Show b, Show c, Show d, Show e, Show f)
=> String -> (a,b,c,d,e,f) -> String
String
s -%%%%%% :: forall a b c d e f.
(Show a, Show b, Show c, Show d, Show e, Show f) =>
String -> (a, b, c, d, e, f) -> String
-%%%%%% (a, b, c, d, e, f)
t = String
s forall a b c d e f.
(Show a, Show b, Show c, Show d, Show e, Show f) =>
String -> (a, b, c, d, e, f) -> String
%%%%%% (a, b, c, d, e, f)
t String -> Char -> String
/% Char
'?'
(+%) :: Show a => String -> a -> String
+% :: forall a. Show a => String -> a -> String
(+%) = forall a. Show a => String -> a -> String
(%)