module Options.Applicative.Help.Chunk
( Chunk(..)
, chunked
, listToChunk
, (<<+>>)
, (<</>>)
, vcatChunks
, vsepChunks
, isEmpty
, stringChunk
, paragraph
, extractChunk
, tabulate
) where
import Control.Applicative
import Control.Monad
import Data.List.NonEmpty (NonEmpty(..))
import Data.Maybe
import Data.Semigroup
import Prelude
import Options.Applicative.Help.Pretty
newtype Chunk a = Chunk
{ forall a. Chunk a -> Maybe a
unChunk :: Maybe a }
deriving (Chunk a -> Chunk a -> Bool
(Chunk a -> Chunk a -> Bool)
-> (Chunk a -> Chunk a -> Bool) -> Eq (Chunk a)
forall a. Eq a => Chunk a -> Chunk a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Chunk a -> Chunk a -> Bool
== :: Chunk a -> Chunk a -> Bool
$c/= :: forall a. Eq a => Chunk a -> Chunk a -> Bool
/= :: Chunk a -> Chunk a -> Bool
Eq, Int -> Chunk a -> ShowS
[Chunk a] -> ShowS
Chunk a -> String
(Int -> Chunk a -> ShowS)
-> (Chunk a -> String) -> ([Chunk a] -> ShowS) -> Show (Chunk a)
forall a. Show a => Int -> Chunk a -> ShowS
forall a. Show a => [Chunk a] -> ShowS
forall a. Show a => Chunk a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Chunk a -> ShowS
showsPrec :: Int -> Chunk a -> ShowS
$cshow :: forall a. Show a => Chunk a -> String
show :: Chunk a -> String
$cshowList :: forall a. Show a => [Chunk a] -> ShowS
showList :: [Chunk a] -> ShowS
Show)
instance Functor Chunk where
fmap :: forall a b. (a -> b) -> Chunk a -> Chunk b
fmap a -> b
f = Maybe b -> Chunk b
forall a. Maybe a -> Chunk a
Chunk (Maybe b -> Chunk b) -> (Chunk a -> Maybe b) -> Chunk a -> Chunk b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> Maybe a -> Maybe b
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (Maybe a -> Maybe b) -> (Chunk a -> Maybe a) -> Chunk a -> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Chunk a -> Maybe a
forall a. Chunk a -> Maybe a
unChunk
instance Applicative Chunk where
pure :: forall a. a -> Chunk a
pure = Maybe a -> Chunk a
forall a. Maybe a -> Chunk a
Chunk (Maybe a -> Chunk a) -> (a -> Maybe a) -> a -> Chunk a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe a
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
Chunk Maybe (a -> b)
f <*> :: forall a b. Chunk (a -> b) -> Chunk a -> Chunk b
<*> Chunk Maybe a
x = Maybe b -> Chunk b
forall a. Maybe a -> Chunk a
Chunk (Maybe (a -> b)
f Maybe (a -> b) -> Maybe a -> Maybe b
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe a
x)
instance Alternative Chunk where
empty :: forall a. Chunk a
empty = Maybe a -> Chunk a
forall a. Maybe a -> Chunk a
Chunk Maybe a
forall a. Maybe a
forall (f :: * -> *) a. Alternative f => f a
Control.Applicative.empty
Chunk a
a <|> :: forall a. Chunk a -> Chunk a -> Chunk a
<|> Chunk a
b = Maybe a -> Chunk a
forall a. Maybe a -> Chunk a
Chunk (Maybe a -> Chunk a) -> Maybe a -> Chunk a
forall a b. (a -> b) -> a -> b
$ Chunk a -> Maybe a
forall a. Chunk a -> Maybe a
unChunk Chunk a
a Maybe a -> Maybe a -> Maybe a
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Chunk a -> Maybe a
forall a. Chunk a -> Maybe a
unChunk Chunk a
b
instance Monad Chunk where
return :: forall a. a -> Chunk a
return = a -> Chunk a
forall a. a -> Chunk a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
Chunk a
m >>= :: forall a b. Chunk a -> (a -> Chunk b) -> Chunk b
>>= a -> Chunk b
f = Maybe b -> Chunk b
forall a. Maybe a -> Chunk a
Chunk (Maybe b -> Chunk b) -> Maybe b -> Chunk b
forall a b. (a -> b) -> a -> b
$ Chunk a -> Maybe a
forall a. Chunk a -> Maybe a
unChunk Chunk a
m Maybe a -> (a -> Maybe b) -> Maybe b
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Chunk b -> Maybe b
forall a. Chunk a -> Maybe a
unChunk (Chunk b -> Maybe b) -> (a -> Chunk b) -> a -> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Chunk b
f
instance Semigroup a => Semigroup (Chunk a) where
<> :: Chunk a -> Chunk a -> Chunk a
(<>) = (a -> a -> a) -> Chunk a -> Chunk a -> Chunk a
forall a. (a -> a -> a) -> Chunk a -> Chunk a -> Chunk a
chunked a -> a -> a
forall a. Semigroup a => a -> a -> a
(<>)
instance Semigroup a => Monoid (Chunk a) where
mempty :: Chunk a
mempty = Maybe a -> Chunk a
forall a. Maybe a -> Chunk a
Chunk Maybe a
forall a. Maybe a
Nothing
mappend :: Chunk a -> Chunk a -> Chunk a
mappend = Chunk a -> Chunk a -> Chunk a
forall a. Semigroup a => a -> a -> a
(<>)
instance MonadPlus Chunk where
mzero :: forall a. Chunk a
mzero = Maybe a -> Chunk a
forall a. Maybe a -> Chunk a
Chunk Maybe a
forall a. Maybe a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
mplus :: forall a. Chunk a -> Chunk a -> Chunk a
mplus Chunk a
m1 Chunk a
m2 = Maybe a -> Chunk a
forall a. Maybe a -> Chunk a
Chunk (Maybe a -> Chunk a) -> Maybe a -> Chunk a
forall a b. (a -> b) -> a -> b
$ Maybe a -> Maybe a -> Maybe a
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus (Chunk a -> Maybe a
forall a. Chunk a -> Maybe a
unChunk Chunk a
m1) (Chunk a -> Maybe a
forall a. Chunk a -> Maybe a
unChunk Chunk a
m2)
chunked :: (a -> a -> a)
-> Chunk a -> Chunk a -> Chunk a
chunked :: forall a. (a -> a -> a) -> Chunk a -> Chunk a -> Chunk a
chunked a -> a -> a
_ (Chunk Maybe a
Nothing) Chunk a
y = Chunk a
y
chunked a -> a -> a
_ Chunk a
x (Chunk Maybe a
Nothing) = Chunk a
x
chunked a -> a -> a
f (Chunk (Just a
x)) (Chunk (Just a
y)) = Maybe a -> Chunk a
forall a. Maybe a -> Chunk a
Chunk (a -> Maybe a
forall a. a -> Maybe a
Just (a -> a -> a
f a
x a
y))
listToChunk :: Semigroup a => [a] -> Chunk a
listToChunk :: forall a. Semigroup a => [a] -> Chunk a
listToChunk [] = Chunk a
forall a. Monoid a => a
mempty
listToChunk (a
x:[a]
xs) = a -> Chunk a
forall a. a -> Chunk a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NonEmpty a -> a
forall a. Semigroup a => NonEmpty a -> a
sconcat (a
x a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
xs))
extractChunk :: Monoid a => Chunk a -> a
= a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
forall a. Monoid a => a
mempty (Maybe a -> a) -> (Chunk a -> Maybe a) -> Chunk a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Chunk a -> Maybe a
forall a. Chunk a -> Maybe a
unChunk
(<<+>>) :: Chunk Doc -> Chunk Doc -> Chunk Doc
<<+>> :: Chunk Doc -> Chunk Doc -> Chunk Doc
(<<+>>) = (Doc -> Doc -> Doc) -> Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. (a -> a -> a) -> Chunk a -> Chunk a -> Chunk a
chunked Doc -> Doc -> Doc
forall ann. Doc ann -> Doc ann -> Doc ann
(<+>)
(<</>>) :: Chunk Doc -> Chunk Doc -> Chunk Doc
<</>> :: Chunk Doc -> Chunk Doc -> Chunk Doc
(<</>>) = (Doc -> Doc -> Doc) -> Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. (a -> a -> a) -> Chunk a -> Chunk a -> Chunk a
chunked Doc -> Doc -> Doc
(</>)
vcatChunks :: [Chunk Doc] -> Chunk Doc
vcatChunks :: [Chunk Doc] -> Chunk Doc
vcatChunks = (Chunk Doc -> Chunk Doc -> Chunk Doc)
-> Chunk Doc -> [Chunk Doc] -> Chunk Doc
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Doc -> Doc -> Doc) -> Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. (a -> a -> a) -> Chunk a -> Chunk a -> Chunk a
chunked Doc -> Doc -> Doc
(.$.)) Chunk Doc
forall a. Monoid a => a
mempty
vsepChunks :: [Chunk Doc] -> Chunk Doc
vsepChunks :: [Chunk Doc] -> Chunk Doc
vsepChunks = (Chunk Doc -> Chunk Doc -> Chunk Doc)
-> Chunk Doc -> [Chunk Doc] -> Chunk Doc
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Doc -> Doc -> Doc) -> Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. (a -> a -> a) -> Chunk a -> Chunk a -> Chunk a
chunked (\Doc
x Doc
y -> Doc
x Doc -> Doc -> Doc
.$. Doc
forall a. Monoid a => a
mempty Doc -> Doc -> Doc
.$. Doc
y)) Chunk Doc
forall a. Monoid a => a
mempty
isEmpty :: Chunk a -> Bool
isEmpty :: forall a. Chunk a -> Bool
isEmpty = Maybe a -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe a -> Bool) -> (Chunk a -> Maybe a) -> Chunk a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Chunk a -> Maybe a
forall a. Chunk a -> Maybe a
unChunk
stringChunk :: String -> Chunk Doc
stringChunk :: String -> Chunk Doc
stringChunk String
"" = Chunk Doc
forall a. Monoid a => a
mempty
stringChunk String
s = Doc -> Chunk Doc
forall a. a -> Chunk a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Doc
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty String
s)
paragraph :: String -> Chunk Doc
paragraph :: String -> Chunk Doc
paragraph = (String -> Chunk Doc -> Chunk Doc)
-> Chunk Doc -> [String] -> Chunk Doc
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Doc -> Doc -> Doc) -> Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. (a -> a -> a) -> Chunk a -> Chunk a -> Chunk a
chunked Doc -> Doc -> Doc
(</>) (Chunk Doc -> Chunk Doc -> Chunk Doc)
-> (String -> Chunk Doc) -> String -> Chunk Doc -> Chunk Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Chunk Doc
stringChunk) Chunk Doc
forall a. Monoid a => a
mempty
([String] -> Chunk Doc)
-> (String -> [String]) -> String -> Chunk Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words
tabulate :: Int -> [(Doc, Doc)] -> Chunk Doc
tabulate :: Int -> [(Doc, Doc)] -> Chunk Doc
tabulate Int
_ [] = Chunk Doc
forall a. Monoid a => a
mempty
tabulate Int
size [(Doc, Doc)]
table = Doc -> Chunk Doc
forall a. a -> Chunk a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Doc -> Chunk Doc) -> Doc -> Chunk Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
forall ann. [Doc ann] -> Doc ann
vcat
[ Int -> Doc -> Doc
forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (Int -> Doc -> Doc
forall ann. Int -> Doc ann -> Doc ann
fillBreak Int
size Doc
key Doc -> Doc -> Doc
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc
value)
| (Doc
key, Doc
value) <- [(Doc, Doc)]
table ]