----------------------------------------------------------------------------
-- |
-- Module      :  Prettyprinter.MetaDoc
-- Copyright   :  (c) Sergey Vinokurov 2018
-- License     :  Apache-2.0 (see LICENSE)
-- Maintainer  :  serg.foo@gmail.com
----------------------------------------------------------------------------

module Prettyprinter.MetaDoc
  ( DocKind(..)
  , MetaDoc
  , mdPayload
  , mdKind
  , compositeMetaDoc
  , atomicMetaDoc

  , metaDocInt
  , metaDocFloat
  , metaDocDouble
  , metaDocInteger
  , metaDocNatural
  , metaDocWord
  , metaDocWord8
  , metaDocWord16
  , metaDocWord32
  , metaDocWord64
  , metaDocInt8
  , metaDocInt16
  , metaDocInt32
  , metaDocInt64
  , metaDocUnit
  , metaDocBool
  , metaDocChar

  , stringMetaDoc
  , strictTextMetaDoc
  , lazyTextMetaDoc
  , strictByteStringMetaDoc
  , lazyByteStringMetaDoc
  , shortByteStringMetaDoc

  , constructorAppMetaDoc
  ) where

import Data.ByteString.Char8 qualified as C8
import Data.ByteString.Lazy.Char8 qualified as CL8
import Data.ByteString.Short qualified as ShortBS
import Data.Int
import Data.Text qualified as T
import Data.Text.Lazy qualified as TL
import Data.Word
import Numeric.Natural
import Prettyprinter
import Prettyprinter qualified as PP
import Prettyprinter.Combinators.Basic

data DocKind = Atomic | Composite
  deriving (DocKind -> DocKind -> Bool
(DocKind -> DocKind -> Bool)
-> (DocKind -> DocKind -> Bool) -> Eq DocKind
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DocKind -> DocKind -> Bool
== :: DocKind -> DocKind -> Bool
$c/= :: DocKind -> DocKind -> Bool
/= :: DocKind -> DocKind -> Bool
Eq, Eq DocKind
Eq DocKind =>
(DocKind -> DocKind -> Ordering)
-> (DocKind -> DocKind -> Bool)
-> (DocKind -> DocKind -> Bool)
-> (DocKind -> DocKind -> Bool)
-> (DocKind -> DocKind -> Bool)
-> (DocKind -> DocKind -> DocKind)
-> (DocKind -> DocKind -> DocKind)
-> Ord DocKind
DocKind -> DocKind -> Bool
DocKind -> DocKind -> Ordering
DocKind -> DocKind -> DocKind
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: DocKind -> DocKind -> Ordering
compare :: DocKind -> DocKind -> Ordering
$c< :: DocKind -> DocKind -> Bool
< :: DocKind -> DocKind -> Bool
$c<= :: DocKind -> DocKind -> Bool
<= :: DocKind -> DocKind -> Bool
$c> :: DocKind -> DocKind -> Bool
> :: DocKind -> DocKind -> Bool
$c>= :: DocKind -> DocKind -> Bool
>= :: DocKind -> DocKind -> Bool
$cmax :: DocKind -> DocKind -> DocKind
max :: DocKind -> DocKind -> DocKind
$cmin :: DocKind -> DocKind -> DocKind
min :: DocKind -> DocKind -> DocKind
Ord, Int -> DocKind
DocKind -> Int
DocKind -> [DocKind]
DocKind -> DocKind
DocKind -> DocKind -> [DocKind]
DocKind -> DocKind -> DocKind -> [DocKind]
(DocKind -> DocKind)
-> (DocKind -> DocKind)
-> (Int -> DocKind)
-> (DocKind -> Int)
-> (DocKind -> [DocKind])
-> (DocKind -> DocKind -> [DocKind])
-> (DocKind -> DocKind -> [DocKind])
-> (DocKind -> DocKind -> DocKind -> [DocKind])
-> Enum DocKind
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: DocKind -> DocKind
succ :: DocKind -> DocKind
$cpred :: DocKind -> DocKind
pred :: DocKind -> DocKind
$ctoEnum :: Int -> DocKind
toEnum :: Int -> DocKind
$cfromEnum :: DocKind -> Int
fromEnum :: DocKind -> Int
$cenumFrom :: DocKind -> [DocKind]
enumFrom :: DocKind -> [DocKind]
$cenumFromThen :: DocKind -> DocKind -> [DocKind]
enumFromThen :: DocKind -> DocKind -> [DocKind]
$cenumFromTo :: DocKind -> DocKind -> [DocKind]
enumFromTo :: DocKind -> DocKind -> [DocKind]
$cenumFromThenTo :: DocKind -> DocKind -> DocKind -> [DocKind]
enumFromThenTo :: DocKind -> DocKind -> DocKind -> [DocKind]
Enum, DocKind
DocKind -> DocKind -> Bounded DocKind
forall a. a -> a -> Bounded a
$cminBound :: DocKind
minBound :: DocKind
$cmaxBound :: DocKind
maxBound :: DocKind
Bounded)

