Text-table overhaul

Just because I needed a simple way to display various numbers (non-rationals, large integers, floats, etc.) in a table, I ended up rewriting text-table almost entirely, except for frame styles (which were also enhanced relatively recently).

What's new:

  • Rows can be aligned 'top, 'center, 'bottom for when cells are multiline.
  • #:->string, #:align and #:row-align arguments use the rather flexible pattern-list->list:
    • (pattern-list->list '(a B C ... ... d) 10)
      β†’(a B C B C B C B C d)
  • ~r* can be used with ->string to easily format columns of numbers (possibly including text)
  • The source code is way more readable, factored and tested, which should help contributing.

(The online docs may take some time to reflect the changes. Download/update the package to get the latest docs.)

Feedback most welcome. Let me know in particular if I've broken your code in any way. I will allow for backward incompatible changes to these new features until the end of March, waiting for feedback.

Some examples:

(let ()
    (define l (build-list 10 (Ξ» (i) (expt (random) -4))))
    (print-table
     #:row-sep? #f
     #:align 'right
     #:->string (list (~r* #:precision '(= 2))
                      (~r* #:precision '(= 2) #:notation 'exponential))
     (transpose (list (list* 'Speed "" l) (list* 'Height "" (reverse l))))))
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Speedβ”‚  Heightβ”‚
β”‚        β”‚        β”‚
β”‚   20.36β”‚2.65e+00β”‚
β”‚44887.08β”‚3.58e+03β”‚
β”‚    2.99β”‚1.14e+00β”‚
β”‚    4.82β”‚3.30e+01β”‚
β”‚ 4181.24β”‚4.42e+01β”‚
β”‚   44.19β”‚4.18e+03β”‚
β”‚   33.03β”‚4.82e+00β”‚
β”‚    1.14β”‚2.99e+00β”‚
β”‚ 3579.13β”‚4.49e+04β”‚
β”‚    2.65β”‚2.04e+01β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”˜

(print-simple-table
   #:border-style 'empty
   #:align '(right left ... ...)
  (list (make-list 10 '*)
        (make-list 10 '**)
        (make-list 10 '***)
        (make-list 10 '****)
        (make-list 10 '*****)
        (make-list 10 "|")))
    **        **        **        **        **    
   ****      ****      ****      ****      ****   
  ******    ******    ******    ******    ******  
 ********  ********  ********  ********  ******** 
**************************************************
    ||        ||        ||        ||        ||    

Make sure to also check out uni-table which has many options and can use ansi colours.

9 Likes

More new:

  • #:row-sep? and the new #:col-sep? are pattern-lists, allowing (finally!) to have a separator just for the header (and more)
  • Fixed the 'latex style to use frames and separators correctly. This may be a somewhat backward-incompatible change as previous latex tables could not handle frames and separators. (But I consider this a bug fix.)
  • Added an 'empty style
> (print-table
  (for/list ((i 5)) (for/list ((j 6)) (* (+ i 1) (+ j 1))))
  #:align 'right
  #:framed? #f
  #:row-sep? '(#t #f)
  #:col-sep? '(#t #f)
  #:border-style 'heavy)
1┃ 2  3  4  5  6
━╋━━━━━━━━━━━━━━
2┃ 4  6  8 10 12
3┃ 6  9 12 15 18
4┃ 8 12 16 20 24
5┃10 15 20 25 30

> (print-table
  (for/list ((i 5)) (for/list ((j 10)) (* (+ i 1) (+ j 1))))
  #:align 'right
  #:framed? #t
  #:row-sep? '(#t #f ... ...)
  #:col-sep? '(#t #f ... ...)
  #:border-style 'heavy)
┏━┳━━━━━┳━━━━━┳━━━━━┳━━━━━┳━━┓
┃1┃ 2  3┃ 4  5┃ 6  7┃ 8  9┃10┃
┣━╋━━━━━╋━━━━━╋━━━━━╋━━━━━╋━━┫
┃2┃ 4  6┃ 8 10┃12 14┃16 18┃20┃
┃3┃ 6  9┃12 15┃18 21┃24 27┃30┃
┣━╋━━━━━╋━━━━━╋━━━━━╋━━━━━╋━━┫
┃4┃ 8 12┃16 20┃24 28┃32 36┃40┃
┃5┃10 15┃20 25┃30 35┃40 45┃50┃
┗━┻━━━━━┻━━━━━┻━━━━━┻━━━━━┻━━┛

> (print-table
  (for/list ((i 5)) (for/list ((j 6)) (* (+ i 1) (+ j 1))))
  #:align 'right
  #:framed? #t
  #:row-sep? '(#t #f)
  #:col-sep? '(#t #f)
  #:border-style 'latex)
\begin{tabular}{|r|rrrrr|}
\hline
1 &  2 &  3 &  4 &  5 &  6 \\
\hline
2 &  4 &  6 &  8 & 10 & 12 \\
3 &  6 &  9 & 12 & 15 & 18 \\
4 &  8 & 12 & 16 & 20 & 24 \\
5 & 10 & 15 & 20 & 25 & 30 \\
\hline
\end{tabular}

3 Likes