module Options.Applicative.Help.Types (
    ParserHelp (..)
  , renderHelp
  ) where

import Data.Semigroup
import Prelude

import Options.Applicative.Help.Chunk
import Options.Applicative.Help.Pretty

data ParserHelp = ParserHelp
  { ParserHelp -> Chunk Doc
helpError :: Chunk Doc
  , ParserHelp -> Chunk Doc
helpSuggestions :: Chunk Doc
  , ParserHelp -> Chunk Doc
helpHeader :: Chunk Doc
  , ParserHelp -> Chunk Doc
helpUsage :: Chunk Doc
  , ParserHelp -> Chunk Doc
helpDescription :: Chunk Doc
  , ParserHelp -> Chunk Doc
helpBody :: Chunk Doc
  , ParserHelp -> Chunk Doc
helpGlobals :: Chunk Doc
  , ParserHelp -> Chunk Doc
helpFooter :: Chunk Doc
  }

instance Show ParserHelp where
  showsPrec :: Int -> ParserHelp -> ShowS
showsPrec Int
_ ParserHelp
h = String -> ShowS
showString (Int -> ParserHelp -> String
renderHelp Int
80 ParserHelp
h)

instance Monoid ParserHelp where
  mempty :: ParserHelp
mempty = Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> ParserHelp
ParserHelp Chunk Doc
forall a. Monoid a => a
mempty Chunk Doc
forall a. Monoid a => a
mempty Chunk Doc
forall a. Monoid a => a
mempty Chunk Doc
forall a. Monoid a => a
mempty Chunk Doc
forall a. Monoid a => a
mempty Chunk Doc
forall a. Monoid a => a
mempty Chunk Doc
forall a. Monoid a => a
mempty Chunk Doc
forall a. Monoid a => a
mempty
  mappend :: ParserHelp -> ParserHelp -> ParserHelp
mappend = ParserHelp -> ParserHelp -> ParserHelp
forall a. Semigroup a => a -> a -> a
(<>)

instance Semigroup ParserHelp where
  (ParserHelp Chunk Doc
e1 Chunk Doc
s1 Chunk Doc
h1 Chunk Doc
u1 Chunk Doc
d1 Chunk Doc
b1 Chunk Doc
g1 Chunk Doc
f1) <> :: ParserHelp -> ParserHelp -> ParserHelp
<> (ParserHelp Chunk Doc
e2 Chunk Doc
s2 Chunk Doc
h2 Chunk Doc
u2 Chunk Doc
d2 Chunk Doc
b2 Chunk Doc
g2 Chunk Doc
f2)
    = Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> Chunk Doc
-> ParserHelp
ParserHelp (Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. Monoid a => a -> a -> a
mappend Chunk Doc
e1 Chunk Doc
e2) (Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. Monoid a => a -> a -> a
mappend Chunk Doc
s1 Chunk Doc
s2)
                 (Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. Monoid a => a -> a -> a
mappend Chunk Doc
h1 Chunk Doc
h2) (Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. Monoid a => a -> a -> a
mappend Chunk Doc
u1 Chunk Doc
u2)
                 (Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. Monoid a => a -> a -> a
mappend Chunk Doc
d1 Chunk Doc
d2) (Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. Monoid a => a -> a -> a
mappend Chunk Doc
b1 Chunk Doc
b2)
                 (Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. Monoid a => a -> a -> a
mappend Chunk Doc
g1 Chunk Doc
g2) (Chunk Doc -> Chunk Doc -> Chunk Doc
forall a. Monoid a => a -> a -> a
mappend Chunk Doc
f1 Chunk Doc
f2)

helpText :: ParserHelp -> Doc
helpText :: ParserHelp -> Doc
helpText (ParserHelp Chunk Doc
e Chunk Doc
s Chunk Doc
h Chunk Doc
u Chunk Doc
d Chunk Doc
b Chunk Doc
g Chunk Doc
f) =
  Chunk Doc -> Doc
forall a. Monoid a => Chunk a -> a
extractChunk (Chunk Doc -> Doc) -> Chunk Doc -> Doc
forall a b. (a -> b) -> a -> b
$
    [Chunk Doc] -> Chunk Doc
vsepChunks [Chunk Doc
e, Chunk Doc
s, Chunk Doc
h, Chunk Doc
u, (Doc -> Doc) -> Chunk Doc -> Chunk Doc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Doc -> Doc
indent Int
2) Chunk Doc
d, Chunk Doc
b, Chunk Doc
g, Chunk Doc
f]

-- | Convert a help text to 'String'.
renderHelp :: Int -> ParserHelp -> String
renderHelp :: Int -> ParserHelp -> String
renderHelp Int
cols
  = (SimpleDoc -> ShowS
`displayS` String
"")
  (SimpleDoc -> String)
-> (ParserHelp -> SimpleDoc) -> ParserHelp -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Int -> Doc -> SimpleDoc
renderPretty Float
1.0 Int
cols
  (Doc -> SimpleDoc)
-> (ParserHelp -> Doc) -> ParserHelp -> SimpleDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParserHelp -> Doc
helpText