instance Semigroup DocKind where
  <> :: DocKind -> DocKind -> DocKind
(<>) = DocKind -> DocKind -> DocKind
forall a. Ord a => a -> a -> a
max

instance Monoid DocKind where
  mempty :: DocKind
mempty = DocKind
forall a. Bounded a => a
minBound

data MetaDoc ann = MetaDoc
  { forall ann. MetaDoc ann -> Doc ann
mdPayload :: Doc ann
  , forall ann. MetaDoc ann -> DocKind
mdKind    :: DocKind
  }

compositeMetaDoc :: Doc ann -> MetaDoc ann
compositeMetaDoc :: forall ann. Doc ann -> MetaDoc ann
compositeMetaDoc Doc ann
x = MetaDoc
  { mdPayload :: Doc ann
mdPayload = Doc ann
x
  , mdKind :: DocKind
mdKind    = DocKind
Composite
  }

atomicMetaDoc :: Doc ann -> MetaDoc ann
atomicMetaDoc :: forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc Doc ann
x = MetaDoc
  { mdPayload :: Doc ann
mdPayload = Doc ann
x
  , mdKind :: DocKind
mdKind    = DocKind
Atomic
  }

instance Semigroup (MetaDoc ann) where
  <> :: MetaDoc ann -> MetaDoc ann -> MetaDoc ann
(<>) (MetaDoc Doc ann
p1 DocKind
kind1) (MetaDoc Doc ann
p2 DocKind
kind2) = MetaDoc
    { mdPayload :: Doc ann
mdPayload = Doc ann
p1 Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
p2
    , mdKind :: DocKind
mdKind    = DocKind
kind1 DocKind -> DocKind -> DocKind
forall a. Semigroup a => a -> a -> a
<> DocKind
kind2
    }

instance Monoid (MetaDoc ann) where
  mempty :: MetaDoc ann
mempty = MetaDoc
    { mdPayload :: Doc ann
mdPayload = Doc ann
forall a. Monoid a => a
mempty
    , mdKind :: DocKind
mdKind    = DocKind
forall a. Monoid a => a
mempty
    }
  mappend :: MetaDoc ann -> MetaDoc ann -> MetaDoc ann
mappend = MetaDoc ann -> MetaDoc ann -> MetaDoc ann
forall a. Semigroup a => a -> a -> a
(<>)

