Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions src/latex/generator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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

Expand Down
24 changes: 16 additions & 8 deletions src/latex/raw.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
4 changes: 2 additions & 2 deletions src/latex/raw.mli
Original file line number Diff line number Diff line change
Expand Up @@ -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 } *)
Expand Down
54 changes: 33 additions & 21 deletions test/latex/expect/test_package+ml/Recent.tex
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,51 @@ \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}%
\ocamlcodefragment{| \ocamltag{constructor}{C}}\label{package-test+u+package+++ml-module-Recent-type-variant.C}%
\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}%
Expand All @@ -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}}\\

Expand Down
8 changes: 5 additions & 3 deletions test/latex/expect/test_package+ml/Recent_impl.B.tex
Original file line number Diff line number Diff line change
@@ -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}%
\\


16 changes: 10 additions & 6 deletions test/latex/expect/test_package+ml/Recent_impl.tex
Original file line number Diff line number Diff line change
@@ -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}}\\
Expand Down
Loading