File: format_doc.mli

package info (click to toggle)
ocaml 5.3.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 43,124 kB
  • sloc: ml: 355,439; ansic: 51,636; sh: 25,098; asm: 5,413; makefile: 3,673; python: 919; javascript: 273; awk: 253; perl: 59; fortran: 21; cs: 9
file content (299 lines) | stat: -rw-r--r-- 9,539 bytes parent folder | download | duplicates (3)
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
(**************************************************************************)
(*                                                                        *)
(*                                 OCaml                                  *)
(*                                                                        *)
(*             Florian Angeletti, projet Cambium, Inria Paris             *)
(*                                                                        *)
(*   Copyright 2024 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.          *)
(*                                                                        *)
(**************************************************************************)

(** Composable document for the {!Format} formatting engine. *)

(** This module introduces a pure and immutable document type which represents a
    sequence of formatting instructions to be printed by a formatting engine at
    later point. At the same time, it also provides format string interpreter
    which produces this document type from format string and their associated
    printers.

    The module is designed to be source compatible with code defining format
    printers: replacing `Format` by `Format_doc` in your code will convert
    `Format` printers to `Format_doc` printers.
*)

(** Definitions and immutable API for composing documents *)
module Doc: sig

  (** {2 Type definitions and core functions }*)

  (** Format box types *)
  type box_type =
    | H
    | V
    | HV
    | HoV
    | B

  type stag = Format.stag

  (** Base formatting instruction recognized by {!Format} *)
  type element =
    | Text of string
    | With_size of int
    | Open_box of { kind: box_type ; indent:int }
    | Close_box
    | Open_tag of Format.stag
    | Close_tag
    | Open_tbox
    | Tab_break of { width : int; offset : int }
    | Set_tab
    | Close_tbox
    | Simple_break of { spaces : int; indent : int }
    | Break of { fits : string * int * string as 'a; breaks : 'a }
    | Flush of { newline:bool }
    | Newline
    | If_newline

    | Deprecated of (Format.formatter -> unit)
    (** Escape hatch: a {!Format} printer used to provide backward-compatibility
        for user-defined printer (from the [#install_printer] toplevel directive
        for instance). *)

  (** Immutable document type*)
  type t

  type ('a,'b) fmt = ('a, t, t,'b) format4

  type printer0 = t -> t
  type 'a printer = 'a -> printer0


  (** Empty document *)
  val empty: t

  (** [format ppf doc] sends the format instruction of [doc] to the Format's
      formatter [doc]. *)
  val format: Format.formatter -> t -> unit

  (** Fold over a document as a sequence of instructions *)
  val fold: ('acc -> element -> 'acc) -> 'acc -> t -> 'acc

  (** {!msg} and {!kmsg} produce a document from a format string and its
      argument *)
  val msg: ('a,t) fmt -> 'a
  val kmsg: (t -> 'b) -> ('a,'b) fmt -> 'a

  (** {!printf} and {!kprintf} produce a printer from a format string and its
      argument*)
  val printf: ('a, printer0) fmt -> 'a
  val kprintf: (t -> 'b) -> ('a, t -> 'b) fmt -> 'a

  (** The functions below mirror {!Format} printers, without the [pp_print_]
      prefix naming convention *)
  val open_box: box_type -> int -> printer0
  val close_box: printer0

  val text: string printer
  val string: string printer
  val bytes: bytes printer
  val with_size: int printer

  val int: int printer
  val float: float printer
  val char: char printer
  val bool: bool printer

  val space: printer0
  val cut: printer0
  val break: spaces:int -> indent:int -> printer0

  val custom_break:
    fits:(string * int * string as 'a) -> breaks:'a -> printer0
  val force_newline: printer0
  val if_newline: printer0

  val flush: printer0
  val force_stop: printer0

  val open_tbox: printer0
  val set_tab: printer0
  val tab: printer0
  val tab_break: width:int -> offset:int -> printer0
  val close_tbox: printer0

  val open_tag: stag printer
  val close_tag: printer0

  val list: ?sep:printer0 -> 'a printer -> 'a list printer
  val iter:
    ?sep:printer0 -> iter:(('a -> unit) -> 'b -> unit) -> 'a printer
    ->'b printer
  val array: ?sep:printer0 -> 'a printer -> 'a array printer
  val seq: ?sep:printer0 -> 'a printer -> 'a Seq.t printer

  val option: ?none:printer0 -> 'a printer -> 'a option printer
  val result: ok:'a printer -> error:'e printer -> ('a,'e) result printer
  val either: left:'a printer -> right:'b printer -> ('a,'b) Either.t printer

end

(** {1 Compatibility API} *)

(** The functions and types below provides source compatibility with format
printers and conversion function from {!Format_doc} printers to {!Format}
printers. The reverse direction is implemented using an escape hatch in the
formatting instruction and should only be used to preserve backward
compatibility. *)

type doc = Doc.t
type t = doc
type formatter
type 'a printer = formatter -> 'a -> unit

val formatter: doc ref -> formatter
(** [formatter rdoc] creates a {!formatter} that updates the [rdoc] reference *)

(** Translate a {!Format_doc} printer to a {!Format} one. *)
type 'a format_printer = Format.formatter -> 'a -> unit
val compat: 'a printer -> 'a format_printer
val compat1: ('p1 -> 'a printer) -> ('p1 -> 'a format_printer)
val compat2: ('p1 -> 'p2 -> 'a printer) -> ('p1 -> 'p2 -> 'a format_printer)

(** If necessary, embbed a {!Format} printer inside a formatting instruction
    stream. This breaks every guarantees provided by {!Format_doc}. *)
val deprecated_printer: (Format.formatter -> unit) -> formatter -> unit
val deprecated: 'a format_printer -> 'a printer
val deprecated1: ('p1 -> 'a format_printer) -> ('p1 -> 'a printer)


(** {2 Format string interpreters }*)

val fprintf : formatter -> ('a, formatter,unit) format -> 'a
val kfprintf:
  (formatter -> 'a) -> formatter ->
  ('b, formatter, unit, 'a) format4 -> 'b

val asprintf :  ('a, formatter, unit, string) format4 -> 'a
val kasprintf : (string -> 'a) -> ('b, formatter, unit, 'a) format4 -> 'b


val dprintf : ('a, formatter, unit, formatter -> unit) format4 -> 'a
val kdprintf:
  ((formatter -> unit) -> 'a) ->
  ('b, formatter, unit, 'a) format4 -> 'b

(** {!doc_printf} and {!kdoc_printf} creates a document directly *)
val doc_printf: ('a, formatter, unit, doc) format4 -> 'a
val kdoc_printf: (doc -> 'r) -> ('a, formatter, unit, 'r) format4 -> 'a

(** {2 Compatibility with {!Doc} }*)

val doc_printer: 'a printer -> 'a Doc.printer
val pp_doc: doc printer

(** {2 Source compatibility with Format}*)

(** {3 String printers } *)

val pp_print_string: string printer
val pp_print_substring: pos:int -> len:int -> string printer
val pp_print_text: string printer
val pp_print_bytes: bytes printer

val pp_print_as: formatter -> int -> string -> unit
val pp_print_substring_as:
  pos:int -> len:int -> formatter -> int -> string -> unit

(** {3 Primitive type printers }*)

val pp_print_char: char printer
val pp_print_int: int printer
val pp_print_float: float printer
val pp_print_bool: bool printer
val pp_print_nothing: unit printer

(** {3 Printer combinators }*)

val pp_print_iter:
  ?pp_sep:unit printer -> (('a -> unit) -> 'b -> unit) ->
  'a printer -> 'b printer

val pp_print_list: ?pp_sep:unit printer -> 'a printer -> 'a list printer
val pp_print_array: ?pp_sep:unit printer -> 'a printer -> 'a array printer
val pp_print_seq: ?pp_sep:unit printer -> 'a printer -> 'a Seq.t printer

val pp_print_option: ?none:unit printer -> 'a printer -> 'a option printer
val pp_print_result: ok:'a printer -> error:'e printer -> ('a,'e) result printer
val pp_print_either:
  left:'a printer -> right:'b printer -> ('a,'b) Either.t printer


(** {3 Boxes and tags }*)

val pp_open_stag: Format.stag printer
val pp_close_stag: unit printer

val pp_open_box: int printer
val pp_close_box: unit printer

(** {3 Break hints} *)

val pp_print_space: unit printer
val pp_print_cut: unit printer
val pp_print_break: formatter -> int -> int -> unit
val pp_print_custom_break:
  formatter -> fits:(string * int * string as 'c) -> breaks:'c -> unit

(** {3 Tabulations }*)

val pp_open_tbox: unit printer
val pp_close_tbox: unit printer
val pp_set_tab: unit printer
val pp_print_tab: unit printer
val pp_print_tbreak: formatter -> int -> int -> unit

(** {3 Newlines and flushing }*)

val pp_print_if_newline: unit printer
val pp_force_newline: unit printer
val pp_print_flush: unit printer
val pp_print_newline: unit printer

(** {1 Compiler specific functions }*)

(** {2 Separators }*)

val comma: unit printer

(** {2 Compiler output} *)

val pp_two_columns :
  ?sep:string -> ?max_lines:int ->
  formatter -> (string * string) list -> unit
(** [pp_two_columns ?sep ?max_lines ppf l] prints the lines in [l] as two
   columns separated by [sep] ("|" by default). [max_lines] can be used to
   indicate a maximum number of lines to print -- an ellipsis gets inserted at
   the middle if the input has too many lines.

   Example:

    {v pp_two_columns ~max_lines:3 Format.std_formatter [
      "abc", "hello";
      "def", "zzz";
      "a"  , "bllbl";
      "bb" , "dddddd";
    ] v}

    prints

    {v
    abc | hello
    ...
    bb  | dddddd
    v}
*)