metaDocInt :: Int -> MetaDoc ann
metaDocInt :: forall ann. Int -> MetaDoc ann
metaDocInt = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann) -> (Int -> Doc ann) -> Int -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Doc ann
forall ann. Int -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocFloat :: Float -> MetaDoc ann
metaDocFloat :: forall ann. Float -> MetaDoc ann
metaDocFloat = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Float -> Doc ann) -> Float -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Doc ann
forall ann. Float -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocDouble :: Double -> MetaDoc ann
metaDocDouble :: forall ann. Double -> MetaDoc ann
metaDocDouble = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Double -> Doc ann) -> Double -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Doc ann
forall ann. Double -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocInteger :: Integer -> MetaDoc ann
metaDocInteger :: forall ann. Integer -> MetaDoc ann
metaDocInteger = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Integer -> Doc ann) -> Integer -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Doc ann
forall ann. Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocNatural :: Natural -> MetaDoc ann
metaDocNatural :: forall ann. Natural -> MetaDoc ann
metaDocNatural = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Natural -> Doc ann) -> Natural -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> Doc ann
forall ann. Natural -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocWord :: Word -> MetaDoc ann
metaDocWord :: forall ann. Word -> MetaDoc ann
metaDocWord = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Word -> Doc ann) -> Word -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> Doc ann
forall ann. Word -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocWord8 :: Word8 -> MetaDoc ann
metaDocWord8 :: forall ann. Word8 -> MetaDoc ann
metaDocWord8 = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Word8 -> Doc ann) -> Word8 -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Doc ann
forall ann. Word8 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocWord16 :: Word16 -> MetaDoc ann
metaDocWord16 :: forall ann. Word16 -> MetaDoc ann
metaDocWord16 = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Word16 -> Doc ann) -> Word16 -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Doc ann
forall ann. Word16 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocWord32 :: Word32 -> MetaDoc ann
metaDocWord32 :: forall ann. Word32 -> MetaDoc ann
metaDocWord32 = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Word32 -> Doc ann) -> Word32 -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Doc ann
forall ann. Word32 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocWord64 :: Word64 -> MetaDoc ann
metaDocWord64 :: forall ann. Word64 -> MetaDoc ann
metaDocWord64 = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Word64 -> Doc ann) -> Word64 -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Doc ann
forall ann. Word64 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocInt8 :: Int8 -> MetaDoc ann
metaDocInt8 :: forall ann. Int8 -> MetaDoc ann
metaDocInt8 = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Int8 -> Doc ann) -> Int8 -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int8 -> Doc ann
forall ann. Int8 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocInt16 :: Int16 -> MetaDoc ann
metaDocInt16 :: forall ann. Int16 -> MetaDoc ann
metaDocInt16 = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Int16 -> Doc ann) -> Int16 -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int16 -> Doc ann
forall ann. Int16 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocInt32 :: Int32 -> MetaDoc ann
metaDocInt32 :: forall ann. Int32 -> MetaDoc ann
metaDocInt32 = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Int32 -> Doc ann) -> Int32 -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Doc ann
forall ann. Int32 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocInt64 :: Int64 -> MetaDoc ann
metaDocInt64 :: forall ann. Int64 -> MetaDoc ann
metaDocInt64 = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Int64 -> Doc ann) -> Int64 -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Doc ann
forall ann. Int64 -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocUnit :: () -> MetaDoc ann
metaDocUnit :: forall ann. () -> MetaDoc ann
metaDocUnit = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann) -> (() -> Doc ann) -> () -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. () -> Doc ann
forall ann. () -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocBool :: Bool -> MetaDoc ann
metaDocBool :: forall ann. Bool -> MetaDoc ann
metaDocBool = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Bool -> Doc ann) -> Bool -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Doc ann
forall ann. Bool -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty

metaDocChar :: Char -> MetaDoc ann
metaDocChar :: forall ann. Char -> MetaDoc ann
metaDocChar = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc (Doc ann -> MetaDoc ann)
-> (Char -> Doc ann) -> Char -> MetaDoc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Doc ann
forall ann. Char -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty


stringMetaDoc :: String -> MetaDoc ann
stringMetaDoc :: forall ann. String -> MetaDoc ann
stringMetaDoc String
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
f (Doc ann -> MetaDoc ann) -> Doc ann -> MetaDoc ann
forall a b. (a -> b) -> a -> b
$ String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty String
str
  where
    f :: Doc ann -> MetaDoc ann
