Add copyright notices and new function String.chomp
[ocaml.git] / ocamldoc / odoc_latex.ml
blob95d1b917827b08103b7b3dbb140802e63aac58cc
1 (***********************************************************************)
2 (* OCamldoc *)
3 (* *)
4 (* Maxence Guesdon, projet Cristal, INRIA Rocquencourt *)
5 (* *)
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. *)
9 (* *)
10 (***********************************************************************)
12 (* $Id$ *)
14 (** Generation of LaTeX documentation. *)
16 let print_DEBUG s = print_string s ; print_newline ()
18 open Odoc_info
19 open Parameter
20 open Value
21 open Type
22 open Exception
23 open Class
24 open Module
26 let new_buf () = Buffer.create 1024
27 let new_fmt () =
28 let b = new_buf () in
29 let fmt = Format.formatter_of_buffer b in
30 (fmt,
31 fun () ->
32 Format.pp_print_flush fmt ();
33 let s = Buffer.contents b in
34 Buffer.reset b;
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
47 [] -> ()
48 | [c] -> f c
49 | c :: q ->
50 f c;
51 ps fmt sep;
52 iter q
54 iter
56 (** Generation of LaTeX code from text structures. *)
57 class text =
58 object (self)
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 =
62 try
63 let sec = List.assoc level !Args.latex_titles in
64 "\\"^sec^"{"^s^"}\n"
65 with Not_found -> s
67 (** Associations of strings to subsitute in latex code. *)
68 val mutable subst_strings = [
69 ("MAXENCE"^"ZZZ", "\\$");
70 ("MAXENCE"^"YYY", "\\&");
71 ("MAXENCE"^"XXX", "{\\textbackslash}") ;
72 ("à", "\\`a") ;
73 ("â", "\\^a") ;
74 ("é", "\\'e") ;
75 ("è", "\\`e") ;
76 ("ê", "\\^e") ;
77 ("ë", "\\\"e") ;
78 ("ç", "\\c{c}") ;
79 ("ô", "\\^o") ;
80 ("ö", "\\\"o") ;
81 ("î", "\\^i") ;
82 ("ï", "\\\"i") ;
83 ("ù", "\\`u") ;
84 ("û", "\\^u") ;
85 ("%", "\\%") ;
86 ("_", "\\_");
87 ("\\.\\.\\.", "$\\ldots$");
88 ("~", "\\~{}");
89 ("#", "\\verb`#`");
90 ("}", "\\}");
91 ("{", "\\{");
92 ("&", "\\&");
93 (">", "$>$");
94 ("<", "$<$");
95 ("=", "$=$");
96 (">=", "$\\geq$");
97 ("<=", "$\\leq$");
98 ("->", "$\\rightarrow$") ;
99 ("<-", "$\\leftarrow$");
100 ("|", "\\textbar ");
101 ("\\^", "\\textasciicircum ") ;
102 ("\\.\\.\\.", "$\\ldots$");
103 ("\\\\", "MAXENCE"^"XXX") ;
104 ("&", "MAXENCE"^"YYY") ;
105 ("\\$", "MAXENCE"^"ZZZ")
108 val mutable subst_strings_simple =
110 ("MAXENCE"^"XXX", "{\\textbackslash}") ;
111 "}", "\\}" ;
112 "{", "\\{" ;
113 ("\\\\", "MAXENCE"^"XXX") ;
116 val mutable subst_strings_code = [
117 ("MAXENCE"^"ZZZ", "\\$");
118 ("MAXENCE"^"YYY", "\\&");
119 ("MAXENCE"^"XXX", "{\\textbackslash}") ;
120 ("%", "\\%") ;
121 ("_", "\\_");
122 ("~", "\\~{}");
123 ("#", "\\verb`#`");
124 ("}", "\\}");
125 ("{", "\\{");
126 ("&", "\\&");
127 ("\\^", "\\textasciicircum ") ;
128 ("&", "MAXENCE"^"YYY") ;
129 ("\\$", "MAXENCE"^"ZZZ") ;
130 ("\\\\", "MAXENCE"^"XXX") ;
133 method subst l s =
134 List.fold_right
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:
152 \ { } $ & # ^ _ % ~
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
159 let (s_no_, s) =
160 match name.[i] with
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)
181 done;
182 Buffer.contents buf
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 =
223 match te with
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}";
265 ps fmt s;
266 ps fmt "\\end{verbatim}"
268 method latex_of_Bold fmt t =
269 ps fmt "{\\bf ";
270 self#latex_of_text fmt t;
271 ps fmt "}"
273 method latex_of_Italic fmt t =
274 ps fmt "{\\it ";
275 self#latex_of_text fmt t;
276 ps fmt "}"
278 method latex_of_Emphasize fmt t =
279 ps fmt "{\\em ";
280 self#latex_of_text fmt t;
281 ps fmt "}"
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";
300 List.iter
301 (fun t ->
302 ps fmt "\\item ";
303 self#latex_of_text fmt t;
304 ps fmt "\n"
307 ps fmt "\\end{itemize}\n"
309 method latex_of_Enum fmt tl =
310 ps fmt "\\begin{enumerate}\n";
311 List.iter
312 (fun t ->
313 ps fmt "\\item ";
314 self#latex_of_text fmt t;
315 ps fmt "\n"
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
331 ps fmt s_title2;
333 match label_opt with
334 None -> ()
335 | Some l ->
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 ;
343 ps fmt "[\\url{";
344 ps fmt s ;
345 ps fmt "}]"
347 method latex_of_Ref fmt name ref_opt =
348 match ref_opt with
349 None ->
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)))^"]"))
355 | Some kind ->
356 let f_label =
357 match kind with
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 =
376 ps fmt "$^{";
377 self#latex_of_text fmt t;
378 ps fmt "}$"
380 method latex_of_Subscript fmt t =
381 ps fmt "$_{";
382 self#latex_of_text fmt t;
383 ps fmt "}$"
387 (** A class used to generate LaTeX code for info structures. *)
388 class virtual info =
389 object (self)
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. *)
403 class latex =
404 object (self)
405 inherit text
406 inherit Odoc_to_text.to_text as to_text
407 inherit info
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 =
417 match i_opt with
418 None -> ([], [])
419 | Some i ->
420 match i.Odoc_info.i_desc with
421 None -> ([], self#text_of_info ~block: true i_opt)
422 | Some t ->
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
433 ((Latex latex) ::
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
455 [] -> ()
456 | [(p,co,cn)] -> print_one (p, co, cn)
457 | l ->
458 ps fmt "(";
459 print_concat fmt ", " print_one t.ty_parameters;
460 ps fmt ")"
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
469 let text =
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 " ");
476 ps fmt2 s_name;
478 match t.ty_manifest with
479 None -> ()
480 | Some typ ->
481 p fmt2 " = %s" (self#normal_type mod_name typ)
483 let s_type3 =
484 p fmt2
485 " %s"
487 match t.ty_kind with
488 Type_abstract -> ""
489 | Type_variant (_, priv) -> "="^(if priv then " private" else "")
490 | Type_record (_, priv) -> "= "^(if priv then "private " else "")^"{"
492 flush2 ()
495 let defs =
496 match t.ty_kind with
497 Type_abstract -> []
498 | Type_variant (l, _) ->
499 (List.flatten
500 (List.map
501 (fun constr ->
502 let s_cons =
503 p fmt2 "@[<h 6> | %s" constr.vc_name;
505 match constr.vc_args with
506 [] -> ()
507 | l ->
508 p fmt2 " %s@ %s"
509 "of"
510 (self#normal_type_list ~par: false mod_name " * " l)
512 flush2 ()
514 [ CodePre s_cons ] @
515 (match constr.vc_text with
516 None -> []
517 | Some t ->
518 let s =
519 ps fmt2 "\\begin{ocamldoccomment}\n";
520 self#latex_of_text fmt2 t;
521 ps fmt2 "\n\\end{ocamldoccomment}\n";
522 flush2 ()
524 [ Latex s]
530 | Type_record (l, _) ->
531 (List.flatten
532 (List.map
533 (fun r ->
534 let s_field =
535 p fmt2
536 "@[<h 6> %s%s :@ %s ;"
537 (if r.rf_mutable then "mutable " else "")
538 r.rf_name
539 (self#normal_type mod_name r.rf_type);
540 flush2 ()
542 [ CodePre s_field ] @
543 (match r.rf_text with
544 None -> []
545 | Some t ->
546 let s =
547 ps fmt2 "\\begin{ocamldoccomment}\n";
548 self#latex_of_text fmt2 t;
549 ps fmt2 "\n\\end{ocamldoccomment}\n";
550 flush2 ()
552 [ Latex s]
558 [ CodePre "}" ]
560 let defs2 = (CodePre s_type3) :: defs in
561 let rec iter = function
562 [] -> []
563 | [e] -> [e]
564 | (CodePre s1) :: (CodePre s2) :: q ->
565 iter ((CodePre (s1^"\n"^s2)) :: q)
566 | e :: q ->
567 e :: (iter q)
569 (iter defs2) @
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
586 Code "functor (";
587 Code p.mp_name ;
588 Code " : ";
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 =
595 match kind with
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
609 [ Code " ";
610 Code (self#relative_idents father s);
613 method latex_of_module_kind fmt father kind =
614 match kind with
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"]
619 | Module_alias a ->
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
636 [ Code " ";
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 =
644 match kind with
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
658 [] -> ()
659 | l ->
660 self#latex_of_text fmt
662 Code "[" ::
663 (self#text_of_class_type_param_expr_list father l) @
664 [Code "] "]
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 =
678 match kind with
679 Class_type cta ->
681 match cta.cta_type_parameters with
682 [] -> ()
683 | l ->
684 self#latex_of_text fmt
685 (Code "[" ::
686 (self#text_of_class_type_param_expr_list father l) @
687 [Code "] "]
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
747 let t =
749 Latex "\\begin{ocamldoccode}\n" ;
750 Code "module ";
751 Code (Name.simple m.m_name);
752 Code " : ";
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;
759 p fmt "@[<h 4>";
760 self#latex_of_module_kind fmt father m.m_kind;
762 match Module.module_is_functor m with
763 false -> ()
764 | true ->
765 self#latex_of_text fmt [Newline];
767 match List.filter (fun (_,d) -> d <> None)
768 (module_parameters ~trans: false m)
769 with
770 [] -> ()
771 | l ->
772 let t =
773 [ Bold [Raw "Parameters: "];
774 List
775 (List.map
776 (fun (p,text_opt) ->
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;
789 p fmt "@]";
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
795 let t =
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;
810 p fmt "@[<h 4>";
811 self#latex_of_module_type_kind fmt father kind
812 | _ ->
813 self#latex_of_text fmt [ Latex "\\end{ocamldoccode}\n" ];
814 self#latex_for_module_type_index fmt mt;
815 p fmt "@[<h 4>";
818 match Module.module_type_is_functor mt with
819 false -> ()
820 | true ->
821 self#latex_of_text fmt [Newline];
823 match List.filter (fun (_,d) -> d <> None)
824 (module_type_parameters ~trans: false mt)
825 with
826 [] -> ()
827 | l ->
828 let t =
829 [ Bold [Raw "Parameters: "];
830 List
831 (List.map
832 (fun (p,text_opt) ->
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;
845 p fmt "@]";
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 ") ::
851 (Code
852 (match im.im_module with
853 None -> im.im_name
854 | Some (Mod m) -> m.m_name
855 | Some (Modtype mt) -> mt.mt_name)
856 ) ::
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
864 let type_params =
865 match c.cl_type_parameters with
866 [] -> ""
867 | l -> (self#normal_class_type_param_list father l)^" "
869 let t =
871 Latex "\\begin{ocamldoccode}\n" ;
872 Code (Printf.sprintf
873 "class %s%s%s : "
874 (if c.cl_virtual then "virtual " else "")
875 type_params
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 *)
884 match c.cl_kind with
885 Class.Class_constr _ ->
886 self#latex_of_class_kind fmt father c.cl_kind
887 | _ ->
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;
893 p fmt "@[<h 4>";
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;
900 p fmt "@]"
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
906 let type_params =
907 match ct.clt_type_parameters with
908 [] -> ""
909 | l -> (self#normal_class_type_param_list father l)^" "
911 let t =
913 Latex "\\begin{ocamldoccode}\n" ;
914 Code (Printf.sprintf
915 "class type %s%s%s = "
916 (if ct.clt_virtual then "virtual " else "")
917 type_params
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;
927 p fmt "@[<h 4>";
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;
931 p fmt "@]"
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];
936 match class_ele with
937 Class_attribute att -> self#latex_of_attribute fmt att
938 | Class_method met -> self#latex_of_method fmt met
939 | Class_comment t ->
940 match t with
941 | [] -> ()
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 =
961 let f inh =
962 match inh.ic_class with
963 None -> (* we can't make the reference *)
964 Newline ::
965 Code ("inherit "^inh.ic_name) ::
966 (match inh.ic_text with
967 None -> []
968 | Some t -> Newline :: t
970 | Some cct ->
971 let label =
972 match cct with
973 Cl _ -> self#class_label inh.ic_name
974 | Cltype _ -> self#class_type_label inh.ic_name
976 (* we can create the reference *)
977 Newline ::
978 Odoc_info.Code ("inherit "^inh.ic_name) ::
979 (Odoc_info.Latex (" ["^(self#make_ref label)^"]")) ::
980 (match inh.ic_text with
981 None -> []
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 =
990 match k with
991 Class_structure ([], _) ->
993 | Class_structure (l, _) ->
994 self#generate_inheritance_info fmt l
995 | Class_constraint (k, _) ->
996 iter_kind k
997 | Class_apply _
998 | Class_constr _ ->
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
1010 | Class_type _ ->
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
1016 let text =
1017 if m.m_text_only then
1018 [ Title (1, None, [Raw m.m_name] @
1019 (match first_t with
1020 [] -> []
1021 | t -> (Raw " : ") :: t)
1024 else
1025 [ Title (1, None,
1026 [ Raw (Odoc_messages.modul^" ") ; Code m.m_name ] @
1027 (match first_t with
1028 [] -> []
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";
1039 List.iter
1040 (fun ele ->
1041 self#latex_of_module_element fmt m.m_name ele;
1042 ps fmt "\n\n"
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
1056 None -> ()
1057 | Some s ->
1058 ps fmt "\\title{";
1059 ps fmt (self#escape s);
1060 ps fmt "}\n"
1062 ps fmt "\\begin{document}\n";
1063 (match !Args.title with
1064 None -> () |
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)
1086 else
1088 let chanout = open_out file in
1089 output_string chanout Odoc_latex_style.content ;
1090 flush chanout ;
1091 close_out chanout;
1092 Odoc_info.verbose (Odoc_messages.file_generated file)
1094 with
1095 Sys_error s ->
1096 prerr_endline s ;
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
1106 let f m =
1108 let chanout =
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 ();
1114 close_out chanout
1115 with
1116 Failure s
1117 | Sys_error s ->
1118 prerr_endline s ;
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;
1128 List.iter
1129 (fun m ->
1130 if !Args.separate_files then
1131 ps fmt ("\\input{"^((Name.simple m.m_name))^".tex}\n")
1132 else
1133 self#generate_for_top_module fmt m
1135 module_list ;
1136 if !Args.with_trailer then ps fmt "\\end{document}";
1137 Format.pp_print_flush fmt ();
1138 close_out chanout
1139 with
1140 Failure s
1141 | Sys_error s ->
1142 prerr_endline s ;
1143 incr Odoc_info.errors