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 (***********************************************************************)
15 let len = String.length s
in
16 let buf = Buffer.create
len in
17 for i
= 0 to len - 1 do
19 ' '
| '
\n'
| '
\t'
| '
\r'
-> ()
20 | c
-> Buffer.add_char
buf c
24 let input_file_as_string nom
=
25 let chanin = open_in_bin nom
in
27 let s = String.create
len in
28 let buf = Buffer.create
len in
31 let n = input
chanin s 0 len in
36 Buffer.add_substring
buf s 0 n;
46 let split_string s chars
=
47 let len = String.length
s in
48 let rec iter acc pos
=
54 if List.mem
s.[pos
] chars
then
56 "" -> iter "" (pos
+ 1)
57 | _
-> acc
:: (iter "" (pos
+ 1))
59 iter (Printf.sprintf
"%s%c" acc
s.[pos
]) (pos
+ 1)
63 let split_with_blanks s = split_string s [' '
; '
\n'
; '
\r'
; '
\t'
]
66 let rec iter = function
69 | h
:: q
-> h
:: sep
:: q
73 let rec string_of_longident li
=
75 | Longident.Lident
s -> s
76 | Longident.Ldot
(li
, s) -> string_of_longident li ^
"." ^
s
77 | Longident.Lapply
(l1
, l2
) ->
78 string_of_longident l1 ^
"(" ^
string_of_longident l2 ^
")"
80 let get_fields type_expr
=
81 let (fields
, _
) = Ctype.flatten_fields
(Ctype.object_fields type_expr
) in
83 (fun acc
-> fun (label
, field_kind
, typ
) ->
88 if label
= "*dummy method*" then
96 let rec string_of_text t
=
101 | Odoc_types.CodePre
s
102 | Odoc_types.Verbatim
s -> s
104 | Odoc_types.Italic t
105 | Odoc_types.Center t
108 | Odoc_types.Emphasize t
-> string_of_text t
109 | Odoc_types.List l
->
111 (List.map
(fun t
-> "\n- "^
(string_of_text t
)) l
))^
113 | Odoc_types.Enum l
->
114 let rec f n = function
117 "\n"^
(string_of_int
n)^
". "^
(string_of_text t
)^
121 | Odoc_types.Newline
-> "\n"
122 | Odoc_types.Block t
-> "\t"^
(string_of_text t
)^
"\n"
123 | Odoc_types.Title
(_
, _
, t
) -> "\n"^
(string_of_text t
)^
"\n"
124 | Odoc_types.Latex
s -> "{% "^
s^
" %}"
125 | Odoc_types.Link
(s, t
) ->
126 "["^
s^
"]"^
(string_of_text t
)
127 | Odoc_types.Ref
(name
, _
) ->
128 iter (Odoc_types.Code name
)
129 | Odoc_types.Superscript t
->
130 "^{"^
(string_of_text t
)^
"}"
131 | Odoc_types.Subscript t
->
132 "^{"^
(string_of_text t
)^
"}"
133 | Odoc_types.Module_list l
->
135 (list_concat (Odoc_types.Raw
", ")
136 (List.map
(fun s -> Odoc_types.Code
s) l
)
138 | Odoc_types.Index_list
->
140 | Odoc_types.Custom
(_
, t
) -> string_of_text t
142 String.concat
"" (List.map
iter t
)
144 let string_of_author_list l
=
149 "* "^
Odoc_messages.authors^
":\n"^
150 (String.concat
", " l
)^
153 let string_of_version_opt v_opt
=
156 | Some v
-> Odoc_messages.version^
": "^v^
"\n"
158 let string_of_since_opt s_opt
=
161 | Some
s -> Odoc_messages.since^
" "^
s^
"\n"
163 let string_of_raised_exceptions l
=
166 | (s, t
) :: [] -> Odoc_messages.raises^
" "^
s^
" "^
(string_of_text t
)^
"\n"
168 Odoc_messages.raises^
"\n"^
171 (fun (ex
, desc
) -> "- "^ex^
" "^
(string_of_text desc
)^
"\n")
176 let string_of_see (see_ref
, t
) =
179 Odoc_types.See_url
s -> [ Odoc_types.Link
(s, t
) ]
180 | Odoc_types.See_file
s -> (Odoc_types.Code
s) :: (Odoc_types.Raw
" ") :: t
181 | Odoc_types.See_doc
s -> (Odoc_types.Italic
[Odoc_types.Raw
s]) :: (Odoc_types.Raw
" ") :: t
185 let string_of_sees l
=
188 | see
:: [] -> Odoc_messages.see_also^
" "^
(string_of_see see
)^
" \n"
190 Odoc_messages.see_also^
"\n"^
193 (fun see
-> "- "^
(string_of_see see
)^
"\n")
198 let string_of_return_opt return_opt
=
199 match return_opt
with
201 | Some
s -> Odoc_messages.returns^
" "^
(string_of_text s)^
"\n"
203 let string_of_info i
=
204 let module M
= Odoc_types
in
205 (match i
.M.i_deprecated
with
207 | Some d
-> Odoc_messages.deprecated^
"! "^
(string_of_text d
)^
"\n")^
208 (match i
.M.i_desc
with
210 | Some d
when d
= [Odoc_types.Raw
""] -> ""
211 | Some d
-> (string_of_text d
)^
"\n"
213 (string_of_author_list i
.M.i_authors
)^
214 (string_of_version_opt i
.M.i_version
)^
215 (string_of_since_opt i
.M.i_since
)^
216 (string_of_raised_exceptions i
.M.i_raised_exceptions
)^
217 (string_of_return_opt i
.M.i_return_value
)
219 let apply_opt f v_opt
=
222 | Some v
-> Some
(f v
)
224 let string_of_date ?
(hour
=true) d
=
225 let add_0 s = if String.length
s < 2 then "0"^
s else s in
226 let t = Unix.localtime d
in
227 (string_of_int
(t.Unix.tm_year
+ 1900))^
"-"^
228 (add_0 (string_of_int
(t.Unix.tm_mon
+ 1)))^
"-"^
229 (add_0 (string_of_int
t.Unix.tm_mday
))^
233 (add_0 (string_of_int
t.Unix.tm_hour
))^
":"^
234 (add_0 (string_of_int
t.Unix.tm_min
))
240 let rec text_list_concat sep l
=
245 t @ (sep
:: (text_list_concat sep q
))
247 let rec text_no_title_no_list t =
250 | Odoc_types.Title
(_
,_
,t) -> text_no_title_no_list t
252 | Odoc_types.Enum l
->
253 (Odoc_types.Raw
" ") ::
255 (Odoc_types.Raw
", ")
256 (List.map
text_no_title_no_list l
))
259 | Odoc_types.CodePre _
260 | Odoc_types.Verbatim _
261 | Odoc_types.Ref _
-> [t_ele
]
262 | Odoc_types.Newline
-> [Odoc_types.Newline
]
263 | Odoc_types.Block
t -> [Odoc_types.Block
(text_no_title_no_list t)]
264 | Odoc_types.Bold
t -> [Odoc_types.Bold
(text_no_title_no_list t)]
265 | Odoc_types.Italic
t -> [Odoc_types.Italic
(text_no_title_no_list t)]
266 | Odoc_types.Center
t -> [Odoc_types.Center
(text_no_title_no_list t)]
267 | Odoc_types.Left
t -> [Odoc_types.Left
(text_no_title_no_list t)]
268 | Odoc_types.Right
t -> [Odoc_types.Right
(text_no_title_no_list t)]
269 | Odoc_types.Emphasize
t -> [Odoc_types.Emphasize
(text_no_title_no_list t)]
270 | Odoc_types.Latex
s -> [Odoc_types.Latex
s]
271 | Odoc_types.Link
(s, t) -> [Odoc_types.Link
(s, (text_no_title_no_list t))]
272 | Odoc_types.Superscript
t -> [Odoc_types.Superscript
(text_no_title_no_list t)]
273 | Odoc_types.Subscript
t -> [Odoc_types.Subscript
(text_no_title_no_list t)]
274 | Odoc_types.Module_list l
->
275 list_concat (Odoc_types.Raw
", ")
277 (fun s -> Odoc_types.Ref
(s, Some
Odoc_types.RK_module
))
280 | Odoc_types.Index_list
-> []
281 | Odoc_types.Custom
(s,t) -> [Odoc_types.Custom
(s, text_no_title_no_list t)]
283 List.flatten
(List.map
iter t)
285 let get_titles_in_text t =
287 let rec iter_ele ele
=
289 | Odoc_types.Title
(n,lopt
,t) -> l := (n,lopt
,t) :: !l
291 | Odoc_types.Enum
l -> List.iter iter_text
l
294 | Odoc_types.CodePre _
295 | Odoc_types.Verbatim _
296 | Odoc_types.Ref _
-> ()
297 | Odoc_types.Newline
-> ()
300 | Odoc_types.Italic
t
301 | Odoc_types.Center
t
304 | Odoc_types.Emphasize
t -> iter_text
t
305 | Odoc_types.Latex
s -> ()
306 | Odoc_types.Link
(_
, t)
307 | Odoc_types.Superscript
t
308 | Odoc_types.Subscript
t -> iter_text
t
309 | Odoc_types.Module_list _
-> ()
310 | Odoc_types.Index_list
-> ()
311 | Odoc_types.Custom
(_
, t) -> iter_text
t
313 List.iter iter_ele te
318 let text_concat (sep
: Odoc_types.text
) l =
319 let rec iter = function
322 | h
:: q
-> h
@ sep
@ (iter q
)
326 (*********************************************************)
327 let rec get_before_dot s =
329 let len = String.length
s in
330 let n = String.index
s '
.'
in
332 (* le point est le dernier caractère *)
336 ' '
| '
\n'
| '
\r'
| '
\t'
->
337 (true, String.sub
s 0 (n+1),
338 String.sub
s (n+1) (len - n - 1))
340 let b, s2
, s_after
= get_before_dot (String.sub
s (n + 1) (len - n - 1)) in
341 (b, (String.sub
s 0 (n+1))^s2
, s_after
)
343 Not_found
-> (false, s, "")
345 let rec first_sentence_text t =
347 [] -> (false, [], [])
349 let (stop
, ele2
, ele3_opt
) = first_sentence_text_ele ele
in
352 match ele3_opt
with None
-> q
| Some e
-> e
:: q
)
354 let (stop2
, q2
, rest
) = first_sentence_text q
in
355 (stop2
, ele2
:: q2
, rest
)
358 and first_sentence_text_ele text_ele
=
360 | Odoc_types.Raw
s ->
361 let b, s2
, s_after
= get_before_dot s in
362 (b, Odoc_types.Raw s2
, Some
(Odoc_types.Raw s_after
))
364 | Odoc_types.CodePre _
365 | Odoc_types.Verbatim _
-> (false, text_ele
, None
)
366 | Odoc_types.Bold
t ->
367 let (b, t2
, t3
) = first_sentence_text t in
368 (b, Odoc_types.Bold t2
, Some
(Odoc_types.Bold t3
))
369 | Odoc_types.Italic
t ->
370 let (b, t2
, t3
) = first_sentence_text t in
371 (b, Odoc_types.Italic t2
, Some
(Odoc_types.Italic t3
))
372 | Odoc_types.Center
t ->
373 let (b, t2
, t3
) = first_sentence_text t in
374 (b, Odoc_types.Center t2
, Some
(Odoc_types.Center t3
))
375 | Odoc_types.Left
t ->
376 let (b, t2
, t3
) = first_sentence_text t in
377 (b, Odoc_types.Left t2
, Some
(Odoc_types.Left t3
))
378 | Odoc_types.Right
t ->
379 let (b, t2
, t3
) = first_sentence_text t in
380 (b, Odoc_types.Right t2
, Some
(Odoc_types.Right t3
))
381 | Odoc_types.Emphasize
t ->
382 let (b, t2
, t3
) = first_sentence_text t in
383 (b, Odoc_types.Emphasize t2
, Some
(Odoc_types.Emphasize t3
))
384 | Odoc_types.Block
t ->
385 let (b, t2
, t3
) = first_sentence_text t in
386 (b, Odoc_types.Block t2
, Some
(Odoc_types.Block t3
))
387 | Odoc_types.Title
(n, l_opt
, t) ->
388 let (b, t2
, t3
) = first_sentence_text t in
390 Odoc_types.Title
(n, l_opt
, t2
),
391 Some
(Odoc_types.Title
(n, l_opt
, t3
)))
392 | Odoc_types.Newline
->
393 (true, Odoc_types.Raw
"", Some
Odoc_types.Newline
)
399 | Odoc_types.Superscript _
400 | Odoc_types.Subscript _
401 | Odoc_types.Module_list _
402 | Odoc_types.Index_list
-> (false, text_ele
, None
)
403 | Odoc_types.Custom _
-> (false, text_ele
, None
)
405 let first_sentence_of_text t =
406 let (_
,t2
,_
) = first_sentence_text t in
409 let first_sentence_and_rest_of_text t =
410 let (_
,t1
, t2
) = first_sentence_text t in
413 let remove_ending_newline s =
414 let len = String.length
s in
419 '
\n'
-> String.sub
s 0 (len-1)
422 let search_string_backward ~pat
=
423 let lenp = String.length pat
in
425 let len = String.length
s in
426 match compare
len lenp with
427 -1 -> raise Not_found
428 | 0 -> if pat
= s then 0 else raise Not_found
430 let pos = len - lenp in
431 let s2 = String.sub
s pos lenp in
435 iter (String.sub
s 0 pos)
441 (*********************************************************)
443 let create_index_lists elements string_of_ele
=
444 let rec f current acc0 acc1 acc2
= function
445 [] -> (acc0
:: acc1
) @ [acc2
]
447 let s = string_of_ele ele
in
449 "" -> f current acc0 acc1
(acc2
@ [ele
]) q
451 let first = Char.uppercase
s.[0] in
454 if current
= first then
455 f current acc0 acc1
(acc2
@ [ele
]) q
457 f first acc0
(acc1
@ [acc2
]) [ele
] q
459 f current
(acc0
@ [ele
]) acc1 acc2 q
461 f '_'
[] [] [] elements
466 let is_optional = Btype.is_optional
467 let label_name = Btype.label_name
469 let remove_option typ
=
472 | Types.Tconstr
(path
, [ty
], _
) when Path.same path
Predef.path_option
-> ty
.Types.desc
482 | Types.Tvariant _
-> t
484 | Types.Tsubst t2
-> iter t2
.Types.desc
486 { typ
with Types.desc
= iter typ
.Types.desc
}