packages feed

codeforces-cli-0.1.0: src/Codeforces/App/Table.hs

--------------------------------------------------------------------------------

module Codeforces.App.Table
    ( Cell(..)
    , Row
    , Table
    , makeTable
    , ColConfig
    ) where

import           Data.Text                      ( Text )
import qualified Data.Text                     as T

import           System.Console.ANSI

--------------------------------------------------------------------------------

-- | A cell of a table consists of SGR styles and some text content
data Cell = Cell [SGR] Text

cellToText :: Cell -> Text
cellToText (Cell sgrs x) =
    T.concat [T.pack $ setSGRCode sgrs, x, T.pack $ setSGRCode [Reset]]

--------------------------------------------------------------------------------

-- | Name and width of a column
type ColConfig = (Text, Int)

type Row = [Cell]

-- | The table output is a list of row strings.
type Table = [Text]

-- | `makeTable` @colConfigs rows@ returns a list of row strings including the
-- header row
makeTable :: [ColConfig] -> [Row] -> Table
makeTable hs rs = makeHeader hs : map (makeRow hs) rs

makeHeader :: [ColConfig] -> Text
makeHeader hs = T.intercalate colSep $ map (\(s, w) -> pad w s) hs

-- | `makeRow` @colConfigs row@ makes a row string from the supplied column
-- widths and row cells.
makeRow :: [ColConfig] -> Row -> Text
makeRow hs row = T.intercalate colSep paddedCells
  where
    paddedCells = zipWith (\(_, w) cell -> fmtCell w cell) hs row
    fmtCell w (Cell sgrs x) = cellToText $ Cell sgrs (pad w x)

colSep :: Text
colSep = "  "

pad :: Int -> Text -> Text
pad w s | len > w   = T.take (w - 2) s <> ".."
        | otherwise = s <> T.replicate (w - len) " "
    where len = T.length s

--------------------------------------------------------------------------------