(* This file is free software, part of containers. See file "license" for more details. *) (** Helpers for Format @since 0.8 *) type 'a iter = ('a -> unit) -> unit (* include Format, and alias all its types. see https://discuss.ocaml.org/t/extend-existing-module/1389/4 *) include module type of struct include Format end (** {{: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Format.html} Documentation for the standard Format module}*) type t = Format.formatter type -'a printer = t -> 'a -> unit (** {2 Combinators} *) val silent : 'a printer (** Prints nothing. *) val unit : unit printer (** Prints "()". *) val int : int printer val string : string printer val bool : bool printer val float3 : float printer (* 3 digits after . *) val float : float printer val exn : exn printer (** Printer using {!Printexc.to_string}. @since 3.0 *) val space : unit printer (** Alias to {!pp_print_space}. @since 3.2 *) val cut : unit printer (** Alias to {!pp_print_cut}. @since 3.2 *) val break : (int * int) printer (** Tuple-ized {!printer} form of {!pp_print_break}. @since 3.2 *) val newline : unit printer (** Force newline (see {!Format.pp_force_newline}). @since 1.2 *) val substring : (string * int * int) printer (** [substring (s,i,len)] prints the substring [(s,i,len)], where [i] is the offset in [s] and [len] the number of bytes in the substring. @raise Invalid_argument if the triple [(s,i,len)] does not describe a proper substring. @since 1.2 *) val text : string printer (** Print string, but replacing spaces with breaks and newlines with {!newline}. See [pp_print_text] on recent versions of OCaml. @since 1.2 *) val string_lines : string printer (** [string_lines out s] prints [s] with all newlines (['\n']) replaced by a cut, in a vertical box. It does {b NOT} insert breakable spaces in place of spaces, unlike {!text}. This means an already formatted string can be displayed inside another formatter without mangling the indentation. @since 3.3 *) val char : char printer (** @since 0.14 *) val int32 : int32 printer (** @since 0.14 *) val int64 : int64 printer (** @since 0.14 *) val nativeint : nativeint printer (** @since 0.14 *) val flush : unit printer (** Alias to {!Format.pp_print_flush}. @since 1.2 *) val string_quoted : string printer (** Similar to {!CCString.print}. @since 0.14 *) val list : ?sep:unit printer -> 'a printer -> 'a list printer val array : ?sep:unit printer -> 'a printer -> 'a array printer val arrayi : ?sep:unit printer -> (int * 'a) printer -> 'a array printer val seq : ?sep:unit printer -> 'a printer -> 'a Seq.t printer val iter : ?sep:unit printer -> 'a printer -> 'a iter printer val opt : 'a printer -> 'a option printer (** [opt pp] prints options as follows: - [Some x] will become "some foo" if [pp x ---> "foo"]. - [None] will become "none". *) (** In the tuple printers, the [sep] argument is only available. @since 0.17 *) val pair : ?sep:unit printer -> 'a printer -> 'b printer -> ('a * 'b) printer val triple : ?sep:unit printer -> 'a printer -> 'b printer -> 'c printer -> ('a * 'b * 'c) printer val quad : ?sep:unit printer -> 'a printer -> 'b printer -> 'c printer -> 'd printer -> ('a * 'b * 'c * 'd) printer val append : unit printer -> unit printer -> unit printer (** [append ppa ppb] first prints [ppa ()], then prints [ppb ()]. @since 3.2 *) val append_l : unit printer list -> unit printer (** [append_l pps] runs the printers in [pps] sequentially. @since 3.2 *) val within : string -> string -> 'a printer -> 'a printer (** [within a b p] wraps [p] inside the strings [a] and [b]. Convenient, for instances, for brackets, parenthesis, quotes, etc. @since 0.17 *) val map : ('a -> 'b) -> 'b printer -> 'a printer val vbox : ?i:int -> 'a printer -> 'a printer (** Wrap the printer in a vertical box. @param i level of indentation within the box (default 0). @since 0.16 *) val hvbox : ?i:int -> 'a printer -> 'a printer (** Wrap the printer in a horizontal/vertical box. @param i level of indentation within the box (default 0). @since 0.16 *) val hovbox : ?i:int -> 'a printer -> 'a printer (** Wrap the printer in a horizontal or vertical box. @param i level of indentation within the box (default 0). @since 0.16 *) val hbox : 'a printer -> 'a printer (** Wrap the printer in an horizontal box. @since 0.16 *) val return : ('a, _, _, 'a) format4 -> unit printer (** [return "some_format_string"] takes a argument-less format string and returns a printer actionable by [()]. Examples: - [return ",@ "] - [return "@{and then@}@,"] - [return "@[a@ b@]"] @since 1.0 *) val of_to_string : ('a -> string) -> 'a printer (** [of_to_string f] converts its input to a string using [f], then prints the string. @since 1.0 *) val const : 'a printer -> 'a -> unit printer (** [const pp x] is a unit printer that uses [pp] on [x]. @since 1.0 *) val some : 'a printer -> 'a option printer (** [some pp] will print options as follows: - [Some x] is printed using [pp] on [x] - [None] is not printed at all @since 1.0 *) val const_string : string -> 'a printer (** [const_string s] is a printer that ignores its input and always prints [s]. @since 3.5 *) val opaque : 'a printer (** [opaque] is [const_string "opaque"]. The exact string used is not stable. @since 3.5 *) val lazy_force : 'a printer -> 'a lazy_t printer (** [lazy_force pp out x] forces [x] and prints the result with [pp]. @since 2.0 *) val lazy_or : ?default:unit printer -> 'a printer -> 'a lazy_t printer (** [lazy_or ?default pp out x] prints [default] if [x] is not evaluated yet, or uses [pp] otherwise. @since 2.0 *) (** {2 ANSI codes} Use ANSI escape codes https://en.wikipedia.org/wiki/ANSI_escape_code to put some colors on the terminal. This uses {b tags} in format strings to specify the style. Current styles are the following: {ul {- "reset" resets style} {- "black" } {- "red" } {- "green" } {- "yellow" } {- "blue" } {- "magenta" } {- "cyan" } {- "white" } {- "bold" bold font} {- "Black" bold black} {- "Red" bold red } {- "Green" bold green } {- "Yellow" bold yellow } {- "Blue" bold blue } {- "Magenta" bold magenta } {- "Cyan" bold cyan } {- "White" bold white } } Example: {[ set_color_default true;; Format.printf "what is your @{favorite color@}? @{blue@}! No, @{red@}! Ahhhhhhh@.";; ]} {b status: unstable} @since 0.15 *) val set_color_tag_handling : t -> unit (** Add functions to support color tags to the given formatter. @since 0.15 *) val set_color_default : bool -> unit (** [set_color_default b] enables color handling on the standard formatters (stdout, stderr) if [b = true] as well as on {!sprintf} formatters; it disables the color handling if [b = false]. *) val with_color : string -> 'a printer -> 'a printer (** [with_color "Blue" pp] behaves like the printer [pp], but with the given style. {b status: unstable} @since 0.16 *) val with_colorf : string -> t -> ('a, t, unit, unit) format4 -> 'a (** [with_colorf "Blue" out "%s %d" "yolo" 42] will behave like {!Format.fprintf}, but wrapping the content with the given style. {b status: unstable} @since 0.16 *) val with_color_sf : string -> ('a, t, unit, string) format4 -> 'a (** [with_color_sf "Blue" out "%s %d" "yolo" 42] will behave like {!sprintf}, but wrapping the content with the given style. Example: {[ CCFormat.with_color_sf "red" "%a" CCFormat.Dump.(list int) [1;2;3] |> print_endline;; ]} {b status: unstable} @since 0.21 *) val with_color_ksf : f:(string -> 'b) -> string -> ('a, t, unit, 'b) format4 -> 'a (** [with_color_ksf "Blue" ~f "%s %d" "yolo" 42] will behave like {!ksprintf}, but wrapping the content with the given style. Example: the following with raise [Failure] with a colored message {[ CCFormat.with_color_ksf "red" ~f:failwith "%a" CCFormat.Dump.(list int) [1;2;3];; ]} @since 1.2 *) (** ANSI escape codes. This contains lower level functions for them. @since 3.5 *) module ANSI_codes : sig type color = [ `Black | `Red | `Yellow | `Green | `Blue | `Magenta | `Cyan | `White ] (** An ANSI color *) type style = [ `FG of color (** foreground *) | `BG of color (** background *) | `Bold | `Reset ] (** A style. Styles can be composed in a list. *) val clear_line : string (** [clear_line] is an escape code to clear the current line. It is very useful for progress bars; for example: {[ let pp_progress i = Printf.printf "%sprogress at %d%!" ANSI_codes.clear_line i ]} if called repeatedly this will print successive progress messages on a single line. *) val reset : string (** The escape code to reset style (colors, bold, etc.) *) val string_of_style : style -> string (** [string_of_style st] is an escape code to set the current style to [st]. It can be printed as is on any output that is a compatible terminal. *) val string_of_style_list : style list -> string (** [string_of_style_list styles] is an escape code for multiple styles at once. For example [string_of_style_list ANSI_codes.([`FG `Red; `BG `Green; `Bold])] is a very shiny style. *) end [@@@ifge 4.8] val styling : ANSI_codes.style list -> 'a printer -> 'a printer (** [styling st p] is the same printer as [p], except it locally sets the style [st]. Available only on OCaml >= 4.08. @since NEXT_RELEASE *) [@@@endif] (** {2 IO} *) val output : t -> 'a printer -> 'a -> unit val to_string : 'a printer -> 'a -> string val of_chan : out_channel -> t (** Alias to {!Format.formatter_of_out_channel}. @since 1.2 *) val with_out_chan : out_channel -> (t -> 'a) -> 'a (** [with_out_chan oc f] turns [oc] into a formatter [fmt], and call [f fmt]. Behaves like [f fmt] from then on, but whether the call to [f] fails or returns, [fmt] is flushed before the call terminates. @since 1.2 *) val stdout : t val stderr : t val tee : t -> t -> t (** [tee a b] makes a new formatter that writes in both [a] and [b]. @since 1.0 *) val sprintf : ('a, t, unit, string) format4 -> 'a (** Print into a string any format string that would usually be compatible with {!fprintf}. Like {!Format.asprintf}. *) val sprintf_no_color : ('a, t, unit, string) format4 -> 'a (** Like {!sprintf} but never prints colors. @since 0.16 *) val sprintf_dyn_color : colors:bool -> ('a, t, unit, string) format4 -> 'a (** Like {!sprintf} but enable/disable colors depending on [colors]. Example: {[ (* with colors *) CCFormat.sprintf_dyn_color ~colors:true "@{%a@}" CCFormat.Dump.(list int) [1;2;3] |> print_endline;; (* without colors *) CCFormat.sprintf_dyn_color ~colors:false "@{%a@}" CCFormat.Dump.(list int) [1;2;3] |> print_endline;; ]} @since 0.21 *) val fprintf : t -> ('a, t, unit ) format -> 'a (** Alias to {!Format.fprintf}. @since 0.14 *) val fprintf_dyn_color : colors:bool -> t -> ('a, t, unit ) format -> 'a (** Like {!fprintf} but enable/disable colors depending on [colors]. @since 0.21 *) val ksprintf : ?margin:int -> f:(string -> 'b) -> ('a, Format.formatter, unit, 'b) format4 -> 'a (** [ksprintf fmt ~f] formats using [fmt], in a way similar to {!sprintf}, and then calls [f] on the resulting string. @param margin set margin (since 2.1) @since 0.14 *) val to_file : string -> ('a, t, unit, unit) format4 -> 'a (** Print to the given file. *) (** {2 Dump} Print structures as OCaml values, so that they can be parsed back by OCaml (typically, in the toplevel, for debugging). Example: {[ Format.printf "%a@." CCFormat.Dump.(list int) CCList.(1 -- 200);; Format.printf "%a@." CCFormat.Dump.(array (list (pair int bool))) [| [1, true; 2, false]; []; [42, false] |];; ]} @since 0.21 *) module Dump : sig type 'a t = 'a printer val unit : unit t val int : int t val string : string t val bool : bool t val float : float t val char : char t val int32 : int32 t val int64 : int64 t val nativeint : nativeint t val list : 'a t -> 'a list t val array : 'a t -> 'a array t val option : 'a t -> 'a option t val pair : 'a t -> 'b t -> ('a * 'b) t val triple : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t val quad : 'a t -> 'b t -> 'c t -> 'd t -> ('a * 'b * 'c * 'd) t val result : 'a t -> ('a, string) result t val result' : 'a t -> 'e t -> ('a, 'e) result t val to_string : 'a t -> 'a -> string (** Alias to {!CCFormat.to_string}. *) end module Infix : sig val (++) : unit printer -> unit printer -> unit printer (** Alias to {!append}. @since 3.2 *) end include module type of Infix