table-layout-0.3.0.0: Layout text as grid or table.

Safe HaskellSafe
LanguageHaskell2010

Text.Layout.Table

Contents

Description

This module provides tools to layout text as grid or table. Besides basic things like specifying column positioning, alignment on the same character and length restriction it also provides advanced features like justifying text and fancy tables with styling support.

Some examples

Layouting text as a plain grid:

>>> putStrLn $ layoutToString [["a", "b"], ["c", "d"]] (repeat defaultL)
a b
c d

Fancy table without header:

>>> putStrLn $ layoutTableToString [rowGroup [["Jack", "184.74"]], rowGroup [["Jane", "162.2"]]] Nothing [defaultL, numL] unicodeRoundS
╭──────┬────────╮
│ Jack │ 184.74 │
├──────┼────────┤
│ Jane │ 162.2  │
╰──────┴────────╯

Fancy table with header:

>>> putStrLn $ layoutTableToString [ rowGroup [["A very long text", "0.42000000"]]
                                   , rowGroup [["Short text", "100200.5"]]
                                   ]
                                   (Just (["Title", "Length"], repeat centerHL))
                                   [ fixedLeftL 20
                                   , LayoutSpec (Fixed 10)
                                                CenterPos
                                                dotAlign
                                                ellipsisCutMark
                                   ]
                                   unicodeRoundS
╭──────────────────────┬────────────╮
│        Title         │   Length   │
╞══════════════════════╪════════════╡
│ A very long text     │    0.4200… │
├──────────────────────┼────────────┤
│ Short text           │ …200.5     │
╰──────────────────────┴────────────╯

Synopsis

Layout types and combinators

Specify the layout of columns. Layout combinators have a L as postfix.

data LayoutSpec Source

Determines the layout of a column.

defaultL :: LayoutSpec Source

The default layout will allow maximum expand and is positioned on the left.

numL :: LayoutSpec Source

Numbers are positioned on the right and aligned on the floating point dot.

fixedL :: Int -> PosSpec -> LayoutSpec Source

Fixes the column length and positions according to the given PosSpec.

fixedLeftL :: Int -> LayoutSpec Source

Fixes the column length and positions on the left.

data LenSpec Source

Determines how long a column will be.

Instances

data PosSpec Source

Determines how a column will be positioned. Note that on an odd number of space, centering is left-biased.

Constructors

LeftPos 
RightPos 
CenterPos 

Instances

data AlignSpec Source

Determines whether a column will align at a specific letter.

noAlign :: AlignSpec Source

Don't align text.

dotAlign :: AlignSpec Source

Align all text at the dot.

data OccSpec Source

Specifies an occurence of a letter.

data CutMarkSpec Source

Specifies how the place looks where a String has been cut. Note that the cut mark may be cut itself, to fit into a column.

defaultCutMark :: CutMarkSpec Source

Default cut mark used when cutting off text.

ellipsisCutMark :: CutMarkSpec Source

A single unicode character showing three dots is used as cut mark.

noCutMark :: CutMarkSpec Source

Don't use a cut mark.

singleCutMark :: String -> CutMarkSpec Source

Use the same cut mark for left and right.

cutMark :: String -> String -> CutMarkSpec Source

Display custom characters on a cut.

Basic grid and table layout

layoutToCells :: [[String]] -> [LayoutSpec] -> [[String]] Source

Modifies cells according to the given LayoutSpec.

layoutToLines :: [[String]] -> [LayoutSpec] -> [String] Source

Behaves like layoutCells but produces lines by joining with whitespace.

layoutToString :: [[String]] -> [LayoutSpec] -> String Source

Behaves like layoutCells but produces a String by joining with the newline character.

Grid modification functions

altLines :: [a -> b] -> [a] -> [b] Source

Applies functions alternating to given lines. This makes it easy to color lines to improve readability in a row.

checkeredCells :: (a -> b) -> (a -> b) -> [[a]] -> [[b]] Source

Applies functions alternating to cells for every line, every other line gets shifted by one. This is useful for distinguishability of single cells in a grid arrangement.

Advanced table layout

data RowGroup Source

Groups rows together, which are not seperated from each other.

rowGroup :: [[String]] -> RowGroup Source

Construct a row group from a list of rows.

data HeaderLayoutSpec Source

