307 lines
14 KiB
OCaml
307 lines
14 KiB
OCaml
|
(**************************************************************************)
|
||
|
(* *)
|
||
|
(* OCaml *)
|
||
|
(* *)
|
||
|
(* Pierre Weis, projet Cristal, INRIA Rocquencourt *)
|
||
|
(* *)
|
||
|
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
||
|
(* en Automatique. *)
|
||
|
(* *)
|
||
|
(* All rights reserved. This file is distributed under the terms of *)
|
||
|
(* the GNU Lesser General Public License version 2.1, with the *)
|
||
|
(* special exception on linking described in the file LICENSE. *)
|
||
|
(* *)
|
||
|
(**************************************************************************)
|
||
|
|
||
|
(* TEZOS CHANGES
|
||
|
|
||
|
* import version 4.03.0
|
||
|
* Removed channel functions
|
||
|
* Removed toplevel effect based functions
|
||
|
* Removed deprecated functions
|
||
|
|
||
|
*)
|
||
|
|
||
|
(** Pretty printing.
|
||
|
|
||
|
This module implements a pretty-printing facility to format values
|
||
|
within 'pretty-printing boxes'. The pretty-printer splits lines
|
||
|
at specified break hints, and indents lines according to the box
|
||
|
structure.
|
||
|
|
||
|
For a gentle introduction to the basics of pretty-printing using
|
||
|
[Format], read
|
||
|
{{:http://caml.inria.fr/resources/doc/guides/format.en.html}
|
||
|
http://caml.inria.fr/resources/doc/guides/format.en.html}.
|
||
|
|
||
|
You may consider this module as providing an extension to the
|
||
|
[printf] facility to provide automatic line splitting. The addition of
|
||
|
pretty-printing annotations to your regular [printf] formats gives you
|
||
|
fancy indentation and line breaks.
|
||
|
Pretty-printing annotations are described below in the documentation of
|
||
|
the function {!Format.fprintf}.
|
||
|
|
||
|
You may also use the explicit box management and printing functions
|
||
|
provided by this module. This style is more basic but more verbose
|
||
|
than the [fprintf] concise formats.
|
||
|
|
||
|
For instance, the sequence
|
||
|
[open_box 0; print_string "x ="; print_space ();
|
||
|
print_int 1; close_box (); print_newline ()]
|
||
|
that prints [x = 1] within a pretty-printing box, can be
|
||
|
abbreviated as [printf "@[%s@ %i@]@." "x =" 1], or even shorter
|
||
|
[printf "@[x =@ %i@]@." 1].
|
||
|
|
||
|
Rule of thumb for casual users of this library:
|
||
|
- use simple boxes (as obtained by [open_box 0]);
|
||
|
- use simple break hints (as obtained by [print_cut ()] that outputs a
|
||
|
simple break hint, or by [print_space ()] that outputs a space
|
||
|
indicating a break hint);
|
||
|
- once a box is opened, display its material with basic printing
|
||
|
functions (e. g. [print_int] and [print_string]);
|
||
|
- when the material for a box has been printed, call [close_box ()] to
|
||
|
close the box;
|
||
|
- at the end of your routine, flush the pretty-printer to display all the
|
||
|
remaining material, e.g. evaluate [print_newline ()].
|
||
|
|
||
|
The behaviour of pretty-printing commands is unspecified
|
||
|
if there is no opened pretty-printing box. Each box opened via
|
||
|
one of the [open_] functions below must be closed using [close_box]
|
||
|
for proper formatting. Otherwise, some of the material printed in the
|
||
|
boxes may not be output, or may be formatted incorrectly.
|
||
|
|
||
|
In case of interactive use, the system closes all opened boxes and
|
||
|
flushes all pending text (as with the [print_newline] function)
|
||
|
after each phrase. Each phrase is therefore executed in the initial
|
||
|
state of the pretty-printer.
|
||
|
|
||
|
Warning: the material output by the following functions is delayed
|
||
|
in the pretty-printer queue in order to compute the proper line
|
||
|
splitting. Hence, you should not mix calls to the printing functions
|
||
|
of the basic I/O system with calls to the functions of this module:
|
||
|
this could result in some strange output seemingly unrelated with
|
||
|
the evaluation order of printing commands.
|
||
|
*)
|
||
|
|
||
|
(** {6 Multiple formatted output} *)
|
||
|
|
||
|
type formatter;;
|
||
|
(** Abstract data corresponding to a pretty-printer (also called a
|
||
|
formatter) and all its machinery.
|
||
|
|
||
|
Defining new pretty-printers permits unrelated output of material in
|
||
|
parallel on several output channels.
|
||
|
All the parameters of a pretty-printer are local to this pretty-printer:
|
||
|
margin, maximum indentation limit, maximum number of boxes
|
||
|
simultaneously opened, ellipsis, and so on, are specific to
|
||
|
each pretty-printer and may be fixed independently.
|
||
|
Given a [Pervasives.out_channel] output channel [oc], a new formatter
|
||
|
writing to that channel is simply obtained by calling
|
||
|
[formatter_of_out_channel oc].
|
||
|
Alternatively, the [make_formatter] function allocates a new
|
||
|
formatter with explicit output and flushing functions
|
||
|
(convenient to output material to strings for instance).
|
||
|
*)
|
||
|
|
||
|
val formatter_of_buffer : Buffer.t -> formatter
|
||
|
(** [formatter_of_buffer b] returns a new formatter writing to
|
||
|
buffer [b]. As usual, the formatter has to be flushed at
|
||
|
the end of pretty printing, using [pp_print_flush] or
|
||
|
[pp_print_newline], to display all the pending material. *)
|
||
|
|
||
|
val make_formatter :
|
||
|
(string -> int -> int -> unit) -> (unit -> unit) -> formatter
|
||
|
(** [make_formatter out flush] returns a new formatter that writes according
|
||
|
to the output function [out], and the flushing function [flush]. For
|
||
|
instance, a formatter to the [Pervasives.out_channel] [oc] is returned by
|
||
|
[make_formatter (Pervasives.output oc) (fun () -> Pervasives.flush oc)]. *)
|
||
|
|
||
|
(** {6 Basic functions to use with formatters} *)
|
||
|
|
||
|
val pp_open_hbox : formatter -> unit -> unit
|
||
|
val pp_open_vbox : formatter -> int -> unit
|
||
|
val pp_open_hvbox : formatter -> int -> unit
|
||
|
val pp_open_hovbox : formatter -> int -> unit
|
||
|
val pp_open_box : formatter -> int -> unit
|
||
|
val pp_close_box : formatter -> unit -> unit
|
||
|
val pp_open_tag : formatter -> string -> unit
|
||
|
val pp_close_tag : formatter -> unit -> unit
|
||
|
val pp_print_string : formatter -> string -> unit
|
||
|
val pp_print_as : formatter -> int -> string -> unit
|
||
|
val pp_print_int : formatter -> int -> unit
|
||
|
val pp_print_float : formatter -> float -> unit
|
||
|
val pp_print_char : formatter -> char -> unit
|
||
|
val pp_print_bool : formatter -> bool -> unit
|
||
|
val pp_print_break : formatter -> int -> int -> unit
|
||
|
val pp_print_cut : formatter -> unit -> unit
|
||
|
val pp_print_space : formatter -> unit -> unit
|
||
|
val pp_force_newline : formatter -> unit -> unit
|
||
|
val pp_print_flush : formatter -> unit -> unit
|
||
|
val pp_print_newline : formatter -> unit -> unit
|
||
|
val pp_print_if_newline : formatter -> unit -> unit
|
||
|
val pp_set_tags : formatter -> bool -> unit
|
||
|
val pp_set_print_tags : formatter -> bool -> unit
|
||
|
val pp_set_mark_tags : formatter -> bool -> unit
|
||
|
val pp_get_print_tags : formatter -> unit -> bool
|
||
|
val pp_get_mark_tags : formatter -> unit -> bool
|
||
|
val pp_set_margin : formatter -> int -> unit
|
||
|
val pp_get_margin : formatter -> unit -> int
|
||
|
val pp_set_max_indent : formatter -> int -> unit
|
||
|
val pp_get_max_indent : formatter -> unit -> int
|
||
|
val pp_set_max_boxes : formatter -> int -> unit
|
||
|
val pp_get_max_boxes : formatter -> unit -> int
|
||
|
val pp_over_max_boxes : formatter -> unit -> bool
|
||
|
val pp_set_ellipsis_text : formatter -> string -> unit
|
||
|
val pp_get_ellipsis_text : formatter -> unit -> string
|
||
|
|
||
|
(** {6 Convenience formatting functions.} *)
|
||
|
|
||
|
val pp_print_list:
|
||
|
?pp_sep:(formatter -> unit -> unit) ->
|
||
|
(formatter -> 'a -> unit) -> (formatter -> 'a list -> unit)
|
||
|
(** [pp_print_list ?pp_sep pp_v ppf l] prints items of list [l],
|
||
|
using [pp_v] to print each item, and calling [pp_sep]
|
||
|
between items ([pp_sep] defaults to {!pp_print_cut}).
|
||
|
Does nothing on empty lists.
|
||
|
|
||
|
@since 4.02.0
|
||
|
*)
|
||
|
|
||
|
val pp_print_text : formatter -> string -> unit
|
||
|
(** [pp_print_text ppf s] prints [s] with spaces and newlines
|
||
|
respectively printed with {!pp_print_space} and
|
||
|
{!pp_force_newline}.
|
||
|
|
||
|
@since 4.02.0
|
||
|
*)
|
||
|
|
||
|
(** {6 [printf] like functions for pretty-printing.} *)
|
||
|
|
||
|
val fprintf : formatter -> ('a, formatter, unit) format -> 'a
|
||
|
|
||
|
(** [fprintf ff fmt arg1 ... argN] formats the arguments [arg1] to [argN]
|
||
|
according to the format string [fmt], and outputs the resulting string on
|
||
|
the formatter [ff].
|
||
|
|
||
|
The format [fmt] is a character string which contains three types of
|
||
|
objects: plain characters and conversion specifications as specified in
|
||
|
the [Printf] module, and pretty-printing indications specific to the
|
||
|
[Format] module.
|
||
|
|
||
|
The pretty-printing indication characters are introduced by
|
||
|
a [@] character, and their meanings are:
|
||
|
- [@\[]: open a pretty-printing box. The type and offset of the
|
||
|
box may be optionally specified with the following syntax:
|
||
|
the [<] character, followed by an optional box type indication,
|
||
|
then an optional integer offset, and the closing [>] character.
|
||
|
Box type is one of [h], [v], [hv], [b], or [hov].
|
||
|
'[h]' stands for an 'horizontal' box,
|
||
|
'[v]' stands for a 'vertical' box,
|
||
|
'[hv]' stands for an 'horizontal-vertical' box,
|
||
|
'[b]' stands for an 'horizontal-or-vertical' box demonstrating indentation,
|
||
|
'[hov]' stands a simple 'horizontal-or-vertical' box.
|
||
|
For instance, [@\[<hov 2>] opens an 'horizontal-or-vertical'
|
||
|
box with indentation 2 as obtained with [open_hovbox 2].
|
||
|
For more details about boxes, see the various box opening
|
||
|
functions [open_*box].
|
||
|
- [@\]]: close the most recently opened pretty-printing box.
|
||
|
- [@,]: output a 'cut' break hint, as with [print_cut ()].
|
||
|
- [@ ]: output a 'space' break hint, as with [print_space ()].
|
||
|
- [@;]: output a 'full' break hint as with [print_break]. The
|
||
|
[nspaces] and [offset] parameters of the break hint may be
|
||
|
optionally specified with the following syntax:
|
||
|
the [<] character, followed by an integer [nspaces] value,
|
||
|
then an integer [offset], and a closing [>] character.
|
||
|
If no parameters are provided, the good break defaults to a
|
||
|
'space' break hint.
|
||
|
- [@.]: flush the pretty printer and split the line, as with
|
||
|
[print_newline ()].
|
||
|
- [@<n>]: print the following item as if it were of length [n].
|
||
|
Hence, [printf "@<0>%s" arg] prints [arg] as a zero length string.
|
||
|
If [@<n>] is not followed by a conversion specification,
|
||
|
then the following character of the format is printed as if
|
||
|
it were of length [n].
|
||
|
- [@\{]: open a tag. The name of the tag may be optionally
|
||
|
specified with the following syntax:
|
||
|
the [<] character, followed by an optional string
|
||
|
specification, and the closing [>] character. The string
|
||
|
specification is any character string that does not contain the
|
||
|
closing character ['>']. If omitted, the tag name defaults to the
|
||
|
empty string.
|
||
|
For more details about tags, see the functions [open_tag] and
|
||
|
[close_tag].
|
||
|
- [@\}]: close the most recently opened tag.
|
||
|
- [@?]: flush the pretty printer as with [print_flush ()].
|
||
|
This is equivalent to the conversion [%!].
|
||
|
- [@\n]: force a newline, as with [force_newline ()], not the normal way
|
||
|
of pretty-printing, you should prefer using break hints inside a vertical
|
||
|
box.
|
||
|
|
||
|
Note: If you need to prevent the interpretation of a [@] character as a
|
||
|
pretty-printing indication, you must escape it with a [%] character.
|
||
|
Old quotation mode [@@] is deprecated since it is not compatible with
|
||
|
formatted input interpretation of character ['@'].
|
||
|
|
||
|
Example: [printf "@[%s@ %d@]@." "x =" 1] is equivalent to
|
||
|
[open_box (); print_string "x ="; print_space ();
|
||
|
print_int 1; close_box (); print_newline ()].
|
||
|
It prints [x = 1] within a pretty-printing 'horizontal-or-vertical' box.
|
||
|
|
||
|
*)
|
||
|
|
||
|
val sprintf : ('a, unit, string) format -> 'a
|
||
|
(** Same as [printf] above, but instead of printing on a formatter,
|
||
|
returns a string containing the result of formatting the arguments.
|
||
|
Note that the pretty-printer queue is flushed at the end of {e each
|
||
|
call} to [sprintf].
|
||
|
|
||
|
In case of multiple and related calls to [sprintf] to output
|
||
|
material on a single string, you should consider using [fprintf]
|
||
|
with the predefined formatter [str_formatter] and call
|
||
|
[flush_str_formatter ()] to get the final result.
|
||
|
|
||
|
Alternatively, you can use [Format.fprintf] with a formatter writing to a
|
||
|
buffer of your own: flushing the formatter and the buffer at the end of
|
||
|
pretty-printing returns the desired string.
|
||
|
*)
|
||
|
|
||
|
val asprintf : ('a, formatter, unit, string) format4 -> 'a
|
||
|
(** Same as [printf] above, but instead of printing on a formatter,
|
||
|
returns a string containing the result of formatting the arguments.
|
||
|
The type of [asprintf] is general enough to interact nicely with [%a]
|
||
|
conversions.
|
||
|
@since 4.01.0
|
||
|
*)
|
||
|
|
||
|
val ifprintf : formatter -> ('a, formatter, unit) format -> 'a
|
||
|
(** Same as [fprintf] above, but does not print anything.
|
||
|
Useful to ignore some material when conditionally printing.
|
||
|
@since 3.10.0
|
||
|
*)
|
||
|
|
||
|
(** Formatted output functions with continuations. *)
|
||
|
|
||
|
val kfprintf :
|
||
|
(formatter -> 'a) -> formatter ->
|
||
|
('b, formatter, unit, 'a) format4 -> 'b
|
||
|
(** Same as [fprintf] above, but instead of returning immediately,
|
||
|
passes the formatter to its first argument at the end of printing. *)
|
||
|
|
||
|
val ikfprintf :
|
||
|
(formatter -> 'a) -> formatter ->
|
||
|
('b, formatter, unit, 'a) format4 -> 'b
|
||
|
(** Same as [kfprintf] above, but does not print anything.
|
||
|
Useful to ignore some material when conditionally printing.
|
||
|
@since 3.12.0
|
||
|
*)
|
||
|
|
||
|
val ksprintf : (string -> 'a) -> ('b, unit, string, 'a) format4 -> 'b
|
||
|
(** Same as [sprintf] above, but instead of returning the string,
|
||
|
passes it to the first argument. *)
|
||
|
|
||
|
val kasprintf : (string -> 'a) -> ('b, formatter, unit, 'a) format4 -> 'b
|
||
|
(** Same as [asprintf] above, but instead of returning the string,
|
||
|
passes it to the first argument.
|
||
|
@since 4.03
|
||
|
*)
|