Skip to content

Instantly share code, notes, and snippets.

@ENAML
Created December 16, 2018 06:09
Show Gist options
  • Save ENAML/e598869076ae06e89b6b6f84e0a9e9ba to your computer and use it in GitHub Desktop.
Save ENAML/e598869076ae06e89b6b6f84e0a9e9ba to your computer and use it in GitHub Desktop.
Creates an ascii table from a 2D list mtx of strings.
open Core
(* Creates an ascii table from a 2D list mtx of strings. *)
let make_tbl data =
(* common vars *)
let (fold, map, map2) = List.(fold, map, map2_exn) in
let (sep_h, sep_v, sep_x) = ('-', '|', '+') in
let text_pad = 2 in
(* compute max length of each column in tbl *)
let col_lengths =
let lengths = fold data
~init: []
~f: (fun acc row ->
match acc with
| [] -> map row ~f:String.length
| _ ->
map2 acc row
~f:(fun cur_max str ->
Pervasives.max cur_max (String.length str)))
in
lengths |> map ~f:((+) text_pad)
in
(* pad each string in the table *)
let padded_tbl = map data
~f: (fun row ->
map2 col_lengths row ~f:(fun len str ->
let half_pad = text_pad / 2 in
let len_diff = len - (String.length str) - half_pad in
(String.make half_pad ' ') ^ str ^ (String.make len_diff ' ')))
in
(* build line separating rows *)
let sep_line =
let x = String.make 1 sep_x in
fold col_lengths
~init: x
~f: (fun acc cur -> acc ^ (String.make cur sep_h) ^ x)
in
(* build rows *)
let res_rows =
let v = String.make 1 sep_v in
map padded_tbl
~f:(fun row ->
fold row
~init: v
~f:(fun acc cur -> acc ^ cur ^ v))
in
(* build result *)
fold res_rows
~init: sep_line
~f: (fun acc cur -> acc ^ "\n" ^ cur ^ "\n" ^ sep_line)
;;
let test_print_tbl () =
let test data =
let tbl = make_tbl data in
print_endline tbl
in
[
["lorem"; "ipsum"; "is"];
["simply"; "dummy"; "text"];
["its"; "origins"; "are"];
["completely"; "unknown"; "!"];
] |> test;
;;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment