-- Copyright © 2011 Bart Massey -- [This program is licensed under the "MIT License"] -- Please see the file COPYING in the source -- distribution of this software for license terms. -- | Format fields in a tabular fashion. This is not -- nearly as sophisticated as the "tabular" package -- on hackage (http://hackage.haskell.org/package/tabular), -- but may be simpler to use and extend. module Text.SimpleTabular (tabular) where import Data.List -- | Given a format string whose characters are 'l', 'r' and -- 'c' for left-justified, right-justified and centered -- columns, and a list of rows, each row consisting of -- columns of strings to be formatted, emit a -- properly-formatted matrix. Short rows will be padded to -- the size of the longest row with empty strings before -- the data is applied to the format string, at which -- point the number of columns per row must match. tabular :: String -> [[String]] -> String tabular fmt tableau = let rawCols = transpose $ padRows tableau where padRows rows = map (padRow $ maximum $ map length rows) rows where padRow l row = row ++ replicate (l - length row) "" in let padCols = padCol fmt rawCols where padCol (c : cs) (col : cols) | c `elem` "lrc" = let w = maximum $ map length col cols' = padCol cs cols in let Just padf = lookup c [ ('l', padLeft), ('r', padRight), ('c', padCenter) ] where padLeft s = s ++ replicate (w - length s) ' ' padRight s = replicate (w - length s) ' ' ++ s padCenter s = let dw = w - length s in let hdw = dw `div` 2 in replicate hdw ' ' ++ s ++ replicate (dw - hdw) ' ' in map padf col : cols' padCol "" [] = [] padCol _ _ = error "tabular data error" in unlines $ map unwords $ transpose padCols