table-layout 0.6.0.1 → 0.7.0.0
raw patch · 5 files changed
+140/−78 lines, 5 filesdep ~QuickCheck
Dependency ranges changed: QuickCheck
Files
- README.md +33/−32
- src/Test.hs +12/−12
- src/Text/Layout/Table.hs +92/−31
- src/Text/Layout/Table/Internal.hs +1/−1
- table-layout.cabal +2/−2
README.md view
@@ -10,16 +10,16 @@ ## Tutorial -### Basic grid layout+### Grid layout Render some text rows as grid: ``` hs-putStrLn $ layoutToString [ ["top left", "top right"]- , ["bottom left", "bottom right"]- ]- [column expand left def def, column expand right def def]+putStrLn $ gridString [column expand left def def, column expand right def def]+ [ ["top left", "top right"]+ , ["bottom left", "bottom right"]+ ] ```-`layoutToString` will join cells with a whitespace and rows with a newline character. The result is not spectacular but does look as expected:+`gridString` will join cells with a whitespace and rows with a newline character. The result is not spectacular but does look as expected: ``` top left top right bottom left bottom right@@ -30,9 +30,9 @@ Additionally some common types are provided. A particularly useful one is `numCol`: ``` hs-mapM_ putStrLn $ layoutToLines (map ((: []) . show) [1.2, 100.5, 0.037, 5000.00001]) [numCol]+mapM_ putStrLn $ gridLines [numCol] (map ((: []) . show) [1.2, 100.5, 0.037, 5000.00001]) ```-We simply display the given numbers as a dot-aligned single column:+This will display the given numbers as a dot-aligned single column: ``` 1.2 100.5 @@ -51,16 +51,17 @@ ### Table layout -Grids are fine, but sometimes we want to explicitly display a table, e.g. as output in a database application. This is where ```layoutTableToString``` comes in handy:+Grids are fine, but sometimes we want to explicitly display a table, e.g. as output in a database application. This is where ```tableString``` comes in handy: ``` hs-putStrLn $ layoutTableToString [ rowG ["Jack", "184.74"]- , rowG ["Jane", "162.2"]- ]- def- [def , numCol] unicodeRoundS+putStrLn $ tableString [def , numCol]+ unicodeRoundS+ def+ [ rowG ["Jack", "184.74"]+ , rowG ["Jane", "162.2"]+ ] ```-A row group is a group of rows which form one cell, meaning that each line of a group is not visually seperated from the other ones. The second argument specifies an optional header, the third the column specifications and the style. This will yield the following result:+A row group is a group of rows which form one cell, meaning that each line of a group is not visually seperated from the other ones. In addition we specify the style and an optional header (which is not used by default). This will yield the following result: ``` ╭──────┬────────╮@@ -72,20 +73,20 @@ ### Table headers -The same is possible with headers:+Optionally we can use table headers. `titlesH` will center titles, whereas `fullH` allows more control: ``` hs-putStrLn $ layoutTableToString [ rowG ["A very long text", "0.42000000"]- , rowG ["Short text", "100200.5"]- ]- (Just (["Title", "Length"], repeat def))- [fixedLeftCol 10, column (fixed 10) center dotAlign def]- unicodeS+putStrLn $ tableString [fixedLeftCol 10, column (fixed 10) center dotAlign def]+ unicodeS+ (titlesH ["Text", "Number"])+ [ rowG ["A very long text", "0.42000000"]+ , rowG ["Short text", "100200.5"]+ ] ```-Some fixed length columns are used this time and the header is displayed with a different style (additionally the header column will be specified differently):+Headers are always displayed with a different style, than the other columns (centered by default). A maximum column width is respected, otherwise a header may acquire additional space. ``` ┌────────────┬────────────┐-│ Title │ Length │+│ Text │ Number │ ╞════════════╪════════════╡ │ A very lo… │ 0.42000… │ ├────────────┼────────────┤@@ -93,16 +94,16 @@ └────────────┴────────────┘ ``` ### Vertical positioning and justified text-Because a row group consists of multiple lines, we may also want to align the content of cells vertically, especially when we don't know how many lines will be there. The following piece of code will display a left-justified text alongside the length of the text:+Because a row group consists of multiple lines, we may also want to align the content of cells vertically, especially when we don't know how many lines there will be. The following piece of code will display a left-justified text alongside the length of the text: ``` hs let txt = "Lorem ipsum ..." -in putStrLn $ layoutTableToString [colsAllG center [ justifyText 50 txt- , [show $ length txt]- ]- ]- (Just (["Text", "Length"], repeat def))- [fixedLeftCol 50, numCol]- asciiS+in putStrLn $ tableString [fixedLeftCol 50, numCol]+ asciiS+ (titlesH ["Text", "Length"])+ [colsAllG center [ justifyText 50 txt+ , [show $ length txt]+ ]+ ] ``` `colsAllG` will merge the given columns into a row group with the given positioning: ```
src/Test.hs view
@@ -5,25 +5,25 @@ import Text.Layout.Table main :: IO ()-main = putStrLn $ layoutTableToString rowGroups- (Just (["Layout", "Result"], repeat def))- [ column (expandUntil 30) left (charAlign ':') def- , column expand center noAlign noCutMark- ]- unicodeRoundS+main = putStrLn $ tableString [ column (expandUntil 30) left (charAlign ':') def+ , column expand center noAlign noCutMark+ ]+ unicodeRoundS+ (titlesH ["Layout", "Result"])+ rowGroups where rowGroups = flip concatMap styles $ \style -> flip map columTs $ \(cSpec, is) -> colsAllG center [ is , genTable cSpec style ]- genTable c s = layoutTableToLines [ rowsG [ [longText, smallNum, "foo"]- , [shortText, bigNum, "bar"]- ]+ genTable c s = tableLines (repeat c)+ s+ (titlesH ["Some text", "Some numbers", "X"])+ [ rowsG [ [longText, smallNum, "foo"]+ , [shortText, bigNum, "bar"] ]- (Just (["Some text", "Some numbers", "X"], repeat def))- (repeat c)- s+ ] longText = "This is long text" shortText = "Short" bigNum = "200300400500600.2"
src/Text/Layout/Table.hs view
@@ -42,27 +42,35 @@ , doubleCutMark , ellipsisCutMark - -- * Basic grid and table layout+ -- * Basic grid layout , Row- , layoutToCells- , layoutToLines- , layoutToString+ , grid+ , gridLines+ , gridString -- * Grid modification functions , altLines , checkeredCells - -- * Advanced table layout+ -- * Table layout+ -- ** Grouping rows , RowGroup , rowsG , rowG , colsG , colsAllG++ -- ** Headers , HeaderColSpec , headerColumn- , layoutTableToLines- , layoutTableToString+ , Header+ , fullH+ , titlesH + -- ** Layout+ , tableLines+ , tableString+ -- * Text justification -- $justify , justify@@ -76,6 +84,15 @@ , bottom , V + -- * Deprecated functions+ , layoutToCells+ , layoutToLines+ , layoutToString+ , layoutTableToLines+ , layoutTableToString+++ -- * Table styles , module Text.Layout.Table.Style @@ -411,23 +428,35 @@ -- Basic layout ------------------------------------------------------------------------------- --- | Modifies cells according to the given 'ColSpec'.-layoutToCells :: [Row String] -> [ColSpec] -> [Row String]-layoutToCells tab specs = zipWith apply tab- . repeat- . zipWith (uncurry columnModifier) (map (position A.&&& cutMark) specs)- $ deriveColModInfos (map (lenSpec A.&&& alignSpec) specs) tab+-- | Modifies cells according to the column specification.+grid :: [ColSpec] -> [Row String] -> [Row String]+grid specs tab = zipWith apply tab+ . repeat+ . zipWith (uncurry columnModifier) (map (position A.&&& cutMark) specs)+ $ deriveColModInfos (map (lenSpec A.&&& alignSpec) specs) tab where apply = zipWith $ flip ($) --- | Behaves like 'layoutToCells' but produces lines by joining with whitespace.+-- | Behaves like 'grid' but produces lines by joining with whitespace.+gridLines :: [ColSpec] -> [Row String] -> [String]+gridLines specs = fmap unwords . grid specs++-- | Behaves like 'gridLines' but produces a string by joining with the newline+-- character.+gridString :: [ColSpec] -> [Row String] -> String+gridString specs = concatLines . gridLines specs++{-# DEPRECATED layoutToCells "Use grid instead." #-}+layoutToCells :: [Row String] -> [ColSpec] -> [Row String]+layoutToCells = flip grid++{-# DEPRECATED layoutToLines "Use gridLines instead." #-} layoutToLines :: [Row String] -> [ColSpec] -> [String]-layoutToLines tab specs = map unwords $ layoutToCells tab specs+layoutToLines = flip gridLines --- | Behaves like 'layoutToCells' but produces a 'String' by joining with the--- newline character.+{-# DEPRECATED layoutToString "Use gridString instead." #-} layoutToString :: [Row String] -> [ColSpec] -> String-layoutToString tab specs = concatLines $ layoutToLines tab specs+layoutToString = flip gridString ------------------------------------------------------------------------------- -- Grid modification functions@@ -458,15 +487,31 @@ colsAllG :: Position V -> [Col String] -> RowGroup colsAllG p = rowsG . colsAsRowsAll p +-- | Specifies a header.+data Header = Header [HeaderColSpec] [String]+ | NoHeader++-- | No header is used by default.+instance Default Header where+ def = NoHeader++-- | Specify a header column for every title.+fullH :: [HeaderColSpec] -> [String] -> Header+fullH = Header++-- | Use titles with the default header column specification.+titlesH :: [String] -> Header+titlesH = fullH $ repeat def+ -- | Layouts a good-looking table with a optional header. Note that specifying -- fewer layout specifications than columns or vice versa will result in not -- showing them.-layoutTableToLines :: [RowGroup] -- ^ Groups- -> Maybe ([String], [HeaderColSpec]) -- ^ Optional header details- -> [ColSpec] -- ^ Layout specification of columns- -> TableStyle -- ^ Visual table style- -> [String]-layoutTableToLines rGs optHeaderInfo specs (TableStyle { .. }) =+tableLines :: [ColSpec] -- ^ Layout specification of columns+ -> TableStyle -- ^ Visual table style+ -> Header -- ^ Optional header details+ -> [RowGroup] -- ^ Rows which form a cell together+ -> [String]+tableLines specs (TableStyle { .. }) header rGs = topLine : addHeaderLines (rowGroupLines ++ [bottomLine]) where -- Helpers for horizontal lines@@ -486,9 +531,9 @@ rowGroupLines = intercalate [groupSepLine] $ map (map (hLine ' ' groupV) . applyRowMods . rows) rGs -- Optional values for the header- (addHeaderLines, fitHeaderIntoCMIs, realTopH, realTopL, realTopC, realTopR) = case optHeaderInfo of- Just (h, headerColSpecs) ->- let headerLine = hLine ' ' headerV (zipApply h headerRowMods)+ (addHeaderLines, fitHeaderIntoCMIs, realTopH, realTopL, realTopC, realTopR) = case header of+ Header headerColSpecs hTitles ->+ let headerLine = hLine ' ' headerV (zipApply hTitles headerRowMods) headerRowMods = zipWith3 (\(HeaderColSpec pos optCutMark) cutMark -> columnModifier pos $ fromMaybe cutMark optCutMark )@@ -497,13 +542,13 @@ (map unalignedCMI cMIs) in ( (headerLine :) . (headerSepLine :)- , zipWith ($) $ zipWith ($) (map ensureWidthOfCMI h) posSpecs+ , zipWith ($) $ zipWith ($) (map ensureWidthOfCMI hTitles) posSpecs , headerTopH , headerTopL , headerTopC , headerTopR )- Nothing ->+ NoHeader -> ( id , id , groupTopH@@ -521,13 +566,29 @@ colWidths = map widthCMI cMIs zipApply = zipWith $ flip ($) +-- | Does the same as 'tableLines', but concatenates lines.+tableString :: [ColSpec] -- ^ Layout specification of columns+ -> TableStyle -- ^ Visual table style+ -> Header -- ^ Optional header details+ -> [RowGroup] -- ^ Rows which form a cell together+ -> String+tableString specs style header rGs = concatLines $ tableLines specs style header rGs++{-# DEPRECATED layoutTableToLines "Use tableLines instead." #-}+layoutTableToLines :: [RowGroup]+ -> Header+ -> [ColSpec]+ -> TableStyle+ -> [String]+layoutTableToLines rGs header specs style = tableLines specs style header rGs++{-# DEPRECATED layoutTableToString "Use tableString instead." #-} layoutTableToString :: [RowGroup]- -> Maybe ([String], [HeaderColSpec])+ -> Header -> [ColSpec] -> TableStyle -> String layoutTableToString rGs optHeaderInfo specs = concatLines . layoutTableToLines rGs optHeaderInfo specs- ------------------------------------------------------------------------------- -- Text justification
src/Text/Layout/Table/Internal.hs view
@@ -8,7 +8,7 @@ -- | Groups rows together, which should not be visually seperated from each other. newtype RowGroup = RowGroup- { rows :: [[String]] + { rows :: [[String]] } -- | Group the given rows together.
table-layout.cabal view
@@ -6,7 +6,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.6.0.1+version: 0.7.0.0 synopsis: Layout text as grid or table. @@ -95,7 +95,7 @@ hs-source-dirs: test-suite, src main-is: Spec.hs build-depends: base >=4.8 && <4.10,- QuickCheck >=2.8 && < 2.9,+ QuickCheck >=2.8 && < 2.10, HUnit ==1.3.*, data-default-class ==0.0.*, data-default-instances-base ==0.1.*,