1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
(***********************************************************************)
(* OCamldoc *)
(* *)
(* Maxence Guesdon, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 2010 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. *)
(* *)
(***********************************************************************)
(* $Id$ *)
(** An OCamldoc generator to retrieve information in "todo" tags and
generate an html page with all todo items. *)
open Odoc_info
module Naming = Odoc_html.Naming
open Odoc_info.Value
open Odoc_info.Module
open Odoc_info.Type
open Odoc_info.Exception
open Odoc_info.Class
let p = Printf.bprintf
module Html =
(val
(
match !Odoc_args.current_generator with
None -> (module Odoc_html.Generator : Odoc_html.Html_generator)
| Some (Odoc_gen.Html m) -> m
| _ ->
failwith
"A non-html generator is already set. Cannot install the Todo-list html generator"
) : Odoc_html.Html_generator)
;;
module Generator =
struct
class scanner html =
object (self)
inherit Odoc_info.Scan.scanner
val b = Buffer.create 256
method buffer = b
method private gen_if_tag name target info_opt =
match info_opt with
None -> ()
| Some i ->
let l =
List.fold_left
(fun acc (t, text) ->
match t with
"todo" ->
begin
match text with
(Odoc_info.Code s) :: q ->
(
try
let n = int_of_string s in
let head =
Odoc_info.Code (Printf.sprintf "[%d] " n)
in
(Some n, head::q) :: acc
with _ -> (None, text) :: acc
)
| _ -> (None, text) :: acc
end
| _ -> acc
)
[]
i.i_custom
in
match l with
[] -> ()
| _ ->
let l = List.sort
(fun a b ->
match a, b with
(None, _), _ -> -1
| _, (None, _) -> 1
| (Some n1, _), (Some n2, _) -> compare n1 n2
)
l
in
p b "<pre><a href=\"%s\">%s</a></pre><div class=\"info\">"
target name;
let col = function
None -> "#000000"
| Some 1 -> "#FF0000"
| Some 2 -> "#AA5555"
| Some 3 -> "#44BB00"
| Some n -> Printf.sprintf "#%2x0000" (0xAA - (n * 0x10))
in
List.iter
(fun (n, e) ->
Printf.bprintf b "<span style=\"color: %s\">" (col n);
html#html_of_text b e;
p b "</span><br/>\n";
)
l;
p b "</div>"
method scan_value v =
self#gen_if_tag
v.val_name
(Odoc_html.Naming.complete_value_target v)
v.val_info
method scan_type t =
self#gen_if_tag
t.ty_name
(Odoc_html.Naming.complete_type_target t)
t.ty_info
method scan_exception e =
self#gen_if_tag
e.ex_name
(Odoc_html.Naming.complete_exception_target e)
e.ex_info
method scan_attribute a =
self#gen_if_tag
a.att_value.val_name
(Odoc_html.Naming.complete_attribute_target a)
a.att_value.val_info
method scan_method m =
self#gen_if_tag
m.met_value.val_name
(Odoc_html.Naming.complete_method_target m)
m.met_value.val_info
(** This method scan the elements of the given module. *)
method scan_module_elements m =
List.iter
(fun ele ->
match ele with
Odoc_module.Element_module m -> self#scan_module m
| Odoc_module.Element_module_type mt -> self#scan_module_type mt
| Odoc_module.Element_included_module im -> self#scan_included_module im
| Odoc_module.Element_class c -> self#scan_class c
| Odoc_module.Element_class_type ct -> self#scan_class_type ct
| Odoc_module.Element_value v -> self#scan_value v
| Odoc_module.Element_exception e -> self#scan_exception e
| Odoc_module.Element_type t -> self#scan_type t
| Odoc_module.Element_module_comment t -> self#scan_module_comment t
)
(Odoc_module.module_elements ~trans: false m)
method scan_included_module _ = ()
method scan_class_pre c =
self#gen_if_tag
c.cl_name
(fst (Odoc_html.Naming.html_files c.cl_name))
c.cl_info;
true
method scan_class_type_pre ct =
self#gen_if_tag
ct.clt_name
(fst (Odoc_html.Naming.html_files ct.clt_name))
ct.clt_info;
true
method scan_module_pre m =
self#gen_if_tag
m.m_name
(fst (Odoc_html.Naming.html_files m.m_name))
m.m_info;
true
method scan_module_type_pre mt =
self#gen_if_tag
mt.mt_name
(fst (Odoc_html.Naming.html_files mt.mt_name))
mt.mt_info;
true
end
class html : Html.html =
object (self)
inherit Html.html as html
(** we have to hack a little because we cannot inherit from
scanner, since public method cannot be hidden and
our html class must respect the type of the default
html generator class *)
val mutable scanner = new scanner (new Html.html )
method generate modules =
(* prevent having the 'todo' tag signaled as not handled *)
tag_functions <- ("todo", (fun _ -> "")) :: tag_functions;
(* generate doc as usual *)
html#generate modules;
(* then retrieve the todo tags and generate the todo.html page *)
let title =
match !Odoc_info.Global.title with
None -> ""
| Some s -> s
in
let b = Buffer.create 512 in
p b "<html>";
self#print_header b title ;
p b "<body><h1>%s</h1>" title;
scanner#scan_module_list modules;
Buffer.add_buffer b scanner#buffer;
let oc = open_out
(Filename.concat !Odoc_info.Global.target_dir "todo.html")
in
Buffer.output_buffer oc b;
close_out oc
initializer
scanner <- new scanner self
end
end
let _ = Odoc_args.set_generator
(Odoc_gen.Html (module Generator : Odoc_html.Html_generator))
;;
|