ocaml/ocamldoc/odoc_args.ml

346 lines
12 KiB
OCaml

(***********************************************************************)
(* OCamldoc *)
(* *)
(* Maxence Guesdon, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 2001 Institut National de Recherche en Informatique et *)
(* en Automatique. All rights reserved. This file is distributed *)
(* under the terms of the Q Public License version 1.0. *)
(* *)
(***********************************************************************)
(* cvsid $Id$ *)
(** Command-line arguments. *)
open Clflags
module M = Odoc_messages
type source_file =
Impl_file of string
| Intf_file of string
| Text_file of string
let include_dirs = Clflags.include_dirs
let bytecode_mode = ref true
class type doc_generator =
object
method generate : Odoc_module.t_module list -> unit
end
let doc_generator = ref (None : doc_generator option)
let merge_options = ref ([] : Odoc_types.merge_option list)
let out_file = ref M.default_out_file
let dot_include_all = ref false
let dot_types = ref false
let dot_reduce = ref false
let dot_colors = ref (List.flatten M.default_dot_colors)
let man_suffix = ref M.default_man_suffix
let man_section = ref M.default_man_section
let man_mini = ref false
(** Analysis of a string defining options. Return the list of
options according to the list giving associations between
[(character, _)] and a list of options. *)
let analyse_option_string l s =
List.fold_left
(fun acc -> fun ((c,_), v) ->
if String.contains s c then
acc @ v
else
acc)
[]
l
(** Analysis of a string defining the merge options to be used.
Returns the list of options specified.*)
let analyse_merge_options s =
let l = [
(M.merge_description, [Odoc_types.Merge_description]) ;
(M.merge_author, [Odoc_types.Merge_author]) ;
(M.merge_version, [Odoc_types.Merge_version]) ;
(M.merge_see, [Odoc_types.Merge_see]) ;
(M.merge_since, [Odoc_types.Merge_since]) ;
(M.merge_deprecated, [Odoc_types.Merge_deprecated]) ;
(M.merge_param, [Odoc_types.Merge_param]) ;
(M.merge_raised_exception, [Odoc_types.Merge_raised_exception]) ;
(M.merge_return_value, [Odoc_types.Merge_return_value]) ;
(M.merge_custom, [Odoc_types.Merge_custom]) ;
(M.merge_all, Odoc_types.all_merge_options)
]
in
analyse_option_string l s
let classic = Clflags.classic
let dump = ref (None : string option)
let load = ref ([] : string list)
(** Allow arbitrary recursive types. *)
let recursive_types = Clflags.recursive_types
let verbose = ref false
(** Optional preprocessor command. *)
let preprocessor = Clflags.preprocessor
let sort_modules = ref false
let no_custom_tags = ref false
let no_stop = ref false
let remove_stars = ref false
let keep_code = ref false
let inverse_merge_ml_mli = ref false
let title = ref (None : string option)
let intro_file = ref (None : string option)
let with_parameter_list = ref false
let hidden_modules = ref ([] : string list)
let target_dir = ref Filename.current_dir_name
let css_style = ref None
let index_only = ref false
let colorize_code = ref false
let html_short_functors = ref false
let with_header = ref true
let with_trailer = ref true
let separate_files = ref false
let latex_titles = ref [
1, "section" ;
2, "subsection" ;
3, "subsubsection" ;
4, "paragraph" ;
5, "subparagraph" ;
]
let with_toc = ref true
let with_index = ref true
let esc_8bits = ref false
let info_section = ref "Objective Caml"
let info_entry = ref []
let files = ref []
let f_latex_title s =
try
let pos = String.index s ',' in
let n = int_of_string (String.sub s 0 pos) in
let len = String.length s in
let command = String.sub s (pos + 1) (len - pos - 1) in
latex_titles := List.remove_assoc n !latex_titles ;
latex_titles := (n, command) :: !latex_titles
with
Not_found
| Invalid_argument _ ->
incr Odoc_global.errors ;
prerr_endline (M.wrong_format s)
let add_hidden_modules s =
let l = Str.split (Str.regexp ",") s in
List.iter
(fun n ->
let name = Str.global_replace (Str.regexp "[ \n\r\t]+") "" n in
match name with
"" -> ()
| _ ->
match name.[0] with
'A'..'Z' -> hidden_modules := name :: !hidden_modules
| _ ->
incr Odoc_global.errors;
prerr_endline (M.not_a_module_name name)
)
l
let latex_value_prefix = ref M.default_latex_value_prefix
let latex_type_prefix = ref M.default_latex_type_prefix
let latex_exception_prefix = ref M.default_latex_exception_prefix
let latex_module_prefix = ref M.default_latex_module_prefix
let latex_module_type_prefix = ref M.default_latex_module_type_prefix
let latex_class_prefix = ref M.default_latex_class_prefix
let latex_class_type_prefix = ref M.default_latex_class_type_prefix
let latex_attribute_prefix = ref M.default_latex_attribute_prefix
let latex_method_prefix = ref M.default_latex_method_prefix
let set_doc_generator (dg_opt : doc_generator option) = doc_generator := dg_opt
(** The default html generator. Initialized in the parse function, to be used during the command line analysis.*)
let default_html_generator = ref (None : doc_generator option)
(** The default latex generator. Initialized in the parse function, to be used during the command line analysis.*)
let default_latex_generator = ref (None : doc_generator option)
(** The default texinfo generator. Initialized in the parse function, to be used during the command line analysis.*)
let default_texi_generator = ref (None : doc_generator option)
(** The default man pages generator. Initialized in the parse function, to be used during the command line analysis.*)
let default_man_generator = ref (None : doc_generator option)
(** The default dot generator. Initialized in the parse function, to be used during the command line analysis.*)
let default_dot_generator = ref (None : doc_generator option)
(** The default option list *)
let options = ref [
"-version", Arg.Unit (fun () -> print_string M.message_version ; print_newline () ; exit 0) , M.option_version ;
"-v", Arg.Unit (fun () -> verbose := true), M.verbose_mode ;
"-I", Arg.String (fun s -> include_dirs := (Misc.expand_directory Config.standard_library s) :: !include_dirs), M.include_dirs ;
"-pp", Arg.String (fun s -> preprocessor := Some s), M.preprocess ;
"-impl", Arg.String (fun s -> files := !files @ [Impl_file s]), M.option_impl ;
"-intf", Arg.String (fun s -> files := !files @ [Intf_file s]), M.option_intf ;
"-text", Arg.String (fun s -> files := !files @ [Text_file s]), M.option_text ;
"-rectypes", Arg.Set recursive_types, M.rectypes ;
"-nolabels", Arg.Unit (fun () -> classic := true), M.nolabels ;
"-warn-error", Arg.Set Odoc_global.warn_error, M.werr ;
"-o", Arg.String (fun s -> out_file := s), M.out_file ;
"-d", Arg.String (fun s -> target_dir := s), M.target_dir ;
"-sort", Arg.Unit (fun () -> sort_modules := true), M.sort_modules ;
"-no-stop", Arg.Set no_stop, M.no_stop ;
"-no-custom-tags", Arg.Set no_custom_tags, M.no_custom_tags ;
"-stars", Arg.Set remove_stars, M.remove_stars ;
"-inv-merge-ml-mli", Arg.Set inverse_merge_ml_mli, M.inverse_merge_ml_mli ;
"-keep-code", Arg.Set keep_code, M.keep_code^"\n" ;
"-dump", Arg.String (fun s -> dump := Some s), M.dump ;
"-load", Arg.String (fun s -> load := !load @ [s]), M.load^"\n" ;
"-t", Arg.String (fun s -> title := Some s), M.option_title ;
"-intro", Arg.String (fun s -> intro_file := Some s), M.option_intro ;
"-hide", Arg.String add_hidden_modules, M.hide_modules ;
"-m", Arg.String (fun s -> merge_options := !merge_options @ (analyse_merge_options s)),
M.merge_options ^
"\n\n *** choosing a generator ***\n";
(* generators *)
"-html", Arg.Unit (fun () -> set_doc_generator !default_html_generator), M.generate_html ;
"-latex", Arg.Unit (fun () -> set_doc_generator !default_latex_generator), M.generate_latex ;
"-texi", Arg.Unit (fun () -> set_doc_generator !default_texi_generator), M.generate_texinfo ;
"-man", Arg.Unit (fun () -> set_doc_generator !default_man_generator), M.generate_man ;
"-dot", Arg.Unit (fun () -> set_doc_generator !default_dot_generator), M.generate_dot ;
"-customdir", Arg.Unit (fun () -> Printf.printf "%s\n" Odoc_config.custom_generators_path; exit 0),
M.display_custom_generators_dir ;
"-i", Arg.String (fun s -> if !bytecode_mode then () else (prerr_endline (M.option_not_in_native_code "-i"); exit 1)),
M.add_load_dir ;
"-g", Arg.String (fun s -> if !bytecode_mode then () else (prerr_endline (M.option_not_in_native_code "-g"); exit 1)),
M.load_file ^
"\n\n *** HTML options ***\n";
(* html only options *)
"-all-params", Arg.Set with_parameter_list, M.with_parameter_list ;
"-css-style", Arg.String (fun s -> css_style := Some s), M.css_style ;
"-index-only", Arg.Set index_only, M.index_only ;
"-colorize-code", Arg.Set colorize_code, M.colorize_code ;
"-short-functors", Arg.Set html_short_functors, M.html_short_functors ^
"\n\n *** LaTeX options ***\n";
(* latex only options *)
"-noheader", Arg.Unit (fun () -> with_header := false), M.no_header ;
"-notrailer", Arg.Unit (fun () -> with_trailer := false), M.no_trailer ;
"-sepfiles", Arg.Set separate_files, M.separate_files ;
"-latextitle", Arg.String f_latex_title, M.latex_title latex_titles ;
"-latex-value-prefix", Arg.String (fun s -> latex_value_prefix := s), M.latex_value_prefix ;
"-latex-type-prefix", Arg.String (fun s -> latex_type_prefix := s), M.latex_type_prefix ;
"-latex-exception-prefix", Arg.String (fun s -> latex_exception_prefix := s), M.latex_exception_prefix ;
"-latex-attribute-prefix", Arg.String (fun s -> latex_attribute_prefix := s), M.latex_attribute_prefix ;
"-latex-method-prefix", Arg.String (fun s -> latex_method_prefix := s), M.latex_method_prefix ;
"-latex-module-prefix", Arg.String (fun s -> latex_module_prefix := s), M.latex_module_prefix ;
"-latex-module-type-prefix", Arg.String (fun s -> latex_module_type_prefix := s), M.latex_module_type_prefix ;
"-latex-class-prefix", Arg.String (fun s -> latex_class_prefix := s), M.latex_class_prefix ;
"-latex-class-type-prefix", Arg.String (fun s -> latex_class_type_prefix := s), M.latex_class_type_prefix ;
"-notoc", Arg.Unit (fun () -> with_toc := false),
M.no_toc ^
"\n\n *** texinfo options ***\n";
(* tex only options *)
"-noindex", Arg.Clear with_index, M.no_index ;
"-esc8", Arg.Set esc_8bits, M.esc_8bits ;
"-info-section", Arg.String ((:=) info_section), M.info_section ;
"-info-entry", Arg.String (fun s -> info_entry := !info_entry @ [ s ]),
M.info_entry ^
"\n\n *** dot options ***\n";
(* dot only options *)
"-dot-colors", Arg.String (fun s -> dot_colors := Str.split (Str.regexp_string ",") s), M.dot_colors ;
"-dot-include-all", Arg.Set dot_include_all, M.dot_include_all ;
"-dot-types", Arg.Set dot_types, M.dot_types ;
"-dot-reduce", Arg.Set dot_reduce, M.dot_reduce^
"\n\n *** man pages options ***\n";
(* man only options *)
"-man-mini", Arg.Set man_mini, M.man_mini ;
"-man-suffix", Arg.String (fun s -> man_suffix := s), M.man_suffix ;
"-man-section", Arg.String (fun s -> man_section := s), M.man_section ;
]
let add_option o =
let (s,_,_) = o in
let rec iter = function
[] -> [o]
| (s2,f,m) :: q ->
if s = s2 then
o :: q
else
(s2,f,m) :: (iter q)
in
options := iter !options
let parse ~html_generator ~latex_generator ~texi_generator ~man_generator ~dot_generator =
let anonymous f =
let sf =
if Filename.check_suffix f "ml" then
Impl_file f
else
if Filename.check_suffix f "mli" then
Intf_file f
else
if Filename.check_suffix f "txt" then
Text_file f
else
failwith (Odoc_messages.unknown_extension f)
in
files := !files @ [sf]
in
default_html_generator := Some html_generator ;
default_latex_generator := Some latex_generator ;
default_texi_generator := Some texi_generator ;
default_man_generator := Some man_generator ;
default_dot_generator := Some dot_generator ;
let _ = Arg.parse !options
anonymous
(M.usage^M.options_are)
in
(* we sort the hidden modules by name, to be sure that for example,
A.B is before A, so we will match against A.B before A in
Odoc_name.hide_modules.*)
hidden_modules := List.sort (fun a -> fun b -> - (compare a b)) !hidden_modules