packages feed

marxup-3.0.0: MarXup/MultiRef.hs

{-# LANGUAGE GeneralizedNewtypeDeriving, GADTs, PackageImports #-}

module MarXup.MultiRef where

import Control.Monad.Fix
import "mtl" Control.Monad.RWS.Lazy
import Control.Applicative
import Control.Arrow (first)

newtype Multi a = Multi {fromMulti :: RWS InterpretMode String (References,[BoxSpec]) a }
  deriving (Functor, Monad, Applicative, MonadWriter String, MonadState (References,[BoxSpec]), MonadFix, MonadReader InterpretMode)

-----------------------------------
-- Basic datatype and semantics
type Label = Int

-- | Size of a box, in points. boxDepth is how far the baseline is
-- from the bottom. boxHeight is how far the baseline is from the top.
-- (These are TeX meanings)
data BoxSpec = BoxSpec {boxWidth, boxHeight, boxDepth :: Double}
             deriving (Show)

nilBoxSpec :: BoxSpec
nilBoxSpec = BoxSpec 0 0 0

raw :: String -> Multi ()
raw s = tell s

getBoxSpec :: Multi BoxSpec
getBoxSpec = do
  (refs,bs) <- get
  case bs of
    [] -> error "display: ran out of boxes!"
    (b:bs') -> do
      put (refs,bs')
      return b
 


-- Reference management
newLabel :: Multi Label -- create a new label
newLabel = do x <- fst <$> get;  modify (first (+1)); return x

type References = Int -- how many labels have been allocated
emptyRefs :: References
emptyRefs = 0

type Mode = InterpretMode -> Bool
data InterpretMode = OutsideBox | InsideBox | Regular deriving Eq