1 (***********************************************************************)
4 (* Maxence Guesdon, projet Cristal, INRIA Rocquencourt *)
6 (* Copyright 2001 Institut National de Recherche en Informatique et *)
7 (* en Automatique. All rights reserved. This file is distributed *)
8 (* under the terms of the Q Public License version 1.0. *)
10 (***********************************************************************)
14 (** Generation of LaTeX documentation. *)
16 let print_DEBUG s
= print_string s
; print_newline
()
26 let new_buf () = Buffer.create
1024
29 let fmt = Format.formatter_of_buffer
b in
32 Format.pp_print_flush
fmt ();
33 let s = Buffer.contents
b in
38 let p = Format.fprintf
39 let ps f
s = Format.fprintf f
"%s" s
42 let bp = Printf.bprintf
43 let bs = Buffer.add_string
45 let print_concat fmt sep f
=
46 let rec iter = function
56 (** Generation of LaTeX code from text structures. *)
59 (** Return latex code to make a sectionning according to the given level,
60 and with the given latex code. *)
61 method section_style level
s =
63 let sec = List.assoc level
!Args.latex_titles
in
67 (** Associations of strings to subsitute in latex code. *)
68 val mutable subst_strings
= [
69 ("MAXENCE"^
"ZZZ", "\\$");
70 ("MAXENCE"^
"YYY", "\\&");
71 ("MAXENCE"^
"XXX", "{\\textbackslash}") ;
87 ("\\.\\.\\.", "$\\ldots$");
98 ("->", "$\\rightarrow$") ;
99 ("<-", "$\\leftarrow$");
101 ("\\^", "\\textasciicircum ") ;
102 ("\\.\\.\\.", "$\\ldots$");
103 ("\\\\", "MAXENCE"^
"XXX") ;
104 ("&", "MAXENCE"^
"YYY") ;
105 ("\\$", "MAXENCE"^
"ZZZ")
108 val mutable subst_strings_simple
=
110 ("MAXENCE"^
"XXX", "{\\textbackslash}") ;
113 ("\\\\", "MAXENCE"^
"XXX") ;
116 val mutable subst_strings_code
= [
117 ("MAXENCE"^
"ZZZ", "\\$");
118 ("MAXENCE"^
"YYY", "\\&");
119 ("MAXENCE"^
"XXX", "{\\textbackslash}") ;
127 ("\\^", "\\textasciicircum ") ;
128 ("&", "MAXENCE"^
"YYY") ;
129 ("\\$", "MAXENCE"^
"ZZZ") ;
130 ("\\\\", "MAXENCE"^
"XXX") ;
135 (fun (s, s2
) -> fun acc
-> Str.global_replace
(Str.regexp
s) s2 acc
)
139 (** Escape the strings which would clash with LaTeX syntax. *)
140 method escape
s = self#subst subst_strings
s
142 (** Escape the ['\'], ['{'] and ['}'] characters. *)
143 method escape_simple
s = self#subst subst_strings_simple
s
145 (** Escape some characters for the code style. *)
146 method escape_code
s = self#subst subst_strings_code
s
148 (** Make a correct latex label from a name. *)
149 (* The following characters are forbidden in LaTeX \index:
150 \ { } $ & # ^ _ % ~ ! " @ | (" to close the double quote)
151 The following characters are forbidden in LaTeX \label:
153 So we will use characters not forbidden in \index if no_ = true.
155 method label ?
(no_
=true) name
=
156 let len = String.length name
in
157 let buf = Buffer.create
len in
158 for i
= 0 to len - 1 do
161 '_'
-> ("-underscore", "_")
162 | '~'
-> ("-tilde", "~")
163 | '
%'
-> ("-percent", "%")
164 | '
@'
-> ("-at", "\"@")
165 | '
!'
-> ("-bang", "\"!")
166 | '
|'
-> ("-pipe", "\"|")
167 | '
<'
-> ("-lt", "<")
168 | '
>'
-> ("-gt", ">")
169 | '^'
-> ("-exp", "^")
170 | '
&'
-> ("-ampersand", "&")
171 | '
+'
-> ("-plus", "+")
172 | '
-'
-> ("-minus", "-")
173 | '
*'
-> ("-star", "*")
174 | '
/'
-> ("-slash", "/")
175 | '$'
-> ("-dollar", "$")
176 | '
='
-> ("-equal", "=")
177 | '
:'
-> ("-colon", ":")
178 | c
-> (String.make
1 c
, String.make
1 c
)
180 Buffer.add_string
buf (if no_
then s_no_
else s)
184 (** Make a correct label from a value name. *)
185 method value_label ?no_ name
= !Args.latex_value_prefix^
(self#label ?no_ name
)
187 (** Make a correct label from an attribute name. *)
188 method attribute_label ?no_ name
= !Args.latex_attribute_prefix^
(self#label ?no_ name
)
190 (** Make a correct label from a method name. *)
191 method method_label ?no_ name
= !Args.latex_method_prefix^
(self#label ?no_ name
)
193 (** Make a correct label from a class name. *)
194 method class_label ?no_ name
= !Args.latex_class_prefix^
(self#label ?no_ name
)
196 (** Make a correct label from a class type name. *)
197 method class_type_label ?no_ name
= !Args.latex_class_type_prefix^
(self#label ?no_ name
)
199 (** Make a correct label from a module name. *)
200 method module_label ?no_ name
= !Args.latex_module_prefix^
(self#label ?no_ name
)
202 (** Make a correct label from a module type name. *)
203 method module_type_label ?no_ name
= !Args.latex_module_type_prefix^
(self#label ?no_ name
)
205 (** Make a correct label from an exception name. *)
206 method exception_label ?no_ name
= !Args.latex_exception_prefix^
(self#label ?no_ name
)
208 (** Make a correct label from a type name. *)
209 method type_label ?no_ name
= !Args.latex_type_prefix^
(self#label ?no_ name
)
211 (** Return latex code for the label of a given label. *)
212 method make_label label
= "\\label{"^label^
"}"
214 (** Return latex code for the ref to a given label. *)
215 method make_ref label
= "\\ref{"^label^
"}"
217 (** Print the LaTeX code corresponding to the [text] parameter.*)
218 method latex_of_text
fmt t
=
219 List.iter (self#latex_of_text_element
fmt) t
221 (** Print the LaTeX code for the [text_element] in parameter. *)
222 method latex_of_text_element
fmt te
=
224 | Odoc_info.Raw
s -> self#latex_of_Raw
fmt s
225 | Odoc_info.Code
s -> self#latex_of_Code
fmt s
226 | Odoc_info.CodePre
s -> self#latex_of_CodePre
fmt s
227 | Odoc_info.Verbatim
s -> self#latex_of_Verbatim
fmt s
228 | Odoc_info.Bold t
-> self#latex_of_Bold
fmt t
229 | Odoc_info.Italic t
-> self#latex_of_Italic
fmt t
230 | Odoc_info.Emphasize t
-> self#latex_of_Emphasize
fmt t
231 | Odoc_info.Center t
-> self#latex_of_Center
fmt t
232 | Odoc_info.Left t
-> self#latex_of_Left
fmt t
233 | Odoc_info.Right t
-> self#latex_of_Right
fmt t
234 | Odoc_info.List tl
-> self#latex_of_List
fmt tl
235 | Odoc_info.Enum tl
-> self#latex_of_Enum
fmt tl
236 | Odoc_info.Newline
-> self#latex_of_Newline
fmt
237 | Odoc_info.Block t
-> self#latex_of_Block
fmt t
238 | Odoc_info.Title
(n
, l_opt
, t
) -> self#latex_of_Title
fmt n l_opt t
239 | Odoc_info.Latex
s -> self#latex_of_Latex
fmt s
240 | Odoc_info.Link
(s, t
) -> self#latex_of_Link
fmt s t
241 | Odoc_info.Ref
(name
, ref_opt
) -> self#latex_of_Ref
fmt name ref_opt
242 | Odoc_info.Superscript t
-> self#latex_of_Superscript
fmt t
243 | Odoc_info.Subscript t
-> self#latex_of_Subscript
fmt t
244 | Odoc_info.Module_list _
-> ()
245 | Odoc_info.Index_list
-> ()
246 | Odoc_info.Custom
(s,t
) -> self#latex_of_custom_text
fmt s t
248 method latex_of_custom_text
fmt s t
= ()
250 method latex_of_Raw
fmt s =
251 ps fmt (self#escape
s)
253 method latex_of_Code
fmt s =
254 let s2 = self#escape_code
s in
255 let s3 = Str.global_replace
(Str.regexp
"\n") ("\\\\\n") s2 in
256 p fmt "{\\tt{%s}}" s3
258 method latex_of_CodePre
fmt s =
259 ps fmt "\\begin{ocamldoccode}\n";
260 ps fmt (self#escape_simple
s);
261 ps fmt "\n\\end{ocamldoccode}\n"
263 method latex_of_Verbatim
fmt s =
264 ps fmt "\\begin{verbatim}";
266 ps fmt "\\end{verbatim}"
268 method latex_of_Bold
fmt t
=
270 self#latex_of_text
fmt t
;
273 method latex_of_Italic
fmt t
=
275 self#latex_of_text
fmt t
;
278 method latex_of_Emphasize
fmt t
=
280 self#latex_of_text
fmt t
;
283 method latex_of_Center
fmt t
=
284 ps fmt "\\begin{center}\n";
285 self#latex_of_text
fmt t
;
286 ps fmt "\\end{center}\n"
288 method latex_of_Left
fmt t
=
289 ps fmt "\\begin{flushleft}\n";
290 self#latex_of_text
fmt t
;
291 ps fmt "\\end{flushleft}\n"
293 method latex_of_Right
fmt t
=
294 ps fmt "\\begin{flushright}\n";
295 self#latex_of_text
fmt t
;
296 ps fmt "\\end{flushright}\n"
298 method latex_of_List
fmt tl
=
299 ps fmt "\\begin{itemize}\n";
303 self#latex_of_text
fmt t
;
307 ps fmt "\\end{itemize}\n"
309 method latex_of_Enum
fmt tl
=
310 ps fmt "\\begin{enumerate}\n";
314 self#latex_of_text
fmt t
;
318 ps fmt "\\end{enumerate}\n"
320 method latex_of_Newline
fmt = ps fmt "\n\n"
322 method latex_of_Block
fmt t
=
323 ps fmt "\\begin{ocamldocdescription}\n";
324 self#latex_of_text
fmt t
;
325 ps fmt "\n\\end{ocamldocdescription}\n"
327 method latex_of_Title
fmt n label_opt t
=
328 let (fmt2
, flush
) = new_fmt () in
329 self#latex_of_text fmt2 t
;
330 let s_title2 = self#section_style n
(flush
()) in
336 ps fmt (self#make_label
(self#label ~no_
: false l
))
339 method latex_of_Latex
fmt s = ps fmt s
341 method latex_of_Link
fmt s t
=
342 self#latex_of_text
fmt t
;
347 method latex_of_Ref
fmt name ref_opt
=
350 self#latex_of_text_element
fmt
351 (Odoc_info.Code
(Odoc_info.use_hidden_modules name
))
352 | Some
(RK_section _
) ->
353 self#latex_of_text_element
fmt
354 (Latex
("["^
(self#make_ref
(self#label ~no_
:false (Name.simple name
)))^
"]"))
358 Odoc_info.RK_module
-> self#module_label
359 | Odoc_info.RK_module_type
-> self#module_type_label
360 | Odoc_info.RK_class
-> self#class_label
361 | Odoc_info.RK_class_type
-> self#class_type_label
362 | Odoc_info.RK_value
-> self#value_label
363 | Odoc_info.RK_type
-> self#type_label
364 | Odoc_info.RK_exception
-> self#exception_label
365 | Odoc_info.RK_attribute
-> self#attribute_label
366 | Odoc_info.RK_method
-> self#method_label
367 | Odoc_info.RK_section _
-> assert false
369 self#latex_of_text
fmt
371 Odoc_info.Code
(Odoc_info.use_hidden_modules name
) ;
372 Latex
("["^
(self#make_ref
(f_label name
))^
"]")
375 method latex_of_Superscript
fmt t
=
377 self#latex_of_text
fmt t
;
380 method latex_of_Subscript
fmt t
=
382 self#latex_of_text
fmt t
;
387 (** A class used to generate LaTeX code for info structures. *)
390 (** The method used to get LaTeX code from a [text]. *)
391 method virtual latex_of_text
: Format.formatter
-> Odoc_info.text
-> unit
393 (** The method used to get a [text] from an optionel info structure. *)
394 method virtual text_of_info
: ?block
: bool -> Odoc_info.info
option -> Odoc_info.text
396 (** Print LaTeX code for a description, except for the [i_params] field. *)
397 method latex_of_info
fmt ?
(block
=false) info_opt
=
398 self#latex_of_text
fmt
399 (self#text_of_info ~block info_opt
)
402 (** This class is used to create objects which can generate a simple LaTeX documentation. *)
406 inherit Odoc_to_text.to_text
as to_text
409 (** Get the first sentence and the rest of a description,
410 from an optional [info] structure. The first sentence
411 can be empty if it would not appear right in a title.
412 In the first sentence, the titles and lists has been removed,
413 since it is used in LaTeX titles and would make LaTeX complain
414 if we has two nested \section commands.
416 method first_and_rest_of_info i_opt
=
420 match i
.Odoc_info.i_desc
with
421 None
-> ([], self#text_of_info ~block
: true i_opt
)
423 let (first
,_
) = Odoc_info.first_sentence_and_rest_of_text t
in
424 let (_
, rest
) = Odoc_info.first_sentence_and_rest_of_text
(self#text_of_info ~block
: false i_opt
) in
425 (Odoc_info.text_no_title_no_list first
, rest
)
427 (** Print LaTeX code for a value. *)
428 method latex_of_value
fmt v
=
429 Odoc_info.reset_type_names
() ;
430 let label = self#value_label v
.val_name
in
431 let latex = self#make_label
label in
432 self#latex_of_text
fmt
434 (to_text#text_of_value v
))
436 (** Print LaTeX code for a class attribute. *)
437 method latex_of_attribute
fmt a
=
438 self#latex_of_text
fmt
439 ((Latex
(self#make_label
(self#attribute_label a
.att_value
.val_name
))) ::
440 (to_text#text_of_attribute a
))
442 (** Print LaTeX code for a class method. *)
443 method latex_of_method
fmt m
=
444 self#latex_of_text
fmt
445 ((Latex
(self#make_label
(self#method_label m
.met_value
.val_name
))) ::
446 (to_text#text_of_method m
))
448 (** Print LaTeX code for the parameters of a type. *)
449 method latex_of_type_params
fmt m_name t
=
450 let print_one (p, co
, cn
) =
451 ps fmt (Odoc_info.string_of_variance t
(co
,cn
));
452 ps fmt (self#normal_type m_name
p)
454 match t
.ty_parameters
with
456 | [(p,co
,cn
)] -> print_one (p, co
, cn
)
459 print_concat fmt ", " print_one t
.ty_parameters
;
462 method latex_of_class_parameter_list
fmt father c
=
463 self#latex_of_text
fmt
464 (self#text_of_class_params father c
)
466 (** Print LaTeX code for a type. *)
467 method latex_of_type
fmt t
=
468 let s_name = Name.simple t
.ty_name
in
470 let (fmt2
, flush2
) = new_fmt () in
471 Odoc_info.reset_type_names
() ;
472 let mod_name = Name.father t
.ty_name
in
473 Format.fprintf fmt2
"@[<h 2>type ";
474 self#latex_of_type_params fmt2
mod_name t
;
475 (match t
.ty_parameters
with [] -> () | _
-> ps fmt2
" ");
478 match t
.ty_manifest
with
481 p fmt2
" = %s" (self#normal_type
mod_name typ
)
489 | Type_variant
(_
, priv
) -> "="^
(if priv
then " private" else "")
490 | Type_record
(_
, priv
) -> "= "^
(if priv
then "private " else "")^
"{"
498 | Type_variant
(l
, _
) ->
503 p fmt2
"@[<h 6> | %s" constr
.vc_name
;
505 match constr
.vc_args
with
510 (self#normal_type_list ~par
: false mod_name " * " l
)
515 (match constr
.vc_text
with
519 ps fmt2
"\\begin{ocamldoccomment}\n";
520 self#latex_of_text fmt2 t
;
521 ps fmt2
"\n\\end{ocamldoccomment}\n";
530 | Type_record
(l
, _
) ->
536 "@[<h 6> %s%s :@ %s ;"
537 (if r
.rf_mutable
then "mutable " else "")
539 (self#normal_type
mod_name r
.rf_type
);
542 [ CodePre
s_field ] @
543 (match r
.rf_text
with
547 ps fmt2
"\\begin{ocamldoccomment}\n";
548 self#latex_of_text fmt2 t
;
549 ps fmt2
"\n\\end{ocamldoccomment}\n";
560 let defs2 = (CodePre
s_type3) :: defs in
561 let rec iter = function
564 | (CodePre s1
) :: (CodePre
s2) :: q
->
565 iter ((CodePre
(s1^
"\n"^
s2)) :: q
)
570 [Latex
("\\index{"^
(self#
label s_name)^
"@\\verb`"^
(self#
label ~no_
:false s_name)^
"`}\n")] @
571 (self#text_of_info t
.ty_info
)
573 self#latex_of_text
fmt
574 ((Latex
(self#make_label
(self#type_label t
.ty_name
))) :: text)
576 (** Print LaTeX code for an exception. *)
577 method latex_of_exception
fmt e
=
578 Odoc_info.reset_type_names
() ;
579 self#latex_of_text
fmt
580 ((Latex
(self#make_label
(self#exception_label e
.ex_name
))) ::
581 (to_text#text_of_exception e
))
583 method latex_of_module_parameter
fmt m_name
p =
584 self#latex_of_text
fmt
590 self#latex_of_module_type_kind
fmt m_name
p.mp_kind
;
591 self#latex_of_text
fmt [ Code
") -> "]
594 method latex_of_module_type_kind
fmt father kind
=
596 Module_type_struct eles
->
597 self#latex_of_text
fmt [Latex
"\\begin{ocamldocsigend}\n"];
598 List.iter (self#latex_of_module_element
fmt father
) eles
;
599 self#latex_of_text
fmt [Latex
"\\end{ocamldocsigend}\n"]
600 | Module_type_functor
(p, k
) ->
601 self#latex_of_module_parameter
fmt father
p;
602 self#latex_of_module_type_kind
fmt father k
603 | Module_type_alias a
->
604 self#latex_of_text
fmt
605 [Code
(self#relative_module_idents father a
.mta_name
)]
606 | Module_type_with
(k
, s) ->
607 self#latex_of_module_type_kind
fmt father k
;
608 self#latex_of_text
fmt
610 Code
(self#relative_idents father
s);
613 method latex_of_module_kind
fmt father kind
=
615 Module_struct eles
->
616 self#latex_of_text
fmt [Latex
"\\begin{ocamldocsigend}\n"];
617 List.iter (self#latex_of_module_element
fmt father
) eles
;
618 self#latex_of_text
fmt [Latex
"\\end{ocamldocsigend}\n"]
620 self#latex_of_text
fmt
621 [Code
(self#relative_module_idents father a
.ma_name
)]
622 | Module_functor
(p, k
) ->
623 self#latex_of_module_parameter
fmt father
p;
624 self#latex_of_module_kind
fmt father k
625 | Module_apply
(k1
, k2
) ->
626 (* TODO: l'application n'est pas correcte dans un .mli.
627 Que faire ? -> afficher le module_type du typedtree *)
628 self#latex_of_module_kind
fmt father k1
;
629 self#latex_of_text
fmt [Code
"("];
630 self#latex_of_module_kind
fmt father k2
;
631 self#latex_of_text
fmt [Code
")"]
632 | Module_with
(k
, s) ->
633 (* TODO: à modifier quand Module_with sera plus détaillé *)
634 self#latex_of_module_type_kind
fmt father k
;
635 self#latex_of_text
fmt
637 Code
(self#relative_idents father
s) ;
639 | Module_constraint
(k
, tk
) ->
640 (* TODO: on affiche quoi ? *)
641 self#latex_of_module_kind
fmt father k
643 method latex_of_class_kind
fmt father kind
=
645 Class_structure
(inh
, eles
) ->
646 self#latex_of_text
fmt [Latex
"\\begin{ocamldocobjectend}\n"];
647 self#generate_inheritance_info
fmt inh
;
648 List.iter (self#latex_of_class_element
fmt father
) eles
;
649 self#latex_of_text
fmt [Latex
"\\end{ocamldocobjectend}\n"]
651 | Class_apply capp
->
652 (* TODO: afficher le type final à partir du typedtree *)
653 self#latex_of_text
fmt [Raw
"class application not handled yet"]
655 | Class_constr cco
->
657 match cco
.cco_type_parameters
with
660 self#latex_of_text
fmt
663 (self#text_of_class_type_param_expr_list father l
) @
667 self#latex_of_text
fmt
668 [Code
(self#relative_idents father cco
.cco_name
)]
670 | Class_constraint
(ck
, ctk
) ->
671 self#latex_of_text
fmt [Code
"( "] ;
672 self#latex_of_class_kind
fmt father ck
;
673 self#latex_of_text
fmt [Code
" : "] ;
674 self#latex_of_class_type_kind
fmt father ctk
;
675 self#latex_of_text
fmt [Code
" )"]
677 method latex_of_class_type_kind
fmt father kind
=
681 match cta
.cta_type_parameters
with
684 self#latex_of_text
fmt
686 (self#text_of_class_type_param_expr_list father l
) @
690 self#latex_of_text
fmt
691 [Code
(self#relative_idents father cta
.cta_name
)]
693 | Class_signature
(inh
, eles
) ->
694 self#latex_of_text
fmt [Latex
"\\begin{ocamldocobjectend}\n"];
695 self#generate_inheritance_info
fmt inh
;
696 List.iter (self#latex_of_class_element
fmt father
) eles
;
697 self#latex_of_text
fmt [Latex
"\\end{ocamldocobjectend}\n"]
699 method latex_for_module_index
fmt m
=
700 let s_name = Name.simple m
.m_name
in
701 self#latex_of_text
fmt
702 [Latex
("\\index{"^
(self#
label s_name)^
"@\\verb`"^
703 (self#
label ~no_
:false s_name)^
"`}\n"
707 method latex_for_module_type_index
fmt mt
=
708 let s_name = Name.simple mt
.mt_name
in
709 self#latex_of_text
fmt
710 [Latex
("\\index{"^
(self#
label s_name)^
"@\\verb`"^
711 (self#
label ~no_
:false (Name.simple
s_name))^
"`}\n"
715 method latex_for_module_label
fmt m
=
716 ps fmt (self#make_label
(self#module_label m
.m_name
))
718 method latex_for_module_type_label
fmt mt
=
719 ps fmt (self#make_label
(self#module_type_label mt
.mt_name
))
722 method latex_for_class_index
fmt c
=
723 let s_name = Name.simple c
.cl_name
in
724 self#latex_of_text
fmt
725 [Latex
("\\index{"^
(self#
label s_name)^
"@\\verb`"^
726 (self#
label ~no_
:false s_name)^
"`}\n"
730 method latex_for_class_type_index
fmt ct
=
731 let s_name = Name.simple ct
.clt_name
in
732 self#latex_of_text
fmt
733 [Latex
("\\index{"^
(self#
label s_name)^
"@\\verb`"^
734 (self#
label ~no_
:false s_name)^
"`}\n"
738 method latex_for_class_label
fmt c
=
739 ps fmt (self#make_label
(self#class_label c
.cl_name
))
741 method latex_for_class_type_label
fmt ct
=
742 ps fmt (self#make_label
(self#class_type_label ct
.clt_name
))
744 (** Print the LaTeX code for the given module. *)
745 method latex_of_module
fmt m
=
746 let father = Name.father m
.m_name
in
749 Latex
"\\begin{ocamldoccode}\n" ;
751 Code
(Name.simple m
.m_name
);
755 self#latex_of_text
fmt t;
756 self#latex_of_text
fmt [ Latex
"\\end{ocamldoccode}\n" ];
757 self#latex_for_module_label
fmt m
;
758 self#latex_for_module_index
fmt m
;
760 self#latex_of_module_kind
fmt father m
.m_kind
;
762 match Module.module_is_functor m
with
765 self#latex_of_text
fmt [Newline
];
767 match List.filter
(fun (_
,d
) -> d
<> None
)
768 (module_parameters ~trans
: false m
)
773 [ Bold
[Raw
"Parameters: "];
777 let t = match text_opt
with None
-> [] | Some
t -> t in
778 ( Raw
p.mp_name
:: Raw
": " :: t)
784 self#latex_of_text
fmt t
787 self#latex_of_text
fmt [Newline
];
788 self#latex_of_info
fmt ~block
: true m
.m_info
;
792 (** Print the LaTeX code for the given module type. *)
793 method latex_of_module_type
fmt mt
=
794 let father = Name.father mt
.mt_name
in
797 Latex
"\\begin{ocamldoccode}\n" ;
798 Code
"module type " ;
799 Code
(Name.simple mt
.mt_name
);
802 self#latex_of_text
fmt t;
804 match mt
.mt_type
, mt
.mt_kind
with
805 | Some mtyp
, Some kind
->
806 self#latex_of_text
fmt [ Code
" = " ];
807 self#latex_of_text
fmt [ Latex
"\\end{ocamldoccode}\n" ];
808 self#latex_for_module_type_label
fmt mt
;
809 self#latex_for_module_type_index
fmt mt
;
811 self#latex_of_module_type_kind
fmt father kind
813 self#latex_of_text
fmt [ Latex
"\\end{ocamldoccode}\n" ];
814 self#latex_for_module_type_index
fmt mt
;
818 match Module.module_type_is_functor mt
with
821 self#latex_of_text
fmt [Newline
];
823 match List.filter
(fun (_
,d
) -> d
<> None
)
824 (module_type_parameters ~trans
: false mt
)
829 [ Bold
[Raw
"Parameters: "];
833 let t = match text_opt
with None
-> [] | Some
t -> t in
834 ( Raw
p.mp_name
:: Raw
": " :: t)
840 self#latex_of_text
fmt t
843 self#latex_of_text
fmt [Newline
];
844 self#latex_of_info
fmt ~block
: true mt
.mt_info
;
847 (** Print the LaTeX code for the given included module. *)
848 method latex_of_included_module
fmt im
=
849 self#latex_of_text
fmt
850 ((Code
"include ") ::
852 (match im
.im_module
with
854 | Some
(Mod m
) -> m
.m_name
855 | Some
(Modtype mt
) -> mt
.mt_name
)
857 (self#text_of_info im
.im_info
)
860 (** Print the LaTeX code for the given class. *)
861 method latex_of_class
fmt c
=
862 Odoc_info.reset_type_names
() ;
863 let father = Name.father c
.cl_name
in
865 match c
.cl_type_parameters
with
867 | l
-> (self#normal_class_type_param_list
father l
)^
" "
871 Latex
"\\begin{ocamldoccode}\n" ;
874 (if c
.cl_virtual
then "virtual " else "")
876 (Name.simple c
.cl_name
)
880 self#latex_of_text
fmt t;
881 self#latex_of_class_parameter_list
fmt father c
;
882 (* avoid a big gap if the kind is a consrt *)
885 Class.Class_constr _
->
886 self#latex_of_class_kind
fmt father c
.cl_kind
890 self#latex_of_text
fmt [ Latex
"\\end{ocamldoccode}\n" ];
891 self#latex_for_class_label
fmt c
;
892 self#latex_for_class_index
fmt c
;
894 (match c
.cl_kind
with
895 Class.Class_constr _
-> ()
896 | _
-> self#latex_of_class_kind
fmt father c
.cl_kind
898 self#latex_of_text
fmt [Newline
];
899 self#latex_of_info
fmt ~block
: true c
.cl_info
;
902 (** Print the LaTeX code for the given class type. *)
903 method latex_of_class_type
fmt ct
=
904 Odoc_info.reset_type_names
() ;
905 let father = Name.father ct
.clt_name
in
907 match ct
.clt_type_parameters
with
909 | l
-> (self#normal_class_type_param_list
father l
)^
" "
913 Latex
"\\begin{ocamldoccode}\n" ;
915 "class type %s%s%s = "
916 (if ct
.clt_virtual
then "virtual " else "")
918 (Name.simple ct
.clt_name
)
922 self#latex_of_text
fmt t;
924 self#latex_of_text
fmt [ Latex
"\\end{ocamldoccode}\n" ];
925 self#latex_for_class_type_label
fmt ct
;
926 self#latex_for_class_type_index
fmt ct
;
928 self#latex_of_class_type_kind
fmt father ct
.clt_kind
;
929 self#latex_of_text
fmt [Newline
];
930 self#latex_of_info
fmt ~block
: true ct
.clt_info
;
933 (** Print the LaTeX code for the given class element. *)
934 method latex_of_class_element
fmt class_name class_ele
=
935 self#latex_of_text
fmt [Newline
];
937 Class_attribute att
-> self#latex_of_attribute
fmt att
938 | Class_method met
-> self#latex_of_method
fmt met
942 | (Title
(_
,_
,_
)) :: _
-> self#latex_of_text
fmt t
943 | _
-> self#latex_of_text
fmt [ Title
((Name.depth class_name
) + 2, None
, t) ]
945 (** Print the LaTeX code for the given module element. *)
946 method latex_of_module_element
fmt module_name module_ele
=
947 self#latex_of_text
fmt [Newline
];
948 match module_ele
with
949 Element_module m
-> self#latex_of_module
fmt m
950 | Element_module_type mt
-> self#latex_of_module_type
fmt mt
951 | Element_included_module im
-> self#latex_of_included_module
fmt im
952 | Element_class c
-> self#latex_of_class
fmt c
953 | Element_class_type ct
-> self#latex_of_class_type
fmt ct
954 | Element_value v
-> self#latex_of_value
fmt v
955 | Element_exception e
-> self#latex_of_exception
fmt e
956 | Element_type
t -> self#latex_of_type
fmt t
957 | Element_module_comment
t -> self#latex_of_text
fmt t
959 (** Generate the LaTeX code for the given list of inherited classes.*)
960 method generate_inheritance_info
fmt inher_l
=
962 match inh
.ic_class
with
963 None
-> (* we can't make the reference *)
965 Code
("inherit "^inh
.ic_name
) ::
966 (match inh
.ic_text
with
968 | Some
t -> Newline
:: t
973 Cl _
-> self#class_label inh
.ic_name
974 | Cltype _
-> self#class_type_label inh
.ic_name
976 (* we can create the reference *)
978 Odoc_info.Code
("inherit "^inh
.ic_name
) ::
979 (Odoc_info.Latex
(" ["^
(self#make_ref
label)^
"]")) ::
980 (match inh
.ic_text
with
982 | Some
t -> Newline
:: t
985 List.iter (self#latex_of_text
fmt) (List.map
f inher_l
)
987 (** Generate the LaTeX code for the inherited classes of the given class. *)
988 method generate_class_inheritance_info
fmt cl
=
989 let rec iter_kind k
=
991 Class_structure
([], _
) ->
993 | Class_structure
(l
, _
) ->
994 self#generate_inheritance_info
fmt l
995 | Class_constraint
(k
, _
) ->
1001 iter_kind cl
.cl_kind
1003 (** Generate the LaTeX code for the inherited classes of the given class type. *)
1004 method generate_class_type_inheritance_info
fmt clt
=
1005 match clt
.clt_kind
with
1006 Class_signature
([], _
) ->
1008 | Class_signature
(l
, _
) ->
1009 self#generate_inheritance_info
fmt l
1013 (** Generate the LaTeX code for the given top module, in the given buffer. *)
1014 method generate_for_top_module
fmt m
=
1015 let (first_t
, rest_t
) = self#first_and_rest_of_info m
.m_info
in
1017 if m
.m_text_only
then
1018 [ Title
(1, None
, [Raw m
.m_name
] @
1021 | t -> (Raw
" : ") :: t)
1026 [ Raw
(Odoc_messages.modul^
" ") ; Code m
.m_name
] @
1029 | t -> (Raw
" : ") :: t)) ;
1032 self#latex_of_text
fmt text;
1033 self#latex_for_module_label
fmt m
;
1034 self#latex_for_module_index
fmt m
;
1035 self#latex_of_text
fmt rest_t
;
1037 self#latex_of_text
fmt [ Newline
] ;
1038 if not m
.m_text_only
then ps fmt "\\ocamldocvspace{0.5cm}\n\n";
1041 self#latex_of_module_element
fmt m
.m_name ele
;
1044 (Module.module_elements ~trans
: false m
)
1046 (** Print the header of the TeX document. *)
1047 method latex_header
fmt module_list
=
1048 ps fmt "\\documentclass[11pt]{article} \n";
1049 ps fmt "\\usepackage[latin1]{inputenc} \n";
1050 ps fmt "\\usepackage[T1]{fontenc} \n";
1051 ps fmt "\\usepackage{fullpage} \n";
1052 ps fmt "\\usepackage{url} \n";
1053 ps fmt "\\usepackage{ocamldoc}\n";
1055 match !Args.title
with
1059 ps fmt (self#escape
s);
1062 ps fmt "\\begin{document}\n";
1063 (match !Args.title
with
1065 Some _
-> ps fmt "\\maketitle\n"
1067 if !Args.with_toc
then ps fmt "\\tableofcontents\n";
1069 let info = Odoc_info.apply_opt
1070 (Odoc_info.info_of_comment_file module_list
)
1071 !Odoc_info.Args.intro_file
1073 (match info with None
-> () | Some _
-> ps fmt "\\vspace{0.2cm}");
1074 self#latex_of_info
fmt info;
1075 (match info with None
-> () | Some _
-> ps fmt "\n\n")
1079 (** Generate the LaTeX style file, if it does not exists. *)
1080 method generate_style_file
=
1082 let dir = Filename.dirname
!Args.out_file
in
1083 let file = Filename.concat
dir "ocamldoc.sty" in
1084 if Sys.file_exists
file then
1085 Odoc_info.verbose
(Odoc_messages.file_exists_dont_generate
file)
1088 let chanout = open_out
file in
1089 output_string
chanout Odoc_latex_style.content
;
1092 Odoc_info.verbose
(Odoc_messages.file_generated
file)
1097 incr
Odoc_info.errors
;
1099 (** Generate the LaTeX file from a module list, in the {!Odoc_info.Args.out_file} file. *)
1100 method generate module_list
=
1101 self#generate_style_file
;
1102 let main_file = !Args.out_file
in
1103 let dir = Filename.dirname
main_file in
1104 if !Args.separate_files
then
1109 open_out
((Filename.concat
dir (Name.simple m
.m_name
))^
".tex")
1111 let fmt = Format.formatter_of_out_channel
chanout in
1112 self#generate_for_top_module
fmt m
;
1113 Format.pp_print_flush
fmt ();
1119 incr
Odoc_info.errors
1121 List.iter f module_list
1125 let chanout = open_out
main_file in
1126 let fmt = Format.formatter_of_out_channel
chanout in
1127 if !Args.with_header
then self#latex_header
fmt module_list
;
1130 if !Args.separate_files
then
1131 ps fmt ("\\input{"^
((Name.simple m
.m_name
))^
".tex}\n")
1133 self#generate_for_top_module
fmt m
1136 if !Args.with_trailer
then ps fmt "\\end{document}";
1137 Format.pp_print_flush
fmt ();
1143 incr
Odoc_info.errors