This file is indexed.

/usr/lib/ocaml/melt/latex.mli is in libmelt-ocaml-dev 1.4.0-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   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
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
(**************************************************************************)
(* Copyright (c) 2009, Romain BARDOU                                      *)
(* All rights reserved.                                                   *)
(*                                                                        *)
(* Redistribution and  use in  source and binary  forms, with  or without *)
(* modification, are permitted provided that the following conditions are *)
(* met:                                                                   *)
(*                                                                        *)
(* * Redistributions  of  source code  must  retain  the above  copyright *)
(*   notice, this list of conditions and the following disclaimer.        *)
(* * Redistributions in  binary form  must reproduce the  above copyright *)
(*   notice, this list of conditions  and the following disclaimer in the *)
(*   documentation and/or other materials provided with the distribution. *)
(* * Neither the  name of Melt nor  the names of its  contributors may be *)
(*   used  to endorse  or  promote products  derived  from this  software *)
(*   without specific prior written permission.                           *)
(*                                                                        *)
(* THIS SOFTWARE  IS PROVIDED BY  THE COPYRIGHT HOLDERS  AND CONTRIBUTORS *)
(* "AS  IS" AND  ANY EXPRESS  OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT *)
(* LIMITED TO, THE IMPLIED  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *)
(* A PARTICULAR PURPOSE  ARE DISCLAIMED. IN NO EVENT  SHALL THE COPYRIGHT *)
(* OWNER OR CONTRIBUTORS BE  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *)
(* SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL  DAMAGES (INCLUDING,  BUT  NOT *)
(* LIMITED TO, PROCUREMENT OF SUBSTITUTE  GOODS OR SERVICES; LOSS OF USE, *)
(* DATA, OR PROFITS; OR BUSINESS  INTERRUPTION) HOWEVER CAUSED AND ON ANY *)
(* THEORY OF  LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY,  OR TORT *)
(* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING  IN ANY WAY OUT OF THE USE *)
(* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   *)
(**************************************************************************)

(** LaTeX output. *)

(** LaTeX expressions. *)
type t

(** {2 LaTeX Pervasives} *)

type size = [
| `In of float
| `Mm of float
| `Cm of float
| `Pt of float
| `Em of float
| `Ex of float

| `Pc of float
| `Bp of float
| `Dd of float
| `Cc of float
| `Sp of float

| `Parindent of float
| `Baselineskip of float
| `Baselinestretch of float
| `Parskip of float
| `Textwidth of float
| `Linewidth of float
| `Textheight of float
| `Unitlength of float

| `Fill
| `Stretch of int
]
  (** The type of LaTeX sizes.
- [`In]: inches
- [`Mm]: millimeters
- [`Cm]: centimeters
- [`Pt]: points (about 1/72 inch)
- [`Em]: approximately the width of an "M" in the current font
- [`Ex]: approximately the width of an "x" in the current font

- [`Pc]: pica (12pt/pc)
- [`Bp]: big pt (72bp/in)
- [`Dd]: didot (1157dd=1238pt)
- [`Cc]: cicero (12dd/cc)
- [`Sp]: scaled point (65536sp/pt)

- [`Parindent]: normal paragraph indentation
- [`Baselineskip]: normal vertical distance between lines in a paragraph
- [`Baselinestretch]: multiplies [`Baselineskip]
- [`Parskip]: the extra vertical space between paragraphs
- [`Textwidth]: the width of text on the page
- [`Linewidth]: width of a line in the local environment
- [`Textheight]: the height of text on the page
- [`Unitlength]: units of length in picture environment

- [`Fill]: rubber length; takes as much space as possible
- [`Stretch]: rubber length; if multiple [`Stretch]-sized commands are issued
  on the same line (or vertical box) they stretch in proportion of their respective
  factor.
*)

val latex_of_size : size -> t
(** Low level function to be used to make new bindings. *)

(** {3 Document} *)

