{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase                 #-}
{- |
Module      : Text.GridTable.ArrayTable
Copyright   : © 2022 Albert Krewinkel
License     : MIT
Maintainer  : Albert Krewinkel <albert@zeitkraut.de>

Grid table representation based on arrays.
-}

module Text.GridTable.ArrayTable
  ( ArrayTable (..)
  , GridCell (..)
  , RowSpan (..)
  , ColSpan (..)
  , CellIndex
  , RowIndex (..)
  , ColIndex (..)
  , Alignment (..)
  , mapCells
  ) where

import Data.Array (Array, Ix)
import Data.Array.MArray (mapArray, thaw)
import Data.Array.ST (runSTArray)

-- | Table representation based on an array; cells are placed on a grid,
-- with indices spanned by other cells containing placeholder cells that
-- point to the spanning cell.
data ArrayTable a = ArrayTable
  { ArrayTable a -> Array CellIndex (GridCell a)
arrayTableCells    :: Array CellIndex (GridCell a)
  , ArrayTable a -> Maybe RowIndex
arrayTableHead     :: Maybe RowIndex
  , ArrayTable a -> Array ColIndex (Alignment, Int)
arrayTableColSpecs :: Array ColIndex (Alignment, Int)
  }
  deriving stock (ArrayTable a -> ArrayTable a -> Bool
(ArrayTable a -> ArrayTable a -> Bool)
-> (ArrayTable a -> ArrayTable a -> Bool) -> Eq (ArrayTable a)
forall a. Eq a => ArrayTable a -> ArrayTable a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ArrayTable a -> ArrayTable a -> Bool
$c/= :: forall a. Eq a => ArrayTable a -> ArrayTable a -> Bool
== :: ArrayTable a -> ArrayTable a -> Bool
$c== :: forall a. Eq a => ArrayTable a -> ArrayTable a -> Bool
Eq, Int -> ArrayTable a -> ShowS
[ArrayTable a] -> ShowS
ArrayTable a -> String
(Int -> ArrayTable a -> ShowS)
-> (ArrayTable a -> String)
-> ([ArrayTable a] -> ShowS)
-> Show (ArrayTable a)
forall a. Show a => Int -> ArrayTable a -> ShowS
forall a. Show a => [ArrayTable a] -> ShowS
forall a. Show a => ArrayTable a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ArrayTable a] -> ShowS
$cshowList :: forall a. Show a => [ArrayTable a] -> ShowS
show :: ArrayTable a -> String
$cshow :: forall a. Show a => ArrayTable a -> String
showsPrec :: Int -> ArrayTable a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> ArrayTable a -> ShowS
Show)

-- | Apply a function to all cell contents in a grid table.
mapCells :: (a -> b) -> ArrayTable a -> ArrayTable b
mapCells :: (a -> b) -> ArrayTable a -> ArrayTable b
mapCells a -> b
f ArrayTable a
gt =
  let f' :: GridCell a -> GridCell b
f' = \case
        ContentCell RowSpan
rs ColSpan
cs a
c  -> RowSpan -> ColSpan -> b -> GridCell b
forall a. RowSpan -> ColSpan -> a -> GridCell a
ContentCell RowSpan
rs ColSpan
cs (b -> GridCell b) -> b -> GridCell b
forall a b. (a -> b) -> a -> b
$ a -> b
f a
c
        ContinuationCell CellIndex
idx -> CellIndex -> GridCell b
forall a. CellIndex -> GridCell a
ContinuationCell CellIndex
idx
      cellArray :: Array CellIndex (GridCell b)
cellArray = (forall s. ST s (STArray s CellIndex (GridCell b)))
-> Array CellIndex (GridCell b)
forall i e. (forall s. ST s (STArray s i e)) -> Array i e
runSTArray ((forall s. ST s (STArray s CellIndex (GridCell b)))
 -> Array CellIndex (GridCell b))
-> (forall s. ST s (STArray s CellIndex (GridCell b)))
-> Array CellIndex (GridCell b)
forall a b. (a -> b) -> a -> b
$ do
        STArray s CellIndex (GridCell a)
mut <- Array CellIndex (GridCell a)
-> ST s (STArray s CellIndex (GridCell a))
forall i (a :: * -> * -> *) e (b :: * -> * -> *) (m :: * -> *).
(Ix i, IArray a e, MArray b e m) =>
a i e -> m (b i e)
thaw (Array CellIndex (GridCell a)
 -> ST s (STArray s CellIndex (GridCell a)))
-> Array CellIndex (GridCell a)
-> ST s (STArray s CellIndex (GridCell a))
forall a b. (a -> b) -> a -> b
$ ArrayTable a -> Array CellIndex (GridCell a)
forall a. ArrayTable a -> Array CellIndex (GridCell a)
arrayTableCells ArrayTable a
gt
        (GridCell a -> GridCell b)
