Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
table.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
module IM = Map.Make (Int) module PM = Map.Make (struct type t = int * int let compare = compare end) type alignment = | Left | Center | Right type cell = Format.formatter -> unit -> unit let left = Left let right = Right let center = Center (* let text ?color value = { color; value = (fun out () -> Format.fprintf out "%s" value) } *) let cell = Fun.id type t = { num_rows : int ; num_cols : int ; cell : row:int -> col:int -> cell option ; columns : alignment list } let max_column_length ~num_rows ~cell col = List.init num_rows (fun row -> Option.fold ~none:0 ~some:(fun value -> Util.Format.rendered_length value ()) (cell ~row ~col)) |> List.fold_left max 0 let make_space n = String.concat "" @@ List.init n (Fun.const " ") let render_cell ~column_width cell align out = let cell_width = Util.Format.rendered_length cell () in let space = column_width - cell_width in let margin = make_space 2 in match align with | Left -> Format.fprintf out "%a%s%s" cell () (make_space space) margin | Center -> let space_left = space / 2 in let space_right = (space / 2) + (space mod 2) in Format.fprintf out "%s%a%s%s" (make_space space_left) cell () (make_space space_right) margin | Right -> Format.fprintf out "%s%a%s" (make_space space) cell () margin let of_list ~columns rows = let cell = let map = List.mapi (fun row -> List.mapi (fun col cell -> ((row, col), cell))) rows |> List.concat |> List.to_seq |> PM.of_seq in fun ~row ~col -> PM.find_opt (row, col) map in let num_rows = List.length rows in let num_cols = Option.fold ~none:0 ~some:List.length (Util.List.head_opt rows) in { cell; num_rows; num_cols; columns } let pp out { num_rows; num_cols; cell; columns } = let open Format in if num_rows = 0 then () else let col_widths = List.init num_cols (max_column_length ~num_rows ~cell) in let cols_and_widths = List.combine columns col_widths in let pp_cell ~row ~col ~column_width out alignment = let cell = Option.fold ~none:(fun _ _ -> ()) ~some:Fun.id @@ cell ~row ~col in render_cell ~column_width cell alignment out in let render_row out row = List.iteri (fun col (column, column_width) -> pp_cell ~row ~col ~column_width out column) cols_and_widths; pp_print_cut out () in let pp_rows out () = List.iter (render_row out) (List.init num_rows Fun.id) in fprintf out "@[<v 0>@,%a@]" pp_rows ()