(************************************************************************) (* * The Rocq Prover / The Rocq Development Team *) (* v * Copyright INRIA, CNRS and contributors *) (* <O___,, * (see version control and CREDITS file for authors & dates) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************)
open Common open Index
(*s Low level output *)
let output_char c = output_char !out_channel c
let output_string s = output_string !out_channel s
let printf s = Printf.fprintf !out_channel s
let sprintf = Printf.sprintf
(*s Rocq keywords *)
let build_table l = let h = Hashtbl.create 101 in List.iter (fun key ->Hashtbl.add h key ()) l;
function s -> try Hashtbl.find h s; truewith Not_found -> false
let current_module : (string * stringoption) ref = ref ("",None)
let get_module withsub = let (m,sub) = !current_module in if withsub then matchsubwith
| None -> m
| Some sub -> m ^ ": " ^ sub else
m
let set_module m sub = current_module := (m,sub);
page_title := get_module true
(*s Common to both LaTeX and HTML *)
let item_level = ref 0 let in_doc = reffalse
(*s Customized and predefined pretty-print *)
let initialize_texmacs () = let ensuremath x = sprintf "<with|mode|math|\\<%s\\>>" x in List.fold_right (fun (s,t) tt -> Tokens.ttree_add tt s t)
[ "*", ensuremath "times"; "->", ensuremath "rightarrow"; "<-", ensuremath "leftarrow"; "<->", ensuremath "leftrightarrow"; "=>", ensuremath "Rightarrow"; "<=", ensuremath "le"; ">=", ensuremath "ge"; "<>", ensuremath "noteq"; "~", ensuremath "lnot"; "/\\", ensuremath "land"; "\\/", ensuremath "lor"; "|-", ensuremath "vdash"
] Tokens.empty_ttree
let token_tree_texmacs = ref (initialize_texmacs ())
let token_tree_latex = ref Tokens.empty_ttree let token_tree_html = ref Tokens.empty_ttree
let initialize_tex_html () = let if_utf8 = if !prefs.encoding.utf8 thenfun x -> Some x elsefun _ -> None in let (tree_latex, tree_html) = List.fold_right (fun (s,l,l') (tt,tt') ->
(Tokens.ttree_add tt s l, match l' with None -> tt' | Some l' -> Tokens.ttree_add tt' s l'))
[ "*" , "\\ensuremath{\\times}", if_utf8 "×"; "|", "\\ensuremath{|}", None; "->", "\\ensuremath{\\rightarrow}", if_utf8 "→"; "->~", "\\ensuremath{\\rightarrow\\lnot}", None; "->~~", "\\ensuremath{\\rightarrow\\lnot\\lnot}", None; "<-", "\\ensuremath{\\leftarrow}", None; "<->", "\\ensuremath{\\leftrightarrow}", if_utf8 "↔"; "=>", "\\ensuremath{\\Rightarrow}", if_utf8 "⇒"; "<=", "\\ensuremath{\\le}", if_utf8 "≤"; ">=", "\\ensuremath{\\ge}", if_utf8 "≥"; "<>", "\\ensuremath{\\not=}", if_utf8 "≠"; "~", "\\ensuremath{\\lnot}", if_utf8 "¬"; "/\\", "\\ensuremath{\\land}", if_utf8 "∧"; "\\/", "\\ensuremath{\\lor}", if_utf8 "∨"; "|-", "\\ensuremath{\\vdash}", None; "forall", "\\ensuremath{\\forall}", if_utf8 "∀"; "exists", "\\ensuremath{\\exists}", if_utf8 "∃"; "Π", "\\ensuremath{\\Pi}", if_utf8 "Π"; "λ", "\\ensuremath{\\lambda}", if_utf8 "λ"; (* "fun", "\\ensuremath{\\lambda}" ? *)
] (Tokens.empty_ttree,Tokens.empty_ttree) in
token_tree_latex := tree_latex;
token_tree_html := tree_html
let add_printing_token s (t1,t2) =
(match t1 with None -> () | Some t1 ->
token_tree_latex := Tokens.ttree_add !token_tree_latex s t1);
(match t2 with None -> () | Some t2 ->
token_tree_html := Tokens.ttree_add !token_tree_html s t2)
let remove_printing_token s =
token_tree_latex := Tokens.ttree_remove !token_tree_latex s;
token_tree_html := Tokens.ttree_remove !token_tree_html s
(*s Table of contents *)
type toc_entry =
| Toc_library ofstring * stringoption
| Toc_section of int * (unit -> unit) * string
let (toc_q : toc_entry Queue.t) = Queue.create ()
let add_toc_entry e = Queue.add e toc_q
let new_label = let r = ref 0 infun () -> incr r; "lab" ^ string_of_int !r
(*s LaTeX output *)
module Latex = struct
let in_title = reffalse
(*s Latex preamble *)
let (preamble : string Queue.t) = Queue.create ()
let push_in_preamble s = Queue.add s preamble
let utf8x_extra_support () =
printf "\n";
printf "%%Warning: tipa declares many non-standard macros used by utf8x to\n";
printf "%%interpret utf8 characters but extra packages might have to be added\n";
printf "%%such as \"textgreek\" for Greek letters not already in tipa\n";
printf "%%or \"stmaryrd\" for mathematical symbols.\n";
printf "%%Utf8 codes missing a LaTeX interpretation can be defined by using\n";
printf "%%\\DeclareUnicodeCharacter{code}{interpretation}.\n";
printf "%%Use coqdoc's option -p to add new packages or declarations.\n";
printf "\\usepackage{tipa}\n";
printf "\n"
let header () = if !prefs.header_trailer thenbegin
printf "\\documentclass[12pt]{report}\n"; if !prefs.encoding.inputenc != ""then
printf "\\usepackage[%s]{inputenc}\n" !prefs.encoding.inputenc; if !prefs.encoding.inputenc = "utf8x"then utf8x_extra_support ();
printf "\\usepackage[T1]{fontenc}\n";
printf "\\usepackage{fullpage}\n";
printf "\\usepackage{coqdoc}\n";
printf "\\usepackage{amsmath,amssymb}\n";
printf "\\usepackage{url}\n";
(match !prefs.toc_depth with
| None -> ()
| Some n -> printf "\\setcounter{tocdepth}{%i}\n" n);
Queue.iter (fun s -> printf "%s\n" s) preamble;
printf "\\begin{document}\n" end;
output_string "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
output_string "%% This file has been automatically generated with the command\n";
output_string "%% ";
Array.iter (fun s -> printf "%s " s) Sys.argv;
printf "\n";
output_string "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
let trailer () = if !prefs.header_trailer thenbegin
printf "\\end{document}\n" end
(*s Latex low-level translation *)
let nbsp () = output_char '~'
let char c = match c with
| '\\' ->
printf "\\symbol{92}"
| '$' | '#' | '%' | '&' | '{' | '}' | '_' ->
output_char '\\'; output_char c
| '^' | '~' ->
output_char '\\'; output_char c; printf "{}"
| _ ->
output_char c
let label_char c = match c with
| '_' -> output_char ' '
| '\\' | '$' | '#' | '%' | '&' | '{' | '}'
| '^' | '~' -> printf "x%X" (Char.code c)
| _ -> if c >= '\x80'then printf "x%X" (Char.code c) else output_char c
let label_ident s =
for i = 0 to String.length s - 1 do label_char s.[i] done
let latex_char = output_char let latex_string = output_string
let html_char _ = () let html_string _ = ()
(*s Latex char escaping *)
let escaped = let buff = Buffer.create 5 in fun s ->
Buffer.clear buff;
for i = 0 to String.length s - 1 do match s.[i] with
| '\\' ->
Buffer.add_string buff "\\symbol{92}"
| '$' | '#' | '%' | '&' | '{' | '}' | '_' as c ->
Buffer.add_char buff '\\'; Buffer.add_char buff c
| '^' | '~' as c ->
Buffer.add_char buff '\\'; Buffer.add_char buff c;
Buffer.add_string buff "{}"
| '\'' -> if i < String.length s - 1 && s.[i+1] = '\'' then begin
Buffer.add_char buff '\''; Buffer.add_char buff '{';
Buffer.add_char buff '}' endelse
Buffer.add_char buff '\''
| c ->
Buffer.add_char buff c
done;
Buffer.contents buff
(*s Latex reference and symbol translation *)
let start_module () = let ln = !prefs.lib_name in ifnot !prefs.short thenbegin
printf "\\coqlibrary{";
label_ident (get_module false);
printf "}{"; if ln <> ""then printf "%s " ln;
printf "}{%s}\n\n" (escaped (get_module true)) end
let start_latex_math () = output_char '$'
let stop_latex_math () = output_char '$'
let start_quote () = output_char '`'; output_char '`' let stop_quote () = output_char '\''; output_char '\''
let start_verbatim inline = if inline then printf "\\texttt{" else printf "\\begin{verbatim}\n"
let stop_verbatim inline = if inline then printf "}" else printf "\\end{verbatim}\n"
let url addr name =
printf "%s\\footnote{\\url{%s}}"
(match name with
| None -> ""
| Some n -> n)
addr
let indentation n = if n == 0 then
printf "\\coqdocnoindent\n" else let space = 0.5 *. (float n) in
printf "\\coqdocindent{%2.2fem}\n" space
let ident_ref m fid typ s = let id = if fid <> ""then (m ^ "." ^ fid) else m in match find_module m with
| Local ->
printf "\\coqref{"; label_ident id;
printf "}{\\coqdoc%s{%s}}" (type_name typ) s
| External m when !prefs.externals ->
printf "\\coqexternalref{"; label_ident fid;
printf "}{%s}{\\coqdoc%s{%s}}" (escaped m) (type_name typ) s
| External _ | Unknown ->
printf "\\coqdoc%s{%s}" (type_name typ) s
let defref m id ty s = if ty <> Notation then
(printf "\\coqdef{"; label_ident (m ^ "." ^ id);
printf "}{%s}{\\coqdoc%s{%s}}" s (type_name ty) s) else (* Glob file still not able to say the exact extent of the definition *) (* so we currently renounce to highlight the notation location *)
(printf "\\coqdef{"; label_ident (m ^ "." ^ id);
printf "}{%s}{%s}" s s)
let reference s = function
| Def [] -> assert false
| Def ((fullid,typ) :: _) ->
defref (get_module false) fullid typ s
| Ref (m,fullid,typ) ->
ident_ref m fullid typ s
(*s The sublexer buffers symbol characters and attached uninterpreted ident and try to apply special translation such as, predefined, translation "->" to "\ensuremath{\rightarrow}" or,
virtually, a user-level translation from "=_h" to "\ensuremath{=_{h}}" *)
let output_sublexer_string doescape issymbchar tag s = let s = if doescape then escaped s else s in match tag with
| Some ref -> reference s ref
| None -> if issymbchar then output_string s else printf "\\coqdocvar{%s}" s
let last_was_in = reffalse
let sublexer c loc = if c = '*' && !last_was_in thenbegin
Tokens.flush_sublexer ();
output_char '*' endelsebegin let tag = try Some (Index.find (get_module false) loc) with Not_found -> None in
Tokens.output_tagged_symbol_char tag c end;
last_was_in := false
let sublexer_in_doc c = if c = '*' && !last_was_in thenbegin
Tokens.flush_sublexer ();
output_char '*' endelse
Tokens.output_tagged_symbol_char None c;
last_was_in := false
(*s Interpreting ident with fallback on sublexer if unknown ident *)
let translate s = match Tokens.translate s with Some s -> s | None -> escaped s
let keyword s loc =
printf "\\coqdockw{%s}" (translate s)
let ident s loc =
last_was_in := s = "in"; try match loc with
| None -> raise Not_found
| Some loc -> let tag = Index.find (get_module false) loc in
reference (translate s) tag with Not_found -> if is_tactic s then
printf "\\coqdoctac{%s}" (translate s) elseif is_keyword s then
printf "\\coqdockw{%s}" (translate s) elseif !prefs.interpolate && !in_doc (* always a var otherwise *) then try let tag = Index.find_string s in
reference (translate s) tag with _ -> Tokens.output_tagged_ident_string s else Tokens.output_tagged_ident_string s
let ident s l = if !in_title then (
printf "\\texorpdfstring{\\protect";
ident s l;
printf "}{%s}" (translate s)) else
ident s l
(*s Translating structure *)
let proofbox () = printf "\\ensuremath{\\Box}"
let rec reach_item_level n = if !item_level < n thenbegin
printf "\n\\begin{itemize}\n\\item "; incr item_level;
reach_item_level n endelseif !item_level > n thenbegin
printf "\n\\end{itemize}\n"; decr item_level;
reach_item_level n end
let item n = let old_level = !item_level in
reach_item_level n; if n <= old_level then printf "\n\\item "
let stop_item () = reach_item_level 0
let start_doc () = in_doc := true
let end_doc () = in_doc := false; stop_item ()
(* This is broken if we are in math mode, but coqdoc currently isn't
tracking that *) let start_emph () = printf "\\textit{"
let stop_emph () = printf "}"
let start_details _ = ()
let stop_details () = ()
let start_comment () = printf "\\begin{coqdoccomment}\n"
let end_comment () = printf "\\end{coqdoccomment}\n"
let section lev f =
stop_item ();
output_string (section_kind lev);
in_title := true; f (); in_title := false;
printf "}\n\n"
let rule () =
printf "\\par\n\\noindent\\hrulefill\\par\n\\noindent{}"
let paragraph () = printf "\n\n"
let line_break () = printf "\\coqdoceol\n"
let empty_line_of_code () = printf "\\coqdocemptyline\n"
let start_inline_coq_block () = line_break (); empty_line_of_code ()
let end_inline_coq_block () = empty_line_of_code ()
let start_inline_coq () = ()
let end_inline_coq () = ()
let make_multi_index () = ()
let make_index () = ()
let make_toc () = printf "\\tableofcontents\n"
end
(*s HTML output *)
module Html = struct
let header () = if !prefs.header_trailer then if !prefs.header_file_spec then let cin = open_in !prefs.header_file in try whiletruedo let s = input_line cin in
printf "%s\n" s
done with End_of_file -> close_in cin else begin
printf "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n";
printf "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
printf "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n";
printf "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\" />\n" !prefs.encoding.charset;
printf "<link href=\"coqdoc.css\" rel=\"stylesheet\" type=\"text/css\" />\n";
printf "<title>%s</title>\n</head>\n\n" !page_title;
printf "<body>\n\n<div id=\"page\">\n\n<div id=\"header\">\n</div>\n\n";
printf "<div id=\"main\">\n\n" end
let trailer () = if !prefs.header_trailer && !prefs.footer_file_spec then let cin = open_in !prefs.footer_file in try whiletruedo let s = input_line cin in
printf "%s\n" s
done with End_of_file -> close_in cin else begin if !prefs.index && (get_module false) <> "Index"then
printf "</div>\n\n<div id=\"footer\">\n<hr/><a href=\"%s.html\">Index</a>" !prefs.index_name;
printf "<hr/>This page has been generated by ";
printf "<a href=\"%s\">coqdoc</a>\n" Coq_config.wwwcoq;
printf "</div>\n\n</div>\n\n</body>\n</html>" end
let start_module () = let ln = !prefs.lib_name in ifnot !prefs.short thenbegin let (m,sub) = !current_module in
add_toc_entry (Toc_library (m,sub)); if ln = ""then
printf "<h1 class=\"libtitle\">%s</h1>\n\n" (get_module true) else
printf "<h1 class=\"libtitle\">%s %s</h1>\n\n" ln (get_module true) end
let indentation n = for _i = 1 to n do printf " " done
let line_break () = printf "<br/>\n"
let empty_line_of_code () =
printf "\n<br/>\n"
let nbsp () = printf " "
let char = function
| '<' -> printf "<"
| '>' -> printf ">"
| '&' -> printf "&"
| c -> output_char c
let escaped = let buff = Buffer.create 5 in fun s ->
Buffer.clear buff;
for i = 0 to String.length s - 1 do match s.[i] with
| '<' -> Buffer.add_string buff "<"
| '>' -> Buffer.add_string buff ">"
| '&' -> Buffer.add_string buff "&"
| '\"' -> Buffer.add_string buff """
| c -> Buffer.add_char buff c
done;
Buffer.contents buff
let sanitize_name s = let rec loop esc i = if i < 0 thenif esc then escaped s else s elsematch s.[i] with
| 'a'..'z' | 'A'..'Z' | '0'..'9' | '.' | '_' -> loop esc (i-1)
| '<' | '>' | '&' | '\'' | '\"' -> loop true (i-1)
| '-' | ':' -> loop esc (i-1) (* should be safe in HTML5 attribute name syntax *)
| _ -> (* This name contains complex characters:
this is probably a notation string, we simply hash it. *)
Digest.to_hex (Digest.string s) in loop false (String.length s - 1)
let latex_char _ = () let latex_string _ = ()
let html_char = output_char let html_string = output_string
let start_latex_math () = () let stop_latex_math () = ()
let start_quote () = char '"' let stop_quote () = start_quote ()
let start_verbatim inline = if inline then printf "<code>" else printf "<pre>\n"
let stop_verbatim inline = if inline then printf "</code>" else printf "</pre>\n"
let url addr name =
printf "<a href=\"%s\">%s</a>" addr
(match name with
| Some n -> n
| None -> addr)
let ident_ref m fid typ s = match find_module m with
| Local ->
printf "<a class=\"idref\" href=\"%s.html#%s\">" m (sanitize_name fid);
printf "<span class=\"id\" title=\"%s\">%s</span></a>" typ s
| External m when !prefs.externals ->
printf "<a class=\"idref\" href=\"%s.html#%s\">" m (sanitize_name fid);
printf "<span class=\"id\" title=\"%s\">%s</span></a>" typ s
| External _ | Unknown ->
printf "<span class=\"id\" title=\"%s\">%s</span>" typ s
let reference s r = match r with
| Def [] -> assert false
| Def [fullid,ty] -> let s' = sanitize_name fullid in
printf "<a id=\"%s\" class=\"idref\" href=\"#%s\">" s' s';
printf "<span class=\"id\" title=\"%s\">%s</span></a>" (type_name ty) s
| Def ((hd_id,_) :: tail as all) -> let hd = sanitize_name hd_id in let all_tys = all
|> List.map (fun (_,ty) -> type_name ty)
|> CList.sort_uniquize String.compare
|> String.concat ", "in
printf "<a id=\"%s\" class=\"idref\" href=\"#%s\"><span class=\"id\" title=\"%s\">" hd hd all_tys; List.iter (fun (fullid,_) -> let s' = sanitize_name fullid in
printf "<span id=\"%s\" class=\"id\">" s')
tail;
printf "%s" s; List.iter (fun _ -> printf "</span>") tail;
printf "</span></a>";
| Ref (m,fullid,ty) ->
ident_ref m fullid (type_name ty) s
let output_sublexer_string doescape issymbchar tag s = let s = if doescape then escaped s else s in match tag with
| Some ref -> reference s ref
| None -> if issymbchar then output_string s else printf "<span class=\"id\" title=\"var\">%s</span>" s
let sublexer c loc = let tag = try Some (Index.find (get_module false) loc) with Not_found -> None in
Tokens.output_tagged_symbol_char tag c
let sublexer_in_doc c =
Tokens.output_tagged_symbol_char None c
let translate s = match Tokens.translate s with Some s -> s | None -> escaped s
let keyword s loc =
printf "<span class=\"id\" title=\"keyword\">%s</span>" (translate s)
let ident s loc = try match loc with
| None -> raise Not_found
| Some loc ->
reference (translate s) (Index.find (get_module false) loc) with Not_found -> if is_tactic s then
printf "<span class=\"id\" title=\"tactic\">%s</span>" (translate s) elseif is_keyword s then
printf "<span class=\"id\" title=\"keyword\">%s</span>" (translate s) elseif !prefs.interpolate && !in_doc (* always a var otherwise *) then try reference (translate s) (Index.find_string s) with Not_found -> Tokens.output_tagged_ident_string s else
Tokens.output_tagged_ident_string s
let proofbox () = printf "<font size=-2>☐</font>"
let rec reach_item_level n = if !item_level < n thenbegin
printf "<ul class=\"doclist\">\n<li>"; incr item_level;
reach_item_level n endelseif !item_level > n thenbegin
printf "\n</li>\n</ul>\n"; decr item_level;
reach_item_level n end
let item n = let old_level = !item_level in
reach_item_level n; if n <= old_level then printf "\n</li>\n<li>"
let stop_item () = reach_item_level 0
let start_coq () = ifnot !prefs.raw_comments then printf "<div class=\"code\">\n"
let end_coq () = ifnot !prefs.raw_comments then printf "</div>\n"
let start_doc () = in_doc := true; ifnot !prefs.raw_comments then
printf "\n<div class=\"doc\">\n"
let end_doc () = in_doc := false;
stop_item (); ifnot !prefs.raw_comments then printf "</div>\n"
let start_emph () = printf "<i>"
let stop_emph () = printf "</i>"
let start_details = function
| Some s -> printf "<details><summary>%s</summary>" s
| _ -> printf "<details>"
let stop_details () = printf "</details>"
let start_comment () = printf "<span class=\"comment\">(*"
let end_comment () = printf "*)</span>"
let start_inline_coq () = if !prefs.inline_notmono then printf "<span class=\"inlinecodenm\">" else printf "<span class=\"inlinecode\">"
let end_inline_coq () = printf "</span>"
let start_inline_coq_block () = line_break (); start_inline_coq ()
let end_inline_coq_block () = end_inline_coq ()
let paragraph () = printf "\n<div class=\"paragraph\"> </div>\n\n"
(* inference rules *) let inf_rule assumptions (_,_,midnm) conclusions = (* this first function replaces any occurrence of 3 or more spaces in a row with " "s. We do this to the assumptions so that
people can put multiple rules on a line with nice formatting *) let replace_spaces str = let rec copy a n = match n with 0 -> [] | n -> (a :: copy a (n - 1)) in let results = Str.full_split (Str.regexp "[' '][' '][' ']+") str in let strs = List.map (fun r -> match r with
| Str.Text s -> [s]
| Str.Delim s ->
copy " " (String.length s))
results in String.concat "" (List.concat strs) in let start_assumption line =
(printf "<tr class=\"infruleassumption\">\n";
printf " <td class=\"infrule\">%s</td>\n" (replace_spaces line)) in let end_assumption () =
(printf " <td></td>\n";
printf "</tr>\n") in let rec print_assumptions hyps = match hyps with
| [] -> start_assumption " "
| [(_,hyp)] -> start_assumption hyp
| ((_,hyp) :: hyps') -> (start_assumption hyp;
end_assumption ();
print_assumptions hyps') in
printf "<center><table class=\"infrule\">\n";
print_assumptions assumptions;
printf " <td class=\"infrulenamecol\" rowspan=\"3\">\n";
(match midnm with
| None -> printf " \n </td>"
| Some s -> printf " %s \n </td>" s);
printf "</tr>\n";
printf "<tr class=\"infrulemiddle\">\n";
printf " <td class=\"infrule\"><hr /></td>\n";
printf "</tr>\n";
print_assumptions conclusions;
end_assumption ();
printf "</table></center>"
let section lev f = let lab = new_label () in let r = sprintf "%s.html#%s" (get_module false) lab in
(match !prefs.toc_depth with
| None -> add_toc_entry (Toc_section (lev, f, r))
| Some n -> if lev <= n then add_toc_entry (Toc_section (lev, f, r)) else ());
stop_item ();
printf "<a id=\"%s\"></a><h%d class=\"section\">" lab lev;
f ();
printf "</h%d>\n" lev
let rule () = printf "<hr/>\n"
(* make a HTML index from a list of triples (name,text,link) *) let index_ref i c = let idxc = sprintf "%s_%c" i.idx_name c in
!prefs.index_name ^ (if !prefs.multi_index then"_" ^ idxc ^ ".html"else".html#" ^ idxc)
let letter_index category idx (c,l) = if l <> [] thenbegin let cat = if category && idx <> "global"then"(" ^ idx ^ ")"else""in
printf "<a id=\"%s_%c\"></a><h2>%s %s</h2>\n" idx c (display_letter c) cat; List.iter
(fun (id,(text,link,t)) -> let id' = escaped (prepare_entry id t) in
printf "<a href=\"%s\">%s</a> %s<br/>\n" link id' text) l;
printf "<br/><br/>" end
let all_letters i = List.iter (letter_index false i.idx_name) i.idx_entries
(* Construction d'une liste des index (1 index global, puis 1
index par catégorie) *) let format_global_index =
Index.map
(fun s (m,t) -> if t = Library then let ln = !prefs.lib_name in if ln <> ""then "[" ^ String.lowercase_ascii ln ^ "]", m ^ ".html", t else "[library]", m ^ ".html", t else
sprintf "[%s, in <a href=\"%s.html\">%s</a>]" (type_name t) m m ,
sprintf "%s.html#%s" m (sanitize_name s), t)
let format_bytype_index = function
| Library, idx ->
Index.map (fun id m -> "", m ^ ".html", Library) idx
| (t,idx) ->
Index.map
(fun s m -> let text = sprintf "[in <a href=\"%s.html\">%s</a>]" m m in
(text, sprintf "%s.html#%s" m (sanitize_name s), t)) idx
(* Impression de la table d'index *) let print_index_table_item i =
printf "<tr>\n<td>%s Index</td>\n" (String.capitalize_ascii i.idx_name); List.iter
(fun (c,l) -> if l <> [] then
printf "<td><a href=\"%s\">%s</a></td>\n" (index_ref i c)
(display_letter c) else
printf "<td>%s</td>\n" (display_letter c))
i.idx_entries; let n = i.idx_size in
printf "<td>(%d %s)</td>\n" n (if n > 1 then"entries"else"entry");
printf "</tr>\n"
let make_one_multi_index prt_tbl i = (* Attn: make_one_multi_index crée un nouveau fichier... *) let idx = i.idx_name in let one_letter ((c,l) as cl) =
open_out_file (sprintf "%s_%s_%c.html" !prefs.index_name idx c); if (!prefs.header_trailer) then header ();
prt_tbl (); printf "<hr/>";
letter_index true idx cl; ifList.length l > 30 thenbegin printf "<hr/>"; prt_tbl () end; if (!prefs.header_trailer) then trailer ();
close_out_file () in List.iter one_letter i.idx_entries
let make_multi_index () = let all_index = let glob,bt = Index.all_entries () in
(format_global_index glob) ::
(List.map format_bytype_index bt) in let print_table () = print_index_table all_index in List.iter (make_one_multi_index print_table) all_index
let make_index () = let all_index = let glob,bt = Index.all_entries () in
(format_global_index glob) ::
(List.map format_bytype_index bt) in let print_table () = print_index_table all_index in let print_one_index i = if i.idx_size > 0 thenbegin
printf "<hr/>\n<h1>%s Index</h1>\n" (String.capitalize_ascii i.idx_name);
all_letters i end in
set_module "Index" None; if !prefs.title <> ""then printf "<h1>%s</h1>\n" !prefs.title;
print_table (); ifnot (!prefs.multi_index) then begin List.iter print_one_index all_index;
printf "<hr/>"; print_table () end
let make_toc () = let ln = !prefs.lib_name in let make_toc_entry = function
| Toc_library (m,sub) ->
stop_item (); let ms = matchsubwith | None -> m | Some s -> m ^ ": " ^ s in if ln = ""then
printf "<h2><a href=\"%s.html\">%s</a></h2>\n" m ms else
printf "<h2><a href=\"%s.html\">%s %s</a></h2>\n" m ln ms
| Toc_section (n, f, r) ->
item n;
printf "<a href=\"%s\">" r; f (); printf "</a>\n" in
printf "<div id=\"toc\">\n";
Queue.iter make_toc_entry toc_q;
stop_item ();
printf "</div>\n"
let header () =
output_string "(*i This file has been automatically generated with the command \n";
output_string " "; Array.iter (fun s -> printf "%s " s) Sys.argv; printf " *)\n"
let trailer () = ()
let nbsp () = output_char ' '
let char_true c = match c with
| '\\' -> printf "\\\\"
| '<' -> printf "\\<"
| '|' -> printf "\\|"
| '>' -> printf "\\>"
| _ -> output_char c
let char c = if !in_doc then char_true c else output_char c
let latex_char = char_true let latex_string = String.iter latex_char
let html_char _ = () let html_string _ = ()
let raw_ident s =
for i = 0 to String.length s - 1 do char s.[i] done
let start_module () = ()
let start_latex_math () = printf "<with|mode|math|"
let stop_latex_math () = output_char '>'
let start_verbatim inline = in_doc := true; printf "<\\verbatim>" let stop_verbatim inline = in_doc := false; printf "</verbatim>"
let url addr name =
printf "%s<\\footnote><\\url>%s</url></footnote>" addr
(match name with
| None -> ""
| Some n -> n)
let start_quote () = output_char '`'; output_char '`' let stop_quote () = output_char '\''; output_char '\''
let indentation n = ()
let keyword s =
printf "<kw|"; raw_ident s; printf ">"
let ident_true s = if is_keyword s then keyword s else raw_ident s
let keyword s loc = keyword s let ident s _ = if !in_doc then ident_true s else raw_ident s
let output_sublexer_string doescape issymbchar tag s = if doescape then raw_ident s else output_string s
let sublexer c l = if !in_doc then Tokens.output_tagged_symbol_char None c else char c
let sublexer_in_doc c =
char c
let initialize () =
Tokens.token_tree := token_tree_texmacs;
Tokens.outfun := output_sublexer_string
let proofbox () = printf "QED"
let rec reach_item_level n = if !item_level < n thenbegin
printf "\n<\\itemize>\n<item>"; incr item_level;
reach_item_level n endelseif !item_level > n thenbegin
printf "\n</itemize>"; decr item_level;
reach_item_level n end
let item n = let old_level = !item_level in
reach_item_level n; if n <= old_level then printf "\n\n<item>"
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.