{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, CPP #-}
-----------------------------------------------------------------------------
-- |
-- Module      : Language.Python.Common.Pretty
-- Copyright   : (c) 2009 Bernie Pope 
-- License     : BSD-style
-- Maintainer  : bjpop@csse.unimelb.edu.au
-- Stability   : experimental
-- Portability : ghc
--
-- Convenience class for pretty printing combinators.
-----------------------------------------------------------------------------

module Language.Python.Common.Pretty (module TextPP, module Language.Python.Common.Pretty) where

#if __GLASGOW_HASKELL__ >= 803
import Prelude hiding ((<>))
#endif

import Text.PrettyPrint as TextPP

--------------------------------------------------------------------------------

-- | All types which can be transformed into a 'Doc'.
class Pretty a where
   pretty :: a -> Doc

-- | Transform values into strings.
prettyText :: Pretty a => a -> String
prettyText :: forall a. Pretty a => a -> String
prettyText = Doc -> String
render (Doc -> String) -> (a -> Doc) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc
forall a. Pretty a => a -> Doc
pretty

-- | Print just the prefix of something
prettyPrefix :: Pretty a => Int -> a -> Doc
prettyPrefix :: forall a. Pretty a => Int -> a -> Doc
prettyPrefix Int
maxLen a
x
   | String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
fullText Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
maxLen = String -> Doc
forall a. Pretty a => a -> Doc
pretty String
fullText
   | Bool
otherwise = String -> Doc
forall a. Pretty a => a -> Doc
pretty (Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
maxLen String
fullText) Doc -> Doc -> Doc
<+> String -> Doc
text String
"..." 
   where
   fullText :: String
fullText = a -> String
forall a. Pretty a => a -> String
prettyText a
x 

instance Pretty String where
   pretty :: String -> Doc
pretty String
s = String -> Doc
text String
s

-- | Conditionally wrap parentheses around an item.
parensIf :: Pretty a => (a -> Bool) -> a -> Doc
parensIf :: forall a. Pretty a => (a -> Bool) -> a -> Doc
parensIf a -> Bool
test a
x = if a -> Bool
test a
x then Doc -> Doc
parens (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ a -> Doc
forall a. Pretty a => a -> Doc
pretty a
x else a -> Doc
forall a. Pretty a => a -> Doc
pretty a
x 

perhaps :: Pretty a => Maybe a -> Doc -> Doc
perhaps :: forall a. Pretty a => Maybe a -> Doc -> Doc
perhaps Maybe a
Nothing Doc
doc = Doc
empty
perhaps (Just {}) Doc
doc = Doc
doc 

-- | A list of things separated by commas.
commaList :: Pretty a => [a] -> Doc
commaList :: forall a. Pretty a => [a] -> Doc
commaList = [Doc] -> Doc
hsep ([Doc] -> Doc) -> ([a] -> [Doc]) -> [a] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> [Doc] -> [Doc]
punctuate Doc
comma ([Doc] -> [Doc]) -> ([a] -> [Doc]) -> [a] -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc) -> [a] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc
forall a. Pretty a => a -> Doc
pretty 

-- | A list of things separated by equals signs.
equalsList :: Pretty a => [a] -> Doc
equalsList :: forall a. Pretty a => [a] -> Doc
equalsList = [Doc] -> Doc
hsep ([Doc] -> Doc) -> ([a] -> [Doc]) -> [a] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> [Doc] -> [Doc]
punctuate (Doc
space Doc -> Doc -> Doc
<> Doc
equals) ([Doc] -> [Doc]) -> ([a] -> [Doc]) -> [a] -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc) -> [a] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc
forall a. Pretty a => a -> Doc
pretty

instance Pretty Int where
  pretty :: Int -> Doc
pretty = Int -> Doc
int

instance Pretty Integer where
  pretty :: Integer -> Doc
pretty = Integer -> Doc
integer

instance Pretty Double where
   pretty :: Double -> Doc
pretty = Double -> Doc
double

instance Pretty Bool where
  pretty :: Bool -> Doc
pretty Bool
True = String -> Doc
text String
"True"
  pretty Bool
False = String -> Doc
text String
"False"

instance Pretty a => Pretty (Maybe a) where
   pretty :: Maybe a -> Doc
pretty Maybe a
Nothing = Doc
empty
   pretty (Just a
x) = a -> Doc
forall a. Pretty a => a -> Doc
pretty a
x