diff --git a/src/latex/generator.ml b/src/latex/generator.ml index d799b3e47a..3f2d09cf1c 100644 --- a/src/latex/generator.ml +++ b/src/latex/generator.ml @@ -148,6 +148,15 @@ let entity ~in_source ~verbatim x = else Txt [escape_entity x] +(** Tables with too many rows are hard to typeset correctly on + the same page. + Splitting tables on multiple pages is unreliable with longtable + hyperref. + Thus we limit the height of the tables that we render as latex tables. + This variable is kept separated because we may want to make it tunable + by the user. +*) +let small_table_height_limit = 10 + let rec pp_elt ppf = function | Txt words -> Fmt.list Fmt.string ~sep:none ppf words @@ -170,8 +179,12 @@ let rec pp_elt ppf = function | Code_fragment x -> Raw.code_fragment pp ppf x | List {typ; items} -> list typ pp ppf items | Description items -> Raw.description pp ppf items - | Table { row_size=Large|Huge as size; tbl } -> large_table size ppf tbl - | Table { row_size=Small|Empty; tbl } -> Raw.small_table pp ppf tbl + | Table { row_size=Large|Huge; tbl } -> large_table ppf tbl + | Table { row_size=Small|Empty; tbl } -> + if List.length tbl <= small_table_height_limit then + Raw.small_table pp ppf tbl + else + large_table ppf tbl | Label x -> Raw.label ppf x | Indented x -> Raw.indent pp ppf x | Ligaturable s -> Fmt.string ppf s @@ -197,21 +210,22 @@ and href ppf (l,txt) = Raw.href l pp ppf txt; Raw.footnote ppf l | None -> Raw.url ppf l -and large_table size ppf tbl = +and large_table ppf tbl = let rec row ppf = function | [] -> Raw.break ppf Line - | [a] -> pp ppf a + | [a] -> pp ppf a; Raw.break ppf Line + | [a;b] -> + Fmt.pf ppf "%a%a%a" + pp a + Raw.break Aesthetic + (Raw.indent pp) b | a :: (_ :: _ as q) -> Fmt.pf ppf "%a%a%a" pp a Raw.break Aesthetic (Raw.indent row) q in - let matrix ppf m = - - List.iter (row ppf) m in - match size with - | Huge -> Raw.break ppf Line; matrix ppf tbl - | Large | _ -> Raw.indent matrix ppf tbl + let matrix ppf m = List.iter (row ppf) m in + Raw.indent matrix ppf tbl and tag s ppf x = Raw.ocamltag s pp ppf x diff --git a/src/latex/raw.ml b/src/latex/raw.ml index ea93f27fb1..a2552840db 100644 --- a/src/latex/raw.ml +++ b/src/latex/raw.ml @@ -138,11 +138,8 @@ let latex_path ppf path = Fmt.string ppf path_s let input ppf x = create "input" latex_path ppf x -let const s ppf = Fmt.pf ppf s - -let longtable ~column_desc pp ppf x = - env "ocamllongtable" - ~opts:[const "l"] +let ocamltabular ~column_desc pp ppf x = + env "ocamltabular" ~args:[ column_desc ] pp ppf x @@ -157,11 +154,22 @@ let small_table pp ppf tbl = Fmt.pf ppf "%t%t" s (repeat (n - 1) s) in let cell ppf = Fmt.pf ppf "p{%.3f\\textwidth}" (1.0 /. float_of_int columns) in let table ppf tbl = - longtable + ocamltabular (repeat columns cell) matrix ppf tbl in - Fmt.pf ppf {|{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}%a}|} - table tbl + (* we add line breaks to never insert tables between delimiters, + to avoid rendering: + | `A + [ | `B ] + | `C + or + field_1: int; + { field_2: int; } + field_3: int; + *) + break ppf Line; + table ppf tbl; + break ppf Line let ocamltag tag pp ppf x = create2 "ocamltag" Fmt.string pp ppf tag x diff --git a/src/latex/raw.mli b/src/latex/raw.mli index 5aeb0502b6..9e62f01055 100644 --- a/src/latex/raw.mli +++ b/src/latex/raw.mli @@ -64,8 +64,8 @@ val code_block: 'a t val indent: 'a t (** expected to be implemented with changepage/adjustwidth*) -val longtable: column_desc:pr -> 'a t -(** any table implementation that can be split on multiple pages, e.g. longtable*) +val ocamltabular: column_desc:pr -> 'a t +(** Any tabular implementation that works well with at most 10 rows *) (** {2 Tags } *) diff --git a/test/latex/expect/test_package+ml/Recent.tex b/test/latex/expect/test_package+ml/Recent.tex index dc6c4dc994..5be480231e 100644 --- a/test/latex/expect/test_package+ml/Recent.tex +++ b/test/latex/expect/test_package+ml/Recent.tex @@ -7,8 +7,7 @@ \section{Module \ocamlinlinecode{Recent}}\label{package-test+u+package+++ml-modu \subsubsection{Signature\label{signature}}% \end{ocamlindent}% \ocamlcodefragment{\ocamltag{keyword}{end}}\\ -\label{package-test+u+package+++ml-module-Recent-type-variant}\ocamlcodefragment{\ocamltag{keyword}{type} variant = }\\ -\ocamlcodefragment{| \ocamltag{constructor}{A}}\label{package-test+u+package+++ml-module-Recent-type-variant.A}% +\label{package-test+u+package+++ml-module-Recent-type-variant}\ocamlcodefragment{\ocamltag{keyword}{type} variant = }\begin{ocamlindent}\ocamlcodefragment{| \ocamltag{constructor}{A}}\label{package-test+u+package+++ml-module-Recent-type-variant.A}% \begin{ocamlindent}\end{ocamlindent}% \ocamlcodefragment{| \ocamltag{constructor}{B} \ocamltag{keyword}{of} int}\label{package-test+u+package+++ml-module-Recent-type-variant.B}% \begin{ocamlindent}\end{ocamlindent}% @@ -16,32 +15,43 @@ \subsubsection{Signature\label{signature}}% \begin{ocamlindent}foo\end{ocamlindent}% \ocamlcodefragment{| \ocamltag{constructor}{D}}\label{package-test+u+package+++ml-module-Recent-type-variant.D}% \begin{ocamlindent}\emph{bar}\end{ocamlindent}% -\ocamlcodefragment{| \ocamltag{constructor}{E} \ocamltag{keyword}{of} \{}{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Recent-type-variant.a}\\ -\end{ocamllongtable}% -}\ocamlcodefragment{\}}\label{package-test+u+package+++ml-module-Recent-type-variant.E}% +\ocamlcodefragment{| \ocamltag{constructor}{E} \ocamltag{keyword}{of} \{}\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Recent-type-variant.a}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\label{package-test+u+package+++ml-module-Recent-type-variant.E}% \begin{ocamlindent}\end{ocamlindent}% -\label{package-test+u+package+++ml-module-Recent-type-gadt}\ocamlcodefragment{\ocamltag{keyword}{type} \_\allowbreak{} gadt = }\\ -\ocamlcodefragment{| \ocamltag{constructor}{A} : int \hyperref[package-test+u+package+++ml-module-Recent-type-gadt]{\ocamlinlinecode{gadt}}}\label{package-test+u+package+++ml-module-Recent-type-gadt.A}% +\end{ocamlindent}% +\label{package-test+u+package+++ml-module-Recent-type-gadt}\ocamlcodefragment{\ocamltag{keyword}{type} \_\allowbreak{} gadt = }\begin{ocamlindent}\ocamlcodefragment{| \ocamltag{constructor}{A} : int \hyperref[package-test+u+package+++ml-module-Recent-type-gadt]{\ocamlinlinecode{gadt}}}\label{package-test+u+package+++ml-module-Recent-type-gadt.A}% \begin{ocamlindent}\end{ocamlindent}% \ocamlcodefragment{| \ocamltag{constructor}{B} : int $\rightarrow$ string \hyperref[package-test+u+package+++ml-module-Recent-type-gadt]{\ocamlinlinecode{gadt}}}\label{package-test+u+package+++ml-module-Recent-type-gadt.B}% \begin{ocamlindent}foo\end{ocamlindent}% -\ocamlcodefragment{| \ocamltag{constructor}{C} : \{}{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Recent-type-gadt.a}\\ -\end{ocamllongtable}% -}\ocamlcodefragment{\} $\rightarrow$ unit \hyperref[package-test+u+package+++ml-module-Recent-type-gadt]{\ocamlinlinecode{gadt}}}\label{package-test+u+package+++ml-module-Recent-type-gadt.C}% +\ocamlcodefragment{| \ocamltag{constructor}{C} : \{}\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Recent-type-gadt.a}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\} $\rightarrow$ unit \hyperref[package-test+u+package+++ml-module-Recent-type-gadt]{\ocamlinlinecode{gadt}}}\label{package-test+u+package+++ml-module-Recent-type-gadt.C}% \begin{ocamlindent}\end{ocamlindent}% -\label{package-test+u+package+++ml-module-Recent-type-polymorphic+u+variant}\ocamlcodefragment{\ocamltag{keyword}{type} polymorphic\_\allowbreak{}variant = [ }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{0.500\textwidth}p{0.500\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{`A}\label{package-test+u+package+++ml-module-Recent-type-polymorphic+u+variant.A}& \\ +\end{ocamlindent}% +\label{package-test+u+package+++ml-module-Recent-type-polymorphic+u+variant}\ocamlcodefragment{\ocamltag{keyword}{type} polymorphic\_\allowbreak{}variant = [ }\\ +\begin{ocamltabular}{p{0.500\textwidth}p{0.500\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{`A}\label{package-test+u+package+++ml-module-Recent-type-polymorphic+u+variant.A}& \\ \ocamlinlinecode{| }\ocamlinlinecode{`B \ocamltag{keyword}{of} int}\label{package-test+u+package+++ml-module-Recent-type-polymorphic+u+variant.B}& \\ \ocamlinlinecode{| }\ocamlinlinecode{`C}\label{package-test+u+package+++ml-module-Recent-type-polymorphic+u+variant.C}& foo\\ \ocamlinlinecode{| }\ocamlinlinecode{`D}\label{package-test+u+package+++ml-module-Recent-type-polymorphic+u+variant.D}& bar\\ -\end{ocamllongtable}% -}\ocamlcodefragment{ ]}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{ ]}\\ \label{package-test+u+package+++ml-module-Recent-type-empty+u+variant}\ocamlcodefragment{\ocamltag{keyword}{type} empty\_\allowbreak{}variant = |}\\ \label{package-test+u+package+++ml-module-Recent-type-nonrec+u+}\ocamlcodefragment{\ocamltag{keyword}{type} \ocamltag{keyword}{nonrec} nonrec\_\allowbreak{} = int}\\ -\label{package-test+u+package+++ml-module-Recent-type-empty+u+conj}\ocamlcodefragment{\ocamltag{keyword}{type} empty\_\allowbreak{}conj = }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{X} : [< `X of \& \ocamltag{type-var}{'a} \& int * float ] $\rightarrow$ \hyperref[package-test+u+package+++ml-module-Recent-type-empty+u+conj]{\ocamlinlinecode{empty\_\allowbreak{}conj}}}\label{package-test+u+package+++ml-module-Recent-type-empty+u+conj.X}\\ -\end{ocamllongtable}% -}\label{package-test+u+package+++ml-module-Recent-type-conj}\ocamlcodefragment{\ocamltag{keyword}{type} conj = }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{X} : [< `X of int \& [< `B of int \& float ] ] $\rightarrow$ \hyperref[package-test+u+package+++ml-module-Recent-type-conj]{\ocamlinlinecode{conj}}}\label{package-test+u+package+++ml-module-Recent-type-conj.X}\\ -\end{ocamllongtable}% -}\label{package-test+u+package+++ml-module-Recent-val-empty+u+conj}\ocamlcodefragment{\ocamltag{keyword}{val} empty\_\allowbreak{}conj : [< `X of \& \ocamltag{type-var}{'a} \& int * float ]}\\ +\label{package-test+u+package+++ml-module-Recent-type-empty+u+conj}\ocamlcodefragment{\ocamltag{keyword}{type} empty\_\allowbreak{}conj = }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{X} : [< `X of \& \ocamltag{type-var}{'a} \& int * float ] $\rightarrow$ \hyperref[package-test+u+package+++ml-module-Recent-type-empty+u+conj]{\ocamlinlinecode{empty\_\allowbreak{}conj}}}\label{package-test+u+package+++ml-module-Recent-type-empty+u+conj.X}\\ +\end{ocamltabular}% +\\ +\label{package-test+u+package+++ml-module-Recent-type-conj}\ocamlcodefragment{\ocamltag{keyword}{type} conj = }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{X} : [< `X of int \& [< `B of int \& float ] ] $\rightarrow$ \hyperref[package-test+u+package+++ml-module-Recent-type-conj]{\ocamlinlinecode{conj}}}\label{package-test+u+package+++ml-module-Recent-type-conj.X}\\ +\end{ocamltabular}% +\\ +\label{package-test+u+package+++ml-module-Recent-val-empty+u+conj}\ocamlcodefragment{\ocamltag{keyword}{val} empty\_\allowbreak{}conj : [< `X of \& \ocamltag{type-var}{'a} \& int * float ]}\\ \label{package-test+u+package+++ml-module-Recent-val-conj}\ocamlcodefragment{\ocamltag{keyword}{val} conj : [< `X of int \& [< `B of int \& float ] ]}\\ \label{package-test+u+package+++ml-module-Recent-module-Z}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[package-test+u+package+++ml-module-Recent-module-Z]{\ocamlinlinecode{Z}}}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent-module-Z-module-Y}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[package-test+u+package+++ml-module-Recent-module-Z-module-Y]{\ocamlinlinecode{Y}}}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent-module-Z-module-Y-module-X}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[package-test+u+package+++ml-module-Recent-module-Z-module-Y-module-X]{\ocamlinlinecode{X}}}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent-module-Z-module-Y-module-X-type-t}\ocamlcodefragment{\ocamltag{keyword}{type} 'a t}\\ \end{ocamlindent}% @@ -56,10 +66,12 @@ \subsubsection{Signature\label{signature}}% \label{package-test+u+package+++ml-module-Recent-module-X-type-v}\ocamlcodefragment{\ocamltag{keyword}{type} v = \hyperref[package-test+u+package+++ml-module-Recent-module-X-type-u]{\ocamlinlinecode{u}} \hyperref[package-test+u+package+++ml-module-Recent-module-Z-module-Y-module-X-type-t]{\ocamlinlinecode{Z.\allowbreak{}Y.\allowbreak{}X.\allowbreak{}t}}}\\ \end{ocamlindent}% \ocamlcodefragment{\ocamltag{keyword}{end}}\\ -\label{package-test+u+package+++ml-module-Recent-module-type-PolyS}\ocamlcodefragment{\ocamltag{keyword}{module} \ocamltag{keyword}{type} \hyperref[package-test+u+package+++ml-module-Recent-module-type-PolyS]{\ocamlinlinecode{PolyS}}}\ocamlcodefragment{ = \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent-module-type-PolyS-type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t = [ }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{`A}\label{package-test+u+package+++ml-module-Recent-module-type-PolyS-type-t.A}\\ +\label{package-test+u+package+++ml-module-Recent-module-type-PolyS}\ocamlcodefragment{\ocamltag{keyword}{module} \ocamltag{keyword}{type} \hyperref[package-test+u+package+++ml-module-Recent-module-type-PolyS]{\ocamlinlinecode{PolyS}}}\ocamlcodefragment{ = \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent-module-type-PolyS-type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t = [ }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{`A}\label{package-test+u+package+++ml-module-Recent-module-type-PolyS-type-t.A}\\ \ocamlinlinecode{| }\ocamlinlinecode{`B}\label{package-test+u+package+++ml-module-Recent-module-type-PolyS-type-t.B}\\ -\end{ocamllongtable}% -}\ocamlcodefragment{ ]}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{ ]}\\ \end{ocamlindent}% \ocamlcodefragment{\ocamltag{keyword}{end}}\\ diff --git a/test/latex/expect/test_package+ml/Recent_impl.B.tex b/test/latex/expect/test_package+ml/Recent_impl.B.tex index 1b9d8233c6..c542754fbf 100644 --- a/test/latex/expect/test_package+ml/Recent_impl.B.tex +++ b/test/latex/expect/test_package+ml/Recent_impl.B.tex @@ -1,5 +1,7 @@ \section{Module \ocamlinlinecode{Recent\_\allowbreak{}impl.\allowbreak{}B}}\label{package-test+u+package+++ml-module-Recent+u+impl-module-B}% -\label{package-test+u+package+++ml-module-Recent+u+impl-module-B-type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t = }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{B}}\label{package-test+u+package+++ml-module-Recent+u+impl-module-B-type-t.B}\\ -\end{ocamllongtable}% -} +\label{package-test+u+package+++ml-module-Recent+u+impl-module-B-type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t = }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{B}}\label{package-test+u+package+++ml-module-Recent+u+impl-module-B-type-t.B}\\ +\end{ocamltabular}% +\\ + diff --git a/test/latex/expect/test_package+ml/Recent_impl.tex b/test/latex/expect/test_package+ml/Recent_impl.tex index d5b42d7d50..d9849e998b 100644 --- a/test/latex/expect/test_package+ml/Recent_impl.tex +++ b/test/latex/expect/test_package+ml/Recent_impl.tex @@ -1,11 +1,15 @@ \section{Module \ocamlinlinecode{Recent\_\allowbreak{}impl}}\label{package-test+u+package+++ml-module-Recent+u+impl}% -\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[package-test+u+package+++ml-module-Recent+u+impl-module-Foo]{\ocamlinlinecode{Foo}}}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-A}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-A]{\ocamlinlinecode{A}}}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-A-type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t = }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A}}\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-A-type-t.A}\\ -\end{ocamllongtable}% -}\end{ocamlindent}% +\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[package-test+u+package+++ml-module-Recent+u+impl-module-Foo]{\ocamlinlinecode{Foo}}}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-A}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-A]{\ocamlinlinecode{A}}}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-A-type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t = }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A}}\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-A-type-t.A}\\ +\end{ocamltabular}% +\\ +\end{ocamlindent}% \ocamlcodefragment{\ocamltag{keyword}{end}}\\ -\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-B}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-B]{\ocamlinlinecode{B}}}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-B-type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t = }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{B}}\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-B-type-t.B}\\ -\end{ocamllongtable}% -}\end{ocamlindent}% +\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-B}\ocamlcodefragment{\ocamltag{keyword}{module} \hyperref[package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-B]{\ocamlinlinecode{B}}}\ocamlcodefragment{ : \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-B-type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t = }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{B}}\label{package-test+u+package+++ml-module-Recent+u+impl-module-Foo-module-B-type-t.B}\\ +\end{ocamltabular}% +\\ +\end{ocamlindent}% \ocamlcodefragment{\ocamltag{keyword}{end}}\\ \end{ocamlindent}% \ocamlcodefragment{\ocamltag{keyword}{end}}\\ diff --git a/test/latex/expect/test_package+ml/Type.tex b/test/latex/expect/test_package+ml/Type.tex index cb31b47ab7..6798b650c6 100644 --- a/test/latex/expect/test_package+ml/Type.tex +++ b/test/latex/expect/test_package+ml/Type.tex @@ -14,50 +14,72 @@ \section{Module \ocamlinlinecode{Type}}\label{package-test+u+package+++ml-module \label{package-test+u+package+++ml-module-Type-type-triple}\ocamlcodefragment{\ocamltag{keyword}{type} triple = int * int * int}\\ \label{package-test+u+package+++ml-module-Type-type-nested+u+pair}\ocamlcodefragment{\ocamltag{keyword}{type} nested\_\allowbreak{}pair = (int * int) * int}\\ \label{package-test+u+package+++ml-module-Type-type-instance}\ocamlcodefragment{\ocamltag{keyword}{type} instance = int \hyperref[package-test+u+package+++ml-module-Type-type-constructor]{\ocamlinlinecode{constructor}}}\\ -\label{package-test+u+package+++ml-module-Type-type-variant+u+e}\ocamlcodefragment{\ocamltag{keyword}{type} variant\_\allowbreak{}e = \{}{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Type-type-variant+u+e.a}\\ -\end{ocamllongtable}% -}\ocamlcodefragment{\}}\\ -\label{package-test+u+package+++ml-module-Type-type-variant}\ocamlcodefragment{\ocamltag{keyword}{type} variant = }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{0.500\textwidth}p{0.500\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A}}\label{package-test+u+package+++ml-module-Type-type-variant.A}& \\ +\label{package-test+u+package+++ml-module-Type-type-variant+u+e}\ocamlcodefragment{\ocamltag{keyword}{type} variant\_\allowbreak{}e = \{}\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Type-type-variant+u+e.a}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\\ +\label{package-test+u+package+++ml-module-Type-type-variant}\ocamlcodefragment{\ocamltag{keyword}{type} variant = }\\ +\begin{ocamltabular}{p{0.500\textwidth}p{0.500\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A}}\label{package-test+u+package+++ml-module-Type-type-variant.A}& \\ \ocamlcodefragment{| \ocamltag{constructor}{B} \ocamltag{keyword}{of} int}\label{package-test+u+package+++ml-module-Type-type-variant.B}& \\ \ocamlcodefragment{| \ocamltag{constructor}{C}}\label{package-test+u+package+++ml-module-Type-type-variant.C}& foo\\ \ocamlcodefragment{| \ocamltag{constructor}{D}}\label{package-test+u+package+++ml-module-Type-type-variant.D}& \emph{bar}\\ \ocamlcodefragment{| \ocamltag{constructor}{E} \ocamltag{keyword}{of} \hyperref[package-test+u+package+++ml-module-Type-type-variant+u+e]{\ocamlinlinecode{variant\_\allowbreak{}e}}}\label{package-test+u+package+++ml-module-Type-type-variant.E}& \\ -\end{ocamllongtable}% -}\label{package-test+u+package+++ml-module-Type-type-variant+u+c}\ocamlcodefragment{\ocamltag{keyword}{type} variant\_\allowbreak{}c = \{}{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Type-type-variant+u+c.a}\\ -\end{ocamllongtable}% -}\ocamlcodefragment{\}}\\ -\label{package-test+u+package+++ml-module-Type-type-gadt}\ocamlcodefragment{\ocamltag{keyword}{type} \_\allowbreak{} gadt = }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A} : int \hyperref[package-test+u+package+++ml-module-Type-type-gadt]{\ocamlinlinecode{gadt}}}\label{package-test+u+package+++ml-module-Type-type-gadt.A}\\ +\end{ocamltabular}% +\\ +\label{package-test+u+package+++ml-module-Type-type-variant+u+c}\ocamlcodefragment{\ocamltag{keyword}{type} variant\_\allowbreak{}c = \{}\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Type-type-variant+u+c.a}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\\ +\label{package-test+u+package+++ml-module-Type-type-gadt}\ocamlcodefragment{\ocamltag{keyword}{type} \_\allowbreak{} gadt = }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A} : int \hyperref[package-test+u+package+++ml-module-Type-type-gadt]{\ocamlinlinecode{gadt}}}\label{package-test+u+package+++ml-module-Type-type-gadt.A}\\ \ocamlcodefragment{| \ocamltag{constructor}{B} : int $\rightarrow$ string \hyperref[package-test+u+package+++ml-module-Type-type-gadt]{\ocamlinlinecode{gadt}}}\label{package-test+u+package+++ml-module-Type-type-gadt.B}\\ \ocamlcodefragment{| \ocamltag{constructor}{C} : \hyperref[package-test+u+package+++ml-module-Type-type-variant+u+c]{\ocamlinlinecode{variant\_\allowbreak{}c}} $\rightarrow$ unit \hyperref[package-test+u+package+++ml-module-Type-type-gadt]{\ocamlinlinecode{gadt}}}\label{package-test+u+package+++ml-module-Type-type-gadt.C}\\ -\end{ocamllongtable}% -}\label{package-test+u+package+++ml-module-Type-type-degenerate+u+gadt}\ocamlcodefragment{\ocamltag{keyword}{type} degenerate\_\allowbreak{}gadt = }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A} : \hyperref[package-test+u+package+++ml-module-Type-type-degenerate+u+gadt]{\ocamlinlinecode{degenerate\_\allowbreak{}gadt}}}\label{package-test+u+package+++ml-module-Type-type-degenerate+u+gadt.A}\\ -\end{ocamllongtable}% -}\label{package-test+u+package+++ml-module-Type-type-private+u+variant}\ocamlcodefragment{\ocamltag{keyword}{type} private\_\allowbreak{}variant = \ocamltag{keyword}{private} }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A}}\label{package-test+u+package+++ml-module-Type-type-private+u+variant.A}\\ -\end{ocamllongtable}% -}\label{package-test+u+package+++ml-module-Type-type-record}\ocamlcodefragment{\ocamltag{keyword}{type} record = \{}{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{0.500\textwidth}p{0.500\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Type-type-record.a}& \\ +\end{ocamltabular}% +\\ +\label{package-test+u+package+++ml-module-Type-type-degenerate+u+gadt}\ocamlcodefragment{\ocamltag{keyword}{type} degenerate\_\allowbreak{}gadt = }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A} : \hyperref[package-test+u+package+++ml-module-Type-type-degenerate+u+gadt]{\ocamlinlinecode{degenerate\_\allowbreak{}gadt}}}\label{package-test+u+package+++ml-module-Type-type-degenerate+u+gadt.A}\\ +\end{ocamltabular}% +\\ +\label{package-test+u+package+++ml-module-Type-type-private+u+variant}\ocamlcodefragment{\ocamltag{keyword}{type} private\_\allowbreak{}variant = \ocamltag{keyword}{private} }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A}}\label{package-test+u+package+++ml-module-Type-type-private+u+variant.A}\\ +\end{ocamltabular}% +\\ +\label{package-test+u+package+++ml-module-Type-type-record}\ocamlcodefragment{\ocamltag{keyword}{type} record = \{}\\ +\begin{ocamltabular}{p{0.500\textwidth}p{0.500\textwidth}}\ocamlinlinecode{a : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Type-type-record.a}& \\ \ocamlinlinecode{\ocamltag{keyword}{mutable} b : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Type-type-record.b}& \\ \ocamlinlinecode{c : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Type-type-record.c}& foo\\ \ocamlinlinecode{d : int;\allowbreak{}}\label{package-test+u+package+++ml-module-Type-type-record.d}& \emph{bar}\\ \ocamlinlinecode{e : a.\allowbreak{} \ocamltag{type-var}{'a};\allowbreak{}}\label{package-test+u+package+++ml-module-Type-type-record.e}& \\ -\end{ocamllongtable}% -}\ocamlcodefragment{\}}\\ -\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant}\ocamlcodefragment{\ocamltag{keyword}{type} polymorphic\_\allowbreak{}variant = [ }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{`A}\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant.A}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{\}}\\ +\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant}\ocamlcodefragment{\ocamltag{keyword}{type} polymorphic\_\allowbreak{}variant = [ }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{`A}\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant.A}\\ \ocamlinlinecode{| }\ocamlinlinecode{`B \ocamltag{keyword}{of} int}\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant.B}\\ \ocamlinlinecode{| }\ocamlinlinecode{`C \ocamltag{keyword}{of} int * unit}\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant.C}\\ \ocamlinlinecode{| }\ocamlinlinecode{`D}\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant.D}\\ -\end{ocamllongtable}% -}\ocamlcodefragment{ ]}\\ -\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant+u+extension}\ocamlcodefragment{\ocamltag{keyword}{type} polymorphic\_\allowbreak{}variant\_\allowbreak{}extension = [ }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{\hyperref[package-test+u+package+++ml-module-Type-type-polymorphic+u+variant]{\ocamlinlinecode{polymorphic\_\allowbreak{}variant}}}\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant+u+extension.polymorphic+u+variant}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{ ]}\\ +\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant+u+extension}\ocamlcodefragment{\ocamltag{keyword}{type} polymorphic\_\allowbreak{}variant\_\allowbreak{}extension = [ }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{\hyperref[package-test+u+package+++ml-module-Type-type-polymorphic+u+variant]{\ocamlinlinecode{polymorphic\_\allowbreak{}variant}}}\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant+u+extension.polymorphic+u+variant}\\ \ocamlinlinecode{| }\ocamlinlinecode{`E}\label{package-test+u+package+++ml-module-Type-type-polymorphic+u+variant+u+extension.E}\\ -\end{ocamllongtable}% -}\ocamlcodefragment{ ]}\\ -\label{package-test+u+package+++ml-module-Type-type-nested+u+polymorphic+u+variant}\ocamlcodefragment{\ocamltag{keyword}{type} nested\_\allowbreak{}polymorphic\_\allowbreak{}variant = [ }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{`A \ocamltag{keyword}{of} [ `B | `C ]}\label{package-test+u+package+++ml-module-Type-type-nested+u+polymorphic+u+variant.A}\\ -\end{ocamllongtable}% -}\ocamlcodefragment{ ]}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{ ]}\\ +\label{package-test+u+package+++ml-module-Type-type-nested+u+polymorphic+u+variant}\ocamlcodefragment{\ocamltag{keyword}{type} nested\_\allowbreak{}polymorphic\_\allowbreak{}variant = [ }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{`A \ocamltag{keyword}{of} [ `B | `C ]}\label{package-test+u+package+++ml-module-Type-type-nested+u+polymorphic+u+variant.A}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{ ]}\\ \label{package-test+u+package+++ml-module-Type-type-private+u+extenion#row}\ocamlcodefragment{\ocamltag{keyword}{type} private\_\allowbreak{}extenion\#row}\\ -\label{package-test+u+package+++ml-module-Type-type-private+u+extenion}\ocamlcodefragment{\ocamltag{keyword}{and} private\_\allowbreak{}extenion = \ocamltag{keyword}{private} [> }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{\hyperref[package-test+u+package+++ml-module-Type-type-polymorphic+u+variant]{\ocamlinlinecode{polymorphic\_\allowbreak{}variant}}}\label{package-test+u+package+++ml-module-Type-type-private+u+extenion.polymorphic+u+variant}\\ -\end{ocamllongtable}% -}\ocamlcodefragment{ ]}\\ +\label{package-test+u+package+++ml-module-Type-type-private+u+extenion}\ocamlcodefragment{\ocamltag{keyword}{and} private\_\allowbreak{}extenion = \ocamltag{keyword}{private} [> }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlinlinecode{| }\ocamlinlinecode{\hyperref[package-test+u+package+++ml-module-Type-type-polymorphic+u+variant]{\ocamlinlinecode{polymorphic\_\allowbreak{}variant}}}\label{package-test+u+package+++ml-module-Type-type-private+u+extenion.polymorphic+u+variant}\\ +\end{ocamltabular}% +\\ +\ocamlcodefragment{ ]}\\ \label{package-test+u+package+++ml-module-Type-type-object+u+}\ocamlcodefragment{\ocamltag{keyword}{type} object\_\allowbreak{} = < a : int;\allowbreak{} b : int;\allowbreak{} c : int;\allowbreak{} >}\\ \label{package-test+u+package+++ml-module-Type-module-type-X}\ocamlcodefragment{\ocamltag{keyword}{module} \ocamltag{keyword}{type} \hyperref[package-test+u+package+++ml-module-Type-module-type-X]{\ocamlinlinecode{X}}}\ocamlcodefragment{ = \ocamltag{keyword}{sig}}\begin{ocamlindent}\label{package-test+u+package+++ml-module-Type-module-type-X-type-t}\ocamlcodefragment{\ocamltag{keyword}{type} t}\\ \label{package-test+u+package+++ml-module-Type-module-type-X-type-u}\ocamlcodefragment{\ocamltag{keyword}{type} u}\\ @@ -83,13 +105,19 @@ \section{Module \ocamlinlinecode{Type}}\label{package-test+u+package+++ml-module \label{package-test+u+package+++ml-module-Type-type-double+u+constrained}\ocamlcodefragment{\ocamltag{keyword}{type} ('a,\allowbreak{} 'b) double\_\allowbreak{}constrained = \ocamltag{type-var}{'a} * \ocamltag{type-var}{'b} \ocamltag{keyword}{constraint} \ocamltag{type-var}{'a} = int \ocamltag{keyword}{constraint} \ocamltag{type-var}{'b} = unit}\\ \label{package-test+u+package+++ml-module-Type-type-as+u+}\ocamlcodefragment{\ocamltag{keyword}{type} as\_\allowbreak{} = int \ocamltag{keyword}{as} 'a * \ocamltag{type-var}{'a}}\\ \label{package-test+u+package+++ml-module-Type-type-extensible}\ocamlcodefragment{\ocamltag{keyword}{type} extensible = .\allowbreak{}.\allowbreak{}}\\ -\ocamlcodefragment{\ocamltag{keyword}{type} \hyperref[package-test+u+package+++ml-module-Type-type-extensible]{\ocamlinlinecode{extensible}} += }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{0.500\textwidth}p{0.500\textwidth}}\ocamlcodefragment{| \ocamltag{extension}{Extension}}\label{package-test+u+package+++ml-module-Type-extension-Extension}& Documentation for \hyperref[package-test+u+package+++ml-module-Type-extension-Extension]{\ocamlinlinecode{\ocamlinlinecode{Extension}}[p\pageref*{package-test+u+package+++ml-module-Type-extension-Extension}]}.\\ +\ocamlcodefragment{\ocamltag{keyword}{type} \hyperref[package-test+u+package+++ml-module-Type-type-extensible]{\ocamlinlinecode{extensible}} += }\\ +\begin{ocamltabular}{p{0.500\textwidth}p{0.500\textwidth}}\ocamlcodefragment{| \ocamltag{extension}{Extension}}\label{package-test+u+package+++ml-module-Type-extension-Extension}& Documentation for \hyperref[package-test+u+package+++ml-module-Type-extension-Extension]{\ocamlinlinecode{\ocamlinlinecode{Extension}}[p\pageref*{package-test+u+package+++ml-module-Type-extension-Extension}]}.\\ \ocamlcodefragment{| \ocamltag{extension}{Another\_\allowbreak{}extension}}\label{package-test+u+package+++ml-module-Type-extension-Another+u+extension}& Documentation for \hyperref[package-test+u+package+++ml-module-Type-extension-Another+u+extension]{\ocamlinlinecode{\ocamlinlinecode{Another\_\allowbreak{}extension}}[p\pageref*{package-test+u+package+++ml-module-Type-extension-Another+u+extension}]}.\\ -\end{ocamllongtable}% -}\label{package-test+u+package+++ml-module-Type-type-mutually}\ocamlcodefragment{\ocamltag{keyword}{type} mutually = }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A} \ocamltag{keyword}{of} \hyperref[package-test+u+package+++ml-module-Type-type-recursive]{\ocamlinlinecode{recursive}}}\label{package-test+u+package+++ml-module-Type-type-mutually.A}\\ -\end{ocamllongtable}% -}\label{package-test+u+package+++ml-module-Type-type-recursive}\ocamlcodefragment{\ocamltag{keyword}{and} recursive = }{\setlength{\LTpre}{0pt}\setlength{\LTpost}{0pt}\begin{ocamllongtable}[l]{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{B} \ocamltag{keyword}{of} \hyperref[package-test+u+package+++ml-module-Type-type-mutually]{\ocamlinlinecode{mutually}}}\label{package-test+u+package+++ml-module-Type-type-recursive.B}\\ -\end{ocamllongtable}% -}\label{package-test+u+package+++ml-module-Type-exception-Foo}\ocamlcodefragment{\ocamltag{keyword}{exception} \ocamltag{exception}{Foo} \ocamltag{keyword}{of} int * int}\\ +\end{ocamltabular}% +\\ +\label{package-test+u+package+++ml-module-Type-type-mutually}\ocamlcodefragment{\ocamltag{keyword}{type} mutually = }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{A} \ocamltag{keyword}{of} \hyperref[package-test+u+package+++ml-module-Type-type-recursive]{\ocamlinlinecode{recursive}}}\label{package-test+u+package+++ml-module-Type-type-mutually.A}\\ +\end{ocamltabular}% +\\ +\label{package-test+u+package+++ml-module-Type-type-recursive}\ocamlcodefragment{\ocamltag{keyword}{and} recursive = }\\ +\begin{ocamltabular}{p{1.000\textwidth}}\ocamlcodefragment{| \ocamltag{constructor}{B} \ocamltag{keyword}{of} \hyperref[package-test+u+package+++ml-module-Type-type-mutually]{\ocamlinlinecode{mutually}}}\label{package-test+u+package+++ml-module-Type-type-recursive.B}\\ +\end{ocamltabular}% +\\ +\label{package-test+u+package+++ml-module-Type-exception-Foo}\ocamlcodefragment{\ocamltag{keyword}{exception} \ocamltag{exception}{Foo} \ocamltag{keyword}{of} int * int}\\ diff --git a/test/latex/expect/visualizer.tex b/test/latex/expect/visualizer.tex index 592dd290b7..35b487a614 100644 --- a/test/latex/expect/visualizer.tex +++ b/test/latex/expect/visualizer.tex @@ -40,8 +40,8 @@ \newcommand{\ocamlcomment}{\color{gray}\normalfont\small} \newcommand{\ocamlstring}{\color{gray}\bfseries} \newenvironment{ocamlindent}{\begin{adjustwidth}{2em}{0pt}}{\end{adjustwidth}} -\newenvironment{ocamllongtable}[2][l]{\begin{longtable}[#1]{#2}}% -{\end{longtable}} +\newenvironment{ocamltabular}[1]{\begin{tabular}{#1}}% +{\end{tabular}} \lstnewenvironment{ocamlcodeblock}{ \lstset{