#if __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE Safe #-}
#endif
module Text.XHtml.BlockTable (
BlockTable,
single,
above,
beside,
getMatrix,
showsTable,
showTable,
) where
infixr 4 `beside`
infixr 3 `above`
instance (Show a) => Show (BlockTable a) where
showsPrec _ = showsTable
type TableI a = [[(a,(Int,Int))]] -> [[(a,(Int,Int))]]
data BlockTable a = Table (Int -> Int -> TableI a) Int Int
single :: a -> BlockTable a
single a = Table (\ x y z -> [(a,(x+1,y+1))] : z) 1 1
above :: BlockTable a -> BlockTable a -> BlockTable a
beside :: BlockTable a -> BlockTable a -> BlockTable a
t1 `above` t2 = trans (combine (trans t1) (trans t2) (.))
t1 `beside` t2 = combine t1 t2 (\ lst1 lst2 r ->
let
beside' (x:xs) (y:ys) = (x ++ y) : beside' xs ys
beside' (x:xs) [] = x : xs ++ r
beside' [] (y:ys) = y : ys ++ r
beside' [] [] = r
in
beside' (lst1 []) (lst2 []))
trans :: BlockTable a -> BlockTable a
trans (Table f1 x1 y1) = Table (flip f1) y1 x1
combine :: BlockTable a
-> BlockTable b
-> (TableI a -> TableI b -> TableI c)
-> BlockTable c
combine (Table f1 x1 y1) (Table f2 x2 y2) comb = Table new_fn (x1+x2) max_y
where
max_y = max y1 y2
new_fn x y =
case compare y1 y2 of
EQ -> comb (f1 0 y) (f2 x y)
GT -> comb (f1 0 y) (f2 x (y + y1 - y2))
LT -> comb (f1 0 (y + y2 - y1)) (f2 x y)
getMatrix :: BlockTable a -> [[(a,(Int,Int))]]
getMatrix (Table r _ _) = r 0 0 []
showsTable :: (Show a) => BlockTable a -> ShowS
showsTable table = shows (getMatrix table)
showTable :: (Show a) => BlockTable a -> String
showTable table = showsTable table ""