-> STArray s CellIndex (GridCell a)
-> ST s (STArray s CellIndex (GridCell b))
forall (a :: * -> * -> *) e' (m :: * -> *) e i.
(MArray a e' m, MArray a e m, Ix i) =>
(e' -> e) -> a i e' -> m (a i e)
mapArray GridCell a -> GridCell b
f' STArray s CellIndex (GridCell a)
mut
  in ArrayTable a
gt { arrayTableCells :: Array CellIndex (GridCell b)
arrayTableCells = Array CellIndex (GridCell b)
cellArray }

-- | Row index in a table array.
newtype RowIndex = RowIndex { RowIndex -> Int
fromRowIndex :: Int }
  deriving stock (RowIndex -> RowIndex -> Bool
(RowIndex -> RowIndex -> Bool)
-> (RowIndex -> RowIndex -> Bool) -> Eq RowIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RowIndex -> RowIndex -> Bool
$c/= :: RowIndex -> RowIndex -> Bool
== :: RowIndex -> RowIndex -> Bool
$c== :: RowIndex -> RowIndex -> Bool
Eq, Ord RowIndex
Ord RowIndex
-> ((RowIndex, RowIndex) -> [RowIndex])
-> ((RowIndex, RowIndex) -> RowIndex -> Int)
-> ((RowIndex, RowIndex) -> RowIndex -> Int)
-> ((RowIndex, RowIndex) -> RowIndex -> Bool)
-> ((RowIndex, RowIndex) -> Int)
-> ((RowIndex, RowIndex) -> Int)
-> Ix RowIndex
(RowIndex, RowIndex) -> Int
(RowIndex, RowIndex) -> [RowIndex]
(RowIndex, RowIndex) -> RowIndex -> Bool
(RowIndex, RowIndex) -> RowIndex -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (RowIndex, RowIndex) -> Int
$cunsafeRangeSize :: (RowIndex, RowIndex) -> Int
rangeSize :: (RowIndex, RowIndex) -> Int
$crangeSize :: (RowIndex, RowIndex) -> Int
inRange :: (RowIndex, RowIndex) -> RowIndex -> Bool
$cinRange :: (RowIndex, RowIndex) -> RowIndex -> Bool
unsafeIndex :: (RowIndex, RowIndex) -> RowIndex -> Int
$cunsafeIndex :: (RowIndex, RowIndex) -> RowIndex -> Int
index :: (RowIndex, RowIndex) -> RowIndex -> Int
$cindex :: (RowIndex, RowIndex) -> RowIndex -> Int
range :: (RowIndex, RowIndex) -> [RowIndex]
$crange :: (RowIndex, RowIndex) -> [RowIndex]
$cp1Ix :: Ord RowIndex
Ix, Eq RowIndex
Eq RowIndex
-> (RowIndex -> RowIndex -> Ordering)
-> (RowIndex -> RowIndex -> Bool)
-> (RowIndex -> RowIndex -> Bool)
-> (RowIndex -> RowIndex -> Bool)
-> (RowIndex -> RowIndex -> Bool)
-> (RowIndex -> RowIndex -> RowIndex)
-> (RowIndex -> RowIndex -> RowIndex)
-> Ord RowIndex
RowIndex -> RowIndex -> Bool
RowIndex -> RowIndex -> Ordering
RowIndex -> RowIndex -> RowIndex
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RowIndex -> RowIndex -> RowIndex
$cmin :: RowIndex -> RowIndex -> RowIndex
max :: RowIndex -> RowIndex -> RowIndex
$cmax :: RowIndex -> RowIndex -> RowIndex
>= :: RowIndex -> RowIndex -> Bool
$c>= :: RowIndex -> RowIndex -> Bool
> :: RowIndex -> RowIndex -> Bool
$c> :: RowIndex -> RowIndex -> Bool
<= :: RowIndex -> RowIndex -> Bool
$c<= :: RowIndex -> RowIndex -> Bool
< :: RowIndex -> RowIndex -> Bool
$c< :: RowIndex -> RowIndex -> Bool
compare :: RowIndex -> RowIndex -> Ordering
$ccompare :: RowIndex -> RowIndex -> Ordering
$cp1Ord :: Eq RowIndex
Ord)
  deriving newtype (Int -> RowIndex
RowIndex -> Int
RowIndex -> [RowIndex]
RowIndex -> RowIndex
RowIndex -> RowIndex -> [RowIndex]
RowIndex -> RowIndex -> RowIndex -> [RowIndex]
(RowIndex -> RowIndex)
-> (RowIndex -> RowIndex)
-> (Int -> RowIndex)
-> (RowIndex -> Int)
-> (RowIndex -> [RowIndex])
-> (RowIndex -> RowIndex -> [RowIndex])
-> (RowIndex -> RowIndex -> [RowIndex])
-> (RowIndex -> RowIndex -> RowIndex -> [RowIndex])
-> Enum RowIndex
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: RowIndex -> RowIndex -> RowIndex -> [RowIndex]
$cenumFromThenTo :: RowIndex -> RowIndex -> RowIndex -> [RowIndex]
enumFromTo :: RowIndex -> RowIndex -> [RowIndex]
$cenumFromTo :: RowIndex -> RowIndex -> [RowIndex]
enumFromThen :: RowIndex -> RowIndex -> [RowIndex]
$cenumFromThen :: RowIndex -> RowIndex -> [RowIndex]
enumFrom :: RowIndex -> [RowIndex]
$cenumFrom :: RowIndex -> [RowIndex]
fromEnum :: RowIndex -> Int
$cfromEnum :: RowIndex -> Int
toEnum :: Int -> RowIndex
$ctoEnum :: Int -> RowIndex
pred :: RowIndex -> RowIndex
$cpred :: RowIndex -> RowIndex
succ :: RowIndex -> RowIndex
$csucc :: RowIndex -> RowIndex
Enum, Integer -> RowIndex
RowIndex -> RowIndex
RowIndex -> RowIndex -> RowIndex
(RowIndex -> RowIndex -> RowIndex)
-> (RowIndex -> RowIndex -> RowIndex)
-> (RowIndex -> RowIndex -> RowIndex)
-> (RowIndex -> RowIndex)
-> (RowIndex -> RowIndex)
-> (RowIndex -> RowIndex)
-> (Integer -> RowIndex)
-> Num RowIndex
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> RowIndex
$cfromInteger :: Integer -> RowIndex
signum :: RowIndex -> RowIndex
$csignum :: RowIndex -> RowIndex
abs :: RowIndex -> RowIndex
$cabs :: RowIndex -> RowIndex
negate :: RowIndex -> RowIndex
$cnegate :: RowIndex -> RowIndex
* :: RowIndex -> RowIndex -> RowIndex
$c* :: RowIndex -> RowIndex -> RowIndex
- :: RowIndex -> RowIndex -> RowIndex
$c- :: RowIndex -> RowIndex -> RowIndex
+ :: RowIndex -> RowIndex -> RowIndex
$c+ :: RowIndex -> RowIndex -> RowIndex
Num, Int -> RowIndex -> ShowS
[RowIndex] -> ShowS
RowIndex -> String
(Int -> RowIndex -> ShowS)
-> (RowIndex -> String) -> ([RowIndex] -> ShowS) -> Show RowIndex
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RowIndex] -> ShowS
$cshowList :: [RowIndex] -> ShowS
show :: RowIndex -> String
$cshow :: RowIndex -> String
showsPrec :: Int -> RowIndex -> ShowS
$cshowsPrec :: Int -> RowIndex -> ShowS
Show)

-- | Column index in a table array.
newtype ColIndex = ColIndex { ColIndex -> Int
fromColIndex :: Int }
  deriving stock (ColIndex -> ColIndex -> Bool
(ColIndex -> ColIndex -> Bool)
-> (ColIndex -> ColIndex -> Bool) -> Eq ColIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ColIndex -> ColIndex -> Bool
$c/= :: ColIndex -> ColIndex -> Bool
== :: ColIndex -> ColIndex -> Bool
$c== :: ColIndex -> ColIndex -> Bool
Eq, Ord ColIndex
Ord ColIndex
-> ((ColIndex, ColIndex) -> [ColIndex])
-> ((ColIndex, ColIndex) -> ColIndex -> Int)
-> ((ColIndex, ColIndex) -> ColIndex -> Int)
-> ((ColIndex, ColIndex) -> ColIndex -> Bool)
-> ((ColIndex, ColIndex) -> Int)
-> ((ColIndex, ColIndex) -> Int)
-> Ix ColIndex
(ColIndex, ColIndex) -> Int
(ColIndex, ColIndex) -> [ColIndex]
(ColIndex, ColIndex) -> ColIndex -> Bool
(ColIndex, ColIndex) -> ColIndex -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (ColIndex, ColIndex) -> Int
$cunsafeRangeSize :: (ColIndex, ColIndex) -> Int
rangeSize :: (ColIndex, ColIndex) -> Int
$crangeSize :: (ColIndex, ColIndex) -> Int
inRange :: (ColIndex, ColIndex) -> ColIndex -> Bool
$cinRange :: (ColIndex, ColIndex) -> ColIndex -> Bool
unsafeIndex :: (ColIndex, ColIndex) -> ColIndex -> Int
$cunsafeIndex :: (ColIndex, ColIndex) -> ColIndex -> Int
index :: (ColIndex, ColIndex) -> ColIndex -> Int
$cindex :: (ColIndex, ColIndex) -> ColIndex -> Int
range :: (ColIndex, ColIndex) -> [ColIndex]
$crange :: (ColIndex, ColIndex) -> [ColIndex]
$cp1Ix :: Ord ColIndex
Ix, Eq ColIndex
Eq ColIndex
-> (ColIndex -> ColIndex -> Ordering)
-> (ColIndex -> ColIndex -> Bool)
-> (ColIndex -> ColIndex -> Bool)
-> (ColIndex -> ColIndex -> Bool)
-> (ColIndex -> ColIndex -> Bool)
-> (ColIndex -> ColIndex -> ColIndex)
-> (ColIndex -> ColIndex -> ColIndex)
-> Ord ColIndex
ColIndex -> ColIndex -> Bool
ColIndex -> ColIndex -> Ordering
ColIndex -> ColIndex -> ColIndex
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ColIndex -> ColIndex -> ColIndex
$cmin :: ColIndex -> ColIndex -> ColIndex
max :: ColIndex -> ColIndex -> ColIndex
$cmax :: ColIndex -> ColIndex -> ColIndex
>= :: ColIndex -> ColIndex -> Bool
$c>= :: ColIndex -> ColIndex -> Bool
> :: ColIndex -> ColIndex -> Bool
$c> :: ColIndex -> ColIndex -> Bool
<= :: ColIndex -> ColIndex -> Bool
$c<= :: ColIndex -> ColIndex -> Bool
< :: ColIndex -> ColIndex -> Bool
$c< :: ColIndex -> ColIndex -> Bool
compare :: ColIndex -> ColIndex -> Ordering
$ccompare :: ColIndex -> ColIndex -> Ordering
$cp1Ord :: Eq ColIndex
Ord)
  deriving newtype (Int -> ColIndex
ColIndex -> Int
ColIndex -> [ColIndex]
ColIndex -> ColIndex
ColIndex -> ColIndex -> [ColIndex]
ColIndex -> ColIndex -> ColIndex -> [ColIndex]
(ColIndex -> ColIndex)
-> (ColIndex -> ColIndex)
-> (Int -> ColIndex)
-> (ColIndex -> Int)
-> (ColIndex -> [ColIndex])
-> (ColIndex -> ColIndex -> [ColIndex])
-> (ColIndex -> ColIndex -> [ColIndex])
-> (ColIndex -> ColIndex -> ColIndex -> [ColIndex])
-> Enum ColIndex
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ColIndex -> ColIndex -> ColIndex -> [ColIndex]
$cenumFromThenTo :: ColIndex -> ColIndex -> ColIndex -> [ColIndex]
enumFromTo :: ColIndex -> ColIndex -> [ColIndex]
$cenumFromTo :: ColIndex -> ColIndex -> [ColIndex]
enumFromThen :: ColIndex -> ColIndex -> [ColIndex]
$cenumFromThen :: ColIndex -> ColIndex -> [ColIndex]
enumFrom :: ColIndex -> [ColIndex]
$cenumFrom :: ColIndex -> [ColIndex]
fromEnum :: ColIndex -> Int
$cfromEnum :: ColIndex -> Int
toEnum :: Int -> ColIndex
$ctoEnum :: Int -> ColIndex
pred :: ColIndex -> ColIndex
$cpred :: ColIndex -> ColIndex
succ :: ColIndex -> ColIndex
$csucc :: ColIndex -> ColIndex
Enum, Integer -> ColIndex
ColIndex -> ColIndex
ColIndex -> ColIndex -> ColIndex
(ColIndex -> ColIndex -> ColIndex)
-> (ColIndex -> ColIndex -> ColIndex)
-> (ColIndex -> ColIndex -> ColIndex)
-> (ColIndex -> ColIndex)
-> (ColIndex -> ColIndex)
-> (ColIndex -> ColIndex)
-> (Integer -> ColIndex)
-> Num ColIndex
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> ColIndex
$cfromInteger :: Integer -> ColIndex
signum :: ColIndex -> ColIndex
$csignum :: ColIndex -> ColIndex
abs :: ColIndex -> ColIndex
$cabs :: ColIndex -> ColIndex
negate :: ColIndex -> ColIndex
$cnegate :: ColIndex -> ColIndex
* :: ColIndex -> ColIndex -> ColIndex
$c* :: ColIndex -> ColIndex -> ColIndex
- :: ColIndex -> ColIndex -> ColIndex
$c- :: ColIndex -> ColIndex -> ColIndex
+ :: ColIndex -> ColIndex -> ColIndex
$c+ :: ColIndex -> ColIndex -> ColIndex
Num, Int -> ColIndex -> ShowS
[ColIndex] -> ShowS
ColIndex -> String
(Int -> ColIndex -> ShowS)
-> (ColIndex -> String) -> ([ColIndex] -> ShowS) -> Show ColIndex
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ColIndex] -> ShowS
$cshowList :: [ColIndex] -> ShowS
show :: ColIndex -> String
$cshow :: ColIndex -> String
showsPrec :: Int -> ColIndex -> ShowS
$cshowsPrec :: Int -> ColIndex -> ShowS
Show)

