diff options
author | Maxence Guesdon <maxence.guesdon@inria.fr> | 2004-03-14 13:52:01 +0000 |
---|---|---|
committer | Maxence Guesdon <maxence.guesdon@inria.fr> | 2004-03-14 13:52:01 +0000 |
commit | 9f320eede0158e9565c0ac404723419ce30980fa (patch) | |
tree | 6833583c3388ccfb7b2a69c41c935184da83277d /ocamldoc/odoc_man.ml | |
parent | ff0f8b35cae93f33cf8879c8cfa2b6264f6d4517 (diff) | |
download | ocaml-9f320eede0158e9565c0ac404723419ce30980fa.tar.gz |
use buffers instead of string concatenation in html and man generators
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@6155 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'ocamldoc/odoc_man.ml')
-rw-r--r-- | ocamldoc/odoc_man.ml | 1046 |
1 files changed, 571 insertions, 475 deletions
diff --git a/ocamldoc/odoc_man.ml b/ocamldoc/odoc_man.ml index 366f655da5..66232db589 100644 --- a/ocamldoc/odoc_man.ml +++ b/ocamldoc/odoc_man.ml @@ -21,6 +21,9 @@ open Class open Module open Search +let new_buf () = Buffer.create 1024 +let bp = Printf.bprintf +let bs = Buffer.add_string (** A class used to get a [text] for info structures. *) class virtual info = @@ -31,76 +34,112 @@ class virtual info = val mutable tag_functions = ([] : (string * (Odoc_info.text -> string)) list) (** Return man code for a [text]. *) - method virtual man_of_text : Odoc_info.text -> string + method virtual man_of_text : Buffer.t -> Odoc_info.text -> unit - (** Groff string for an author list. *) - method man_of_author_list l = + (** Print groff string for an author list. *) + method man_of_author_list b l = match l with - [] -> - "" + [] -> () | _ -> - ".B \""^Odoc_messages.authors^"\"\n:\n"^ - (String.concat ", " l)^ - "\n.sp\n" - - (** Groff string for the given optional version information.*) - method man_of_version_opt v_opt = + bs b ".B \""; + bs b Odoc_messages.authors; + bs b "\"\n:\n"; + bs b (String.concat ", " l); + bs b "\n.sp\n" + + (** Print groff string for the given optional version information.*) + method man_of_version_opt b v_opt = match v_opt with - None -> "" - | Some v -> ".B \""^Odoc_messages.version^"\"\n:\n"^v^"\n.sp\n" - - (** Groff string for the given optional since information.*) - method man_of_since_opt s_opt = + None -> () + | Some v -> + bs b ".B \""; + bs b Odoc_messages.version; + bs b "\"\n:\n"; + bs b v; + bs b "\n.sp\n" + + (** Print groff string for the given optional since information.*) + method man_of_since_opt b s_opt = match s_opt with - None -> "" - | Some s -> ".B \""^Odoc_messages.since^"\"\n"^s^"\n.sp\n" - - (** Groff string for the given list of raised exceptions.*) - method man_of_raised_exceptions l = + None -> () + | Some s -> + bs b ".B \""; + bs b Odoc_messages.since; + bs b "\"\n"; + bs b s; + bs b "\n.sp\n" + + (** Print groff string for the given list of raised exceptions.*) + method man_of_raised_exceptions b l = match l with - [] -> "" - | (s, t) :: [] -> ".B \""^Odoc_messages.raises^" "^s^"\"\n"^(self#man_of_text t)^"\n.sp\n" + [] -> () + | (s, t) :: [] -> + bs b ".B \""; + bs b Odoc_messages.raises; + bs b (" "^s^"\"\n"); + self#man_of_text b t; + bs b "\n.sp\n" | _ -> - ".B \""^Odoc_messages.raises^"\"\n"^ - (String.concat "" - (List.map - (fun (ex, desc) -> ".TP\n.B \""^ex^"\"\n"^(self#man_of_text desc)^"\n") - l - ) - )^"\n.sp\n" - - (** Groff string for the given "see also" reference. *) - method man_of_see (see_ref, t) = + bs b ".B \""; + bs b Odoc_messages.raises; + bs b "\"\n"; + List.iter + (fun (ex, desc) -> + bs b ".TP\n.B \""; + bs b ex; + bs b "\"\n"; + self#man_of_text b desc; + bs b "\n" + ) + l; + bs b "\n.sp\n" + + (** Print groff string for the given "see also" reference. *) + method man_of_see b (see_ref, t) = let t_ref = match see_ref with Odoc_info.See_url s -> [ Odoc_info.Link (s, t) ] | Odoc_info.See_file s -> (Odoc_info.Code s) :: (Odoc_info.Raw " ") :: t | Odoc_info.See_doc s -> (Odoc_info.Italic [Odoc_info.Raw s]) :: (Odoc_info.Raw " ") :: t in - self#man_of_text t_ref + self#man_of_text b t_ref - (** Groff string for the given list of "see also" references.*) - method man_of_sees l = + (** Print groff string for the given list of "see also" references.*) + method man_of_sees b l = match l with - [] -> "" - | see :: [] -> ".B \""^Odoc_messages.see_also^"\"\n"^(self#man_of_see see)^"\n.sp\n" + [] -> () + | see :: [] -> + bs b ".B \""; + bs b Odoc_messages.see_also; + bs b "\"\n"; + self#man_of_see b see; + bs b "\n.sp\n" | _ -> - ".B \""^Odoc_messages.see_also^"\"\n"^ - (String.concat "" - (List.map - (fun see -> ".TP\n \"\"\n"^(self#man_of_see see)^"\n") - l - ) - )^"\n.sp\n" - - (** Groff string for the given optional return information.*) - method man_of_return_opt return_opt = + bs b ".B \""; + bs b Odoc_messages.see_also; + bs b "\"\n"; + List.iter + (fun see -> + bs b ".TP\n \"\"\n"; + self#man_of_see b see; + bs b "\n" + ) + l; + bs b "\n.sp\n" + + (** Print groff string for the given optional return information.*) + method man_of_return_opt b return_opt = match return_opt with - None -> "" - | Some s -> ".B "^Odoc_messages.returns^"\n"^(self#man_of_text s)^"\n.sp\n" - - (** Return man code for the given list of custom tagged texts. *) - method man_of_custom l = + None -> () + | Some s -> + bs b ".B "; + bs b Odoc_messages.returns; + bs b "\n"; + self#man_of_text b s; + bs b "\n.sp\n" + + (** Print man code for the given list of custom tagged texts. *) + method man_of_custom b l = let buf = Buffer.create 50 in List.iter (fun (tag, text) -> @@ -111,31 +150,39 @@ class virtual info = Not_found -> Odoc_info.warning (Odoc_messages.tag_not_handled tag) ) - l; - Buffer.contents buf + l - (** Return the groff string to display an optional info structure. *) - method man_of_info info_opt = + (** Print the groff string to display an optional info structure. *) + method man_of_info b info_opt = match info_opt with - None -> - "" + None -> () | Some info -> let module M = Odoc_info in - (match info.M.i_deprecated with - None -> "" - | Some d -> ".B \""^Odoc_messages.deprecated^"\"\n"^(self#man_of_text d)^"\n.sp\n")^ - (match info.M.i_desc with - None -> "" - | Some d when d = [Odoc_info.Raw ""] -> "" - | Some d -> (self#man_of_text d)^"\n.sp\n" - )^ - (self#man_of_author_list info.M.i_authors)^ - (self#man_of_version_opt info.M.i_version)^ - (self#man_of_since_opt info.M.i_since)^ - (self#man_of_raised_exceptions info.M.i_raised_exceptions)^ - (self#man_of_return_opt info.M.i_return_value)^ - (self#man_of_sees info.M.i_sees)^ - (self#man_of_custom info.M.i_custom) + ( + match info.M.i_deprecated with + None -> () + | Some d -> + bs b ".B \""; + bs b Odoc_messages.deprecated; + bs b "\"\n"; + self#man_of_text b d; + bs b "\n.sp\n" + ); + ( + match info.M.i_desc with + None -> () + | Some d when d = [Odoc_info.Raw ""] -> () + | Some d -> + self#man_of_text b d; + bs b "\n.sp\n" + ); + self#man_of_author_list b info.M.i_authors; + self#man_of_version_opt b info.M.i_version; + self#man_of_since_opt b info.M.i_since; + self#man_of_raised_exceptions b info.M.i_raised_exceptions; + self#man_of_return_opt b info.M.i_return_value; + self#man_of_sees b info.M.i_sees; + self#man_of_custom b info.M.i_custom end (** This class is used to create objects which can generate a simple html documentation. *) @@ -157,71 +204,74 @@ class man = let f = Filename.concat !Args.target_dir file in open_out f - (** Return the groff string for a text, without correction of blanks. *) - method private man_of_text2 t = String.concat "" (List.map self#man_of_text_element t) - - (** Return the groff string for a text, with blanks corrected. *) - method man_of_text t = - let s = self#man_of_text2 t in + (** Print groff string for a text, without correction of blanks. *) + method private man_of_text2 b t = + List.iter (self#man_of_text_element b) t + + (** Print the groff string for a text, with blanks corrected. *) + method man_of_text b t = + let b2 = new_buf () in + self#man_of_text2 b2 t ; + let s = Buffer.contents b2 in let s2 = Str.global_replace (Str.regexp "\n[ ]*") "\n" s in - Str.global_replace (Str.regexp "\n\n") "\n" s2 + bs b (Str.global_replace (Str.regexp "\n\n") "\n" s2) (** Return the given string without no newlines. *) method remove_newlines s = Str.global_replace (Str.regexp "[ ]*\n[ ]*") " " s - (** Return the groff string for a text element. *) - method man_of_text_element te = + (** Print the groff string for a text element. *) + method man_of_text_element b te = match te with - | Odoc_info.Raw s -> s + | Odoc_info.Raw s -> bs b s | Odoc_info.Code s -> - let s2 = "\n.B "^(Str.global_replace (Str.regexp "\n") "\n.B " (self#escape s))^"\n" in - s2 + bs b "\n.B "; + bs b ((Str.global_replace (Str.regexp "\n") "\n.B " (self#escape s))^"\n") | Odoc_info.CodePre s -> - let s2 = "\n.B "^(Str.global_replace (Str.regexp "\n") "\n.B " (self#escape s))^"\n" in - s2 - | Odoc_info.Verbatim s -> self#escape s + bs b "\n.B "; + bs b ((Str.global_replace (Str.regexp "\n") "\n.B " (self#escape s))^"\n") + | Odoc_info.Verbatim s -> + bs b (self#escape s) | Odoc_info.Bold t | Odoc_info.Italic t | Odoc_info.Emphasize t | Odoc_info.Center t | Odoc_info.Left t - | Odoc_info.Right t -> self#man_of_text2 t + | Odoc_info.Right t -> + self#man_of_text2 b t | Odoc_info.List tl -> - (String.concat "" - (List.map - (fun t -> ".TP\n \"\"\n"^(self#man_of_text2 t)^"\n") - tl - ) - )^"\n" + List.iter + (fun t -> bs b ".TP\n \"\"\n"; self#man_of_text2 b t; bs b "\n") + tl; + bs b "\n" | Odoc_info.Enum tl -> - (String.concat "" - (List.map - (fun t -> ".TP\n \"\"\n"^(self#man_of_text2 t)^"\n") - tl - ) - )^"\n" + List.iter + (fun t -> bs b ".TP\n \"\"\n"; self#man_of_text2 b t; bs b "\n") + tl; + bs b "\n" | Odoc_info.Newline -> - "\n.sp\n" + bs b "\n.sp\n" | Odoc_info.Block t -> - "\n.sp\n"^(self#man_of_text2 t)^"\n.sp\n" + bs b "\n.sp\n"; + self#man_of_text2 b t; + bs b "\n.sp\n" | Odoc_info.Title (n, l_opt, t) -> - self#man_of_text2 [Odoc_info.Code (Odoc_info.string_of_text t)] + self#man_of_text2 b [Odoc_info.Code (Odoc_info.string_of_text t)] | Odoc_info.Latex _ -> (* don't care about LaTeX stuff in HTML. *) - "" + () | Odoc_info.Link (s, t) -> - self#man_of_text2 t + self#man_of_text2 b t | Odoc_info.Ref (name, _) -> - self#man_of_text_element + self#man_of_text_element b (Odoc_info.Code (Odoc_info.use_hidden_modules name)) | Odoc_info.Superscript t -> - "^{"^(self#man_of_text2 t) + bs b "^{"; self#man_of_text2 b t | Odoc_info.Subscript t -> - "_{"^(self#man_of_text2 t) + bs b "_{"; self#man_of_text2 b t - (** Groff string to display code. *) - method man_of_code s = self#man_of_text [ Code s ] + (** Print groff string to display code. *) + method man_of_code b s = self#man_of_text b [ Code s ] (** Take a string and return the string where fully qualified idents have been replaced by idents relative to the given module name.*) @@ -240,297 +290,355 @@ class man = in s2 - (** Groff string to display a [Types.type_expr].*) - method man_of_type_expr m_name t = + (** Print groff string to display a [Types.type_expr].*) + method man_of_type_expr b m_name t = let s = String.concat "\n" (Str.split (Str.regexp "\n") (Odoc_print.string_of_type_expr t)) in let s2 = Str.global_replace (Str.regexp "\n") "\n.B " s in - "\n.B "^(self#relative_idents m_name s2)^"\n" + bs b "\n.B "; + bs b (self#relative_idents m_name s2); + bs b "\n" - (** Groff string to display a [Types.class_type].*) - method man_of_class_type_expr m_name t = + (** Print groff string to display a [Types.class_type].*) + method man_of_class_type_expr b m_name t = let s = String.concat "\n" (Str.split (Str.regexp "\n") (Odoc_print.string_of_class_type t)) in let s2 = Str.global_replace (Str.regexp "\n") "\n.B " s in - "\n.B "^(self#relative_idents m_name s2)^"\n" + bs b "\n.B "; + bs b (self#relative_idents m_name s2); + bs b "\n" - (** Groff string to display a [Types.type_expr list].*) - method man_of_type_expr_list m_name sep l = + (** Print groff string to display a [Types.type_expr list].*) + method man_of_type_expr_list b m_name sep l = let s = Odoc_str.string_of_type_list sep l in let s2 = Str.global_replace (Str.regexp "\n") "\n.B " s in - "\n.B "^(self#relative_idents m_name s2)^"\n" + bs b "\n.B "; + bs b (self#relative_idents m_name s2); + bs b "\n" - (** Groff string to display the parameters of a type.*) - method man_of_type_expr_param_list m_name t = + (** Print groff string to display the parameters of a type.*) + method man_of_type_expr_param_list b m_name t = match t.ty_parameters with - [] -> "" + [] -> () | l -> let s = Odoc_str.string_of_type_param_list t in let s2 = Str.global_replace (Str.regexp "\n") "\n.B " s in - "\n.B "^(self#relative_idents m_name s2)^"\n" + bs b "\n.B "; + bs b (self#relative_idents m_name s2); + bs b "\n" - (** Groff string to display a [Types.module_type]. *) - method man_of_module_type m_name t = + (** Print groff string to display a [Types.module_type]. *) + method man_of_module_type b m_name t = let s = String.concat "\n" (Str.split (Str.regexp "\n") (Odoc_print.string_of_module_type t)) in let s2 = Str.global_replace (Str.regexp "\n") "\n.B " s in - "\n.B "^(self#relative_idents m_name s2)^"\n" + bs b "\n.B "; + bs b (self#relative_idents m_name s2); + bs b "\n" - (** Groff string code for a value. *) - method man_of_value v = + (** Print groff string code for a value. *) + method man_of_value b v = Odoc_info.reset_type_names () ; - "\n.I val "^(Name.simple v.val_name)^" \n: "^ - (self#man_of_type_expr (Name.father v.val_name) v.val_type)^ - ".sp\n"^ - (self#man_of_info v.val_info)^ - "\n.sp\n" - - (** Groff string code for an exception. *) - method man_of_exception e = + bs b "\n.I val "; + bs b (Name.simple v.val_name); + bs b " \n: "; + self#man_of_type_expr b (Name.father v.val_name) v.val_type; + bs b ".sp\n"; + self#man_of_info b v.val_info; + bs b "\n.sp\n" + + (** Print groff string code for an exception. *) + method man_of_exception b e = Odoc_info.reset_type_names () ; - "\n.I exception "^(Name.simple e.ex_name)^" \n"^ - (match e.ex_args with - [] -> "" - | _ -> - ".B of "^ - (self#man_of_type_expr_list (Name.father e.ex_name) " * " e.ex_args) - )^ - (match e.ex_alias with - None -> "" - | Some ea -> " = "^ - ( - match ea.ea_ex with - None -> ea.ea_name - | Some e -> e.ex_name - ) - )^ - "\n.sp\n"^ - (self#man_of_info e.ex_info)^ - "\n.sp\n" + bs b "\n.I exception "; + bs b (Name.simple e.ex_name); + bs b " \n"; + ( + match e.ex_args with + [] -> () + | _ -> + bs b ".B of "; + self#man_of_type_expr_list b (Name.father e.ex_name) " * " e.ex_args + ); + ( + match e.ex_alias with + None -> () + | Some ea -> + bs b " = "; + bs b + ( + match ea.ea_ex with + None -> ea.ea_name + | Some e -> e.ex_name + ) + ); + bs b "\n.sp\n"; + self#man_of_info b e.ex_info; + bs b "\n.sp\n" - (** Groff string for a type. *) - method man_of_type t = + (** Print groff string for a type. *) + method man_of_type b t = Odoc_info.reset_type_names () ; let father = Name.father t.ty_name in - ".I type "^ - (self#man_of_type_expr_param_list father t)^ - (match t.ty_parameters with [] -> "" | _ -> ".I ")^(Name.simple t.ty_name)^" \n"^ - (match t.ty_manifest with None -> "" | Some typ -> "= "^(self#man_of_type_expr father typ))^ + bs b ".I type "; + self#man_of_type_expr_param_list b father t; + ( + match t.ty_parameters with + [] -> () + | _ -> bs b ".I " + ); + bs b (Name.simple t.ty_name); + bs b " \n"; + ( + match t.ty_manifest with + None -> () + | Some typ -> + bs b "= "; + self#man_of_type_expr b father typ + ); ( match t.ty_kind with - Type_abstract -> - "" + Type_abstract -> () | Type_variant (l, priv) -> - "="^(if priv then " private" else "")^"\n "^ - (String.concat "" - (List.map - (fun constr -> - "| "^constr.vc_name^ - (match constr.vc_args, constr.vc_text with - [], None -> "\n " - | [], (Some t) -> " (* "^(self#man_of_text t)^" *)\n " - | l, None -> - "\n.B of "^(self#man_of_type_expr_list father " * " l)^" " - | l, (Some t) -> - "\n.B of "^(self#man_of_type_expr_list father " * " l)^ - ".I \" \"\n"^ - "(* "^(self#man_of_text t)^" *)\n " - ) - ) - l - ) - ) + bs b "="; + if priv then bs b " private"; + bs b "\n "; + List.iter + (fun constr -> + bs b ("| "^constr.vc_name); + ( + match constr.vc_args, constr.vc_text with + [], None -> bs b "\n " + | [], (Some t) -> + bs b " (* "; + self#man_of_text b t; + bs b " *)\n " + | l, None -> + bs b "\n.B of "; + self#man_of_type_expr_list b father " * " l; + bs b " " + | l, (Some t) -> + bs b "\n.B of "; + self#man_of_type_expr_list b father " * " l; + bs b ".I \" \"\n"; + bs b "(* "; + self#man_of_text b t; + bs b " *)\n " + ) + ) + l | Type_record (l, priv) -> - "= "^(if priv then "private " else "")^"{"^ - (String.concat "" - (List.map - (fun r -> - (if r.rf_mutable then "\n\n.B mutable \n" else "\n ")^ - r.rf_name^" : "^(self#man_of_type_expr father r.rf_type)^";"^ - (match r.rf_text with - None -> - "" - | Some t -> - " (* "^(self#man_of_text t)^" *) " - )^"" - ) - l - ) - )^ - "\n }\n" - )^ - "\n.sp\n"^(self#man_of_info t.ty_info)^ - "\n.sp\n" - - (** Groff string for a class attribute. *) - method man_of_attribute a = - ".I val "^ - (if a.att_mutable then Odoc_messages.mutab^" " else "")^ - (Name.simple a.att_value.val_name)^" : "^ - (self#man_of_type_expr (Name.father a.att_value.val_name) a.att_value.val_type)^ - "\n.sp\n"^(self#man_of_info a.att_value.val_info)^ - "\n.sp\n" - - (** Groff string for a class method. *) - method man_of_method m = - ".I method "^ - (if m.met_private then "private " else "")^ - (if m.met_virtual then "virtual " else "")^ - (Name.simple m.met_value.val_name)^" : "^ - (self#man_of_type_expr (Name.father m.met_value.val_name) m.met_value.val_type)^ - "\n.sp\n"^(self#man_of_info m.met_value.val_info)^ - "\n.sp\n" + bs b "= "; + if priv then bs b "private "; + bs b "{"; + List.iter + (fun r -> + bs b (if r.rf_mutable then "\n\n.B mutable \n" else "\n "); + bs b (r.rf_name^" : "); + self#man_of_type_expr b father r.rf_type; + bs b ";"; + ( + match r.rf_text with + None -> () + | Some t -> + bs b " (* "; + self#man_of_text b t; + bs b " *) " + ); + ) + l; + bs b "\n }\n" + ); + bs b "\n.sp\n"; + self#man_of_info b t.ty_info; + bs b "\n.sp\n" + + (** Print groff string for a class attribute. *) + method man_of_attribute b a = + bs b ".I val "; + if a.att_mutable then bs b (Odoc_messages.mutab^" "); + bs b ((Name.simple a.att_value.val_name)^" : "); + self#man_of_type_expr b (Name.father a.att_value.val_name) a.att_value.val_type; + bs b "\n.sp\n"; + self#man_of_info b a.att_value.val_info; + bs b "\n.sp\n" + + (** Print groff string for a class method. *) + method man_of_method b m = + bs b ".I method "; + if m.met_private then bs b "private "; + if m.met_virtual then bs b "virtual "; + bs b ((Name.simple m.met_value.val_name)^" : "); + self#man_of_type_expr b + (Name.father m.met_value.val_name) m.met_value.val_type; + bs b "\n.sp\n"; + self#man_of_info b m.met_value.val_info; + bs b "\n.sp\n" (** Groff for a list of parameters. *) - method man_of_parameter_list m_name l = + method man_of_parameter_list b m_name l = match l with - [] -> - "" + [] -> () | _ -> - "\n.B "^Odoc_messages.parameters^": \n"^ - (String.concat "" - (List.map - (fun p -> - ".TP\n"^ - "\""^(Parameter.complete_name p)^"\"\n"^ - (self#man_of_type_expr m_name (Parameter.typ p))^"\n"^ - (self#man_of_parameter_description p)^"\n" - ) - l - ) - )^"\n" + bs b "\n.B "; + bs b Odoc_messages.parameters; + bs b ": \n"; + List.iter + (fun p -> + bs b ".TP\n"; + bs b "\""; + bs b (Parameter.complete_name p); + bs b "\"\n"; + self#man_of_type_expr b m_name (Parameter.typ p); + bs b "\n"; + self#man_of_parameter_description b p; + bs b "\n" + ) + l; + bs b "\n" (** Groff for the description of a function parameter. *) - method man_of_parameter_description p = + method man_of_parameter_description b p = match Parameter.names p with - [] -> - "" + [] -> () | name :: [] -> ( (* Only one name, no need for label for the description. *) match Parameter.desc_by_name p name with - None -> "" - | Some t -> "\n "^(self#man_of_text t) + None -> () + | Some t -> bs b "\n "; self#man_of_text b t ) | l -> (* A list of names, we display those with a description. *) - String.concat "" - (List.map - (fun n -> - match Parameter.desc_by_name p n with - None -> "" - | Some t -> (self#man_of_code (n^" : "))^(self#man_of_text t) - ) - l + List.iter + (fun n -> + match Parameter.desc_by_name p n with + None -> () + | Some t -> + self#man_of_code b (n^" : "); + self#man_of_text b t ) + l - (** Groff string for a list of module parameters. *) - method man_of_module_parameter_list m_name l = + (** Print groff string for a list of module parameters. *) + method man_of_module_parameter_list b m_name l = match l with - [] -> - "" + [] -> () | _ -> - ".B \""^Odoc_messages.parameters^":\"\n"^ - (String.concat "" - (List.map - (fun (p, desc_opt) -> - ".TP\n"^ - "\""^p.mp_name^"\"\n"^ - (self#man_of_module_type m_name p.mp_type)^"\n"^ - (match desc_opt with - None -> "" - | Some t -> self#man_of_text t)^ - "\n" - ) - l - ) - )^"\n\n" + bs b ".B \""; + bs b Odoc_messages.parameters; + bs b ":\"\n"; + List.iter + (fun (p, desc_opt) -> + bs b ".TP\n"; + bs b ("\""^p.mp_name^"\"\n"); + self#man_of_module_type b m_name p.mp_type; + bs b "\n"; + ( + match desc_opt with + None -> () + | Some t -> self#man_of_text b t + ); + bs b "\n" + ) + l; + bs b "\n\n" - (** Groff string for a class. *) - method man_of_class c = - let buf = Buffer.create 32 in - let p = Printf.bprintf in + (** Print groff string for a class. *) + method man_of_class b c = Odoc_info.reset_type_names () ; let father = Name.father c.cl_name in - p buf ".I class %s" - (if c.cl_virtual then "virtual " else ""); + bs b ".I class "; + if c.cl_virtual then bs b "virtual "; ( match c.cl_type_parameters with [] -> () - | l -> p buf "%s " (Odoc_str.string_of_class_type_param_list l) + | l -> + bs b (Odoc_str.string_of_class_type_param_list l); + bs b " " ); - p buf "%s : %s" - (Name.simple c.cl_name) - (self#man_of_class_type_expr (Name.father c.cl_name) c.cl_type); - p buf "\n.sp\n%s\n.sp\n" (self#man_of_info c.cl_info); - Buffer.contents buf - - (** Groff string for a class type. *) - method man_of_class_type ct = - let buf = Buffer.create 32 in - let p = Printf.bprintf in + bs b (Name.simple c.cl_name); + bs b " : " ; + self#man_of_class_type_expr b (Name.father c.cl_name) c.cl_type; + bs b "\n.sp\n"; + self#man_of_info b c.cl_info; + bs b "\n.sp\n" + + (** Print groff string for a class type. *) + method man_of_class_type b ct = Odoc_info.reset_type_names () ; - p buf ".I class type %s" - (if ct.clt_virtual then "virtual " else ""); + bs b ".I class type "; + if ct.clt_virtual then bs b "virtual " ; ( match ct.clt_type_parameters with [] -> () - | l -> p buf "%s " (Odoc_str.string_of_class_type_param_list l) + | l -> + bs b (Odoc_str.string_of_class_type_param_list l); + bs b " " ); - p buf "%s = %s" - (Name.simple ct.clt_name) - (self#man_of_class_type_expr (Name.father ct.clt_name) ct.clt_type); - p buf "\n.sp\n%s\n.sp\n" (self#man_of_info ct.clt_info); - Buffer.contents buf - - (** Groff string for a module. *) - method man_of_module m = - ".I module "^(Name.simple m.m_name)^ - " : "^(self#man_of_module_type (Name.father m.m_name) m.m_type)^ - "\n.sp\n"^(self#man_of_info m.m_info)^"\n.sp\n" - - (** Groff string for a module type. *) - method man_of_modtype mt = - ".I module type "^(Name.simple mt.mt_name)^ - " = "^ + bs b (Name.simple ct.clt_name); + bs b " = " ; + self#man_of_class_type_expr b (Name.father ct.clt_name) ct.clt_type; + bs b "\n.sp\n"; + self#man_of_info b ct.clt_info; + bs b "\n.sp\n" + + (** Print groff string for a module. *) + method man_of_module b m = + bs b ".I module "; + bs b (Name.simple m.m_name); + bs b " : "; + self#man_of_module_type b (Name.father m.m_name) m.m_type; + bs b "\n.sp\n"; + self#man_of_info b m.m_info; + bs b "\n.sp\n" + + (** Print groff string for a module type. *) + method man_of_modtype b mt = + bs b ".I module type "; + bs b (Name.simple mt.mt_name); + bs b " = "; (match mt.mt_type with - None -> "" - | Some t -> self#man_of_module_type (Name.father mt.mt_name) t - )^ - "\n.sp\n"^(self#man_of_info mt.mt_info)^"\n.sp\n" - - (** Groff string for a module comment.*) - method man_of_module_comment text = - "\n.pp\n"^ - (self#man_of_text [Code ("=== "^(Odoc_misc.string_of_text text)^" ===")])^ - "\n.pp\n" - - (** Groff string for a class comment.*) - method man_of_class_comment text = - "\n.pp\n"^ - (self#man_of_text [Code ("=== "^(Odoc_misc.string_of_text text)^" ===")])^ - "\n.pp\n" - - (** Groff string for an included module. *) - method man_of_included_module m_name im = - ".I include "^ + None -> () + | Some t -> + self#man_of_module_type b (Name.father mt.mt_name) t + ); + bs b "\n.sp\n"; + self#man_of_info b mt.mt_info; + bs b "\n.sp\n" + + (** Print groff string for a module comment.*) + method man_of_module_comment b text = + bs b "\n.pp\n"; + self#man_of_text b [Code ("=== "^(Odoc_misc.string_of_text text)^" ===")]; + bs b "\n.pp\n" + + (** Print groff string for a class comment.*) + method man_of_class_comment b text = + bs b "\n.pp\n"; + self#man_of_text b [Code ("=== "^(Odoc_misc.string_of_text text)^" ===")]; + bs b "\n.pp\n" + + (** Print groff string for an included module. *) + method man_of_included_module b m_name im = + bs b ".I include "; ( match im.im_module with - None -> im.im_name + None -> bs b im.im_name | Some mmt -> let name = match mmt with Mod m -> m.m_name | Modtype mt -> mt.mt_name in - self#relative_idents m_name name - )^ - "\n.sp\n"^ - (self#man_of_info im.im_info)^ - "\n.sp\n" + bs b (self#relative_idents m_name name) + ); + bs b "\n.sp\n"; + self#man_of_info b im.im_info; + bs b "\n.sp\n" (** Generate the man page for the given class.*) method generate_for_class cl = @@ -539,12 +647,13 @@ class man = let file = self#file_name cl.cl_name in try let chanout = self#open_out file in - output_string chanout - (".TH \""^Odoc_messages.clas^"\" "^ - cl.cl_name^" "^ - "\""^(Odoc_misc.string_of_date ~hour: false date)^"\" "^ - "OCamldoc "^ - "\""^(match !Args.title with Some t -> t | None -> "")^"\"\n"); + let b = new_buf () in + bs b ".TH \""; + bs b Odoc_messages.clas; + bs b ("\" "^cl.cl_name^" "); + bs b ("\""^(Odoc_misc.string_of_date ~hour: false date)^"\" "); + bs b "OCamldoc "; + bs b ("\""^(match !Args.title with Some t -> t | None -> "")^"\"\n"); let abstract = match cl.cl_info with @@ -554,22 +663,18 @@ class man = self#remove_newlines s in - output_string chanout - ( - ".SH NAME\n"^ - cl.cl_name^" \\- "^abstract^"\n"^ - ".SH "^Odoc_messages.clas^"\n"^ - Odoc_messages.clas^" "^cl.cl_name^"\n"^ - ".SH "^Odoc_messages.documentation^"\n"^ - ".sp\n" - ); - output_string chanout (self#man_of_class cl); + bs b ".SH NAME\n"; + bs b (cl.cl_name^" \\- "^abstract^"\n"); + bs b (".SH "^Odoc_messages.clas^"\n"); + bs b (Odoc_messages.clas^" "^cl.cl_name^"\n"); + bs b (".SH "^Odoc_messages.documentation^"\n"); + bs b ".sp\n"; + self#man_of_class b cl; (* parameters *) - output_string chanout - (self#man_of_parameter_list "" cl.cl_parameters); + self#man_of_parameter_list b "" cl.cl_parameters; (* a large blank *) - output_string chanout "\n.sp\n.sp\n"; + bs b "\n.sp\n.sp\n"; (* (* class inheritance *) @@ -580,14 +685,15 @@ class man = (fun element -> match element with Class_attribute a -> - output_string chanout (self#man_of_attribute a) + self#man_of_attribute b a | Class_method m -> - output_string chanout (self#man_of_method m) + self#man_of_method b m | Class_comment t -> - output_string chanout (self#man_of_class_comment t) + self#man_of_class_comment b t ) (Class.class_elements cl); + Buffer.output_buffer chanout b; close_out chanout with Sys_error s -> @@ -601,12 +707,12 @@ class man = let file = self#file_name ct.clt_name in try let chanout = self#open_out file in - output_string chanout - (".TH \""^Odoc_messages.class_type^"\" "^ - ct.clt_name^" "^ - "\""^(Odoc_misc.string_of_date ~hour: false date)^"\" "^ - "OCamldoc "^ - "\""^(match !Args.title with Some t -> t | None -> "")^"\"\n"); + let b = new_buf () in + bs b (".TH \""^Odoc_messages.class_type^"\" "); + bs b (ct.clt_name^" "); + bs b ("\""^(Odoc_misc.string_of_date ~hour: false date)^"\" "); + bs b "OCamldoc "; + bs b ("\""^(match !Args.title with Some t -> t | None -> "")^"\"\n"); let abstract = match ct.clt_info with @@ -616,19 +722,17 @@ class man = self#remove_newlines s in - output_string chanout - ( - ".SH NAME\n"^ - ct.clt_name^" \\- "^abstract^"\n"^ - ".SH "^Odoc_messages.class_type^"\n"^ - Odoc_messages.class_type^" "^ct.clt_name^"\n"^ - ".SH "^Odoc_messages.documentation^"\n"^ - ".sp\n" - ); - output_string chanout (self#man_of_class_type ct); + bs b ".SH NAME\n"; + bs b (ct.clt_name^" \\- "^abstract^"\n"); + bs b (".SH "^Odoc_messages.class_type^"\n"); + bs b (Odoc_messages.class_type^" "^ct.clt_name^"\n"); + bs b (".SH "^Odoc_messages.documentation^"\n"); + bs b ".sp\n"; + + self#man_of_class_type b ct; (* a large blank *) - output_string chanout "\n.sp\n.sp\n"; + bs b "\n.sp\n.sp\n"; (* (* class inheritance *) self#generate_class_inheritance_info chanout cl; @@ -638,14 +742,15 @@ class man = (fun element -> match element with Class_attribute a -> - output_string chanout (self#man_of_attribute a) + self#man_of_attribute b a | Class_method m -> - output_string chanout (self#man_of_method m) + self#man_of_method b m | Class_comment t -> - output_string chanout (self#man_of_class_comment t) + self#man_of_class_comment b t ) (Class.class_type_elements ct); + Buffer.output_buffer chanout b; close_out chanout with Sys_error s -> @@ -659,12 +764,12 @@ class man = let file = self#file_name mt.mt_name in try let chanout = self#open_out file in - output_string chanout - (".TH \""^Odoc_messages.module_type^"\" "^ - mt.mt_name^" "^ - "\""^(Odoc_misc.string_of_date ~hour: false date)^"\" "^ - "OCamldoc "^ - "\""^(match !Args.title with Some t -> t | None -> "")^"\"\n"); + let b = new_buf () in + bs b (".TH \""^Odoc_messages.module_type^"\" "); + bs b (mt.mt_name^" "); + bs b ("\""^(Odoc_misc.string_of_date ~hour: false date)^"\" "); + bs b "OCamldoc "; + bs b ("\""^(match !Args.title with Some t -> t | None -> "")^"\"\n"); let abstract = match mt.mt_info with @@ -673,57 +778,56 @@ class man = let s = Odoc_info.string_of_text (Odoc_info.first_sentence_of_text t) in self#remove_newlines s in - output_string chanout - ( - ".SH NAME\n"^ - mt.mt_name^" \\- "^abstract^"\n"^ - ".SH "^Odoc_messages.module_type^"\n"^ - Odoc_messages.module_type^" "^mt.mt_name^"\n"^ - ".SH "^Odoc_messages.documentation^"\n"^ - ".sp\n"^ - Odoc_messages.module_type^"\n"^ - ".BI \""^(Name.simple mt.mt_name)^"\"\n"^ - " = "^ - (match mt.mt_type with - None -> "" - | Some t -> self#man_of_module_type (Name.father mt.mt_name) t - )^ - "\n.sp\n"^ - (self#man_of_info mt.mt_info)^"\n"^ - ".sp\n" - ); + bs b ".SH NAME\n"; + bs b (mt.mt_name^" \\- "^abstract^"\n"); + bs b (".SH "^Odoc_messages.module_type^"\n"); + bs b (Odoc_messages.module_type^" "^mt.mt_name^"\n"); + bs b (".SH "^Odoc_messages.documentation^"\n"); + bs b ".sp\n"; + bs b (Odoc_messages.module_type^"\n"); + bs b (".BI \""^(Name.simple mt.mt_name)^"\"\n"); + bs b " = "; + ( + match mt.mt_type with + None -> () + | Some t -> + self#man_of_module_type b (Name.father mt.mt_name) t + ); + bs b "\n.sp\n"; + self#man_of_info b mt.mt_info; + bs b "\n.sp\n"; (* parameters for functors *) - output_string chanout - (self#man_of_module_parameter_list "" (Module.module_type_parameters mt)); + self#man_of_module_parameter_list b "" (Module.module_type_parameters mt); (* a large blank *) - output_string chanout "\n.sp\n.sp\n"; + bs b "\n.sp\n.sp\n"; (* module elements *) List.iter (fun ele -> match ele with Element_module m -> - output_string chanout (self#man_of_module m) + self#man_of_module b m | Element_module_type mt -> - output_string chanout (self#man_of_modtype mt) + self#man_of_modtype b mt | Element_included_module im -> - output_string chanout (self#man_of_included_module mt.mt_name im) + self#man_of_included_module b mt.mt_name im | Element_class c -> - output_string chanout (self#man_of_class c) + self#man_of_class b c | Element_class_type ct -> - output_string chanout (self#man_of_class_type ct) + self#man_of_class_type b ct | Element_value v -> - output_string chanout (self#man_of_value v) + self#man_of_value b v | Element_exception e -> - output_string chanout (self#man_of_exception e) + self#man_of_exception b e | Element_type t -> - output_string chanout (self#man_of_type t) + self#man_of_type b t | Element_module_comment text -> - output_string chanout (self#man_of_module_comment text) + self#man_of_module_comment b text ) (Module.module_type_elements mt); + Buffer.output_buffer chanout b; close_out chanout with @@ -738,12 +842,14 @@ class man = let file = self#file_name m.m_name in try let chanout = self#open_out file in - output_string chanout - (".TH \""^Odoc_messages.modul^"\" "^ - m.m_name^" "^ - "\""^(Odoc_misc.string_of_date ~hour: false date)^"\" "^ - "OCamldoc "^ - "\""^(match !Args.title with Some t -> t | None -> "")^"\"\n"); + let b = new_buf () in + bs b ".TH \""; + bs b Odoc_messages.modul; + bs b "\" "; + bs b (m.m_name^" "); + bs b ("\""^(Odoc_misc.string_of_date ~hour: false date)^"\" "); + bs b "OCamldoc "; + bs b ("\""^(match !Args.title with Some t -> t | None -> "")^"\"\n"); let abstract = match m.m_info with @@ -753,53 +859,51 @@ class man = self#remove_newlines s in - output_string chanout - ( - ".SH NAME\n"^ - m.m_name^" \\- "^abstract^"\n"^ - ".SH "^Odoc_messages.modul^"\n"^ - Odoc_messages.modul^" "^m.m_name^"\n"^ - ".SH "^Odoc_messages.documentation^"\n"^ - ".sp\n"^ - Odoc_messages.modul^"\n"^ - ".BI \""^(Name.simple m.m_name)^"\"\n"^ - " : "^(self#man_of_module_type (Name.father m.m_name) m.m_type)^ - "\n.sp\n"^ - (self#man_of_info m.m_info)^"\n"^ - ".sp\n" - ); + bs b ".SH NAME\n"; + bs b (m.m_name^" \\- "^abstract^"\n"); + bs b (".SH "^Odoc_messages.modul^"\n"); + bs b (Odoc_messages.modul^" "^m.m_name^"\n"); + bs b (".SH "^Odoc_messages.documentation^"\n"); + bs b ".sp\n"; + bs b (Odoc_messages.modul^"\n"); + bs b (".BI \""^(Name.simple m.m_name)^"\"\n"); + bs b " : "; + self#man_of_module_type b (Name.father m.m_name) m.m_type; + bs b "\n.sp\n"; + self#man_of_info b m.m_info; + bs b "\n.sp\n"; (* parameters for functors *) - output_string chanout - (self#man_of_module_parameter_list "" (Module.module_parameters m)); + self#man_of_module_parameter_list b "" (Module.module_parameters m); (* a large blank *) - output_string chanout "\n.sp\n.sp\n"; + bs b "\n.sp\n.sp\n"; (* module elements *) List.iter (fun ele -> match ele with Element_module m -> - output_string chanout (self#man_of_module m) + self#man_of_module b m | Element_module_type mt -> - output_string chanout (self#man_of_modtype mt) + self#man_of_modtype b mt | Element_included_module im -> - output_string chanout (self#man_of_included_module m.m_name im) + self#man_of_included_module b m.m_name im | Element_class c -> - output_string chanout (self#man_of_class c) + self#man_of_class b c | Element_class_type ct -> - output_string chanout (self#man_of_class_type ct) + self#man_of_class_type b ct | Element_value v -> - output_string chanout (self#man_of_value v) + self#man_of_value b v | Element_exception e -> - output_string chanout (self#man_of_exception e) + self#man_of_exception b e | Element_type t -> - output_string chanout (self#man_of_type t) + self#man_of_type b t | Element_module_comment text -> - output_string chanout (self#man_of_module_comment text) + self#man_of_module_comment b text ) (Module.module_elements m); + Buffer.output_buffer chanout b; close_out chanout with @@ -867,52 +971,44 @@ class man = let file = self#file_name name in try let chanout = self#open_out file in - output_string chanout - ( - ".TH \""^name^"\" "^ - "man "^ - "\""^(Odoc_misc.string_of_date ~hour: false date)^"\" "^ - "OCamldoc "^ - "\""^(match !Args.title with Some t -> t | None -> "")^"\"\n"^ - ".SH NAME\n"^ - name^" \\- all "^name^" elements\n\n" - ); + let b = new_buf () in + bs b (".TH \""^name^"\" "); + bs b "man "; + bs b ("\""^(Odoc_misc.string_of_date ~hour: false date)^"\" "); + bs b "OCamldoc "; + bs b ("\""^(match !Args.title with Some t -> t | None -> "")^"\"\n"); + bs b ".SH NAME\n"; + bs b (name^" \\- all "^name^" elements\n\n"); let f ele = match ele with Res_value v -> - output_string chanout - ("\n.SH "^Odoc_messages.modul^" "^(Name.father v.val_name)^"\n"^ - (self#man_of_value v)) + bs b ("\n.SH "^Odoc_messages.modul^" "^(Name.father v.val_name)^"\n"); + self#man_of_value b v | Res_type t -> - output_string chanout - ("\n.SH "^Odoc_messages.modul^" "^(Name.father t.ty_name)^"\n"^ - (self#man_of_type t)) + bs b ("\n.SH "^Odoc_messages.modul^" "^(Name.father t.ty_name)^"\n"); + self#man_of_type b t | Res_exception e -> - output_string chanout - ("\n.SH "^Odoc_messages.modul^" "^(Name.father e.ex_name)^"\n"^ - (self#man_of_exception e)) + bs b ("\n.SH "^Odoc_messages.modul^" "^(Name.father e.ex_name)^"\n"); + self#man_of_exception b e | Res_attribute a -> - output_string chanout - ("\n.SH "^Odoc_messages.clas^" "^(Name.father a.att_value.val_name)^"\n"^ - (self#man_of_attribute a)) + bs b ("\n.SH "^Odoc_messages.clas^" "^(Name.father a.att_value.val_name)^"\n"); + self#man_of_attribute b a | Res_method m -> - output_string chanout - ("\n.SH "^Odoc_messages.clas^" "^(Name.father m.met_value.val_name)^"\n"^ - (self#man_of_method m)) + bs b ("\n.SH "^Odoc_messages.clas^" "^(Name.father m.met_value.val_name)^"\n"); + self#man_of_method b m | Res_class c -> - output_string chanout - ("\n.SH "^Odoc_messages.modul^" "^(Name.father c.cl_name)^"\n"^ - (self#man_of_class c)) + bs b ("\n.SH "^Odoc_messages.modul^" "^(Name.father c.cl_name)^"\n"); + self#man_of_class b c | Res_class_type ct -> - output_string chanout - ("\n.SH "^Odoc_messages.modul^" "^(Name.father ct.clt_name)^"\n"^ - (self#man_of_class_type ct)) + bs b ("\n.SH "^Odoc_messages.modul^" "^(Name.father ct.clt_name)^"\n"); + self#man_of_class_type b ct | _ -> (* normalement on ne peut pas avoir de module ici. *) () in List.iter f l; + Buffer.output_buffer chanout b; close_out chanout with Sys_error s -> |