Specifies how a header is layout, by omitting the cut mark it will use the one specified in the LayoutSpec like the other cells in that column.

centerHL :: HeaderLayoutSpec Source

A centered header layout.

leftHL :: HeaderLayoutSpec Source

A left-positioned header layout.

layoutTableToLines Source

Arguments

:: [RowGroup]

Groups

-> Maybe ([String], [HeaderLayoutSpec])

Optional header details

-> [LayoutSpec]

Layout specification of columns

-> TableStyle

Visual table style

-> [String] 

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.

Text justification

Text can easily be justified and distributed over multiple lines. Such columns can easily be combined with other columns.

justify :: Int -> [String] -> [String] Source

Fits as many words on a line, depending on the given width. Every line, but the last one, gets equally filled with spaces between the words, as far as possible.

justifyText :: Int -> String -> [String] Source

Uses words to split the text into words and justifies it with justify.

>>> justifyText 10 "This text will not fit on one line."
["This  text","will   not","fit on one","line."]

columnsAsGrid :: VertPosSpec -> [[[a]]] -> [[[a]]] Source

Merges multiple columns together and merges them to a valid grid without holes. The following example clarifies this:

>>> columnsAsGrid TopVPos [justifyText 10 "This text will not fit on one line.", ["42", "23"]]
[["This  text","42"],["will   not","23"],["fit on one",""],["line.",""]]

justifyTextsAsGrid :: [(Int, String)] -> [[String]] Source

Justifies texts and presents the resulting lines in a grid structure (each text in one column).

justifyWordListsAsGrid :: [(Int, [String])] -> [[String]] Source

Justifies lists of words and presents the resulting lines in a grid structure (each list of words in one column). This is useful if you don't want to split just at whitespaces.

Table styles

Column modification functions

pad :: PosSpec -> Int -> String -> String Source

Assume the given length is greater or equal than the length of the String passed. Pads the given String accordingly, using the position specification.

>>> pad LeftPos 10 "foo"
"foo       "

trimOrPad :: PosSpec -> CutMarkSpec -> Int -> String -> String Source

If the given text is too long, the String will be shortened according to the position specification, also adds some dots to indicate that the column has been trimmed in length, otherwise behaves like pad.

>>> trimOrPad LeftPos (singleCutMark "..") 10 "A longer text."
"A longer.."

align :: OccSpec -> AlignInfo -> String -> String Source

Align a column by first finding the position to pad with and then padding the missing lengths to the maximum value. If no such position is found, it will align it such that it gets aligned before that position.

This function assumes:

ai <> deriveAlignInfo s = ai

alignFixed :: PosSpec -> CutMarkSpec -> Int -> OccSpec -> AlignInfo -> String -> String Source

Aligns a column using a fixed width, fitting it to the width by either filling or cutting while respecting the alignment.

Column modifaction primitives

data ColModInfo Source

Specifies how a column should be modified.

widthCMI :: ColModInfo -> Int Source

Get the exact width after the modification.

unalignedCMI :: ColModInfo -> ColModInfo Source

Remove alignment from a ColModInfo. This is used to change alignment of headers, while using the combined width information.

ensureWidthCMI :: Int -> PosSpec -> ColModInfo -> ColModInfo Source

Ensures that the modification provides a minimum width, but only if it is not limited.

ensureWidthOfCMI :: String -> PosSpec -> ColModInfo -> ColModInfo Source

Ensures that the given String will fit into the modified columns.

columnModifier :: PosSpec -> CutMarkSpec -> ColModInfo -> String -> String Source

Generates a function which modifies a given String according to PosSpec, CutMarkSpec and ColModInfo.

data AlignInfo Source

Specifies the length before and after a letter.

Constructors

AlignInfo Int Int 

Instances

Show AlignInfo Source 
Monoid AlignInfo Source

Since determining a maximum in two directions is not possible, a Monoid instance is provided.

widthAI :: AlignInfo -> Int Source

The column width when using the AlignInfo.

deriveColModInfos :: [(LenSpec, AlignSpec)] -> [[String]] -> [ColModInfo] Source

Derive the ColModInfo by using layout specifications and looking at the cells.

deriveAlignInfo :: OccSpec -> String -> AlignInfo Source

Generate the AlignInfo of a cell using the OccSpec.