12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667(*
* (¯`·._.·(¯`·._.· PEOPLE, READ THIS BEFORE YOU EDIT ·._.·´¯)·._.·´¯)
*
* At times it is necessary to write a function that's super-general and
* reusable, but really has no proper place within the codebase. Hence the Util
* module. Welcome to the sin bin.
*
* Before you start to write that function, take a minute to search Core to see
* if there is a function there that does what you want to do. Here's convenient
* link to its documentation page:
*
* https://ocaml.janestreet.com/ocaml-core/latest/doc/
*
* Next, check this library's dependencies to see if that function's already
* been written elsewhere. Finally, give this library a quick grep to see if the
* function might have been written in some other module as a one-off. In that
* case, for the sake of posterity, move it in here and reuse it.
*
* If after all that you're still without the function you need, have at it
* below.
*)(* prevent core from overwriting this *)modulePrintexn=PrintexcopenCoreletmake_string_offormatterx=letopenFormatinletbuf=Buffer.create100inletfmt=formatter_of_bufferbufinpp_set_marginfmt80;formatterfmtx;fprintffmt"@?";Buffer.contentsbufletpp_exceptions()=Printexn.register_printer(funexn->Option.try_with(fun()->Location.report_exceptionFormat.str_formatterexn;Format.flush_str_formatter()))letmap_fstlst~f=List.maplst~f:(fun(x,y)->(fx,y))letmap_sndlst~f=List.maplst~f:(fun(x,y)->(x,fy))(*===========================================================================*)(* Graphviz *)(*===========================================================================*)letcompile_dot?(format="pdf")?(engine="dot")?(title=engine)data:string=letoutput_file=Filename.temp_file(title^"_")("."^format)inletto_dot=Unix.open_process_out(sprintf"dot -T%s -o %s"formatoutput_file)inOut_channel.output_stringto_dotdata;Out_channel.closeto_dot;ignore(Unix.close_process_outto_dot);output_fileletshow_dot?format?title?enginedata:unit=compile_dot?format?title?enginedata|>Open.in_default_app|>ignoreletshow_dot_file?format?title?enginefile:unit=In_channel.read_allfile|>show_dot?format?title?engine