f | (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') String
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
compositeMetaDoc
      | Bool
otherwise        = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc

strictTextMetaDoc :: T.Text -> MetaDoc ann
strictTextMetaDoc :: forall ann. Text -> MetaDoc ann
strictTextMetaDoc Text
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
f (Doc ann -> MetaDoc ann) -> Doc ann -> MetaDoc ann
forall a b. (a -> b) -> a -> b
$ Text -> Doc ann
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Text
str
  where
    f :: Doc ann -> MetaDoc ann
f | (Char -> Bool) -> Text -> Bool
T.any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') Text
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
compositeMetaDoc
      | Bool
otherwise          = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc

lazyTextMetaDoc :: TL.Text -> MetaDoc ann
lazyTextMetaDoc :: forall ann. Text -> MetaDoc ann
lazyTextMetaDoc Text
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
f (Doc ann -> MetaDoc ann) -> Doc ann -> MetaDoc ann
forall a b. (a -> b) -> a -> b
$ Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
str
  where
    f :: Doc ann -> MetaDoc ann
f | (Char -> Bool) -> Text -> Bool
TL.any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') Text
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
compositeMetaDoc
      | Bool
otherwise           = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc

strictByteStringMetaDoc :: C8.ByteString -> MetaDoc ann
strictByteStringMetaDoc :: forall ann. ByteString -> MetaDoc ann
strictByteStringMetaDoc ByteString
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
f (Doc ann -> MetaDoc ann) -> Doc ann -> MetaDoc ann
forall a b. (a -> b) -> a -> b
$ String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> String -> Doc ann
forall a b. (a -> b) -> a -> b
$ ByteString -> String
C8.unpack ByteString
str
  where
    f :: Doc ann -> MetaDoc ann
f | (Char -> Bool) -> ByteString -> Bool
C8.any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') ByteString
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
compositeMetaDoc
      | Bool
otherwise           = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc

lazyByteStringMetaDoc :: CL8.ByteString -> MetaDoc ann
lazyByteStringMetaDoc :: forall ann. ByteString -> MetaDoc ann
lazyByteStringMetaDoc ByteString
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
f (Doc ann -> MetaDoc ann) -> Doc ann -> MetaDoc ann
forall a b. (a -> b) -> a -> b
$ String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> String -> Doc ann
forall a b. (a -> b) -> a -> b
$ ByteString -> String
CL8.unpack ByteString
str
  where
    f :: Doc ann -> MetaDoc ann
f | (Char -> Bool) -> ByteString -> Bool
CL8.any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') ByteString
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
compositeMetaDoc
      | Bool
otherwise            = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc

shortByteStringMetaDoc :: ShortBS.ShortByteString -> MetaDoc ann
shortByteStringMetaDoc :: forall ann. ShortByteString -> MetaDoc ann
shortByteStringMetaDoc ShortByteString
str = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
f (Doc ann -> MetaDoc ann) -> Doc ann -> MetaDoc ann
forall a b. (a -> b) -> a -> b
$ String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> String -> Doc ann
forall a b. (a -> b) -> a -> b
$ ByteString -> String
C8.unpack ByteString
str'
  where
    str' :: ByteString
str' = ShortByteString -> ByteString
ShortBS.fromShort ShortByteString
str
    f :: Doc ann -> MetaDoc ann
f | (Char -> Bool) -> ByteString -> Bool
C8.any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') ByteString
str' = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
compositeMetaDoc
      | Bool
otherwise            = Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
atomicMetaDoc

constructorAppMetaDoc :: MetaDoc ann -> [MetaDoc ann] -> MetaDoc ann
constructorAppMetaDoc :: forall ann. MetaDoc ann -> [MetaDoc ann] -> MetaDoc ann
constructorAppMetaDoc MetaDoc ann
constructor [MetaDoc ann]
args =
  case (MetaDoc ann -> MetaDoc ann) -> [MetaDoc ann] -> [MetaDoc ann]
forall a b. (a -> b) -> [a] -> [b]
map MetaDoc ann -> MetaDoc ann
forall ann. MetaDoc ann -> MetaDoc ann
field [MetaDoc ann]
args of
    []  -> MetaDoc ann
constructor
    [MetaDoc ann
f] -> Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
compositeMetaDoc (Doc ann -> MetaDoc ann) -> Doc ann -> MetaDoc ann
forall a b. (a -> b) -> a -> b
$ MetaDoc ann -> Doc ann
forall ann. MetaDoc ann -> Doc ann
mdPayload MetaDoc ann
constructor Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
group (MetaDoc ann -> Doc ann
forall ann. MetaDoc ann -> Doc ann
mdPayload MetaDoc ann
f)
    [MetaDoc ann]
fs  -> Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
compositeMetaDoc (Doc ann -> MetaDoc ann) -> Doc ann -> MetaDoc ann
forall a b. (a -> b) -> a -> b
$ Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
PP.align (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ MetaDoc ann -> Doc ann
forall ann. MetaDoc ann -> Doc ann
mdPayload MetaDoc ann
constructor Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
## [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
PP.vsep ((MetaDoc ann -> Doc ann) -> [MetaDoc ann] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map MetaDoc ann -> Doc ann
forall ann. MetaDoc ann -> Doc ann
mdPayload [MetaDoc ann]
fs)
  where
    field :: MetaDoc ann -> MetaDoc ann
    field :: forall ann. MetaDoc ann -> MetaDoc ann
field MetaDoc ann
md =
      case MetaDoc ann -> DocKind
forall ann. MetaDoc ann -> DocKind
mdKind MetaDoc ann
md of
        DocKind
Atomic    -> MetaDoc ann
md
        DocKind
Composite -> Doc ann -> MetaDoc ann
forall ann. Doc ann -> MetaDoc ann
compositeMetaDoc (Doc ann -> MetaDoc ann) -> Doc ann -> MetaDoc ann
forall a b. (a -> b) -> a -> b
$ Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
PP.flatAlt Doc ann
payload (Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
PP.parens Doc ann
payload)
      where
        payload :: Doc ann
payload = MetaDoc ann -> Doc ann
forall ann. MetaDoc ann -> Doc ann
mdPayload MetaDoc ann
md