2.1Lists
2.2Strings
~r*
8.18
top
← prev up next →

Text TableπŸ”— i

Laurent Orseau

A simple package to display utf-8 textual tables.

License: APACHE2+MIT

To install:

raco pkg install text-table

See the example in the main submodule of the "main.rkt" file. You can observe the results by running:

racket -l text-table

Examples:
;Minimalistic example:
'((abcdefggggh)
(123456775415646547987411)
(111223333445678888)))

┌───┬───┬────┬──┬─┬──────────┬────┬────┐

│a│b│c │d │e│f │gggg│h

├───┼───┼────┼──┼─┼──────────┼────┼────┤

│123│456│77│54│1│5646547987│41│1

├───┼───┼────┼──┼─┼──────────┼────┼────┤

│111│22 │3333│44│5│6 │7 │8888│

└───┴───┴────┴──┴─┴──────────┴────┴────┘

;With more bells and whistles
'((abcdefggggh)
(123456775415646547987411)
(111223333445678888))
#:border-style'double
#:framed?#f
#:row-sep?#t
#:align'(leftcenterright))

a║ b ║ c║ d║e║ f║gggg║ h

═══╬═══╬════╬══╬═╬══════════╬════╬════

123║456║77║54║1║5646547987║41║ 1

═══╬═══╬════╬══╬═╬══════════╬════╬════

111║22 ║3333║44║5║ 6║ 7║8888

;Custom border style using border-style-frame/c
> (print-table '((abcabcabc)
(abcdefababcdef)
(aabcdefabc))
#:border-style
'("╭─┬╮"
"│.││"
"├─┼┤"
"╰─┴╯")
#:align'(center)
#:framed?#t
#:row-sep?#t)

╭──────┬──────┬──────╮

│.abc..│.abc..│.abc..│

├──────┼──────┼──────┤

│abcdef│..ab..│abcdef│

├──────┼──────┼──────┤

│..a...│abcdef│.abc..│

╰──────┴──────┴──────╯

;Custom border style using border-style2/c
> (print-table '((abcabcabc)
(abcdefababcdef)
(aabcdefabc))
#:border-style
'(("<table>""""""")
("<tr><td> "" "" </td><td> "" </td></tr>")
("""""""")
("</table>"""""""))
#:framed?#t
#:row-sep?#f)

<table>

<tr><td> abc</td><td> abc</td><td> abc</td></tr>

<tr><td> abcdef </td><td> ab </td><td> abcdef </td></tr>

<tr><td> a</td><td> abcdef </td><td> abc</td></tr>

</table>

;LaTeX style
> (print-table '((abcabcabc)
(abcdefababcdef)
(aabcdefabc))
#:border-style'latex)

\begin{tabular}{|l|l|l|}

\hline

abc& abc& abc\\

\hline

abcdef & ab & abcdef \\

\hline

a& abcdef & abc\\

\hline

\end{tabular}

