table-layout-0.5.1.1: 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 (given a list of rows):

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

Fancy table without header:

>>> putStrLn $ layoutTableToString [rowGroup [["Jack", "184.74"]], rowGroup [["Jane", "162.2"]]] def [def , numCol] 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 def))
                                   [fixedLeftCol 20, column (fixed 10) center dotAlign def]
                                   unicodeRoundS
╭──────────────────────┬────────────╮
│        Title         │   Length   │
╞══════════════════════╪════════════╡
│ A very long text     │    0.4200… │
├──────────────────────┼────────────┤
│ Short text           │ …200.5     │
╰──────────────────────┴────────────╯

Synopsis

Layout combinators

Specify how a column is rendered with the combinators in this section. Sensible default values are provided with def.

Columns

data ColSpec Source

Specifies the layout of a column.

column :: LenSpec -> Position H -> AlignSpec -> CutMark -> ColSpec Source

Smart constructor to specify a column.

numCol :: ColSpec Source

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

fixedCol :: Int -> Position H -> ColSpec Source

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

fixedLeftCol :: Int -> ColSpec Source

Fixes the column length and positions on the left.

Length of columns

data LenSpec Source

Determines how long a column will be.

expand :: LenSpec Source

Allows columns to use as much space as needed.

fixed :: Int -> LenSpec Source

Fixes column length to a specific width.

expandUntil :: Int -> LenSpec Source

The column will expand as long as it is smaller as the given width.

fixedUntil :: Int -> LenSpec Source

The column will be at least as wide as the given width.

Positional alignment

data Position orientation Source

Specifies a position relative from a beginning.

Instances

Show (Position orientation) Source 
Default (Position o) Source 

data H Source

Horizontal orientation.

center :: Position orientation Source

Alignment of cells at characters

data AlignSpec Source

Determines whether a column will align at a specific letter.

Instances

Default AlignSpec Source

No alignment is the default.

noAlign :: AlignSpec Source

Don't align text.

charAlign :: Char -> AlignSpec Source

Align text at the first occurence of a given Char.

predAlign :: (Char -> Bool) -> AlignSpec Source

Align at the first match of a predicate.

dotAlign :: AlignSpec Source

Align all text at the first dot from the left. This is most useful for floating point numbers.

Cut marks

data CutMark 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.

Instances

Default CutMark Source

A single ellipsis unicode character is used to show cut marks.

noCutMark :: CutMark Source

Don't show any cut mark when text is cut.

singleCutMark :: String -> CutMark Source

Use the cut mark on both sides by reversing it on the other.

doubleCutMark :: String -> String -> CutMark Source

Specify two different cut marks, one for cuts on the left and one for cuts on the right.

ellipsisCutMark :: CutMark Source

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

Basic grid and table layout

type Row a = [a] Source

An alias for lists, conceptually for values with a horizontal arrangement.

layoutToCells :: [Row String] -> [ColSpec] -> [Row String] Source

Modifies cells according to the given ColSpec.

layoutToLines :: [Row String] -> [ColSpec] -> [String] Source

Behaves like layoutToCells but produces lines by joining with whitespace.

layoutToString :: [Row String] -> [ColSpec] -> String Source

Behaves like layoutToCells 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 :: [Row String] -> RowGroup Source

Construct a row group from a list of rows.

data HeaderColSpec Source

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

layoutTableToLines Source

Arguments

:: [RowGroup]

Groups

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

Optional header details

-> [ColSpec]

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."]

type Col a = [a] Source

An alias for lists, conceptually for values with a vertical arrangement.

columnsAsGrid :: Position V -> [Col [a]] -> [Row [a]] Source

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

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

The result is intended to be used with layoutToCells or with rowGroup.

data V Source

Vertical orientation

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

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

justifyWordListsAsGrid :: [(Int, [String])] -> [Row 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 :: Position o -> 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 left 10 "foo"
"foo       "

trimOrPad :: Position o -> CutMark -> 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 left (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 :: Position o -> CutMark -> 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

Render your own kind of tables with the following functions.

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 -> Position H -> ColModInfo -> ColModInfo Source

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

ensureWidthOfCMI :: String -> Position H -> ColModInfo -> ColModInfo Source

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

columnModifier :: Position H -> CutMark -> ColModInfo -> String -> String Source

Generates a function which modifies a given String according to Position, CutMark and ColModInfo.

data AlignInfo Source

Specifies the length before and after a letter.

Instances

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)] -> [Row 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.

data OccSpec Source

Specifies an occurence of a letter.