    module Text.Tabular.SimpleText where

    import Data.List (intersperse, transpose)
    import Text.Tabular

    render :: String -- ^ delim
           -> (rh -> String)
           -> (ch -> String)
           -> (a -> String)
           -> Table rh ch a
           -> String
    render :: forall rh ch a.
    String
    -> (rh -> String)
    -> (ch -> String)
    -> (a -> String)
    -> Table rh ch a
    -> String
    render String
    delim rh -> String
    fr ch -> String
    fc a -> String
    f (Table Header rh
    rh Header ch
    ch [[a]]
    cells) =
      [String] -> String
    unlines ([String] -> String) -> [String] -> String
    forall a b. (a -> b) -> a -> b
    $ [ String -> Header String -> String
    renderColumns String
    delim Header String
    ch2
                ] [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++
                (Header String -> [String]
    forall {a}. Header a -> [a]
    renderRs (Header String -> [String]) -> Header String -> [String]
    forall a b. (a -> b) -> a -> b
    $ (([a], String) -> String) -> Header ([a], String) -> Header String
    forall a b. (a -> b) -> Header a -> Header b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ([a], String) -> String
    renderR (Header ([a], String) -> Header String)
    -> Header ([a], String) -> Header String
    forall a b. (a -> b) -> a -> b
    $ [a] -> [[a]] -> Header String -> Header ([a], String)
    forall h a. h -> [h] -> Header a -> Header (h, a)
    zipHeader [] [[a]]
    cells (Header String -> Header ([a], String))
    -> Header String -> Header ([a], String)
    forall a b. (a -> b) -> a -> b
    $ (rh -> String) -> Header rh -> Header String
    forall a b. (a -> b) -> Header a -> Header b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap rh -> String
    fr Header rh
    rh)
     where
      -- ch2 and cell2 include the row and column labels
      ch2 :: Header String
    ch2 = Properties -> [Header String] -> Header String
    forall h. Properties -> [Header h] -> Header h
    Group Properties
    DoubleLine [String -> Header String
    forall h. h -> Header h
    Header String
    "", (ch -> String) -> Header ch -> Header String
    forall a b. (a -> b) -> Header a -> Header b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ch -> String
    fc Header ch
    ch]
      cells2 :: [[String]]
    cells2 = Header String -> [String]
    forall {a}. Header a -> [a]
    headerContents Header String
    ch2
             [String] -> [[String]] -> [[String]]
    forall a. a -> [a] -> [a]
    : (String -> [a] -> [String]) -> [String] -> [[a]] -> [[String]]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (\String
    h [a]
    cs -> String
    h String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : (a -> String) -> [a] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> String
    f [a]
    cs) [String]
    rhStrings [[a]]
    cells
      --
      renderR :: ([a], String) -> String
    renderR ([a]
    cs,String
    h) = String -> Header String -> String
    renderColumns String
    delim (Header String -> String) -> Header String -> String
    forall a b. (a -> b) -> a -> b
    $ Properties -> [Header String] -> Header String
    forall h. Properties -> [Header h] -> Header h
    Group Properties
    DoubleLine
                        [ String -> Header String
    forall h. h -> Header h
    Header String
    h
                        , ((String, ch) -> String) -> Header (String, ch) -> Header String
    forall a b. (a -> b) -> Header a -> Header b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (String, ch) -> String
    forall a b. (a, b) -> a
    fst (Header (String, ch) -> Header String)
    -> Header (String, ch) -> Header String
    forall a b. (a -> b) -> a -> b
    $ String -> [String] -> Header ch -> Header (String, ch)
    forall h a. h -> [h] -> Header a -> Header (h, a)
    zipHeader String
    "" ((a -> String) -> [a] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> String
    f [a]
    cs) Header ch
    ch]
      rhStrings :: [String]
    rhStrings = (rh -> String) -> [rh] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map rh -> String
    fr ([rh] -> [String]) -> [rh] -> [String]
    forall a b. (a -> b) -> a -> b
    $ Header rh -> [rh]
    forall {a}. Header a -> [a]
    headerContents Header rh
    rh
      renderRs :: Header a -> [a]
    renderRs (Header a
    s)   = [a
    s]
      renderRs (Group Properties
    _ [Header a]
    hs) = (Header a -> [a]) -> [Header a] -> [a]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap Header a -> [a]
    renderRs [Header a]
    hs

    renderColumns :: String
                  -> Header String
                  -> String
    renderColumns :: String -> Header String -> String
    renderColumns String
    delim Header String
    h =
      (Either Properties String -> String)
    -> [Either Properties String] -> String
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap Either Properties String -> String
    forall {a}. Either a String -> String
    helper ([Either Properties String] -> String)
    -> [Either Properties String] -> String
    forall a b. (a -> b) -> a -> b
    $ Header String -> [Either Properties String]
    forall h. Header h -> [Either Properties h]
    flattenHeader Header String
    h
     where
      helper :: Either a String -> String
    helper = (a -> String) -> (String -> String) -> Either a String -> String
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (String -> a -> String
    forall a b. a -> b -> a
    const String
    delim) String -> String
    forall a. a -> a
    id