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 (***********************************************************************)
12 (* $Id: odoc_html.ml 9125 2008-11-10 13:03:55Z guesdon $ *)
14 (** Generation of html documentation.*)
16 let print_DEBUG s = print_string s ; print_newline ()
27 (** The functions used for naming files and html marks.*)
30 (** The prefix for types marks. *)
31 let mark_type = "TYPE"
33 (** The prefix for functions marks. *)
34 let mark_function = "FUN"
36 (** The prefix for exceptions marks. *)
37 let mark_exception = "EXCEPTION"
39 (** The prefix for values marks. *)
40 let mark_value = "VAL"
42 (** The prefix for attributes marks. *)
43 let mark_attribute = "ATT"
45 (** The prefix for methods marks. *)
46 let mark_method = "METHOD"
48 (** The prefix for code files.. *)
49 let code_prefix = "code_"
51 (** The prefix for type files.. *)
52 let type_prefix = "type_"
54 (** Return the two html files names for the given module or class name.*)
56 let html_file = name^".html" in
57 let html_frame_file = name^"-frame.html" in
58 (html_file, html_frame_file)
60 (** Return the target for the given prefix and simple name. *)
61 let target pref simple_name = pref^simple_name
63 (** Return the complete link target (file#target) for the given prefix string and complete name.*)
64 let complete_target pref complete_name =
65 let simple_name = Name.simple complete_name in
67 let s = Name.father complete_name in
68 if s = "" then simple_name else s
70 let (html_file, _) = html_files module_name in
71 html_file^"#"^(target pref simple_name)
73 (** Return the link target for the given type. *)
74 let type_target t = target mark_type (Name.simple t.ty_name)
76 (** Return the complete link target for the given type. *)
77 let complete_type_target t = complete_target mark_type t.ty_name
79 (** Return the link target for the given exception. *)
80 let exception_target e = target mark_exception (Name.simple e.ex_name)
82 (** Return the complete link target for the given exception. *)
83 let complete_exception_target e = complete_target mark_exception e.ex_name
85 (** Return the link target for the given value. *)
86 let value_target v = target mark_value (Name.simple v.val_name)
88 (** Return the given value name where symbols accepted in infix values
89 are replaced by strings, to avoid clashes with the filesystem.*)
90 let subst_infix_symbols name =
91 let len = String.length name in
92 let buf = Buffer.create len in
93 let ch c = Buffer.add_char buf c in
94 let st s = Buffer.add_string buf s in
95 for i = 0 to len - 1 do
104 | '-' -> st "_minus_"
106 | '/' -> st "_slash_"
107 | '$' -> st "_dollar_"
108 | '%' -> st "_percent_"
109 | '=' -> st "_equal_"
110 | ':' -> st "_column_"
111 | '~' -> st "_tilde_"
113 | '?' -> st "_questionmark_"
118 (** Return the complete link target for the given value. *)
119 let complete_value_target v = complete_target mark_value v.val_name
121 (** Return the complete filename for the code of the given value. *)
122 let file_code_value_complete_target v =
123 let f = code_prefix^mark_value^(subst_infix_symbols v.val_name)^".html" in
126 (** Return the link target for the given attribute. *)
127 let attribute_target a = target mark_attribute (Name.simple a.att_value.val_name)
129 (** Return the complete link target for the given attribute. *)
130 let complete_attribute_target a = complete_target mark_attribute a.att_value.val_name
132 (** Return the complete filename for the code of the given attribute. *)
133 let file_code_attribute_complete_target a =
134 let f = code_prefix^mark_attribute^a.att_value.val_name^".html" in
137 (** Return the link target for the given method. *)
138 let method_target m = target mark_method (Name.simple m.met_value.val_name)
140 (** Return the complete link target for the given method. *)
141 let complete_method_target m = complete_target mark_method m.met_value.val_name
143 (** Return the complete filename for the code of the given method. *)
144 let file_code_method_complete_target m =
145 let f = code_prefix^mark_method^m.met_value.val_name^".html" in
148 (** Return the link target for the given label section. *)
149 let label_target l = target "" l
151 (** Return the complete link target for the given section label. *)
152 let complete_label_target l = complete_target "" l
154 (** Return the complete filename for the code of the type of the
155 given module or module type name. *)
156 let file_type_module_complete_target name =
157 let f = type_prefix^name^".html" in
160 (** Return the complete filename for the code of the
161 given module name. *)
162 let file_code_module_complete_target name =
163 let f = code_prefix^name^".html" in
166 (** Return the complete filename for the code of the type of the
167 given class or class type name. *)
168 let file_type_class_complete_target name =
169 let f = type_prefix^name^".html" in
173 module StringSet = Set.Make (struct type t = string let compare = compare end)
175 (** A class with a method to colorize a string which represents OCaml code. *)
178 method html_of_code b ?(with_pre=true) code =
179 Odoc_ocamlhtml.html_of_code b ~with_pre: with_pre code
182 let new_buf () = Buffer.create 1024
183 let bp = Printf.bprintf
184 let bs = Buffer.add_string
187 (** Generation of html code from text structures. *)
190 (** We want to display colorized code. *)
193 (** Escape the strings which would clash with html syntax, and
194 make some replacements (double newlines replaced by <br>). *)
195 method escape s = Odoc_ocamlhtml.escape_base s
197 method keep_alpha_num s =
198 let len = String.length s in
199 let buf = Buffer.create len in
200 for i = 0 to len - 1 do
202 'a'..'z' | 'A'..'Z' | '0'..'9' -> Buffer.add_char buf s.[i]
207 (** Return a label created from the first sentence of a text. *)
208 method label_of_text t=
209 let t2 = Odoc_info.first_sentence_of_text t in
210 let s = Odoc_info.string_of_text t2 in
211 let s2 = self#keep_alpha_num s in
214 (** Create a label for the associated title.
215 Return the label specified by the user or a label created
216 from the title level and the first sentence of the title. *)
217 method create_title_label (n,label_opt,t) =
220 | None -> Printf.sprintf "%d_%s" n (self#label_of_text t)
222 (** Print the html code corresponding to the [text] parameter. *)
223 method html_of_text b t =
224 List.iter (self#html_of_text_element b) t
226 (** Print the html code for the [text_element] in parameter. *)
227 method html_of_text_element b te =
228 print_DEBUG "text::html_of_text_element";
230 | Odoc_info.Raw s -> self#html_of_Raw b s
231 | Odoc_info.Code s -> self#html_of_Code b s
232 | Odoc_info.CodePre s -> self#html_of_CodePre b s
233 | Odoc_info.Verbatim s -> self#html_of_Verbatim b s
234 | Odoc_info.Bold t -> self#html_of_Bold b t
235 | Odoc_info.Italic t -> self#html_of_Italic b t
236 | Odoc_info.Emphasize t -> self#html_of_Emphasize b t
237 | Odoc_info.Center t -> self#html_of_Center b t
238 | Odoc_info.Left t -> self#html_of_Left b t
239 | Odoc_info.Right t -> self#html_of_Right b t
240 | Odoc_info.List tl -> self#html_of_List b tl
241 | Odoc_info.Enum tl -> self#html_of_Enum b tl
242 | Odoc_info.Newline -> self#html_of_Newline b
243 | Odoc_info.Block t -> self#html_of_Block b t
244 | Odoc_info.Title (n, l_opt, t) -> self#html_of_Title b n l_opt t
245 | Odoc_info.Latex s -> self#html_of_Latex b s
246 | Odoc_info.Link (s, t) -> self#html_of_Link b s t
247 | Odoc_info.Ref (name, ref_opt) -> self#html_of_Ref b name ref_opt
248 | Odoc_info.Superscript t -> self#html_of_Superscript b t
249 | Odoc_info.Subscript t -> self#html_of_Subscript b t
250 | Odoc_info.Module_list l -> self#html_of_Module_list b l
251 | Odoc_info.Index_list -> self#html_of_Index_list b
252 | Odoc_info.Custom (s,t) -> self#html_of_custom_text b s t
254 method html_of_custom_text b s t = ()
256 method html_of_Raw b s = bs b (self#escape s)
258 method html_of_Code b s =
259 if !Args.colorize_code then
260 self#html_of_code b ~with_pre: false s
263 bs b "<code class=\"";
264 bs b Odoc_ocamlhtml.code_class ;
266 bs b (self#escape s);
270 method html_of_CodePre =
271 let remove_useless_newlines s =
272 let len = String.length s in
273 let rec iter_first n =
278 | '\n' -> iter_first (n+1)
281 match iter_first 0 with
284 let rec iter_last n =
289 '\t' -> iter_last (n-1)
292 match iter_last (len-1) with
293 None -> String.sub s first 1
294 | Some last -> String.sub s first ((last-first)+1)
297 if !Args.colorize_code then
300 self#html_of_code b (remove_useless_newlines s);
305 bs b "<pre><code class=\"";
306 bs b Odoc_ocamlhtml.code_class;
308 bs b (self#escape (remove_useless_newlines s));
312 method html_of_Verbatim b s =
314 bs b (self#escape s);
317 method html_of_Bold b t =
319 self#html_of_text b t;
322 method html_of_Italic b t =
324 self#html_of_text b t;
327 method html_of_Emphasize b t =
329 self#html_of_text b t ;
332 method html_of_Center b t =
334 self#html_of_text b t;
337 method html_of_Left b t =
338 bs b "<div align=left>";
339 self#html_of_text b t;
342 method html_of_Right b t =
343 bs b "<div align=right>";
344 self#html_of_text b t;
347 method html_of_List b tl =
350 (fun t -> bs b "<li>"; self#html_of_text b t; bs b "</li>\n")
354 method html_of_Enum b tl =
357 (fun t -> bs b "<li>"; self#html_of_text b t; bs b"</li>\n")
361 method html_of_Newline b = bs b "\n<p>\n"
363 method html_of_Block b t =
364 bs b "<blockquote>\n";
365 self#html_of_text b t;
366 bs b "</blockquote>\n"
368 method html_of_Title b n label_opt t =
369 let label1 = self#create_title_label (n, label_opt, t) in
371 bs b (Naming.label_target label1);
375 (Printf.sprintf "div class=\"h%d\"" n, "div")
377 let t = Printf.sprintf "h%d" n in (t, t)
382 self#html_of_text b t;
387 method html_of_Latex b _ = ()
388 (* don't care about LaTeX stuff in HTML. *)
390 method html_of_Link b s t =
394 self#html_of_text b t;
397 method html_of_Ref b name ref_opt =
400 self#html_of_text_element b (Odoc_info.Code name)
402 let h name = Odoc_info.Code (Odoc_info.use_hidden_modules name) in
406 | Odoc_info.RK_module_type
408 | Odoc_info.RK_class_type ->
409 let (html_file, _) = Naming.html_files name in
411 | Odoc_info.RK_value -> (Naming.complete_target Naming.mark_value name, h name)
412 | Odoc_info.RK_type -> (Naming.complete_target Naming.mark_type name, h name)
413 | Odoc_info.RK_exception -> (Naming.complete_target Naming.mark_exception name, h name)
414 | Odoc_info.RK_attribute -> (Naming.complete_target Naming.mark_attribute name, h name)
415 | Odoc_info.RK_method -> (Naming.complete_target Naming.mark_method name, h name)
416 | Odoc_info.RK_section t -> (Naming.complete_label_target name,
417 Odoc_info.Italic [Raw (Odoc_info.string_of_text t)])
419 bs b ("<a href=\""^target^"\">");
420 self#html_of_text_element b text;
423 method html_of_Superscript b t =
424 bs b "<sup class=\"superscript\">";
425 self#html_of_text b t;
428 method html_of_Subscript b t =
429 bs b "<sub class=\"subscript\">";
430 self#html_of_text b t;
433 method virtual html_of_info_first_sentence : _
435 method html_of_Module_list b l =
436 bs b "<br>\n<table class=\"indextable\">\n";
443 List.find (fun m -> m.m_name = name) self#list_modules
445 let (html, _) = Naming.html_files m.m_name in
446 bp b "<a href=\"%s\">%s</a></td>" html m.m_name;
448 self#html_of_info_first_sentence b m.m_info;
451 Odoc_messages.pwarning (Odoc_messages.cross_module_not_found name);
452 bp b "%s</td><td>" name
459 method html_of_Index_list b =
460 let index_if_not_empty l url m =
463 | _ -> bp b "<a href=\"%s\">%s</a><br>\n" url m
465 index_if_not_empty self#list_types self#index_types Odoc_messages.index_of_types;
466 index_if_not_empty self#list_exceptions self#index_exceptions Odoc_messages.index_of_exceptions;
467 index_if_not_empty self#list_values self#index_values Odoc_messages.index_of_values;
468 index_if_not_empty self#list_attributes self#index_attributes Odoc_messages.index_of_attributes;
469 index_if_not_empty self#list_methods self#index_methods Odoc_messages.index_of_methods;
470 index_if_not_empty self#list_classes self#index_classes Odoc_messages.index_of_classes;
471 index_if_not_empty self#list_class_types self#index_class_types Odoc_messages.index_of_class_types;
472 index_if_not_empty self#list_modules self#index_modules Odoc_messages.index_of_modules;
473 index_if_not_empty self#list_module_types self#index_module_types Odoc_messages.index_of_module_types
475 method virtual list_types : Odoc_info.Type.t_type list
476 method virtual index_types : string
477 method virtual list_exceptions : Odoc_info.Exception.t_exception list
478 method virtual index_exceptions : string
479 method virtual list_values : Odoc_info.Value.t_value list
480 method virtual index_values : string
481 method virtual list_attributes : Odoc_info.Value.t_attribute list
482 method virtual index_attributes : string
483 method virtual list_methods : Odoc_info.Value.t_method list
484 method virtual index_methods : string
485 method virtual list_classes : Odoc_info.Class.t_class list
486 method virtual index_classes : string
487 method virtual list_class_types : Odoc_info.Class.t_class_type list
488 method virtual index_class_types : string
489 method virtual list_modules : Odoc_info.Module.t_module list
490 method virtual index_modules : string
491 method virtual list_module_types : Odoc_info.Module.t_module_type list
492 method virtual index_module_types : string
496 (** A class used to generate html code for info structures. *)
499 (** The list of pairs [(tag, f)] where [f] is a function taking
500 the [text] associated to [tag] and returning html code.
501 Add a pair here to handle a tag.*)
502 val mutable tag_functions = ([] : (string * (Odoc_info.text -> string)) list)
504 (** The method used to get html code from a [text]. *)
505 method virtual html_of_text : Buffer.t -> Odoc_info.text -> unit
507 (** Print html for an author list. *)
508 method html_of_author_list b l =
512 bp b "<b>%s:</b> %s<br>\n"
513 Odoc_messages.authors
514 (String.concat ", " l)
516 (** Print html code for the given optional version information.*)
517 method html_of_version_opt b v_opt =
521 bp b "<b>%s:</b> %s<br>\n" Odoc_messages.version v
523 (** Print html code for the given optional since information.*)
524 method html_of_since_opt b s_opt =
528 bp b "<b>%s</b> %s<br>\n" Odoc_messages.since s
530 (** Print html code for the given list of raised exceptions.*)
531 method html_of_raised_exceptions b l =
535 bp b "<b>%s</b> <code>%s</code> "
538 self#html_of_text b t;
541 bp b "<b>%s</b><ul>" Odoc_messages.raises;
544 bp b "<li><code>%s</code> " ex ;
545 self#html_of_text b desc;
551 (** Print html code for the given "see also" reference. *)
552 method html_of_see b (see_ref, t) =
555 Odoc_info.See_url s -> [ Odoc_info.Link (s, t) ]
556 | Odoc_info.See_file s -> (Odoc_info.Code s) :: (Odoc_info.Raw " ") :: t
557 | Odoc_info.See_doc s -> (Odoc_info.Italic [Odoc_info.Raw s]) :: (Odoc_info.Raw " ") :: t
559 self#html_of_text b t_ref
561 (** Print html code for the given list of "see also" references.*)
562 method html_of_sees b l =
566 bp b "<b>%s</b> " Odoc_messages.see_also;
567 self#html_of_see b see;
570 bp b "<b>%s</b><ul>" Odoc_messages.see_also;
574 self#html_of_see b see;
580 (** Print html code for the given optional return information.*)
581 method html_of_return_opt b return_opt =
582 match return_opt with
585 bp b "<b>%s</b> " Odoc_messages.returns;
586 self#html_of_text b s;
589 (** Print html code for the given list of custom tagged texts. *)
590 method html_of_custom b l =
594 let f = List.assoc tag tag_functions in
595 Buffer.add_string b (f text)
598 Odoc_info.warning (Odoc_messages.tag_not_handled tag)
602 (** Print html code for a description, except for the [i_params] field.
603 @param indent can be specified not to use the style of info comments;
606 method html_of_info ?(indent=true) b info_opt =
611 let module M = Odoc_info in
612 if indent then bs b "<div class=\"info\">\n";
614 match info.M.i_deprecated with
617 bs b "<span class=\"warning\">";
618 bs b Odoc_messages.deprecated ;
620 self#html_of_text b d;
624 match info.M.i_desc with
626 | Some d when d = [Odoc_info.Raw ""] -> ()
627 | Some d -> self#html_of_text b d; bs b "<br>\n"
629 self#html_of_author_list b info.M.i_authors;
630 self#html_of_version_opt b info.M.i_version;
631 self#html_of_since_opt b info.M.i_since;
632 self#html_of_raised_exceptions b info.M.i_raised_exceptions;
633 self#html_of_return_opt b info.M.i_return_value;
634 self#html_of_sees b info.M.i_sees;
635 self#html_of_custom b info.M.i_custom;
636 if indent then bs b "</div>\n"
638 (** Print html code for the first sentence of a description.
639 The titles and lists in this first sentence has been removed.*)
640 method html_of_info_first_sentence b info_opt =
644 let module M = Odoc_info in
645 let dep = info.M.i_deprecated <> None in
646 bs b "<div class=\"info\">\n";
647 if dep then bs b "<font color=\"#CCCCCC\">";
649 match info.M.i_desc with
651 | Some d when d = [Odoc_info.Raw ""] -> ()
654 (Odoc_info.text_no_title_no_list
655 (Odoc_info.first_sentence_of_text d));
658 if dep then bs b "</font>";
665 let opt = Odoc_info.apply_opt
667 let print_concat b sep f =
668 let rec iter = function
678 let newline_to_indented_br s =
679 let len = String.length s in
680 let b = Buffer.create len in
681 for i = 0 to len - 1 do
683 '\n' -> Buffer.add_string b "<br> "
684 | c -> Buffer.add_char b c
688 (** This class is used to create objects which can generate a simple html documentation. *)
694 val mutable doctype =
695 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
696 val mutable character_encoding =
697 "<meta content=\"text/html; charset=iso-8859-1\" http-equiv=\"Content-Type\">\n"
699 (** The default style options. *)
700 val mutable default_style_options =
701 ["a:visited {color : #416DFF; text-decoration : none; }" ;
702 "a:link {color : #416DFF; text-decoration : none;}" ;
703 "a:hover {color : Red; text-decoration : none; background-color: #5FFF88}" ;
704 "a:active {color : Red; text-decoration : underline; }" ;
705 ".keyword { font-weight : bold ; color : Red }" ;
706 ".keywordsign { color : #C04600 }" ;
707 ".superscript { font-size : 4 }" ;
708 ".subscript { font-size : 4 }" ;
709 ".comment { color : Green }" ;
710 ".constructor { color : Blue }" ;
711 ".type { color : #5C6585 }" ;
712 ".string { color : Maroon }" ;
713 ".warning { color : Red ; font-weight : bold }" ;
714 ".info { margin-left : 3em; margin-right : 3em }" ;
715 ".param_info { margin-top: 4px; margin-left : 3em; margin-right : 3em }" ;
716 ".code { color : #465F91 ; }" ;
717 "h1 { font-size : 20pt ; text-align: center; }" ;
719 "h2 { font-size : 20pt ; border: 1px solid #000000; "^
720 "margin-top: 5px; margin-bottom: 2px;"^
721 "text-align: center; background-color: #90BDFF ;"^
724 "h3 { font-size : 20pt ; border: 1px solid #000000; "^
725 "margin-top: 5px; margin-bottom: 2px;"^
726 "text-align: center; background-color: #90DDFF ;"^
729 "h4 { font-size : 20pt ; border: 1px solid #000000; "^
730 "margin-top: 5px; margin-bottom: 2px;"^
731 "text-align: center; background-color: #90EDFF ;"^
734 "h5 { font-size : 20pt ; border: 1px solid #000000; "^
735 "margin-top: 5px; margin-bottom: 2px;"^
736 "text-align: center; background-color: #90FDFF ;"^
739 "h6 { font-size : 20pt ; border: 1px solid #000000; "^
740 "margin-top: 5px; margin-bottom: 2px;"^
741 "text-align: center; background-color: #C0FFFF ; "^
744 "div.h7 { font-size : 20pt ; border: 1px solid #000000; "^
745 "margin-top: 5px; margin-bottom: 2px;"^
746 "text-align: center; background-color: #E0FFFF ; "^
749 "div.h8 { font-size : 20pt ; border: 1px solid #000000; "^
750 "margin-top: 5px; margin-bottom: 2px;"^
751 "text-align: center; background-color: #F0FFFF ; "^
754 "div.h9 { font-size : 20pt ; border: 1px solid #000000; "^
755 "margin-top: 5px; margin-bottom: 2px;"^
756 "text-align: center; background-color: #FFFFFF ; "^
759 ".typetable { border-style : hidden }" ;
760 ".indextable { border-style : hidden }" ;
761 ".paramstable { border-style : hidden ; padding: 5pt 5pt}" ;
762 "body { background-color : White }" ;
763 "tr { background-color : White }" ;
764 "td.typefieldcomment { background-color : #FFFFFF ; font-size: smaller ;}" ;
765 "pre { margin-bottom: 4px }" ;
767 "div.sig_block {margin-left: 2em}" ;
770 (** The style file for all pages. *)
771 val mutable style_file = "style.css"
773 (** The code to import the style. Initialized in [init_style]. *)
774 val mutable style = ""
776 (** The known types names.
777 Used to know if we must create a link to a type
778 when printing a type. *)
779 val mutable known_types_names = StringSet.empty
781 (** The known class and class type names.
782 Used to know if we must create a link to a class
783 or class type or not when printing a type. *)
784 val mutable known_classes_names = StringSet.empty
786 (** The known modules and module types names.
787 Used to know if we must create a link to a type or not
788 when printing a module type. *)
789 val mutable known_modules_names = StringSet.empty
791 method index_prefix =
792 if !Odoc_args.out_file = Odoc_messages.default_out_file then
795 Filename.basename !Odoc_args.out_file
797 (** The main file. *)
799 let p = self#index_prefix in
800 Printf.sprintf "%s.html" p
802 (** The file for the index of values. *)
803 method index_values = Printf.sprintf "%s_values.html" self#index_prefix
804 (** The file for the index of types. *)
805 method index_types = Printf.sprintf "%s_types.html" self#index_prefix
806 (** The file for the index of exceptions. *)
807 method index_exceptions = Printf.sprintf "%s_exceptions.html" self#index_prefix
808 (** The file for the index of attributes. *)
809 method index_attributes = Printf.sprintf "%s_attributes.html" self#index_prefix
810 (** The file for the index of methods. *)
811 method index_methods = Printf.sprintf "%s_methods.html" self#index_prefix
812 (** The file for the index of classes. *)
813 method index_classes = Printf.sprintf "%s_classes.html" self#index_prefix
814 (** The file for the index of class types. *)
815 method index_class_types = Printf.sprintf "%s_class_types.html" self#index_prefix
816 (** The file for the index of modules. *)
817 method index_modules = Printf.sprintf "%s_modules.html" self#index_prefix
818 (** The file for the index of module types. *)
819 method index_module_types = Printf.sprintf "%s_module_types.html" self#index_prefix
822 (** The list of attributes. Filled in the [generate] method. *)
823 val mutable list_attributes = []
824 method list_attributes = list_attributes
825 (** The list of methods. Filled in the [generate] method. *)
826 val mutable list_methods = []
827 method list_methods = list_methods
828 (** The list of values. Filled in the [generate] method. *)
829 val mutable list_values = []
830 method list_values = list_values
831 (** The list of exceptions. Filled in the [generate] method. *)
832 val mutable list_exceptions = []
833 method list_exceptions = list_exceptions
834 (** The list of types. Filled in the [generate] method. *)
835 val mutable list_types = []
836 method list_types = list_types
837 (** The list of modules. Filled in the [generate] method. *)
838 val mutable list_modules = []
839 method list_modules = list_modules
840 (** The list of module types. Filled in the [generate] method. *)
841 val mutable list_module_types = []
842 method list_module_types = list_module_types
843 (** The list of classes. Filled in the [generate] method. *)
844 val mutable list_classes = []
845 method list_classes = list_classes
846 (** The list of class types. Filled in the [generate] method. *)
847 val mutable list_class_types = []
848 method list_class_types = list_class_types
850 (** The header of pages. Must be prepared by the [prepare_header] method.*)
851 val mutable header = fun b -> fun ?(nav=None) -> fun ?(comments=[]) -> fun _ -> ()
853 (** Init the style. *)
855 (match !Args.css_style with
857 let default_style = String.concat "\n" default_style_options in
860 let file = Filename.concat !Args.target_dir style_file in
861 if Sys.file_exists file then
862 Odoc_info.verbose (Odoc_messages.file_exists_dont_generate file)
865 let chanout = open_out file in
866 output_string chanout default_style ;
869 Odoc_info.verbose (Odoc_messages.file_generated file)
874 incr Odoc_info.errors ;
879 style <- "<link rel=\"stylesheet\" href=\""^style_file^"\" type=\"text/css\">\n"
881 (** Get the title given by the user *)
882 method title = match !Args.title with None -> "" | Some t -> self#escape t
884 (** Get the title given by the user completed with the given subtitle. *)
885 method inner_title s =
886 (match self#title with "" -> "" | t -> t^" : ")^
889 (** Get the page header. *)
890 method print_header b ?nav ?comments title = header b ?nav ?comments title
892 (** A function to build the header of pages. *)
893 method prepare_header module_list =
894 let f b ?(nav=None) ?(comments=[]) t =
895 let link_if_not_empty l m url =
899 bp b "<link title=\"%s\" rel=Appendix href=\"%s\">\n" m url
903 bs b character_encoding ;
904 bs b "<link rel=\"Start\" href=\"";
910 | Some (pre_opt, post_opt, name) ->
914 bp b "<link rel=\"previous\" href=\"%s\">\n"
915 (fst (Naming.html_files name));
920 bp b "<link rel=\"next\" href=\"%s\">\n"
921 (fst (Naming.html_files name));
924 let father = Name.father name in
925 let href = if father = "" then self#index else fst (Naming.html_files father) in
926 bp b "<link rel=\"Up\" href=\"%s\">\n" href
929 link_if_not_empty self#list_types Odoc_messages.index_of_types self#index_types;
930 link_if_not_empty self#list_exceptions Odoc_messages.index_of_exceptions self#index_exceptions;
931 link_if_not_empty self#list_values Odoc_messages.index_of_values self#index_values;
932 link_if_not_empty self#list_attributes Odoc_messages.index_of_attributes self#index_attributes;
933 link_if_not_empty self#list_methods Odoc_messages.index_of_methods self#index_methods;
934 link_if_not_empty self#list_classes Odoc_messages.index_of_classes self#index_classes;
935 link_if_not_empty self#list_class_types Odoc_messages.index_of_class_types self#index_class_types;
936 link_if_not_empty self#list_modules Odoc_messages.index_of_modules self#index_modules;
937 link_if_not_empty self#list_module_types Odoc_messages.index_of_module_types self#index_module_types;
939 let html_file = fst (Naming.html_files m.m_name) in
940 bp b "<link title=\"%s\" rel=\"Chapter\" href=\"%s\">"
943 print_concat b "\n" print_one module_list;
944 self#html_sections_links b comments;
947 bs b "</title>\n</head>\n"
951 (** Build the html code for the link tags in the header, defining section and
952 subsections for the titles found in the given comments.*)
953 method html_sections_links b comments =
954 let titles = List.flatten (List.map Odoc_info.get_titles_in_text comments) in
966 let sorted_levels = List.sort compare levels in
967 let (section_level, subsection_level) =
968 match sorted_levels with
970 | [n] -> (Some n, None)
971 | n :: m :: _ -> (Some n, Some m)
973 let titles_per_level level_opt =
976 | Some n -> List.filter (fun (m,_,_) -> m = n) titles
978 let section_titles = titles_per_level section_level in
979 let subsection_titles = titles_per_level subsection_level in
980 let print_lines s_rel titles =
983 let s = Odoc_info.string_of_text t in
984 let label = self#create_title_label (n,lopt,t) in
985 bp b "<link title=\"%s\" rel=\"%s\" href=\"#%s\">\n" s s_rel label
989 print_lines "Section" section_titles ;
990 print_lines "Subsection" subsection_titles
993 (** Html code for navigation bar.
994 @param pre optional name for optional previous module/class
995 @param post optional name for optional next module/class
996 @param name name of current module/class *)
997 method print_navbar b pre post name =
998 bs b "<div class=\"navbar\">";
1003 bp b "<a href=\"%s\">%s</a>\n"
1004 (fst (Naming.html_files name))
1005 Odoc_messages.previous
1008 let father = Name.father name in
1009 let href = if father = "" then self#index else fst (Naming.html_files father) in
1010 bp b "<a href=\"%s\">%s</a>\n" href Odoc_messages.up;
1016 bp b "<a href=\"%s\">%s</a>\n"
1017 (fst (Naming.html_files name))
1022 (** Return html code with the given string in the keyword style.*)
1024 "<span class=\"keyword\">"^s^"</span>"
1026 (** Return html code with the given string in the constructor style. *)
1027 method constructor s = "<span class=\"constructor\">"^s^"</span>"
1029 (** Output the given ocaml code to the given file name. *)
1030 method private output_code in_title file code =
1032 let chanout = open_out file in
1033 let b = new_buf () in
1035 self#print_header b (self#inner_title in_title);
1037 self#html_of_code b code;
1038 bs b "</body></html>";
1039 Buffer.output_buffer chanout b;
1043 incr Odoc_info.errors ;
1046 (** Take a string and return the string where fully qualified
1047 type (or class or class type) idents
1048 have been replaced by links to the type referenced by the ident.*)
1049 method create_fully_qualified_idents_links m_name s =
1051 let match_s = Str.matched_string str_t in
1052 let rel = Name.get_relative m_name match_s in
1053 let s_final = Odoc_info.apply_if_equal
1054 Odoc_info.use_hidden_modules
1058 if StringSet.mem match_s known_types_names then
1059 "<a href=\""^(Naming.complete_target Naming.mark_type match_s)^"\">"^
1063 if StringSet.mem match_s known_classes_names then
1064 let (html_file, _) = Naming.html_files match_s in
1065 "<a href=\""^html_file^"\">"^s_final^"</a>"
1069 let s2 = Str.global_substitute
1070 (Str.regexp "\\([A-Z]\\([a-zA-Z_'0-9]\\)*\\.\\)+\\([a-z][a-zA-Z_'0-9]*\\)")
1076 (** Take a string and return the string where fully qualified module idents
1077 have been replaced by links to the module referenced by the ident.*)
1078 method create_fully_qualified_module_idents_links m_name s =
1080 let match_s = Str.matched_string str_t in
1081 let rel = Name.get_relative m_name match_s in
1082 let s_final = Odoc_info.apply_if_equal
1083 Odoc_info.use_hidden_modules
1087 if StringSet.mem match_s known_modules_names then
1088 let (html_file, _) = Naming.html_files match_s in
1089 "<a href=\""^html_file^"\">"^s_final^"</a>"
1093 let s2 = Str.global_substitute
1094 (Str.regexp "\\([A-Z]\\([a-zA-Z_'0-9]\\)*\\.\\)+\\([A-Z][a-zA-Z_'0-9]*\\)")
1100 (** Print html code to display a [Types.type_expr]. *)
1101 method html_of_type_expr b m_name t =
1102 let s = Odoc_info.remove_ending_newline (Odoc_info.string_of_type_expr t) in
1103 let s2 = newline_to_indented_br s in
1104 bs b "<code class=\"type\">";
1105 bs b (self#create_fully_qualified_idents_links m_name s2);
1108 (** Print html code to display a [Types.type_expr list]. *)
1109 method html_of_type_expr_list ?par b m_name sep l =
1110 print_DEBUG "html#html_of_type_expr_list";
1111 let s = Odoc_info.string_of_type_list ?par sep l in
1112 print_DEBUG "html#html_of_type_expr_list: 1";
1113 let s2 = newline_to_indented_br s in
1114 print_DEBUG "html#html_of_type_expr_list: 2";
1115 bs b "<code class=\"type\">";
1116 bs b (self#create_fully_qualified_idents_links m_name s2);
1119 (** Print html code to display a [Types.type_expr list] as type parameters
1120 of a class of class type. *)
1121 method html_of_class_type_param_expr_list b m_name l =
1122 let s = Odoc_info.string_of_class_type_param_list l in
1123 let s2 = newline_to_indented_br s in
1124 bs b "<code class=\"type\">[";
1125 bs b (self#create_fully_qualified_idents_links m_name s2);
1128 method html_of_class_parameter_list b father c =
1129 let s = Odoc_info.string_of_class_params c in
1130 let s = Odoc_info.remove_ending_newline s in
1131 let s2 = newline_to_indented_br s in
1132 bs b "<code class=\"type\">";
1133 bs b (self#create_fully_qualified_idents_links father s2);
1136 (** Print html code to display a list of type parameters for the given type.*)
1137 method html_of_type_expr_param_list b m_name t =
1138 let s = Odoc_info.string_of_type_param_list t in
1139 let s2 = newline_to_indented_br s in
1140 bs b "<code class=\"type\">";
1141 bs b (self#create_fully_qualified_idents_links m_name s2);
1144 (** Print html code to display a [Types.module_type]. *)
1145 method html_of_module_type b ?code m_name t =
1146 let s = Odoc_info.remove_ending_newline (Odoc_info.string_of_module_type ?code t) in
1147 bs b "<code class=\"type\">";
1148 bs b (self#create_fully_qualified_module_idents_links m_name s);
1151 (** Print html code to display the given module kind. *)
1152 method html_of_module_kind b father ?modu kind =
1154 Module_struct eles ->
1155 self#html_of_text b [Code "sig"];
1159 bs b "<div class=\"sig_block\">";
1160 List.iter (self#html_of_module_element b father) eles;
1163 let (html_file, _) = Naming.html_files m.m_name in
1164 bp b " <a href=\"%s\">..</a> " html_file
1166 self#html_of_text b [Code "end"]
1168 bs b "<code class=\"type\">";
1169 bs b (self#create_fully_qualified_module_idents_links father a.ma_name);
1171 | Module_functor (p, k) ->
1172 if !Odoc_info.Args.html_short_functors then
1175 bs b "<div class=\"sig_block\">";
1176 self#html_of_module_parameter b father p;
1179 Module_functor _ -> ()
1180 | _ when !Odoc_info.Args.html_short_functors ->
1184 self#html_of_module_kind b father ?modu k;
1185 if not !Odoc_info.Args.html_short_functors then
1187 | Module_apply (k1, k2) ->
1188 (* TODO: l'application n'est pas correcte dans un .mli.
1189 Que faire ? -> afficher le module_type du typedtree *)
1190 self#html_of_module_kind b father k1;
1191 self#html_of_text b [Code "("];
1192 self#html_of_module_kind b father k2;
1193 self#html_of_text b [Code ")"]
1194 | Module_with (k, s) ->
1195 (* TODO: à modifier quand Module_with sera plus détaillé *)
1196 self#html_of_module_type_kind b father ?modu k;
1197 bs b "<code class=\"type\"> ";
1198 bs b (self#create_fully_qualified_module_idents_links father s);
1200 | Module_constraint (k, tk) ->
1201 (* TODO: on affiche quoi ? *)
1202 self#html_of_module_kind b father ?modu k
1204 method html_of_module_parameter b father p =
1205 let (s_functor,s_arrow) =
1206 if !Odoc_info.Args.html_short_functors then
1213 Code (s_functor^"(");
1217 self#html_of_module_type_kind b father p.mp_kind;
1218 self#html_of_text b [ Code (") "^s_arrow)]
1220 method html_of_module_element b father ele =
1223 self#html_of_module b ~complete: false m
1224 | Element_module_type mt ->
1225 self#html_of_modtype b ~complete: false mt
1226 | Element_included_module im ->
1227 self#html_of_included_module b im
1228 | Element_class c ->
1229 self#html_of_class b ~complete: false c
1230 | Element_class_type ct ->
1231 self#html_of_class_type b ~complete: false ct
1232 | Element_value v ->
1233 self#html_of_value b v
1234 | Element_exception e ->
1235 self#html_of_exception b e
1237 self#html_of_type b t
1238 | Element_module_comment text ->
1239 self#html_of_module_comment b text
1241 (** Print html code to display the given module type kind. *)
1242 method html_of_module_type_kind b father ?modu ?mt kind =
1244 Module_type_struct eles ->
1245 self#html_of_text b [Code "sig"];
1252 bs b "<div class=\"sig_block\">";
1253 List.iter (self#html_of_module_element b father) eles;
1256 let (html_file, _) = Naming.html_files m.m_name in
1257 bp b " <a href=\"%s\">..</a> " html_file
1260 let (html_file, _) = Naming.html_files mt.mt_name in
1261 bp b " <a href=\"%s\">..</a> " html_file
1263 self#html_of_text b [Code "end"]
1264 | Module_type_functor (p, k) ->
1265 self#html_of_module_parameter b father p;
1266 self#html_of_module_type_kind b father ?modu ?mt k
1267 | Module_type_alias a ->
1268 bs b "<code class=\"type\">";
1269 bs b (self#create_fully_qualified_module_idents_links father a.mta_name);
1271 | Module_type_with (k, s) ->
1272 self#html_of_module_type_kind b father ?modu ?mt k;
1273 bs b "<code class=\"type\"> ";
1274 bs b (self#create_fully_qualified_module_idents_links father s);
1277 (** Print html code to display the type of a module parameter.. *)
1278 method html_of_module_parameter_type b m_name p =
1279 self#html_of_module_type b m_name ~code: p.mp_type_code p.mp_type
1281 (** Generate a file containing the module type in the given file name. *)
1282 method output_module_type in_title file mtyp =
1283 let s = Odoc_info.remove_ending_newline (Odoc_info.string_of_module_type ~complete: true mtyp) in
1284 self#output_code in_title file s
1286 (** Generate a file containing the class type in the given file name. *)
1287 method output_class_type in_title file ctyp =
1288 let s = Odoc_info.remove_ending_newline (Odoc_info.string_of_class_type ~complete: true ctyp) in
1289 self#output_code in_title file s
1291 (** Print html code for a value. *)
1292 method html_of_value b v =
1293 Odoc_info.reset_type_names ();
1295 bs b (self#keyword "val");
1298 bp b "<a name=\"%s\"></a>" (Naming.value_target v);
1300 match v.val_code with
1301 None -> bs b (self#escape (Name.simple v.val_name))
1303 let file = Naming.file_code_value_complete_target v in
1304 self#output_code v.val_name (Filename.concat !Args.target_dir file) c;
1305 bp b "<a href=\"%s\">%s</a>" file (self#escape (Name.simple v.val_name))
1308 self#html_of_type_expr b (Name.father v.val_name) v.val_type;
1310 self#html_of_info b v.val_info;
1312 if !Args.with_parameter_list then
1313 self#html_of_parameter_list b (Name.father v.val_name) v.val_parameters
1315 self#html_of_described_parameter_list b (Name.father v.val_name) v.val_parameters
1318 (** Print html code for an exception. *)
1319 method html_of_exception b e =
1320 Odoc_info.reset_type_names ();
1322 bs b (self#keyword "exception");
1325 bp b "<a name=\"%s\"></a>%s"
1326 (Naming.exception_target e)
1327 (Name.simple e.ex_name);
1329 match e.ex_args with
1332 bs b (" "^(self#keyword "of")^" ");
1333 self#html_of_type_expr_list
1334 ~par: false b (Name.father e.ex_name) " * " e.ex_args
1337 match e.ex_alias with
1343 None -> bs b ea.ea_name
1345 bp b "<a href=\"%s\">%s</a>" (Naming.complete_exception_target e) e.ex_name
1349 self#html_of_info b e.ex_info
1351 (** Print html code for a type. *)
1352 method html_of_type b t =
1353 Odoc_info.reset_type_names ();
1354 let father = Name.father t.ty_name in
1356 (match t.ty_manifest, t.ty_kind with
1357 None, Type_abstract -> "<pre>"
1358 | None, Type_variant _
1359 | None, Type_record _ -> "<br><code>"
1360 | Some _, Type_abstract -> "<pre>"
1361 | Some _, Type_variant _
1362 | Some _, Type_record _ -> "<pre>"
1364 bs b ((self#keyword "type")^" ");
1366 bp b "<a name=\"%s\"></a>" (Naming.type_target t);
1367 self#html_of_type_expr_param_list b father t;
1368 (match t.ty_parameters with [] -> () | _ -> bs b " ");
1369 bs b ((Name.simple t.ty_name)^" ");
1370 let priv = t.ty_private = Asttypes.Private in
1372 match t.ty_manifest with
1376 if priv then bs b "private ";
1377 self#html_of_type_expr b father typ;
1380 (match t.ty_kind with
1381 Type_abstract -> bs b "</pre>"
1384 if priv then bs b "private ";
1387 match t.ty_manifest with
1389 | Some _ -> "</pre>"
1391 bs b "<table class=\"typetable\">\n";
1392 let print_one constr =
1393 bs b "<tr>\n<td align=\"left\" valign=\"top\" >\n";
1395 bs b (self#keyword "|");
1396 bs b "</code></td>\n<td align=\"left\" valign=\"top\" >\n";
1398 bs b (self#constructor constr.vc_name);
1400 match constr.vc_args with
1403 bs b (" " ^ (self#keyword "of") ^ " ");
1404 self#html_of_type_expr_list ~par: false b father " * " l;
1406 bs b "</code></td>\n";
1408 match constr.vc_text with
1411 bs b "<td class=\"typefieldcomment\" align=\"left\" valign=\"top\" >";
1414 bs b "</code></td>";
1415 bs b "<td class=\"typefieldcomment\" align=\"left\" valign=\"top\" >";
1416 self#html_of_text b t;
1418 bs b "<td class=\"typefieldcomment\" align=\"left\" valign=\"bottom\" >";
1421 bs b "</code></td>";
1425 print_concat b "\n" print_one l;
1430 if priv then bs b "private " ;
1434 match t.ty_manifest with
1436 | Some _ -> "</pre>"
1438 bs b "<table class=\"typetable\">\n" ;
1440 bs b "<tr>\n<td align=\"left\" valign=\"top\" >\n";
1441 bs b "<code> </code>";
1442 bs b "</td>\n<td align=\"left\" valign=\"top\" >\n";
1444 if r.rf_mutable then bs b (self#keyword "mutable ") ;
1445 bs b (r.rf_name ^ " : ") ;
1446 self#html_of_type_expr b father r.rf_type;
1447 bs b ";</code></td>\n";
1449 match r.rf_text with
1452 bs b "<td class=\"typefieldcomment\" align=\"left\" valign=\"top\" >";
1455 bs b "</code></td>";
1456 bs b "<td class=\"typefieldcomment\" align=\"left\" valign=\"top\" >";
1457 self#html_of_text b t;
1458 bs b "</td><td class=\"typefieldcomment\" align=\"left\" valign=\"bottom\" >";
1459 bs b "<code>*)</code></td>";
1463 print_concat b "\n" print_one l;
1464 bs b "</table>\n}\n"
1467 self#html_of_info b t.ty_info;
1470 (** Print html code for a class attribute. *)
1471 method html_of_attribute b a =
1472 let module_name = Name.father (Name.father a.att_value.val_name) in
1474 bs b (self#keyword "val");
1477 bp b "<a name=\"%s\"></a>" (Naming.attribute_target a);
1479 if a.att_virtual then
1480 bs b ((self#keyword "virtual")^ " ")
1485 if a.att_mutable then
1486 bs b ((self#keyword Odoc_messages.mutab)^ " ")
1490 match a.att_value.val_code with
1491 None -> bs b (Name.simple a.att_value.val_name)
1493 let file = Naming.file_code_attribute_complete_target a in
1494 self#output_code a.att_value.val_name (Filename.concat !Args.target_dir file) c;
1495 bp b "<a href=\"%s\">%s</a>" file (Name.simple a.att_value.val_name);
1498 self#html_of_type_expr b module_name a.att_value.val_type;
1500 self#html_of_info b a.att_value.val_info
1502 (** Print html code for a class method. *)
1503 method html_of_method b m =
1504 let module_name = Name.father (Name.father m.met_value.val_name) in
1506 bs b ((self#keyword "method")^" ");
1508 bp b "<a name=\"%s\"></a>" (Naming.method_target m);
1509 if m.met_private then bs b ((self#keyword "private")^" ");
1510 if m.met_virtual then bs b ((self#keyword "virtual")^" ");
1512 match m.met_value.val_code with
1513 None -> bs b (Name.simple m.met_value.val_name)
1515 let file = Naming.file_code_method_complete_target m in
1516 self#output_code m.met_value.val_name (Filename.concat !Args.target_dir file) c;
1517 bp b "<a href=\"%s\">%s</a>" file (Name.simple m.met_value.val_name);
1520 self#html_of_type_expr b module_name m.met_value.val_type;
1522 self#html_of_info b m.met_value.val_info;
1524 if !Args.with_parameter_list then
1525 self#html_of_parameter_list b
1526 module_name m.met_value.val_parameters
1528 self#html_of_described_parameter_list b
1529 module_name m.met_value.val_parameters
1532 (** Print html code for the description of a function parameter. *)
1533 method html_of_parameter_description b p =
1534 match Parameter.names p with
1539 (* Only one name, no need for label for the description. *)
1540 match Parameter.desc_by_name p name with
1542 | Some t -> self#html_of_text b t
1545 (* A list of names, we display those with a description. *)
1546 let l2 = List.filter
1547 (fun n -> (Parameter.desc_by_name p n) <> None)
1551 match Parameter.desc_by_name p n with
1557 self#html_of_text b t
1559 print_concat b "<br>\n" print_one l2
1561 (** Print html code for a list of parameters. *)
1562 method html_of_parameter_list b m_name l =
1566 bs b "<div class=\"param_info\">";
1567 bs b "<table border=\"0\" cellpadding=\"3\" width=\"100%\">\n";
1568 bs b "<tr>\n<td align=\"left\" valign=\"top\" width=\"1%\">";
1570 bs b Odoc_messages.parameters;
1571 bs b ": </b></td>\n" ;
1572 bs b "<td>\n<table class=\"paramstable\">\n";
1574 bs b "<tr>\n<td align=\"center\" valign=\"top\" width=\"15%\" class=\"code\">\n";
1577 match Parameter.complete_name p with
1581 bs b "</td>\n<td align=\"center\" valign=\"top\">:</td>\n";
1583 self#html_of_type_expr b m_name (Parameter.typ p);
1585 self#html_of_parameter_description b p;
1588 List.iter print_one l;
1589 bs b "</table>\n</td>\n</tr>\n</table></div>\n"
1591 (** Print html code for the parameters which have a name and description. *)
1592 method html_of_described_parameter_list b m_name l =
1593 (* get the params which have a name, and at least one name described. *)
1594 let l2 = List.filter
1597 (fun n -> (Parameter.desc_by_name p n) <> None)
1598 (Parameter.names p))
1602 bs b "<div class=\"param_info\"><code class=\"code\">";
1603 bs b (Parameter.complete_name p);
1605 self#html_of_parameter_description b p;
1610 (** Print html code for a list of module parameters. *)
1611 method html_of_module_parameter_list b m_name l =
1616 bs b "<table border=\"0\" cellpadding=\"3\" width=\"100%\">\n";
1618 bs b "<td align=\"left\" valign=\"top\" width=\"1%%\"><b>";
1619 bs b Odoc_messages.parameters ;
1620 bs b ": </b></td>\n<td>\n";
1621 bs b "<table class=\"paramstable\">\n";
1623 (fun (p, desc_opt) ->
1625 bs b "<td align=\"center\" valign=\"top\" width=\"15%\">\n<code>" ;
1627 bs b "</code></td>\n" ;
1628 bs b "<td align=\"center\" valign=\"top\">:</td>\n";
1630 self#html_of_module_parameter_type b m_name p;
1637 self#html_of_text b t;
1642 bs b "</table>\n</td>\n</tr>\n</table>\n"
1644 (** Print html code for a module. *)
1645 method html_of_module b ?(info=true) ?(complete=true) ?(with_link=true) m =
1646 let (html_file, _) = Naming.html_files m.m_name in
1647 let father = Name.father m.m_name in
1649 bs b ((self#keyword "module")^" ");
1652 bp b "<a href=\"%s\">%s</a>" html_file (Name.simple m.m_name)
1654 bs b (Name.simple m.m_name)
1658 Module_functor _ when !Odoc_info.Args.html_short_functors ->
1662 self#html_of_module_kind b father ~modu: m m.m_kind;
1667 self#html_of_info ~indent: false
1669 self#html_of_info_first_sentence
1674 (** Print html code for a module type. *)
1675 method html_of_modtype b ?(info=true) ?(complete=true) ?(with_link=true) mt =
1676 let (html_file, _) = Naming.html_files mt.mt_name in
1677 let father = Name.father mt.mt_name in
1679 bs b ((self#keyword "module type")^" ");
1682 bp b "<a href=\"%s\">%s</a>" html_file (Name.simple mt.mt_name)
1684 bs b (Name.simple mt.mt_name)
1686 (match mt.mt_kind with
1690 self#html_of_module_type_kind b father ~mt k
1696 self#html_of_info ~indent: false
1698 self#html_of_info_first_sentence
1703 (** Print html code for an included module. *)
1704 method html_of_included_module b im =
1706 bs b ((self#keyword "include")^" ");
1708 match im.im_module with
1715 let (html_file, _) = Naming.html_files m.m_name in
1716 (html_file, m.m_name)
1718 let (html_file, _) = Naming.html_files mt.mt_name in
1719 (html_file, mt.mt_name)
1721 bp b "<a href=\"%s\">%s</a>" file name
1724 self#html_of_info b im.im_info
1726 method html_of_class_element b element =
1728 Class_attribute a ->
1729 self#html_of_attribute b a
1731 self#html_of_method b m
1732 | Class_comment t ->
1733 self#html_of_class_comment b t
1735 method html_of_class_kind b father ?cl kind =
1737 Class_structure (inh, eles) ->
1738 self#html_of_text b [Code "object"];
1747 self#generate_inheritance_info b inh
1749 List.iter (self#html_of_class_element b) eles;
1751 let (html_file, _) = Naming.html_files cl.cl_name in
1752 bp b " <a href=\"%s\">..</a> " html_file
1754 self#html_of_text b [Code "end"]
1756 | Class_apply capp ->
1757 (* TODO: afficher le type final à partir du typedtree *)
1758 self#html_of_text b [Raw "class application not handled yet"]
1760 | Class_constr cco ->
1762 match cco.cco_type_parameters with
1765 self#html_of_class_type_param_expr_list b father l;
1768 bs b "<code class=\"type\">";
1769 bs b (self#create_fully_qualified_idents_links father cco.cco_name);
1772 | Class_constraint (ck, ctk) ->
1773 self#html_of_text b [Code "( "] ;
1774 self#html_of_class_kind b father ck;
1775 self#html_of_text b [Code " : "] ;
1776 self#html_of_class_type_kind b father ctk;
1777 self#html_of_text b [Code " )"]
1779 method html_of_class_type_kind b father ?ct kind =
1783 match cta.cta_type_parameters with
1786 self#html_of_class_type_param_expr_list b father l;
1789 bs b "<code class=\"type\">";
1790 bs b (self#create_fully_qualified_idents_links father cta.cta_name);
1793 | Class_signature (inh, eles) ->
1794 self#html_of_text b [Code "object"];
1802 | _ -> self#generate_inheritance_info b inh
1804 List.iter (self#html_of_class_element b) eles
1806 let (html_file, _) = Naming.html_files ct.clt_name in
1807 bp b " <a href=\"%s\">..</a> " html_file
1809 self#html_of_text b [Code "end"]
1811 (** Print html code for a class. *)
1812 method html_of_class b ?(complete=true) ?(with_link=true) c =
1813 let father = Name.father c.cl_name in
1814 Odoc_info.reset_type_names ();
1815 let (html_file, _) = Naming.html_files c.cl_name in
1817 bs b ((self#keyword "class")^" ");
1818 (* we add a html tag, the same as for a type so we can
1819 go directly here when the class name is used as a type name *)
1820 bp b "<a name=\"%s\"></a>"
1822 { ty_name = c.cl_name ;
1823 ty_info = None ; ty_parameters = [] ;
1824 ty_kind = Type_abstract ; ty_private = Asttypes.Public; ty_manifest = None ;
1825 ty_loc = Odoc_info.dummy_loc ;
1829 print_DEBUG "html#html_of_class : virtual or not" ;
1830 if c.cl_virtual then bs b ((self#keyword "virtual")^" ");
1832 match c.cl_type_parameters with
1835 self#html_of_class_type_param_expr_list b father l;
1838 print_DEBUG "html#html_of_class : with link or not" ;
1841 bp b "<a href=\"%s\">%s</a>" html_file (Name.simple c.cl_name)
1843 bs b (Name.simple c.cl_name)
1847 self#html_of_class_parameter_list b father c ;
1848 self#html_of_class_kind b father ~cl: c c.cl_kind;
1850 print_DEBUG "html#html_of_class : info" ;
1853 self#html_of_info ~indent: false
1855 self#html_of_info_first_sentence
1858 (** Print html code for a class type. *)
1859 method html_of_class_type b ?(complete=true) ?(with_link=true) ct =
1860 Odoc_info.reset_type_names ();
1861 let father = Name.father ct.clt_name in
1862 let (html_file, _) = Naming.html_files ct.clt_name in
1864 bs b ((self#keyword "class type")^" ");
1865 (* we add a html tag, the same as for a type so we can
1866 go directly here when the class type name is used as a type name *)
1867 bp b "<a name=\"%s\"></a>"
1869 { ty_name = ct.clt_name ;
1870 ty_info = None ; ty_parameters = [] ;
1871 ty_kind = Type_abstract ; ty_private = Asttypes.Public; ty_manifest = None ;
1872 ty_loc = Odoc_info.dummy_loc ;
1876 if ct.clt_virtual then bs b ((self#keyword "virtual")^" ");
1878 match ct.clt_type_parameters with
1881 self#html_of_class_type_param_expr_list b father l;
1886 bp b "<a href=\"%s\">%s</a>" html_file (Name.simple ct.clt_name)
1888 bs b (Name.simple ct.clt_name);
1891 self#html_of_class_type_kind b father ~ct ct.clt_kind;
1895 self#html_of_info ~indent: false
1897 self#html_of_info_first_sentence
1900 (** Return html code to represent a dag, represented as in Odoc_dag2html. *)
1901 method html_of_dag dag =
1903 let (name, cct_opt) = n.Odoc_dag2html.valu in
1904 (* if we have a c_opt = Some class then we take its information
1905 because we are sure the name is complete. *)
1906 let (name2, html_file) =
1908 None -> (name, fst (Naming.html_files name))
1909 | Some (Cl c) -> (c.cl_name, fst (Naming.html_files c.cl_name))
1910 | Some (Cltype (ct, _)) -> (ct.clt_name, fst (Naming.html_files ct.clt_name))
1913 "<table border=1>\n<tr><td>"^
1914 "<a href=\""^html_file^"\">"^name2^"</a>"^
1915 "</td></tr>\n</table>\n"
1917 { n with Odoc_dag2html.valu = new_v }
1919 let a = Array.map f dag.Odoc_dag2html.dag in
1920 Odoc_dag2html.html_of_dag { Odoc_dag2html.dag = a }
1922 (** Print html code for a module comment.*)
1923 method html_of_module_comment b text =
1925 self#html_of_text b text;
1928 (** Print html code for a class comment.*)
1929 method html_of_class_comment b text =
1930 (* Add some style if there is no style for the first part of the text. *)
1933 | (Odoc_info.Raw s) :: q ->
1934 (Odoc_info.Title (2, None, [Odoc_info.Raw s])) :: q
1937 self#html_of_text b text2
1939 (** Generate html code for the given list of inherited classes.*)
1940 method generate_inheritance_info b inher_l =
1942 match inh.ic_class with
1943 None -> (* we can't make the link. *)
1944 (Odoc_info.Code inh.ic_name) ::
1945 (match inh.ic_text with
1947 | Some t -> (Odoc_info.Raw " ") :: t)
1949 (* we can create the link. *)
1950 let real_name = (* even if it should be the same *)
1953 | Cltype (ct, _) -> ct.clt_name
1955 let (class_file, _) = Naming.html_files real_name in
1956 (Odoc_info.Link (class_file, [Odoc_info.Code real_name])) ::
1957 (match inh.ic_text with
1959 | Some t -> (Odoc_info.Raw " ") :: t)
1962 Odoc_info.Bold [Odoc_info.Raw Odoc_messages.inherits] ;
1963 Odoc_info.List (List.map f inher_l)
1966 self#html_of_text b text
1968 (** Generate html code for the inherited classes of the given class. *)
1969 method generate_class_inheritance_info b cl =
1970 let rec iter_kind k =
1972 Class_structure ([], _) ->
1974 | Class_structure (l, _) ->
1975 self#generate_inheritance_info b l
1976 | Class_constraint (k, ct) ->
1982 iter_kind cl.cl_kind
1984 (** Generate html code for the inherited classes of the given class type. *)
1985 method generate_class_type_inheritance_info b clt =
1986 match clt.clt_kind with
1987 Class_signature ([], _) ->
1989 | Class_signature (l, _) ->
1990 self#generate_inheritance_info b l
1994 (** A method to create index files. *)
1995 method generate_elements_index :
1998 ('a -> Odoc_info.Name.t) ->
1999 ('a -> Odoc_info.info option) ->
2000 ('a -> string) -> string -> string -> unit =
2001 fun elements name info target title simple_file ->
2003 let chanout = open_out (Filename.concat !Args.target_dir simple_file) in
2004 let b = new_buf () in
2006 self#print_header b (self#inner_title title);
2007 bs b "<body>\n<center><h1>";
2009 bs b "</h1></center>\n" ;
2011 let sorted_elements = List.sort
2012 (fun e1 e2 -> compare (Name.simple (name e1)) (Name.simple (name e2)))
2015 let groups = Odoc_info.create_index_lists sorted_elements (fun e -> Name.simple (name e)) in
2017 let simple_name = Name.simple (name e) in
2018 let father_name = Name.father (name e) in
2019 bp b "<tr><td><a href=\"%s\">%s</a> " (target e) (self#escape simple_name);
2020 if simple_name <> father_name && father_name <> "" then
2021 bp b "[<a href=\"%s\">%s</a>]" (fst (Naming.html_files father_name)) father_name;
2023 self#html_of_info_first_sentence b (info e);
2024 bs b "</td></tr>\n";
2031 match (Char.uppercase (Name.simple (name e)).[0]) with
2032 'A'..'Z' as c -> String.make 1 c
2035 bs b "<tr><td align=\"left\"><br>";
2037 bs b "</td></tr>\n" ;
2041 List.iter f_group groups ;
2042 bs b "</table><br>\n" ;
2043 bs b "</body>\n</html>";
2044 Buffer.output_buffer chanout b;
2050 (** A method to generate a list of module/class files. *)
2051 method generate_elements :
2052 'a. ('a option -> 'a option -> 'a -> unit) -> 'a list -> unit =
2054 let rec iter pre_opt = function
2056 | ele :: [] -> f_generate pre_opt None ele
2057 | ele1 :: ele2 :: q ->
2058 f_generate pre_opt (Some ele2) ele1 ;
2059 iter (Some ele1) (ele2 :: q)
2063 (** Generate the code of the html page for the given class.*)
2064 method generate_for_class pre post cl =
2065 Odoc_info.reset_type_names ();
2066 let (html_file, _) = Naming.html_files cl.cl_name in
2067 let type_file = Naming.file_type_class_complete_target cl.cl_name in
2069 let chanout = open_out (Filename.concat !Args.target_dir html_file) in
2070 let b = new_buf () in
2071 let pre_name = opt (fun c -> c.cl_name) pre in
2072 let post_name = opt (fun c -> c.cl_name) post in
2076 ~nav: (Some (pre_name, post_name, cl.cl_name))
2077 ~comments: (Class.class_comments cl)
2078 (self#inner_title cl.cl_name);
2080 self#print_navbar b pre_name post_name cl.cl_name;
2081 bs b "<center><h1>";
2082 bs b (Odoc_messages.clas^" ");
2083 if cl.cl_virtual then bs b "virtual " ;
2084 bp b "<a href=\"%s\">%s</a>" type_file cl.cl_name;
2085 bs b "</h1></center>\n<br>\n";
2086 self#html_of_class b ~with_link: false cl;
2088 self#html_of_described_parameter_list b
2089 (Name.father cl.cl_name) cl.cl_parameters;
2090 (* class inheritance *)
2091 self#generate_class_inheritance_info b cl;
2092 (* a horizontal line *)
2093 bs b "<hr width=\"100%\">\n";
2094 (* the various elements *)
2095 List.iter (self#html_of_class_element b)
2096 (Class.class_elements ~trans:false cl);
2097 bs b "</body></html>";
2098 Buffer.output_buffer chanout b;
2101 (* generate the file with the complete class type *)
2102 self#output_class_type
2104 (Filename.concat !Args.target_dir type_file)
2110 (** Generate the code of the html page for the given class type.*)
2111 method generate_for_class_type pre post clt =
2112 Odoc_info.reset_type_names ();
2113 let (html_file, _) = Naming.html_files clt.clt_name in
2114 let type_file = Naming.file_type_class_complete_target clt.clt_name in
2116 let chanout = open_out (Filename.concat !Args.target_dir html_file) in
2117 let b = new_buf () in
2118 let pre_name = opt (fun ct -> ct.clt_name) pre in
2119 let post_name = opt (fun ct -> ct.clt_name) post in
2123 ~nav: (Some (pre_name, post_name, clt.clt_name))
2124 ~comments: (Class.class_type_comments clt)
2125 (self#inner_title clt.clt_name);
2128 self#print_navbar b pre_name post_name clt.clt_name;
2129 bs b "<center><h1>";
2130 bs b (Odoc_messages.class_type^" ");
2131 if clt.clt_virtual then bs b "virtual ";
2132 bp b "<a href=\"%s\">%s</a>" type_file clt.clt_name;
2133 bs b "</h1></center>\n<br>\n";
2134 self#html_of_class_type b ~with_link: false clt;
2136 (* class inheritance *)
2137 self#generate_class_type_inheritance_info b clt;
2138 (* a horizontal line *)
2139 bs b "<hr width=\"100%\">\n";
2140 (* the various elements *)
2141 List.iter (self#html_of_class_element b)
2142 (Class.class_type_elements ~trans: false clt);
2143 bs b "</body></html>";
2144 Buffer.output_buffer chanout b;
2147 (* generate the file with the complete class type *)
2148 self#output_class_type
2150 (Filename.concat !Args.target_dir type_file)
2156 (** Generate the html file for the given module type.
2157 @raise Failure if an error occurs.*)
2158 method generate_for_module_type pre post mt =
2160 let (html_file, _) = Naming.html_files mt.mt_name in
2161 let type_file = Naming.file_type_module_complete_target mt.mt_name in
2162 let chanout = open_out (Filename.concat !Args.target_dir html_file) in
2163 let b = new_buf () in
2164 let pre_name = opt (fun mt -> mt.mt_name) pre in
2165 let post_name = opt (fun mt -> mt.mt_name) post in
2169 ~nav: (Some (pre_name, post_name, mt.mt_name))
2170 ~comments: (Module.module_type_comments mt)
2171 (self#inner_title mt.mt_name);
2173 self#print_navbar b pre_name post_name mt.mt_name;
2174 bp b "<center><h1>";
2175 bs b (Odoc_messages.module_type^" ");
2177 match mt.mt_type with
2178 Some _ -> bp b "<a href=\"%s\">%s</a>" type_file mt.mt_name
2179 | None-> bs b mt.mt_name
2181 bs b "</h1></center>\n<br>\n" ;
2182 self#html_of_modtype b ~with_link: false mt;
2184 (* parameters for functors *)
2185 self#html_of_module_parameter_list b
2186 (Name.father mt.mt_name)
2187 (Module.module_type_parameters mt);
2188 (* a horizontal line *)
2189 bs b "<hr width=\"100%\">\n";
2190 (* module elements *)
2192 (self#html_of_module_element b (Name.father mt.mt_name))
2193 (Module.module_type_elements mt);
2195 bs b "</body></html>";
2196 Buffer.output_buffer chanout b;
2199 (* generate html files for submodules *)
2200 self#generate_elements self#generate_for_module (Module.module_type_modules mt);
2201 (* generate html files for module types *)
2202 self#generate_elements self#generate_for_module_type (Module.module_type_module_types mt);
2203 (* generate html files for classes *)
2204 self#generate_elements self#generate_for_class (Module.module_type_classes mt);
2205 (* generate html files for class types *)
2206 self#generate_elements self#generate_for_class_type (Module.module_type_class_types mt);
2208 (* generate the file with the complete module type *)
2210 match mt.mt_type with
2213 self#output_module_type
2215 (Filename.concat !Args.target_dir type_file)
2222 (** Generate the html file for the given module.
2223 @raise Failure if an error occurs.*)
2224 method generate_for_module pre post modu =
2226 Odoc_info.verbose ("Generate for module "^modu.m_name);
2227 let (html_file, _) = Naming.html_files modu.m_name in
2228 let type_file = Naming.file_type_module_complete_target modu.m_name in
2229 let code_file = Naming.file_code_module_complete_target modu.m_name in
2230 let chanout = open_out (Filename.concat !Args.target_dir html_file) in
2231 let b = new_buf () in
2232 let pre_name = opt (fun m -> m.m_name) pre in
2233 let post_name = opt (fun m -> m.m_name) post in
2237 ~nav: (Some (pre_name, post_name, modu.m_name))
2238 ~comments: (Module.module_comments modu)
2239 (self#inner_title modu.m_name);
2241 self#print_navbar b pre_name post_name modu.m_name ;
2242 bs b "<center><h1>";
2243 if modu.m_text_only then
2249 if Module.module_is_functor modu then
2250 Odoc_messages.functo
2254 bp b " <a href=\"%s\">%s</a>" type_file modu.m_name;
2256 match modu.m_code with
2258 | Some _ -> bp b " (<a href=\"%s\">.ml</a>)" code_file
2261 bs b "</h1></center>\n<br>\n";
2263 if not modu.m_text_only then self#html_of_module b ~with_link: false modu;
2265 (* parameters for functors *)
2266 self#html_of_module_parameter_list b
2267 (Name.father modu.m_name)
2268 (Module.module_parameters modu);
2270 (* a horizontal line *)
2271 if not modu.m_text_only then bs b "<hr width=\"100%\">\n";
2273 (* module elements *)
2275 (self#html_of_module_element b (Name.father modu.m_name))
2276 (Module.module_elements modu);
2278 bs b "</body></html>";
2279 Buffer.output_buffer chanout b;
2282 (* generate html files for submodules *)
2283 self#generate_elements self#generate_for_module (Module.module_modules modu);
2284 (* generate html files for module types *)
2285 self#generate_elements self#generate_for_module_type (Module.module_module_types modu);
2286 (* generate html files for classes *)
2287 self#generate_elements self#generate_for_class (Module.module_classes modu);
2288 (* generate html files for class types *)
2289 self#generate_elements self#generate_for_class_type (Module.module_class_types modu);
2291 (* generate the file with the complete module type *)
2292 self#output_module_type
2294 (Filename.concat !Args.target_dir type_file)
2297 match modu.m_code with
2302 (Filename.concat !Args.target_dir code_file)
2308 (** Generate the [<index_prefix>.html] file corresponding to the given module list.
2309 @raise Failure if an error occurs.*)
2310 method generate_index module_list =
2312 let chanout = open_out (Filename.concat !Args.target_dir self#index) in
2313 let b = new_buf () in
2314 let title = match !Args.title with None -> "" | Some t -> self#escape t in
2317 self#print_header b self#title;
2319 bs b "<center><h1>";
2321 bs b "</h1></center>\n" ;
2322 let info = Odoc_info.apply_opt
2323 (Odoc_info.info_of_comment_file module_list)
2324 !Odoc_info.Args.intro_file
2329 self#html_of_Index_list b;
2331 self#html_of_Module_list b
2332 (List.map (fun m -> m.m_name) module_list);
2333 bs b "</body>\n</html>"
2334 | Some i -> self#html_of_info ~indent: false b info
2336 Buffer.output_buffer chanout b;
2342 (** Generate the values index in the file [index_values.html]. *)
2343 method generate_values_index module_list =
2344 self#generate_elements_index
2346 (fun v -> v.val_name)
2347 (fun v -> v.val_info)
2348 Naming.complete_value_target
2349 Odoc_messages.index_of_values
2352 (** Generate the exceptions index in the file [index_exceptions.html]. *)
2353 method generate_exceptions_index module_list =
2354 self#generate_elements_index
2355 self#list_exceptions
2356 (fun e -> e.ex_name)
2357 (fun e -> e.ex_info)
2358 Naming.complete_exception_target
2359 Odoc_messages.index_of_exceptions
2360 self#index_exceptions
2362 (** Generate the types index in the file [index_types.html]. *)
2363 method generate_types_index module_list =
2364 self#generate_elements_index
2366 (fun t -> t.ty_name)
2367 (fun t -> t.ty_info)
2368 Naming.complete_type_target
2369 Odoc_messages.index_of_types
2372 (** Generate the attributes index in the file [index_attributes.html]. *)
2373 method generate_attributes_index module_list =
2374 self#generate_elements_index
2375 self#list_attributes
2376 (fun a -> a.att_value.val_name)
2377 (fun a -> a.att_value.val_info)
2378 Naming.complete_attribute_target
2379 Odoc_messages.index_of_attributes
2380 self#index_attributes
2382 (** Generate the methods index in the file [index_methods.html]. *)
2383 method generate_methods_index module_list =
2384 self#generate_elements_index
2386 (fun m -> m.met_value.val_name)
2387 (fun m -> m.met_value.val_info)
2388 Naming.complete_method_target
2389 Odoc_messages.index_of_methods
2392 (** Generate the classes index in the file [index_classes.html]. *)
2393 method generate_classes_index module_list =
2394 self#generate_elements_index
2396 (fun c -> c.cl_name)
2397 (fun c -> c.cl_info)
2398 (fun c -> fst (Naming.html_files c.cl_name))
2399 Odoc_messages.index_of_classes
2402 (** Generate the class types index in the file [index_class_types.html]. *)
2403 method generate_class_types_index module_list =
2404 self#generate_elements_index
2405 self#list_class_types
2406 (fun ct -> ct.clt_name)
2407 (fun ct -> ct.clt_info)
2408 (fun ct -> fst (Naming.html_files ct.clt_name))
2409 Odoc_messages.index_of_class_types
2410 self#index_class_types
2412 (** Generate the modules index in the file [index_modules.html]. *)
2413 method generate_modules_index module_list =
2414 self#generate_elements_index
2418 (fun m -> fst (Naming.html_files m.m_name))
2419 Odoc_messages.index_of_modules
2422 (** Generate the module types index in the file [index_module_types.html]. *)
2423 method generate_module_types_index module_list =
2424 self#generate_elements_index
2425 self#list_module_types
2426 (fun mt -> mt.mt_name)
2427 (fun mt -> mt.mt_info)
2428 (fun mt -> fst (Naming.html_files mt.mt_name))
2429 Odoc_messages.index_of_module_types
2430 self#index_module_types
2432 (** Generate all the html files from a module list. The main
2433 file is [<index_prefix>.html]. *)
2434 method generate module_list =
2435 (* init the style *)
2437 (* init the lists of elements *)
2438 list_values <- Odoc_info.Search.values module_list ;
2439 list_exceptions <- Odoc_info.Search.exceptions module_list ;
2440 list_types <- Odoc_info.Search.types module_list ;
2441 list_attributes <- Odoc_info.Search.attributes module_list ;
2442 list_methods <- Odoc_info.Search.methods module_list ;
2443 list_classes <- Odoc_info.Search.classes module_list ;
2444 list_class_types <- Odoc_info.Search.class_types module_list ;
2445 list_modules <- Odoc_info.Search.modules module_list ;
2446 list_module_types <- Odoc_info.Search.module_types module_list ;
2448 (* prepare the page header *)
2449 self#prepare_header module_list ;
2450 (* Get the names of all known types. *)
2451 let types = Odoc_info.Search.types module_list in
2452 known_types_names <-
2454 (fun acc t -> StringSet.add t.ty_name acc)
2457 (* Get the names of all class and class types. *)
2458 let classes = Odoc_info.Search.classes module_list in
2459 let class_types = Odoc_info.Search.class_types module_list in
2460 known_classes_names <-
2462 (fun acc c -> StringSet.add c.cl_name acc)
2465 known_classes_names <-
2467 (fun acc ct -> StringSet.add ct.clt_name acc)
2470 (* Get the names of all known modules and module types. *)
2471 let module_types = Odoc_info.Search.module_types module_list in
2472 let modules = Odoc_info.Search.modules module_list in
2473 known_modules_names <-
2475 (fun acc m -> StringSet.add m.m_name acc)
2478 known_modules_names <-
2480 (fun acc mt -> StringSet.add mt.mt_name acc)
2483 (* generate html for each module *)
2484 if not !Args.index_only then
2485 self#generate_elements self#generate_for_module module_list ;
2488 self#generate_index module_list;
2489 self#generate_values_index module_list ;
2490 self#generate_exceptions_index module_list ;
2491 self#generate_types_index module_list ;
2492 self#generate_attributes_index module_list ;
2493 self#generate_methods_index module_list ;
2494 self#generate_classes_index module_list ;
2495 self#generate_class_types_index module_list ;
2496 self#generate_modules_index module_list ;
2497 self#generate_module_types_index module_list ;
2501 incr Odoc_info.errors
2504 Odoc_ocamlhtml.html_of_comment :=
2506 let b = new_buf () in
2507 self#html_of_text b (Odoc_text.Texter.text_of_string s);