-- | Index to a cell in a table part.
type CellIndex = (RowIndex, ColIndex)

-- | A grid cell contains either a real table cell, or is the
-- continuation of a column or row-spanning cell. In the latter case,
-- the index of the continued cell is provided.
data GridCell a
  = ContentCell RowSpan ColSpan a
  | ContinuationCell CellIndex
  deriving stock (GridCell a -> GridCell a -> Bool
(GridCell a -> GridCell a -> Bool)
-> (GridCell a -> GridCell a -> Bool) -> Eq (GridCell a)
forall a. Eq a => GridCell a -> GridCell a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GridCell a -> GridCell a -> Bool
$c/= :: forall a. Eq a => GridCell a -> GridCell a -> Bool
== :: GridCell a -> GridCell a -> Bool
$c== :: forall a. Eq a => GridCell a -> GridCell a -> Bool
Eq, Int -> GridCell a -> ShowS
[GridCell a] -> ShowS
GridCell a -> String
(Int -> GridCell a -> ShowS)
-> (GridCell a -> String)
-> ([GridCell a] -> ShowS)
-> Show (GridCell a)
forall a. Show a => Int -> GridCell a -> ShowS
forall a. Show a => [GridCell a] -> ShowS
forall a. Show a => GridCell a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GridCell a] -> ShowS
$cshowList :: forall a. Show a => [GridCell a] -> ShowS
show :: GridCell a -> String
$cshow :: forall a. Show a => GridCell a -> String
showsPrec :: Int -> GridCell a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> GridCell a -> ShowS
Show)

