Skip to main content

LibOA Update

I am working on other tasks today, but I will get back to FeedPipe development soon. One thing that I did today was update my LibOA library. LibOA is a collection of functions that I use with optparse-applicative and ansi-wl-pprint. I do not feel that it is worth maintaining yet another helper package on Hackage, so I currently just copy the code to different projects as required.

One helper function that has been in LibOA since the beginning is the table function. It originally formatted two-column tables because that was all I needed. I rewrote the function to add the following features:

  • Tables can have any number of columns.
  • Rows can have different number of columns.
  • The number of spaces between columns can be configured.
  • Each cell of the table can be formatted. For example, header cells can be shown in bold and data cells can be color-coded.

Here is the implementation:

table :: Int -> [[(String, Doc -> Doc)]] -> Doc
table sep rows = Doc.vcat $
    map (fromMaybe Doc.empty . foldr go Nothing . zip lengths) rows
  where
    lengths :: [Int]
    lengths = map ((+) sep . maximum . map (length . fst)) $ transpose rows

    go :: (Int, (String, Doc -> Doc)) -> Maybe Doc -> Maybe Doc
    go (len, (s, f)) = Just . \case
      Just doc -> Doc.fill len (f $ Doc.string s) <> doc
      Nothing  -> f $ Doc.string s

The table_ function formats tables without formatting:

table_ :: Int -> [[String]] -> Doc
table_ sep = table sep . (map . map) (, id)

The full library can be seen on GitHub.

Author

Travis Cardwell

Published

Tags