text-table
table->string
simple-table->string
print-table
print-simple-table
border-style/  c
border-style1/  c
border-style2/  c
border-style-frame/  c
string-length=/  c
8.3

text-table

Laurent Orseau

A simple package to display utf-8 textual tables.

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:
> (print-table
   '((a b c d e f gggg h)
     (123 456 77 54 1  5646547987 41 1)
     (111 22 3333 44 5 6 7 8888)))

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

│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
> (print-table
   '((a b c d e f gggg h)
     (123 456 77 54 1  5646547987 41 1)
     (111 22 3333 44 5 6 7 8888))
   #:border-style 'double
   #:framed? #f
   #:row-sep? #t
   #:align '(left center right))

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 '((abc abc abc)
                 (abcdef ab abcdef)
                 (a abcdef abc))
               #: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 '((abc abc abc)
                (abcdef ab abcdef)
                (a abcdef abc))
              #: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>

procedure

(table->string table    
  [#:->string to-string    
  #:border-style border-style    
  #:framed? framed?    
  #:row-sep? row-sep?    
  #:align align])  string?
  table : (listof list?)
  to-string : procedure? = ~a
  border-style : border-style/c = 'single
  framed? : boolean? = #t
  row-sep? : boolean? = #t
  align : 
(or/c (listof (or/c 'left 'center 'right))
      (or/c 'left 'center 'right))
 = 'left
Accepts a table specified as a list of lists, and returns a string representing the table. The lists must all be of the same length.

The to-string procedure is used to convert cell values to strings.

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.

When row-sep? is false, no separators are drawn between the rows.

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.

procedure

(simple-table->string table    
  [#:->string to-string    
  #:border-style border-style    
  #:framed? framed?    
  #:row-sep? row-sep?    
  #:align align])  string?
  table : (listof list?)
  to-string : procedure? = ~a
  border-style : border-style/c = 'space
  framed? : boolean? = #f
  row-sep? : boolean? = #f
  align : 
(or/c (listof (or/c 'left 'center 'right))
      (or/c 'left 'center 'right))
 = 'left
Like table->string, but with different default arguments to output a minimalistic table.

Example:
> (displayln
   (simple-table->string
    #:align '(left right)
    '((a b c d e f gggg h)
      (123 456 77 54 1  5646547987 41 1)
      (111 22 3333 44 5 6 7 8888))))

a     b    c  d e          f gggg    h

123 456   77 54 1 5646547987   41    1

111  22 3333 44 5          6    7 8888

syntax

(print-table args ...)

Shorthand form for (displayln (table->string args ...)). Takes the same arguments as table->string.

syntax

(print-simple-table args ...)

Shorthand form for (displayln (simple-table->string args ...)). Takes the same arguments as simple-table->string.

value

border-style/c : contract?

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

value

border-style1/c : contract?

 = 
(list/c char? ; row sep
        (list/c string? string? string?) ; text line
        (list/c string? string? string?) ; top line
        (list/c string? string? string?) ; middle line
        (list/c string? string? string?) ; bottom line)
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 " ".

value

border-style2/c : contract?

 = 
(list/c (list/c string? string? string? string?) ; top line
        (list/c string? string? string? string?) ; text line
        (list/c string? string? string? string?) ; middle line
        (list/c string? string? string? string?) ; bottom line)
Each string specifies one of the elements of the frame of the table. The strings can be of arbitrary length
> (print-table
   '((_ _ ___ _)
     (_ _ _ _)
     (_ "_\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.

value

border-style-frame/c : contract?

 = 
(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 '((abc abc abc)
       (abcdef ab abcdef)
       (a abcdef abc))
     #: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?

  n : integer?
  x : any/c
Returns #true if x is a string of length n.