-- | The number of rows spanned by a cell.
newtype RowSpan = RowSpan Int
  deriving stock (RowSpan -> RowSpan -> Bool
(RowSpan -> RowSpan -> Bool)
-> (RowSpan -> RowSpan -> Bool) -> Eq RowSpan
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RowSpan -> RowSpan -> Bool
$c/= :: RowSpan -> RowSpan -> Bool
== :: RowSpan -> RowSpan -> Bool
$c== :: RowSpan -> RowSpan -> Bool
Eq, Eq RowSpan
Eq RowSpan
-> (RowSpan -> RowSpan -> Ordering)
-> (RowSpan -> RowSpan -> Bool)
-> (RowSpan -> RowSpan -> Bool)
-> (RowSpan -> RowSpan -> Bool)
-> (RowSpan -> RowSpan -> Bool)
-> (RowSpan -> RowSpan -> RowSpan)
-> (RowSpan -> RowSpan -> RowSpan)
-> Ord RowSpan
RowSpan -> RowSpan -> Bool
RowSpan -> RowSpan -> Ordering
RowSpan -> RowSpan -> RowSpan
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RowSpan -> RowSpan -> RowSpan
$cmin :: RowSpan -> RowSpan -> RowSpan
max :: RowSpan -> RowSpan -> RowSpan
$cmax :: RowSpan -> RowSpan -> RowSpan
>= :: RowSpan -> RowSpan -> Bool
$c>= :: RowSpan -> RowSpan -> Bool
> :: RowSpan -> RowSpan -> Bool
$c> :: RowSpan -> RowSpan -> Bool
<= :: RowSpan -> RowSpan -> Bool
$c<= :: RowSpan -> RowSpan -> Bool
< :: RowSpan -> RowSpan -> Bool
$c< :: RowSpan -> RowSpan -> Bool
compare :: RowSpan -> RowSpan -> Ordering
$ccompare :: RowSpan -> RowSpan -> Ordering
$cp1Ord :: Eq RowSpan
Ord)
  deriving newtype (Int -> RowSpan
RowSpan -> Int
RowSpan -> [RowSpan]
RowSpan -> RowSpan
RowSpan -> RowSpan -> [RowSpan]
RowSpan -> RowSpan -> RowSpan -> [RowSpan]
(RowSpan -> RowSpan)
-> (RowSpan -> RowSpan)
-> (Int -> RowSpan)
-> (RowSpan -> Int)
-> (RowSpan -> [RowSpan])
-> (RowSpan -> RowSpan -> [RowSpan])
-> (RowSpan -> RowSpan -> [RowSpan])
-> (RowSpan -> RowSpan -> RowSpan -> [RowSpan])
-> Enum RowSpan
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: RowSpan -> RowSpan -> RowSpan -> [RowSpan]
$cenumFromThenTo :: RowSpan -> RowSpan -> RowSpan -> [RowSpan]
enumFromTo :: RowSpan -> RowSpan -> [RowSpan]
$cenumFromTo :: RowSpan -> RowSpan -> [RowSpan]
enumFromThen :: RowSpan -> RowSpan -> [RowSpan]
$cenumFromThen :: RowSpan -> RowSpan -> [RowSpan]
enumFrom :: RowSpan -> [RowSpan]
$cenumFrom :: RowSpan -> [RowSpan]
fromEnum :: RowSpan -> Int
$cfromEnum :: RowSpan -> Int
toEnum :: Int -> RowSpan
$ctoEnum :: Int -> RowSpan
pred :: RowSpan -> RowSpan
$cpred :: RowSpan -> RowSpan
succ :: RowSpan -> RowSpan
$csucc :: RowSpan -> RowSpan
Enum, Integer -> RowSpan
RowSpan -> RowSpan
RowSpan -> RowSpan -> RowSpan
(RowSpan -> RowSpan -> RowSpan)
-> (RowSpan -> RowSpan -> RowSpan)
-> (RowSpan -> RowSpan -> RowSpan)
-> (RowSpan -> RowSpan)
-> (RowSpan -> RowSpan)
-> (RowSpan -> RowSpan)
-> (Integer -> RowSpan)
-> Num RowSpan
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> RowSpan
$cfromInteger :: Integer -> RowSpan
signum :: RowSpan -> RowSpan
$csignum :: RowSpan -> RowSpan
abs :: RowSpan -> RowSpan
$cabs :: RowSpan -> RowSpan
negate :: RowSpan -> RowSpan
$cnegate :: RowSpan -> RowSpan
* :: RowSpan -> RowSpan -> RowSpan
$c* :: RowSpan -> RowSpan -> RowSpan
- :: RowSpan -> RowSpan -> RowSpan
$c- :: RowSpan -> RowSpan -> RowSpan
+ :: RowSpan -> RowSpan -> RowSpan
$c+ :: RowSpan -> RowSpan -> RowSpan
Num, ReadPrec [RowSpan]
ReadPrec RowSpan
Int -> ReadS RowSpan
ReadS [RowSpan]
(Int -> ReadS RowSpan)
-> ReadS [RowSpan]
-> ReadPrec RowSpan
-> ReadPrec [RowSpan]
-> Read RowSpan
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [RowSpan]
$creadListPrec :: ReadPrec [RowSpan]
readPrec :: ReadPrec RowSpan
$creadPrec :: ReadPrec RowSpan
readList :: ReadS [RowSpan]
$creadList :: ReadS [RowSpan]
readsPrec :: Int -> ReadS RowSpan
$creadsPrec :: Int -> ReadS RowSpan
Read, Int -> RowSpan -> ShowS
[RowSpan] -> ShowS
RowSpan -> String
(Int -> RowSpan -> ShowS)
-> (RowSpan -> String) -> ([RowSpan] -> ShowS) -> Show RowSpan
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RowSpan] -> ShowS
$cshowList :: [RowSpan] -> ShowS
show :: RowSpan -> String
$cshow :: RowSpan -> String
showsPrec :: Int -> RowSpan -> ShowS
$cshowsPrec :: Int -> RowSpan -> ShowS
Show)

