I have need of a way to print using any existing printer, with the output stripped of all cuts, linebreaks, and indents (think of presenting messages containing probably-small bits of pretty-printed data to users in confined UI spaces).
I landed on this pattern:
let plain fmt =
let open Format in
let b = Buffer.create 64 in
let ppf = formatter_of_buffer b in
let fns = pp_get_formatter_out_functions ppf () in
pp_set_formatter_out_functions ppf {fns with out_newline = ignore; out_indent = ignore};
fprintf ppf "%t" fmt;
pp_print_flush ppf ();
Buffer.contents b
let str = plain @@ Format.dprintf "foo%a" (Iter.pp_seq Int.pp) Int.(0 -- 100)
....
This certainly gets the job done, but I would very much like to have a single function to call as with asprintf
. Unfortunately, whatever I try seems to get in the way of the compiler producing the correct type for the format string and its args:
let p2 x = plain @@ Format.dprintf x
let _ = print_endline @@ p2 "%d" 5
Error: This function has type
(Format.formatter -> unit, Format.formatter, unit,
Format.formatter -> unit)
format4 -> string
It is applied to too many arguments; maybe you forgot a `;'.
I suspect that this is not possible given (my understanding) that the return type of the proximate printing function (p2
here) is what the compiler keys on, but I thought I’d be hopeful and see if there’s any way to get a tidy asprintf
-like function with the custom behaviour described above.