type documentclass = 
    [ `Article | `Report | `Book | `Letter | `Slides | `Beamer | `Custom of string]
type documentoptions = [ `Landscape | `A4paper | `TwoColumn | `Pt of
    int ]

val document:
  ?documentclass: documentclass ->
  ?options: documentoptions list ->
  ?title: t ->
  ?author: t ->
  ?date: t ->
  ?prelude: t ->
  ?packages: (t * t) list -> t -> t
(** The [~packages] argument takes a list of [(name, opt)] where [name] is the
name of the package and [opt] is its option. This is equivalent to
using several calls to [usepackage] in the [~prelude]. *)

(** {3 Variables} *)

(** {4 Basic Constructors} *)

(** Variables are similar to LaTeX counters, except that they are computed
    when pretty-printing the LaTeX AST.
    
    The two basic operations on variables are [get] and [setf].
    [get] outputs an ast depending on the current contents of a
    variable.
    [setf] updates the contents of a variable.

    [get] can also use the contents of a variable at a different
    position in the document.
    To use a position, you need to declare one first with
    [position]. then you can place that position in you document with
    [place]. You must not place a position more than one time.
    If a position isn't placed, the contents of the variables at that
    position will be the default one.

    The final contents of variables is obtained by a fixpoint
    computation wich is performed by the printing functions
    {!to_buffer}, {!to_channel}, {!to_file}, {!to_string}. That
    fixpoint may not terminate. In that case, the log will tell you which
    variable did not converge. *)

type 'a variable

val variable: ?eq:('a -> 'a -> bool) -> ?name:string ->
  ?printer:('a -> string) -> 'a -> 'a variable
(** Declare a new variable.  The last argument is the default value of
    the variable.

    [eq] is the equality function on the type of the variable. Default is [=].

    [name] and [printer] are used to print information when the
    fixpoint calculation diverged. *)

val setf: 'a variable -> ('a -> 'a) -> t
(** Change the value of a variable in the rest of the document. *)

val setf2: 'a variable -> 'b variable -> ('a -> 'b -> 'b) -> t
(** [setf var_in var_out f]
    Change the value of the variable [var_out] in the rest of the document
    using the contents of [var_in]. *)

type position
(** The type of positions in documents. *)

val position: ?name:string -> unit -> position
(** Declare a new position.
    [name] is used to print information when the fixpoint computation
    diverged. *)

val place: position -> t
(** Place a position in the document. *)

val get: ?position:position -> 'a variable -> ('a -> t) -> t
(** Use the contents of a variable to compute part of the document.
    If [get] has no parameter [position] then the current value of the
    variable is taken. Otherwise it is the value at [position]. *)

(** {4 Useful Stuff About Variables} *)

(** All these functions are defined using the above constructors. *)

val set: 'a variable -> 'a -> t
  (** Change the value of a variable.

      [set x v]: return a node which, when evaluated, changes the contents
      of variable [x] to value [v]. *)

val final: 'a variable -> ('a -> t) -> t
  (** Like [get], but the value of the variable is taken at the end of
      the document. *)

val incr_var: int variable -> t
  (** Increment an integer variable.

      [incr_var x] is equivalent to [setf x (fun x -> x + 1)]. *)

val decr_var: int variable -> t
  (** Decrement an integer variable.

      [decr_var x] is equivalent to [setf x (fun x -> x - 1)]. *)

val vari: int variable -> t
  (** Print an integer variable.

      [vari x] is equivalent to [get x (fun x -> text (string_of_int x))]. *)

val varf: float variable -> t
  (** Print a float variable.

      [varf x] is equivalent to [get x (fun x -> text (string_of_float x))]. *)

val varb: bool variable -> t
  (** Print a boolean variable.

      [varb x] is equivalent to [get x (fun x -> text (string_of_bool x))]. *)

val vars: string variable -> t
  (** Print a string variable.

      [vars x] is equivalent to [get x text]. *)

val vart: t variable -> t
  (** Print a variable containing a LaTeX AST.

      [vart x] is equivalent to [get x (fun x -> x)]. *)

val finali: int variable -> t
  (** Print the last value of an integer variable.

      [finali x] is equivalent to [final x (fun x -> text (string_of_int x))]. *)

val finalf: float variable -> t
  (** Print the last value of a float variable.

      [finalf x] is equivalent to [final x (fun x -> text (string_of_float x))]. *)

val finalb: bool variable -> t
  (** Print the last value of a boolean variable.

      [finalb x] is equivalent to [final x (fun x -> text (string_of_bool x))]. *)

val finals: string variable -> t
  (** Print the last value of a string variable.

      [finals x] is equivalent to [final x text]. *)

val finalt: t variable -> t
  (** Print the last value of a variable containing a LaTeX AST.

      [finalt x] is equivalent to [final x (fun x -> x)]. *)

(** {3 References and Labels} *)

(** Example (using the Melt pre-processor):

[let lbl_intro = label ()]

[let intro = section ~label: lbl_intro "This is Section~{ref_ lbl_intro}."] *)

type label

val label: ?name: string -> unit -> label
  (** Declare a new label.

Argument [name]  can be  used to force  the name  of the label  in the
LaTeX file. This can  be useful if you need to refer  to this label in
an external LaTeX  file or if the label itself  is declared in another
LaTeX file. The default value of [name] is ["latex_lib_label_n"] where
[n] is a counter. *)

val ref_: label -> t
  (** Make a reference to the label. *)

(** {3 Figures} *)

type float_position = [ `H | `T | `P | `B | `Force ]
  (** Floating element (figure, ...) positions.
      - [`H]: here
      - [`T]: top of page
      - [`B]: bottom of page
      - [`P]: put on a special page for floats only
      - [`Force]: override internal LaTeX parameters *)
val float_all: float_position list
  (** [[ `H; `T; `B; `P ]] *)

val figure: ?label: label -> ?pos: float_position list -> ?center: bool ->
  ?side_caption: bool -> ?caption: t -> ?wide: bool -> t -> t
  (** Floating figure.

      Default value for [center] is false.
      If [side_caption] is [true], the caption will be placed at the side of
      the figure instead of at the bottom. This uses package [sidecap].
      Default value is [false].

      Argument [~wide: true] must be used for multi-columns documents if you
      want the figure to use the full width of the page. In this case,
      positions [`H] has no effect, and position [`B] adds package
      [stfloats].

      To prevent wide figures from being placed out-of-order with respect to
      their "non-wide" counterparts, use package [fixltx2e]. *)

type wrapfigure_position =
    [ `L | `R | `I | `O | `Force of [ `L | `R | `I | `O ] ]
  (** Figure positions for package [wrapfig].
      - [`L]: left
      - [`R]: right
      - [`I]: inside (if document is twosided)
      - [`O]: outside (if document is twosided)
      - [`Force _]: force the figure to start precisely where specified
(may cause it to run over page breaks) *)

val wrapfigure: ?label: label -> ?pos: wrapfigure_position ->
  ?lines: int -> ?width: size -> ?center: bool -> ?caption: t -> t -> t
  (** Floating figure which makes text wrap around it.

      Uses package [wrapfig].
      Argument [lines] specifies the height of the figure in number of lines.
      It can be useful if LaTeX fails to compute it correctly.
      Default value for [width] is half the text width.
      Default value for [center] is false.

      If there is too much space on top and below the figure, and [lines] does
      not do what you want, you can add
      some negative [vspace]s. In general it is better to let
      LaTeX place the figure for you, though. *)

type floatingfigure_position = [ `L | `R | `P ]
  (** Figure positions for package [floatflt].
      - [`L]: left
      - [`R]: right
      - [`P]: right if the pagenumber is odd, left if even *)

val floatingfigure: ?label: label -> ?pos: floatingfigure_position ->
  ?width: size -> ?center: bool -> ?caption: t -> t -> t
  (** Floating figure which makes text wrap around it.

      Uses package [floatflt].
      Default value for [width] is half the text width.
      Default value for [center] is false. *)

val subfloat: ?label: label -> ?caption: t -> t -> t
  (** Sub-figure.

      Uses package [subfig].
      Use it inside a [figure] to insert sub-figures. *)

(** {3 Miscellaneous Commands} *)

val hyphen: t
  (** Tell LaTeX where to cut words at the end of lines. *)

val index: t -> t -> t
  (** [index x y] produces [{x}_{y}] *)

val exponent: t -> t -> t
  (** [exponent x y] produces [{x}^{y}] *)

val index_exponent: t -> t -> t -> t
  (** [index_exponent x y z] produces [{x}_{y}^{z}].

      This is NOT equivalent to [exponent (index x y) z] as this would
      produce [{{x}_{y}}^{z}]. The former allows the exponent to be printed
      above the index, while the latter does not. *)

val tableofcontents: t
val listoffigures: t
val listoftables: t

val appendix: t

(** [printindex] output an index listing the various point which have
      been referenced by [place_index key]. [key] can be a phrase
      in which case it appears as-is in the index, or some more complex
      instruction (documentation for index
      keys can be found in the Not So Short Introduction to Latex (available
      online) or the Latex Companion).

      If you use at least one of [place_index] or [printindex], a file .idx
      will be produced at the same time as the .aux. It needs to be processed
      by the program makeindex (makeindex file.idx). Then (pdf)latex
      needs to be run again. *)
val place_index: t -> t
val printindex: t

val today: t

val maketitle: t
  (** You should not need [maketitle] if you use {!document}. *)

val part: ?label: label -> t -> t
  (** For the report style. *)

val chapter: ?label: label -> ?short: t -> t -> t
val section: ?label: label -> ?short: t -> t -> t
val subsection: ?label: label -> ?short: t -> t -> t
val subsubsection: ?label: label -> ?short: t -> t -> t
val paragraph: t -> t

val chapter': ?label: label -> ?short: t -> t -> t
  (** Same as [chapter] but with no numbering. *)
val section': ?label: label -> ?short: t -> t -> t
  (** Same as [section] but with no numbering. *)
val subsection': ?label: label -> ?short: t -> t -> t
  (** Same as [subsection] but with no numbering. *)
val subsubsection': ?label: label -> ?short: t -> t -> t
  (** Same as [subsubsection] but with no numbering. *)

val par: t
val displaymath: t -> t
val equation: ?label: label -> t -> t
val hfill: t
val vfill: t
val vfil: t
val footnote: t -> t
val latex_of_int: int -> t
val latex_of_float: float -> t
val itemize: t list -> t
val enumerate: t list -> t
val newline: t
  (** Start a new line. *)
val newline_size: size -> t
  (** A newline followed by a vertical space. *)
val newpage: t
  (** Start a new page. *)
val clearpage: t
  (** Same as [newpage], but also force figures and tables floating in the
current page to be printed. *)
val noindent: t
val space : t
  (** Forces a space, same as "\ " in LaTeX *)
val quad: t
val qquad : t
val includegraphics: t -> t
val symbol: int -> t
val symbolc: char -> t
  (** Convert a [char] into an [int] and apply [symbol]. *)

val center: t -> t
val flushleft: t -> t
val flushright: t -> t

val quote: t -> t
val quotation: t -> t

val stackrel: t -> t -> t

val vspace: size -> t
  (** A vertical space. *)
val hspace: size -> t
  (** An horizontal, possibly negative space. *)
val addvspace: size -> t
  (** Similar to [vspace], but an [addvspace x] followed by an [addvspace y]
will produce an [addvspace] of [max x y]. *)
val ignorespaces: t
  (** Tells LaTeX to ignore following spaces and new lines. Useful at the
      end of a display environment, for instance. *)
val smallskip: t (** A small [vspace]. *)
val medskip: t (** A medium [vspace]. *)
val bigskip: t (** A big [vspace]. *)
val nointerlineskip: t (** Delete the interline vertical space. *)

val phantom: t -> t
  (** Take the space of the argument without actually drawing it *)
val vphantom: t -> t (** Vertical-only phantom *)
val hphantom: t -> t (** Horizontal-only phantom *)

val rule_: ?lift:size -> size -> size -> t
  (** [rule_ width height] draws a rule (i.e. a black box) of width [width]
      and height [height] (for instance a horizontal or vertical line).
      The optional argument [lift] moves the rule up if positive and down
      if negative.
      A special case is when [width] is null. In this case the rule,
      called a strut, does not display, it only makes sure that the
      surrounding box has at least its height. *)

type valignment = [ `T | `C | `B ]
  (** (`T)op, (`C)enter, (`B)ottom. *)

val parbox: size -> ?valign:valignment -> t -> t
  (** A box in which new lines and paragraphs may be used. Useful to display
      code listings, for instance.
      The [valign] optional argument controls the vertical alignment of
      the box with respect to the surrounding text. *)
val minipage: size -> ?valign:valignment -> t -> t
  (** A box in which almost all command may be used. A more robust kind of
      [parbox]. *)

type halignment = [ `C | `L | `R | `S ]
  (** (`C)enter, flush (`L)eft, flush (`R)ight or (`S)pread. *)

type xsize = [
    size
  | `Width of float
  | `Height of float
  | `Depth of float
  | `Totalheight of float
  ]
(** Horizontal box commands ({!makebox}, {!framebox} and {!raisebox})
    can use extra size information in their definition. These are computed
    from their content:
    [`Width] is the width of the content
    [`Height] is the height above the baseline
    [`Depth] is the height below the baseline
    [`Totalheight] is the sum of [`Height] and [`Depth]
 *)

val makebox : xsize -> ?halign:halignment -> t -> t
  (** A box which only deals with horizontaly aligned material. *)
val framebox : xsize -> ?halign:halignment -> t -> t
  (** Same as [makebox] but draws a frame around the box. *)

val raisebox : shift:xsize -> ?fakeheight:xsize*xsize -> t -> t
  (** [raisebox ~shift x] displays x vertically displaced by [shift].
      If [~fakeheight] is not specified, then the line is built as if
      [x] had not been moved.
      If [~fakeheight:(h,d)] then the line building algorithm sees a box
      which extends [h] above the baseline (height) and [d] below the
      baseline (depth). *)


type alignment = [ `L | `C | `R ]
type array_column =  [ alignment | `Vert | `Sep of t]
type array_line

val array: ?valign:valignment -> array_column list -> array_line list -> t
val array_line: ?sep: size -> ?layout:(int*[alignment|`I]) list -> t list -> array_line
  (** Extra alignment [`I] in layout means that the column inherits the alignment
        of the first corresponding column in the array layout.
        The integers in the layout correspond to over how many of the array's column
        will the cell will span.*)
val array_command : t -> array_line
  (** [array_command x] is a low level command. It gives [x] as an array line to Latex.
         Meant to define alternative commands to draw horizontal lines in arrays.*)
(*spiwack: todo: horizontal line commands, like [hline], [midrule], etc… *)

(* Actually, I don't know what these do. *)
val frontmatter: t
val backmatter: t
val mainmatter: t
val underbrace: t -> t -> t
val overbrace: t -> t -> t

(** {3 Fonts} *)

(** {4 Font Styles} *)

val emph: t -> t (** Emphasize *)

val texttt: t -> t (** Monospace *)
val textsc: t -> t (** Small caps *)
val textit: t -> t (** Italic *)
val textbf: t -> t (** Bold *)
val textrm: t -> t (** Roman *)
val textsf: t -> t (** Sans serif *)

val mathit: t -> t (** Italic (for math mode) *)
val mathbf: t -> t (** Bold (for math mode) *)
val mathrm: t -> t (** Roman (for math mode) *)
val mathsf: t -> t (** Sans serif (for math mode) *)
val mathcal: t -> t (** Caligraphic *)

(** {4 Font Sizes} *)

(** From the smallest to the largest. *)

val tiny: t -> t
val scriptsize: t -> t
val footnotesize: t -> t
val small: t -> t
val normalsize: t -> t
val large: t -> t
val large2: t -> t
val large3: t -> t
val huge: t -> t
val huge2: t -> t

(** {3 Math Accents} *)

val hat: t -> t
val grave: t -> t
val bar: t -> t
val acute: t -> t
val mathring: t -> t
val check: t -> t
val dot: t -> t
val vec: t -> t
val breve: t -> t
val tilde: t -> t
val ddot: t -> t
val widehat: t -> t
  (** A wide [hat] which spreads over the whole argument. *)
val widetilde: t -> t
  (** A wide [tilde] which spreads over the whole argument. *)
val overline: t -> t
  (** A wide [bar] which spreads over the whole argument. *)

(** {3 Greek Letters} *)

(** {4 Lowercase} *)

val alpha: t
val beta: t
val gamma: t
val delta: t
val epsilon: t
val varepsilon: t
val zeta: t
val eta: t
val theta: t
val vartheta: t
val iota: t
val kappa: t
val varkappa: t
val lambda: t
val mu: t
val nu: t
val xi: t
val pi: t
val varpi: t
val rho: t
val varrho: t
val sigma: t
val varsigma: t
val tau: t
val upsilon: t
val phi: t
val varphi: t
val chi: t
val psi: t
val omega: t

val digamma: t

(** {4 Uppercase} *)

val gamma_: t
val delta_: t
val theta_: t
val lambda_: t
val xi_: t
val pi_: t
val sigma_: t
val upsilon_: t
val phi_: t
val psi_: t
val omega_: t

(** {3 Hebrew Letters} *)

val aleph: t
val beth: t
val gimel: t
val daleth: t

(** {3 Mathematical Symbols} *)

(** {4 Binary Relations} *)

val le: t (** less or equal *)
val leq: t (** less or equal (same as {!le}) *)
val leqslant: t (** less or equal (with equal bar parallel to the 'less than' sign *)
val ge: t (** greater or equal *)
val geq: t (** greater or equal (same as {!ge}) *)
val geqslant: t (** greater or equal (with equal bar parallel to the 'less than' sign *)
val equiv: t (** = with 3 bars *)
val ll: t (** << *)
val gg: t (** >> *)
val doteq: t (** = with . on top *)
val prec: t (** trumpet < *)
val succ: t (** trumpet > *)
val sim: t (** ~ *)
val preceq: t (** trumpet < or equal *)
val succeq: t (** trumpet > or equal *)
val simeq: t (** ~ or equal *)
val subset: t
val supset: t
val approx: t (** double ~ *)
val subseteq: t
val supseteq: t
val cong: t (** = with ~ on top *)
val sqsubset: t (** square strict subset (latexsym package) *)
val sqsupset: t (** square strict superset (latexsym package) *)
val join_: t (** small bowtie (latexsym package) *)
val sqsubseteq: t (** square subset or equal *)
val sqsupseteq: t (** square superset or equal *)
val bowtie: t
val in_: t (** in set *)
val owns: t (** inverted in set *)
val propto: t (** infinite with open right buckle *)
val vdash: t (** |- *)
val dashv: t (** -| *)
val models: t (** |= *)
val mid: t (** | *)
val parallel: t (** || *)
val perp: t (** _|_ *)
val smile: t
val frown: t
val asymp: t (** frown with smile on top *)
val not_: t -> t (** generic negation of binary symbol. [not_ in_] will print as ∉ *)
val notin: t (** not in set (∉) *)
val ne: t (** not equal (≠)*)
val neq: t (** not equal (same as {!ne}) *)

(** {4 Binary Operators} *)

val pm: t (** - with + on top (∓) *)
val mp: t (** + with - on top (±)*)
val triangleleft: t (** ◃ *)
val cdot: t (** centered . *)
val div: t (** - with . on top and . on the bottom (÷)*)
val triangleright: t (** ▹ *)
val times: t (** × *)
val setminus: t (** backslash *)
val star: t (** 5-branches star *)
val cup: t (** set union *)
val cap: t (** set intersection *)
val ast: t (** asterisk * (6-branches star) *)
val sqcup: t (** square cup *)
val sqcap: t (** square cap *)
val circ: t (** a small circle *)
val lor_: t (** \/ *)
val land_: t (** /\ *)
val bullet: t (** a small filled circle *)
val oplus: t (** a circle with a + inside *)
val ominus: t (** a circle with a - inside *)
val diamond: t (** a small square rotated 45 degrees *)
val odot: t (** a circle with a centered . inside *)
val oslash: t (** a slashed circle *)
val uplus: t (** a cup with a + inside *)
val otimes: t (** a crossed circle *)
val bigcirc: t
val amalg: t
val bigtriangleup: t
val bigtriangledown: t
val dagger: t
val lhd: t (** bigger [triangleleft] (latexsym package) *)
val rhd: t (** bigger [triangleright] (latexsym package) *)
val ddagger: t (** double dagger ([dagger] with one more cross on the bottom) *)
val unlhd: t (** bigger, underlined [triangleleft] (latexsym package) *)
val unrhd: t (** bigger, underlined [triangleright] (latexsym package) *)
val wr: t (** a vertical ~ *)

(** {4 BIG Operators} *)

val sum: t
val prod: t
val coprod: t
val bigcup: t
val bigcap: t
val bigvee: t
val bigwedge: t
val bigsqcup: t
val biguplus: t
val int: t
val oint: t
val bigodot: t
val bigoplus: t
val bigotimes: t

(** {4 Arrows} *)

val leftarrow: t (** <- *)
val rightarrow: t (** -> *)
val to_: t (** -> (same as {!rightarrow}) *)
val leftrightarrow: t (** <-> *)
val leftarrow_: t (** <= *)
val rightarrow_: t (** => *)
val leftrightarrow_: t (** <=> *)
val longleftarrow: t (** <-- *)
val longrightarrow: t (** --> *)
val longleftrightarrow: t (** <--> *)
val longleftarrow_: t (** <== *)
val longrightarrow_: t (** ==> *)
val longleftrightarrow_: t (** <==> *)
val iff: t (** <==> (bigger spaces) *)

val mapsto: t
val longmapsto: t
val hookleftarrow: t
val hookrightarrow: t
val leftharpoonup: t
val rightharpoonup: t
val leftharpoondown: t
val rightharpoondown: t
val rightleftharpoons: t
val uparrow: t
val downarrow: t
val updownarrow: t
val uparrow_: t (** double [uparrow] *)
val downarrow_: t (** double [downarrow] *)
val updownarrow_: t (** double [updownarrow] *)
val nearrow: t (** North-East arrow *)
val searrow: t (** South-East arrow *)
val swarrow: t (** South-West arrow *)
val nwarrow: t (** North-West arrow *)
val leadsto: t (** ~> (latexsym package) *)

(** {4 Symbols to be Sorted (Stay Tuned)} *)

val box_: t
  (** A square box, for instance to end proofs (QED).
      Adds package [latexsym]. *)

val langle: t (** ⟨ *)
val rangle: t (** ⟩ *)
val lceil: t (** ⌈ *)
val rceil: t (** ⌉ *)

val frac: t -> t -> t

val land_: t (** /\ *)
val lor_: t (** \/ *)
val lnot: t (** ¬ *)
val neg: t (** ¬ (like {!lnot}) *)
val forall: t (** ∀ *)
val exists: t (** ∃ *)

val top : t (** ⊤ *)
val bot : t (** ⊥ *)

val sharp : t

val dots: t
val cdots: t (** Centered dots [...] *)
val ldots: t (** elipsis, works in math and text mode *)

val emptyset: t

type doublable_delimiter =
    [ `Down | `Up | `Up_down | `Vert ]
type delimiter =
    [ `None | `Brace | `Paren | `Bracket | `Angle | `Floor | `Ceil | `Slash
    | doublable_delimiter | `Double of doublable_delimiter ]

val left: delimiter -> t
val right: delimiter -> t

val just_left: delimiter -> t -> t
  (** [just_left d x]: concatenation of [left d], [x] and [right `None]. *)

val just_right: delimiter -> t -> t
  (** [just_right d x]: concatenation of [left `None], [x] and [right d]. *)

val between: delimiter -> t -> t
  (** [between d x]: concatenation of [left d], [x] and [right d]. *)

val oe: t (** French e in o as in "coeur", "noeud"... *)

(** {4 AMS} *)

val mathbb: t -> t
val mathfrak: t -> t
val align : t -> t
(** the AMS align environment to align equations using & *)
val align_ : t -> t
(** same as [align], but without numbering *)

val gather : t -> t
val gather_ : t -> t
val split : t -> t
val proof : ?opt:t -> t -> t

val twoheadrightarrow : t (** ->> *)
val square: t

val par_: t (** The paragraph symbol. *)

val black_triangle_left: t
val black_triangle_right: t

(** {4 Mathpartir} *)

val mathpar : t list -> t
  (** Math paragraph.
This function inserts [and] commands between each item to split them. *)

val inferrule : ?lab: t -> ?left: t -> ?right: t -> ?vdots: size ->
  ?width: size -> ?leftskip: size -> ?rightskip: size -> t list -> t list -> t
  (** Inference rule.
[inferrule pre post] builds an inference rule with [pre] at the top and [post]
at the bottom. If [pre] or [post] is empty, the bar is not drawn.
    @param lab label to put above the rule
    @param left label to put on the left of the rule
    @param right label to put on the right of the rule
    @param vdots raise the rule and draw vertical dots ; the length argument
is translated to a number of line-skips *)

(** {4 Saint Mary Road} *)

(** The package ["stmaryrd"] is automatically added by these commands. *)

val llbracket: t (** [\[|] *)
val rrbracket: t (** [|\]] *)
val llparenthesis: t (** [(|] *)
val rrparenthesis: t (** [|)] *)

(** {3 Slide Document Class} *)

val slide: t -> t

(** {3 Beamer Document Class} *)

module type BEAMER = sig
  type beamertemplate = [ `NavigationSymbols | `Footline ]
  type tocoptions = [ `CurrentSection | `CurrentSubsection | `HideAllSubsections
  | `HideOtherSubsections | `PauseSections | `PauseSubsections ]

  val frame: ?title: t -> ?subtitle: t -> t -> t
    (** One slide. *)

  val setbeamertemplate: beamertemplate -> t -> t

  val insertpagenumber: t
  val insertdocumentendpage: t
  val inserttitle: t
  val insertsection: t
  val insertsubsection: t
  val insertshorttitle: t
  val insertshortsection: t
  val insertshortsubsection: t

  val tableofcontents: tocoptions list -> t
  val at_begin_section: t -> t
  val at_begin_subsection: t -> t
  val at_begin_subsubsection: t -> t
  val block: t -> t -> t (** [block title body] *)

  type color = [
  | `Gray
  | `Red
  | `Green
  | `Blue
  | `Yellow
  | `RGB of float * float * float
  ]

  val color: color -> t -> t

  type overlays_spec = [`I of int]

  (*val command: ?packages: (string * string) list -> string -> ?only: overlays_spec list -> 
    ?opt: (mode * t) -> (mode * t) list -> mode -> t*)
    
  val only: overlays_spec list -> t -> t

  val includegraphics: ?only: overlays_spec list -> t -> t
    (** Same as {!Latex.includegraphics} but with the [only] parameter. *)

  (** {2 Columns} *)

  type column_alignment = [ `T | `C | `B ]
    (** Vertical alignment of a column: top, center or bottom. *)

  val columns: ?align: column_alignment -> t -> t
    (** Put your columns in this environment.

        The [align] argument is the default vertical alignment for each
        column.

        The last argument must be a concatenation of several {!column}s. *)

  val column: ?align: column_alignment -> size -> t -> t
    (** One column.

        Columns must be put inside the {!columns} environment. *)

  val equi_columns: ?align: column_alignment -> t list -> t
    (** Several columns with the same size each.

        The size of each column is [`Textwidth (1. /. c)] where [c] is the
        length of the list. The [align]ment is the same for each column.

        Example with two columns: [equi_columns ["Hello"; "World"]]*)
end

module Beamer : BEAMER

(** {3 Verbatim Modes} *)

module Verbatim: sig
  val verbatim: string -> t
    (** Replace all non-alphanumerical characters by an application of the
[symbol] command, all spaces by escaped spaces, and all new lines
by actual new lines. *)

  val regexps: (Str.regexp * (string -> t)) list -> (string -> t) -> string -> t
    (** [regexps [r1, a1; r2, a2; ...] f s]: apply [a1] on all matches of [r1]
in [s], then [a2] on all matches of [r2], and so on.
Note that [r2] is only tested on the parts of [s] which do not match [r1].
[f] is applied on the parts of [s] which are not matched by any of the
regular expressions. *)

  val keywords: ?apply: (t -> t) -> string list -> string -> t
    (** [keywords k s]: apply [verbatim] on [s] but also apply [~apply] on all
  keywords given in [k]. The default value of [~apply] is [textbf] (bold
  font).

  [keywords ["let"; "in"]] is the same as
  [regexps [Str.regexp "let\\|in", fun x -> textbf (verbatim x)] verbatim]. *)

  val pseudocode:
    ?trim: (string -> string) ->
    ?id_regexp: Str.regexp ->
    ?kw_apply: (t -> t) ->
    ?id_apply: (t -> t) ->
    ?rem_apply: (string -> t) ->
    ?keywords: string list ->
    ?symbols: (string * t) list ->
    ?keyword_symbols: (string * t) list ->
    ?underscore: Str.regexp ->
    string -> t
    (** Pseudocode parsing.
        @param trim apply this function first (default is [trim ['\n']])
        @param id_regexp the regular expression used to parse identifiers,
including keywords (default is words starting with a letter or an underscore
followed by any number of letter or digit, followed by any number
of groups of underscore followed by at least one letter or digit:
[Str.regexp "[_a-zA-Z][a-zA-Z0-9]*\\(_[a-zA-Z0-9]+\\)*"])
        @param kw_apply applied to keywords (default is [textbf])
        @param id_apply applied to identifiers (default is [mathit])
        @param rem_apply applied to remaining parts (default is [verbatim])
        @param keywords keyword list 
        @param symbols symbol list and the way they are printed
        @param keyword_symbols keyword list that should be printed in a special
way, as symbols, but parsed as identifiers
        @param underscore delimiter used to split identifiers
(default is underscore (['_']))

Keywords, keyword symbols and identifiers are split using
[underscore] as delimiter.
The first part is replaced by the corresponding [Latex.t].
The other parts are displayed as indexes separated by commas ([',']).
They are also treated as identifiers, potentiel keywords or keyword symbols. *)

  (** {2 Tools to Build Modes} *)

  val trim: char list -> string -> string
    (** Delete characters at the beginning and at the end of a string.
        [trim [' '; '\n'] s] will return a copy of s without spaces and
new lines at the beginning and at the end. *)

  val trim_begin: char list -> string -> string
    (** Delete characters at the beginning of a string.
        [trim [' '; '\n'] s] will return a copy of s without spaces and
new lines at the beginning. *)

  val trim_end: char list -> string -> string
    (** Delete characters at the end of a string.
        [trim [' '; '\n'] s] will return a copy of s without spaces and
new lines at the end. *)

  val split_lines: string -> string list
    (** Split a string according to the ['\n'] delimiter, which is not kept. *)
end

(** {2 Low-Level LaTeX} *)

(** LaTeX mode: math, text or any. *)
type mode = M | T | A

(** {3 Constructors} *)

val empty: t
  (** The empty LaTeX tree.

      Equivalent to [concat []] or [text ""]. *)

val is_empty: t -> bool
  (** Test whether a LaTeX tree is empty.

      A concatenation of empty trees is also empty.

      A tree containing a {!set} node is not empty.

      A tree containing {!get} or {!final} nodes is
      not empty, even if the call will produce an empty tree when
      evaluating variables. *)

(** Raw LaTeX. *)
val text: string -> t

(** Concatenation. *)
val concat: t list -> t

(** Infix Concatenation. *)
val (^^): t -> t -> t

(** LaTeX Command. *)
val command: ?packages: (string * string) list -> string -> ?opt: (mode * t) ->
  (mode * t) list -> mode -> t
(** [command name args mode] produces the LaTeX command [name] applied to
arguments [args].

The command should be used in mode [mode]. For exemple,
the [ensuremath] LaTeX command should be used in math mode. The command will
be coerced using [mbox] or [$ ... $] if [mode] differs from the mode it is
used in.

The [opt] optional parameter may be used to provide an optional parameter
(in brackets [[]]) to the LaTeX command.

Arguments [opt] and [args] must be given with their expected mode and will
be coerced if needed. For example, the [mbox] command expect an argument in
text mode (the argument must be coerced using [$ ... $] if it is math).
The [ensuremath] command expects an argument in any mode.

All packages [(name, opt)] given using [packages] will automatically be used by
[document]. *)

type arg_kind
  val bracket : arg_kind
  val brace : arg_kind
  val nobr : arg_kind
val unusual_command : ?packages: (string * string) list -> string -> 
  (mode * arg_kind * t) list -> mode -> t
(** [unusual_command] does the same as [command], but is more low level.
      Instead of having a single optional argument and a list of mandatory
      arguments, it only has a list of arguments.

      Each argument comes not only with its content and mode, but with an
      "argument kind" (type [arg_kind]) specifying whether it is a brace
      argument (corresponding to mandatory arguments in [command]) or a bracket
      argument (corresponding, in turn, to the option argument of [command]).

      This allows to handle commands which have several optional arguments, 
      or where optional and mandatory arguments are interleaved. *)

val within_braces: t -> t
  (** [within_braces x] produces [{x}].
      Typically meant to be used together with [unusual_command]. *)

(** LaTeX Environment. *)
val environment: ?packages: (string * string) list -> string ->
  ?opt: (mode * t) -> ?args: (mode * t) list -> (mode * t) -> mode -> t
(** Same as function [command], except that it only takes one argument
(the environment body) and produces an environment, i.e. using the
[begin] and [end] commands. The [args] parameters may be used to give
additional arguments, such as the columns of an array.

All packages [(name, opt)] given using [packages] will automatically be used by
[document]. *)

(** Ensure text or math mode. *)
val mode: mode -> t -> t
(** [mode m x] returns [x] if its mode is already [m]. If its mode is not [m],
the result is [x] coerced using [mbox] or [$ ... $]. *)

(** {3 Basic blocks to make custom [document] functions} *)

val documentclass : ?opt:(mode*t) -> t -> t
  (** All document must start with a single document class declaration,
optionnally with arguments. [documentclass cls] means that [cls]
(represented as a [Latex.t]) is the class of the document. The optional
argument is given as a [Latex.t] as well, for generality. *)

val required_packages : t
  (** Your prelude must contain the list of packages required by your
document. That is a single occurence of [required_packages]. Note that
it does not make sense out of the document's prelude. *)

val require_packages : (t*t) list -> t
  (** [require_packages] takes as argument a list of pairs
[package,option]. Each [package] is required (see {!packages}) with
option [option]. The argument [~packages] of {!document} is implemented
as a [require_package]. This command can be used anywhere in a document,
if needed. *)

val documentmatter : t -> t
  (** [documentmatter body] renders your actual document, [body],
according to the rules specified in the prelude. It is simply
LaTeX's [document] command. *)

(** {3 Miscellaneous} *)

val latex: t
  (** "LaTeX" written in a fancy but official way. *)

val usepackage: ?opt: t -> t -> t
  (** You can use this in the [~prelude] of your [document], but it is better
to use the [~packages] argument of [document]. Note that some commandes
add their own packages to the document automatically. *)

val input: t -> t
  (** Include a LaTeX file. Usually you'd prefer to open an OCaml module,
but this can be useful if you have a [.tex] file with macros that you want
to reuse. *)

val newcommand: int -> t -> t -> t
(** [newcommand parameter_count name body] defines a new command with
[parameter_count] arguments, where you can use the [i]th argument by writing
[#i] in the body, just as in Latex. Normally you'd prefer to just define
an OCaml value with [let]. *)

val renewcommand: int -> t -> t -> t
(** Same as [newcommand] except that it can redefine existing LaTeX commands. *)

val block: t -> t
  (** [block x] produces [{x}]. Should only be used in some rare cases when
      you want to be very precise about what LaTeX should do.
      If [x] is empty, the braces are not added. If you need braces even if
      [x] is empty, use {!within_braces}. *)

val place_label: label -> t
  (** [place_label lbl] places label [lbl]. Normally you would prefer using
the various [~label] optional arguments available, and only use [place_label]
for unimplemented features or if you are feeling hackish. *)

val atbegindocument: t -> t
val addcontentsline: t -> t -> t -> t
  (** [addcontentsline toc section name] *)

val pagestyle: t -> t
val thispagestyle: t -> t

val list_insert: 'a -> 'a list -> 'a list
  (** Inserts an element between each elements of a list.

      Examples:
      - [list_insert 1 [] = []]
      - [list_insert 1 [2] = [2]]
      - [list_insert 1 [2; 3; 4] = [2; 1; 3; 1; 4]] *)

(** {2 Printing} *)

type env
(* environment used to keep track of the content of variables between
   multiple applications of to_* functions *)

val get_in_env: ?position:position -> 'a variable -> env -> 'a

(** All printing functions take the expected mode as a parameter
(default is text). The printed expression will be coerced if its mode differs. *)

val to_buffer: ?mode: mode -> ?env: env -> Buffer.t -> t -> env
val to_channel: ?mode: mode -> ?env: env -> out_channel -> t -> env
val to_file: ?mode: mode -> ?env: env -> string -> t -> env
val to_string: ?mode: mode -> t -> string
val to_string_with_env: ?mode: mode -> ?env: env -> t -> string * env