-- | The number of columns spanned by a cell.
newtype ColSpan = ColSpan Int
  deriving stock (ColSpan -> ColSpan -> Bool
(ColSpan -> ColSpan -> Bool)
-> (ColSpan -> ColSpan -> Bool) -> Eq ColSpan
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ColSpan -> ColSpan -> Bool
$c/= :: ColSpan -> ColSpan -> Bool
== :: ColSpan -> ColSpan -> Bool
$c== :: ColSpan -> ColSpan -> Bool
Eq, Eq ColSpan
Eq ColSpan
-> (ColSpan -> ColSpan -> Ordering)
-> (ColSpan -> ColSpan -> Bool)
-> (ColSpan -> ColSpan -> Bool)
-> (ColSpan -> ColSpan -> Bool)
-> (ColSpan -> ColSpan -> Bool)
-> (ColSpan -> ColSpan -> ColSpan)
-> (ColSpan -> ColSpan -> ColSpan)
-> Ord ColSpan
ColSpan -> ColSpan -> Bool
ColSpan -> ColSpan -> Ordering
ColSpan -> ColSpan -> ColSpan
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ColSpan -> ColSpan -> ColSpan
$cmin :: ColSpan -> ColSpan -> ColSpan
max :: ColSpan -> ColSpan -> ColSpan
$cmax :: ColSpan -> ColSpan -> ColSpan
>= :: ColSpan -> ColSpan -> Bool
$c>= :: ColSpan -> ColSpan -> Bool
> :: ColSpan -> ColSpan -> Bool
$c> :: ColSpan -> ColSpan -> Bool
<= :: ColSpan -> ColSpan -> Bool
$c<= :: ColSpan -> ColSpan -> Bool
< :: ColSpan -> ColSpan -> Bool
$c< :: ColSpan -> ColSpan -> Bool
compare :: ColSpan -> ColSpan -> Ordering
$ccompare :: ColSpan -> ColSpan -> Ordering
$cp1Ord :: Eq ColSpan
Ord)
  deriving newtype (Int -> ColSpan
ColSpan -> Int
ColSpan -> [ColSpan]
ColSpan -> ColSpan
ColSpan -> ColSpan -> [ColSpan]
ColSpan -> ColSpan -> ColSpan -> [ColSpan]
(ColSpan -> ColSpan)
-> (ColSpan -> ColSpan)
-> (Int -> ColSpan)
-> (ColSpan -> Int)
-> (ColSpan -> [ColSpan])
-> (ColSpan -> ColSpan -> [ColSpan])
-> (ColSpan -> ColSpan -> [ColSpan])
-> (ColSpan -> ColSpan -> ColSpan -> [ColSpan])
-> Enum ColSpan
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ColSpan -> ColSpan -> ColSpan -> [ColSpan]
$cenumFromThenTo :: ColSpan -> ColSpan -> ColSpan -> [ColSpan]
enumFromTo :: ColSpan -> ColSpan -> [ColSpan]
$cenumFromTo :: ColSpan -> ColSpan -> [ColSpan]
enumFromThen :: ColSpan -> ColSpan -> [ColSpan]
$cenumFromThen :: ColSpan -> ColSpan -> [ColSpan]
enumFrom :: ColSpan -> [ColSpan]
$cenumFrom :: ColSpan -> [ColSpan]
fromEnum :: ColSpan -> Int
$cfromEnum :: ColSpan -> Int
toEnum :: Int -> ColSpan
$ctoEnum :: Int -> ColSpan
pred :: ColSpan -> ColSpan
$cpred :: ColSpan -> ColSpan
succ :: ColSpan -> ColSpan
$csucc :: ColSpan -> ColSpan
Enum, Integer -> ColSpan
ColSpan -> ColSpan
ColSpan -> ColSpan -> ColSpan
(ColSpan -> ColSpan -> ColSpan)
-> (ColSpan -> ColSpan -> ColSpan)
-> (ColSpan -> ColSpan -> ColSpan)
-> (ColSpan -> ColSpan)
-> (ColSpan -> ColSpan)
-> (ColSpan -> ColSpan)
-> (Integer -> ColSpan)
-> Num ColSpan
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> ColSpan
$cfromInteger :: Integer -> ColSpan
signum :: ColSpan -> ColSpan
$csignum :: ColSpan -> ColSpan
abs :: ColSpan -> ColSpan
$cabs :: ColSpan -> ColSpan
negate :: ColSpan -> ColSpan
$cnegate :: ColSpan -> ColSpan
* :: ColSpan -> ColSpan -> ColSpan
$c* :: ColSpan -> ColSpan -> ColSpan
- :: ColSpan -> ColSpan -> ColSpan
$c- :: ColSpan -> ColSpan -> ColSpan
+ :: ColSpan -> ColSpan -> ColSpan
$c+ :: ColSpan -> ColSpan -> ColSpan
Num, ReadPrec [ColSpan]
ReadPrec ColSpan
Int -> ReadS ColSpan
ReadS [ColSpan]
(Int -> ReadS ColSpan)
-> ReadS [ColSpan]
-> ReadPrec ColSpan
-> ReadPrec [ColSpan]
-> Read ColSpan
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ColSpan]
$creadListPrec :: ReadPrec [ColSpan]
readPrec :: ReadPrec ColSpan
$creadPrec :: ReadPrec ColSpan
readList :: ReadS [ColSpan]
$creadList :: ReadS [ColSpan]
readsPrec :: Int -> ReadS ColSpan
$creadsPrec :: Int -> ReadS ColSpan
Read, Int -> ColSpan -> ShowS
[ColSpan] -> ShowS
ColSpan -> String
(Int -> ColSpan -> ShowS)
-> (ColSpan -> String) -> ([ColSpan] -> ShowS) -> Show ColSpan
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ColSpan] -> ShowS
$cshowList :: [ColSpan] -> ShowS
show :: ColSpan -> String
$cshow :: ColSpan -> String
showsPrec :: Int -> ColSpan -> ShowS
$cshowsPrec :: Int -> ColSpan -> ShowS
Show)

