-- | 'Box' with many functions in a 'Reader' monad. -- -- The advantage of this module over "Rainbox" is that many of the -- functions have fewer arguments because they are instead carried -- in the 'Reader' monad. This also allows you to use four infix -- operators to easily join up 'Box'. The disadvantage is that -- using the 'Reader' monad adds a layer of indirection. module Rainbox.Reader ( -- * Backgrounds B.Background(..) , R.defaultBackground , R.same -- * Box properties , B.Bar(..) , B.Box , B.unBox -- * Height and columns , B.Height(..) , B.height , B.Width(..) , B.HasWidth(..) -- * Alignment , B.Align , B.Vert , B.Horiz , B.center , B.top , B.bottom , B.left , B.right -- * Reader monad , Specs(..) , Env , runEnv -- * Making Boxes , B.blank , blankH , blankV , B.chunks , R.chunk -- * Pasting Boxes together , catH , catV , sepH , sepV , punctuateH , punctuateV , (<->) , (<+>) , (/-/) , (/+/) -- * Viewing Boxes , view , viewH , viewV -- * Growing Boxes , grow , growH , growV , column -- * Resizing , resize , resizeH , resizeV -- * Printing Boxes , R.render , R.printBox ) where import Control.Monad.Trans.Reader import Data.Functor.Identity import qualified Rainbox.Box.Primitives as B import qualified Rainbox.Box as R import Rainbox.Box.Primitives ( Box , Height , Width , Align , Horiz , Vert ) data Specs = Specs { background :: B.Background , alignH :: Align Horiz , alignV :: Align Vert , spaceH :: Int -- ^ Amount of intervening space for horizontal joins , spaceV :: Int -- ^ Amount of intervening space for vertical joins } deriving (Eq, Show) type Env = ReaderT Specs runEnv :: Specs -> Env Identity a -> a runEnv s = runIdentity . ($ s) . runReaderT blankH :: Monad m => Int -> Env m Box blankH i = do b <- asks background return $ R.blankH b i blankV :: Monad m => Int -> Env m Box blankV i = do b <- asks background return $ R.blankV b i catH :: Monad m => [Box] -> Env m Box catH bxs = do bk <- asks background al <- asks alignV return $ B.catH bk al bxs catV :: Monad m => [Box] -> Env m Box catV bxs = do bk <- asks background al <- asks alignH return $ B.catV bk al bxs grow :: Monad m => Height -> Width -> Box -> Env m Box grow r c bx = do b <- asks background h <- asks alignH v <- asks alignV return $ R.grow b r c v h bx growH :: Monad m => Int -> Box -> Env m Box growH i bx = do b <- asks background h <- asks alignH return $ R.growH b i h bx growV :: Monad m => Int -> Box -> Env m Box growV i bx = do b <- asks background v <- asks alignV return $ R.growV b i v bx column :: Monad m => [Box] -> Env m [Box] column bs = do bk <- asks background ah <- asks alignH return $ R.column bk ah bs resize :: Monad m => Height -> Width -> Box -> Env m Box resize r c bx = do b <- asks background h <- asks alignH v <- asks alignV return $ R.resize b r c v h bx resizeH :: Monad m => Int -> Box -> Env m Box resizeH i bx = do b <- asks background h <- asks alignH return $ R.resizeH b i h bx resizeV :: Monad m => Int -> Box -> Env m Box resizeV i bx = do b <- asks background v <- asks alignV return $ R.resizeV b i v bx sepH :: Monad m => Int -> [Box] -> Env m Box sepH i bx = do b <- asks background v <- asks alignV return $ R.sepH b i v bx sepV :: Monad m => Int -> [Box] -> Env m Box sepV i bx = do b <- asks background h <- asks alignH return $ R.sepV b i h bx punctuateH :: Monad m => Box -> [Box] -> Env m Box punctuateH bx bxs = do b <- asks background v <- asks alignV return $ R.punctuateH b v bx bxs punctuateV :: Monad m => Box -> [Box] -> Env m Box punctuateV bx bxs = do b <- asks background h <- asks alignH return $ R.punctuateV b h bx bxs view :: Monad m => Height -> Width -> Box -> Env m Box view h w b = do av <- asks alignV ah <- asks alignH return $ R.view h w av ah b viewH :: Monad m => Int -> Box -> Env m Box viewH h b = do ah <- asks alignH return $ B.viewH h ah b viewV :: Monad m => Int -> Box -> Env m Box viewV h b = do av <- asks alignV return $ B.viewV h av b -- | Paste two 'Box' together horizontally with no intervening -- space. Left fixity, precedence 5. (<->) :: Monad m => Box -> Box -> Env m Box (<->) l r = do b <- asks background a <- asks alignV return $ B.catH b a [l, r] infixl 5 <-> -- | Paste two 'Box' together horizontally. Intervening space is -- determined by 'spaceH'. -- Left fixity, precedence 5. (<+>) :: Monad m => Box -> Box -> Env m Box (<+>) l r = do bk <- asks background a <- asks alignV sp <- asks spaceH bx <- blankH sp return $ B.catH bk a [ l, bx, r ] infixl 5 <+> -- | Paste two 'Box' together vertically with no intervening space. -- Left fixity, precedence 6. (/-/) :: Monad m => Box -> Box -> Env m Box (/-/) h l = do b <- asks background a <- asks alignH return $ B.catV b a [ h, l ] infixl 6 /-/ -- | Paste two 'Box' together vertically. Intervening space is -- determined by 'spaceV'. Left fixity, precedence 6. (/+/) :: Monad m => Box -> Box -> Env m Box (/+/) h l = do bk <- asks background a <- asks alignH sp <- asks spaceV bx <- blankV sp return $ B.catV bk a [ h, bx, l ] infixl 6 /+/