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

{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Prettyprinter.Combinators.Basic
  ( (##)
  , ppListWithDelimSep
  ) where

import Data.Foldable
import Data.Semigroup as Semigroup
import Prettyprinter as PP

infixr 6 ##

(##) :: Doc ann -> Doc ann -> Doc ann
## :: Doc ann -> Doc ann -> Doc ann
(##) Doc ann
x Doc ann
y = Int -> Doc ann -> Doc ann
forall ann. Int -> Doc ann -> Doc ann
PP.nest Int
2 (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ Doc ann
x Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
Semigroup.<> Doc ann
forall ann. Doc ann
PP.line Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
y

{-# INLINABLE ppListWithDelimSep #-}
ppListWithDelimSep
  :: forall f ann. Foldable f
  => Doc ann
  -> Doc ann
  -> Doc ann
  -> f (Doc ann)
  -> Doc ann
ppListWithDelimSep :: Doc ann -> Doc ann -> Doc ann -> f (Doc ann) -> Doc ann
ppListWithDelimSep Doc ann
separator Doc ann
left Doc ann
right f (Doc ann)
xs =
  case f (Doc ann) -> [Doc ann]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f (Doc ann)
xs of
    []   -> Doc ann
left Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
right
    [Doc ann
y]  -> Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
PP.flatAlt (Doc ann
left Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
y Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
right) (Doc ann
left Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
y Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
right)
    Doc ann
y:[Doc ann]
ys ->
      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
$
        Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
PP.group (Doc ann -> Doc ann) -> Doc ann -> Doc 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
left Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
PP.<+> Doc ann
y Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
forall ann. Doc ann
PP.line' Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<>
             [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
PP.vcat [Doc ann]
fields Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
forall ann. Doc ann
PP.line Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<>
             Doc ann
right)
            (Doc ann
left Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
PP.<> Doc ann
y Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
PP.vcat [Doc ann]
fields Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
right)
      where
        fields :: [Doc ann]
        fields :: [Doc ann]
fields = (Doc ann -> Doc ann) -> [Doc ann] -> [Doc ann]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Doc ann
x -> Doc ann
separator Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
PP.<+> Doc ann
x) [Doc ann]
ys