-- | Cell alignment
data Alignment
  = AlignDefault
  | AlignLeft
  | AlignCenter
  | AlignRight
  deriving stock (Int -> Alignment
Alignment -> Int
Alignment -> [Alignment]
Alignment -> Alignment
Alignment -> Alignment -> [Alignment]
Alignment -> Alignment -> Alignment -> [Alignment]
(Alignment -> Alignment)
-> (Alignment -> Alignment)
-> (Int -> Alignment)
-> (Alignment -> Int)
-> (Alignment -> [Alignment])
-> (Alignment -> Alignment -> [Alignment])
-> (Alignment -> Alignment -> [Alignment])
-> (Alignment -> Alignment -> Alignment -> [Alignment])
-> Enum Alignment
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Alignment -> Alignment -> Alignment -> [Alignment]
$cenumFromThenTo :: Alignment -> Alignment -> Alignment -> [Alignment]
enumFromTo :: Alignment -> Alignment -> [Alignment]
$cenumFromTo :: Alignment -> Alignment -> [Alignment]
enumFromThen :: Alignment -> Alignment -> [Alignment]
$cenumFromThen :: Alignment -> Alignment -> [Alignment]
enumFrom :: Alignment -> [Alignment]
$cenumFrom :: Alignment -> [Alignment]
fromEnum :: Alignment -> Int
$cfromEnum :: Alignment -> Int
toEnum :: Int -> Alignment
$ctoEnum :: Int -> Alignment
pred :: Alignment -> Alignment
$cpred :: Alignment -> Alignment
succ :: Alignment -> Alignment
$csucc :: Alignment -> Alignment
Enum, Alignment -> Alignment -> Bool
(Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool) -> Eq Alignment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Alignment -> Alignment -> Bool
$c/= :: Alignment -> Alignment -> Bool
== :: Alignment -> Alignment -> Bool
$c== :: Alignment -> Alignment -> Bool
Eq, Eq Alignment
Eq Alignment
-> (Alignment -> Alignment -> Ordering)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Bool)
-> (Alignment -> Alignment -> Alignment)
-> (Alignment -> Alignment -> Alignment)
-> Ord Alignment
Alignment -> Alignment -> Bool
Alignment -> Alignment -> Ordering
Alignment -> Alignment -> Alignment
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Alignment -> Alignment -> Alignment
$cmin :: Alignment -> Alignment -> Alignment
max :: Alignment -> Alignment -> Alignment
$cmax :: Alignment -> Alignment -> Alignment
>= :: Alignment -> Alignment -> Bool
$c>= :: Alignment -> Alignment -> Bool
> :: Alignment -> Alignment -> Bool
$c> :: Alignment -> Alignment -> Bool
<= :: Alignment -> Alignment -> Bool
$c<= :: Alignment -> Alignment -> Bool
< :: Alignment -> Alignment -> Bool
$c< :: Alignment -> Alignment -> Bool
compare :: Alignment -> Alignment -> Ordering
$ccompare :: Alignment -> Alignment -> Ordering
$cp1Ord :: Eq Alignment
Ord, ReadPrec [Alignment]
ReadPrec Alignment
Int -> ReadS Alignment
ReadS [Alignment]
(Int -> ReadS Alignment)
-> ReadS [Alignment]
-> ReadPrec Alignment
-> ReadPrec [Alignment]
-> Read Alignment
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Alignment]
$creadListPrec :: ReadPrec [Alignment]
readPrec :: ReadPrec Alignment
$creadPrec :: ReadPrec Alignment
readList :: ReadS [Alignment]
$creadList :: ReadS [Alignment]
readsPrec :: Int -> ReadS Alignment
$creadsPrec :: Int -> ReadS Alignment
Read, Int -> Alignment -> ShowS
[Alignment] -> ShowS
Alignment -> String
(Int -> Alignment -> ShowS)
-> (Alignment -> String)
-> ([Alignment] -> ShowS)
-> Show Alignment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Alignment] -> ShowS
$cshowList :: [Alignment] -> ShowS
show :: Alignment -> String
$cshow :: Alignment -> String
showsPrec :: Int -> Alignment -> ShowS
$cshowsPrec :: Int -> Alignment -> ShowS
Show)