;Aligning numbers (incorrectly then well)
#:row-sep?'(#t#f...)
#:col-sep?'(#t#f...)
#:align'(leftright...center)
#:->string
(list
~a ;Name
~a (~r* )(~r* #:precision'(=2))(~r* #:notation'exponential);Speed
~a );Unit
;The table:
`((NameSpeed...Unit)
(Alice10..."km/h")
(Bob,(sqrt 2)..."m/s")
(Charlie+inf.0+nan.0......n/a)
(light,(* 299792458(expt 103))..."mm/s"))))

┌───────┬─────────────────────────────────────────────────────────────────┐

│Name SpeedSpeed SpeedSpeed Unit│

├───────┼─────────────────────────────────────────────────────────────────┤

│Alice10 10 10.001e+01 km/h│

│Bob│1.4142135623730951 1.4142141.41 1.414214e+00 m/s │

│Charlie│+inf.0 +nan.0+inf.0 +nan.0 n/a │

│light299792458000 299792458000 299792458000.00 2.997925e+11 mm/s│

└───────┴─────────────────────────────────────────────────────────────────┘

;Empty style and doubly repeating alignments
#:border-style'empty
#:align'(rightleft......)
(list (make-list10'*)
(make-list10'**)
(make-list10'***)
(make-list10'****)
(make-list10'*****)
(make-list10"|")))

**********

********************

******************************

****************************************

**************************************************

||||||||||

;Multiple separators
> (print-table (for/list ((i6))(for/list ((j10))(* (+ i1)(+ j1))))
#:row-sep?'(#t#f......)
#:col-sep?'(#t#f......))

┌─┬─────┬─────┬─────┬─────┬──┐

│1│23 │45 │67 │89 │10│

├─┼─────┼─────┼─────┼─────┼──┤

│2│46 │810│12 14│16 18│20│

│3│69 │12 15│18 21│24 27│30│

├─┼─────┼─────┼─────┼─────┼──┤

│4│812│16 20│24 28│32 36│40│

│5│10 15│20 25│30 35│40 45│50│

├─┼─────┼─────┼─────┼─────┼──┤

│6│12 18│24 30│36 42│48 54│60│

└─┴─────┴─────┴─────┴─────┴──┘

1TablesπŸ”— i

procedure

( table->string table
[ #:->stringto-string
#:border-styleborder-style
#:framed?framed?
#:row-sep?row-sep?
#:col-sep?col-sep?
#:alignalign
#:row-alignrow-align])string?
table:(listof list? )
border-style:border-style/c ='single
framed?:boolean? =#t
row-sep?:(pattern-list-of boolean? )=#t
col-sep?:(pattern-list-of boolean? )=#t
align:(pattern-list-of (or/c 'left'center'right))='left
row-align : (pattern-list-of (or/c 'top'center'bottom))
= 'top
Accepts a table specified as a list of lists, and returns a string representing the table. The lists must all be of the same lengths.

The to-string procedure is used to convert cell values to strings, or a pattern-list of such procedures. Note that strings are not converted.

The border-style specifies the style of lines to be used in drawing the table.

When framed? is #true, a frame is drawn around the outside of the table.

The row-sep? and col-sep? arguments specify whether separators are added between rows or columns.

The align specification indicates how the contents of the cells are to be aligned within their cells. A single-symbol specification applies to all cells, or a list of symbols of the same length as the rows can be applied in order to specify the alignment of each column independently. When align is a list, it is trimmed to the length of the columns if it is too long, or the last element of the list is used for the remaining columns if it is too short.

The row-align specification indicates how the contents of the cells are aligned in a row, when cells are strings with multiple lines.

The to-string, align and row-align, row-sep? and col-sep? arguments accept pattern lists.

procedure

[ #:->stringto-string
#:border-styleborder-style
#:framed?framed?
#:row-sep?row-sep?
#:col-sep?col-sep?
#:alignalign
#:row-alignrow-align])string?
table:(listof list? )
border-style:border-style/c ='single
framed?:boolean? =#f
row-sep?:(pattern-list-of boolean? )=#f
col-sep?:(pattern-list-of boolean? )=#f
align:(pattern-list-of (or/c 'left'center'right))='left
row-align : (pattern-list-of (or/c 'top'center'bottom))
= 'top
Like table->string , but with different default arguments to output a minimalistic table.

Example:
#:align'(leftright)
'((abcdefggggh)
(123456775415646547987411)
(111223333445678888))))

a bcd ef ggggh

123 456 77 54 1 5646547987 411

11122 3333 44 567 8888

procedure

( print-table table
[ #:->stringto-string
#:border-styleborder-style
#:framed?framed?
#:row-sep?row-sep?
#:col-sep?col-sep?
#:alignalign
#:row-alignrow-align])void?
table:(listof list? )
border-style:border-style/c ='single
framed?:boolean? =#t
row-sep?:(pattern-list-of boolean? )=#t
col-sep?:(pattern-list-of boolean? )=#t
align:(pattern-list-of (or/c 'left'center'right))='left
row-align : (pattern-list-of (or/c 'top'center'bottom))
= 'top
Shorthand form for (displayln (table->string args... )). Takes the same arguments as table->string .

procedure

[ #:->stringto-string
#:border-styleborder-style
#:framed?framed?
#:row-sep?row-sep?
#:col-sep?col-sep?
#:alignalign
#:row-alignrow-align])void?
table:(listof list? )
border-style:border-style/c ='single
framed?:boolean? =#f
row-sep?:(pattern-list-of boolean? )=#f
col-sep?:(pattern-list-of boolean? )=#f
align:(pattern-list-of (or/c 'left'center'right))='left
row-align : (pattern-list-of (or/c 'top'center'bottom))
= 'top
Shorthand form for (displayln (simple-table->string args... )). Takes the same arguments as simple-table->string .

=
(or/c
'empty'latex'space'space-single'single'rounded'double'heavy
Border style contract. The list element is for custom border styles. See the example at the top of this document.

The old border style. Obsolete but kept for backward compatibility. See border-style2/c instead. Note that, compared to border-style2/c , the first an second lists are in reverse order, the row separator is the same for all lines, and the space filler is always " ".

Each string specifies one of the elements of the frame of the table. The strings can be of arbitrary length
'((______)
(____)
(_"_\n__"__))
#:border-style
'(("╭""^""┬""╮")
("{"".""│""}")
("├""─""+""┤")
("╰""v""┴""╯")))

╭^^┬^^┬^^^^┬^╮

{_.│_.│____│_}

├──+──+────+─┤

{_.│_.│_...│_}

├──+──+────+─┤

{__│_.│_...│_}

{..│__│....│.}

╰vv┴vv┴vvvv┴v╯

The element "." is a space filler. Note that each element can be a multi-character string rather than a single char. See also border-style-frame/c .

=
(list/c (string-length=/c 5);top line
(string-length=/c 5);text line
(string-length=/c 5);middle line
(string-length=/c 5);bottom line)
A simplification of border-style2/c where each element of the frame is a single character, so they can all be specified in a single string per line.
> (print-table '((abcabcabc)
(abcdefababcdef)
(aabcdefabc))
#:border-style
'("╭─┬╮"
"│.││"
"├─┼┤"
"╰─┴╯")
#:align'(center))

╭──────┬──────┬──────╮

│.abc..│.abc..│.abc..│

├──────┼──────┼──────┤

│abcdef│..ab..│abcdef│

├──────┼──────┼──────┤

│..a...│abcdef│.abc..│

╰──────┴──────┴──────╯

Note that the "." is the space filler.

procedure

(( string-length=/c n)x)boolean?

x:any/c
Returns #true if x is a string of length n, #false otherwise.

2UtilitiesπŸ”— i

Utilities used to build text tables.

2.1ListsπŸ”— i

procedure

(( pattern-list-of pred?)x)boolean?

x:any/c
Returns #true if either x is not a list and (pred?x) is #true, or x is a list (head... dots... tail... ) satisfying (andmap pred?(head... tail... )) and (dots... ) is a list of '... not longer than (head... ).

procedure

[ #:truncate-ok?truncate-ok?]
result-length)list?
truncate-ok?:any/c =#f

Examples:

'(aaa)

'(aaa)

> (pattern-list->list '(ab)5)

'(abbbb)

> (pattern-list->list '(ab...)5)

'(abbbb)

> (pattern-list->list '(abc......)10)

'(abcbcbcbcb)

> (pattern-list->list '(abcd.........ef)10)

'(abcdbcdbef)

> (pattern-list->list '(abcd.........ef)2)

Minimum length of list l exceeds n-elt '(a b c d ... ... ...

e f) 2

> (pattern-list->list '(abcd.........ef)2#:truncate-ok?#t)

'(ae)

procedure

( transpose l)(listof list? )

Returns a new list where the columns and rows of l are swapped.

Example:
> (transpose '((abc)(123)))

'((a1)(b2)(c3))

procedure

( group-by-lengths llengths)(listof list? )

l:list?
Returns a list with the same elements as l but grouped in sublists of lengths given by lengths.

Example:
> (group-by-lengths '(abcdefg)
'(102301))

'((a)()(bc)(def)()(g))

2.2StringsπŸ”— i

Returns a string of length len by repeating str.

Examples:
> (string-repeat "abc"5)

"abcab"

> (string-repeat "abc"2)

"ab"

procedure

( ~r* [ #:signsign
#:basebase
#:precisionprecision
#:notationnotation
#:format-exponentformat-exponent
#:min-widthmin-width
#:pad-stringpad-string
#:groupsgroups
#:group-sepgroup-sep
#:decimal-sepdecimal-sep])
(any/c . -> .string? )
sign :
(or/c #f'+'++'parens
(list/c indindind)))
= #f
base : (or/c (integer-in 236)(list/c 'up(integer-in 236)))
= 10
notation :
(or/c 'positional'exponential
(-> rational? (or/c 'positional'exponential)))
= 'positional
format-exponent : (or/c #fstring? (-> exact-integer? string? ))
= #f
pad-string:non-empty-string? =" "
group-sep:string? =""
decimal-sep:string? ="."
Like ~r but curried, and also accepts non-rationals, which are printed with ~a instead.

Example:
#:->string(list ~a ;1
(~r* );2
(~r* #:notation'exponential);3
(~r* #:precision'(=2));4 (good)
(~r* #:notation'exponential#:precision'(=2));5 (good)
(~r* #:min-width10#:pad-string"."));6
#:align'(right...)
#:row-sep?'(#f#t#f...)
(cons
'("1""2""3""4 (good)""5 (good)""6")
(make-list6`(header1111.1122.2223333000.04440000000000.0,(sqrt 2))))))

┌──────────────────┬─────────────┬────────────┬────────────────┬────────┬─────────────┐

1│2│ 3│4 (good)│5 (good)│6│

header│ header│header│header│header│ header....│

├──────────────────┼─────────────┼────────────┼────────────────┼────────┼─────────────┤

1111.11│1111.11│ 1.11111e+03│ 1111.11│1.11e+03│ ...1111.11│

22.222│ 22.222│2.2222e+01│ 22.22│2.22e+01│ ....22.222│

3333000.0│3333000│ 3.333e+06│3333000.00│3.33e+06│ ...3333000│

4440000000000.0│4440000000000│4.44e+12│4440000000000.00│4.44e+12│4440000000000│

│1.4142135623730951│ 1.414214│1.414214e+00│1.41│1.41e+00│ ..1.414214│

└──────────────────┴─────────────┴────────────┴────────────────┴────────┴─────────────┘

top
← prev up next →

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /