2002-03-27 08:20:32 -08:00
|
|
|
(***********************************************************************)
|
2012-08-01 05:09:31 -07:00
|
|
|
(* *)
|
2002-03-27 08:20:32 -08:00
|
|
|
(* 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. *)
|
|
|
|
(* *)
|
|
|
|
(***********************************************************************)
|
|
|
|
|
|
|
|
exception Text_syntax of int * int * string (* line, char, string *)
|
|
|
|
|
2003-11-24 13:20:51 -08:00
|
|
|
open Odoc_types
|
|
|
|
|
2002-03-27 08:20:32 -08:00
|
|
|
module Texter =
|
|
|
|
struct
|
|
|
|
(* builds a text structure from a string. *)
|
|
|
|
let text_of_string s =
|
|
|
|
let lexbuf = Lexing.from_string s in
|
|
|
|
try
|
2002-07-23 07:12:03 -07:00
|
|
|
Odoc_text_lexer.init ();
|
|
|
|
Odoc_text_parser.main Odoc_text_lexer.main lexbuf
|
2002-03-27 08:20:32 -08:00
|
|
|
with
|
2002-07-23 07:12:03 -07:00
|
|
|
_ ->
|
2006-01-04 08:55:50 -08:00
|
|
|
raise (Text_syntax (!Odoc_text_lexer.line_number,
|
|
|
|
!Odoc_text_lexer.char_number,
|
2002-07-23 07:12:03 -07:00
|
|
|
s)
|
|
|
|
)
|
2003-11-24 13:20:51 -08:00
|
|
|
|
|
|
|
let count s c =
|
|
|
|
let count = ref 0 in
|
|
|
|
for i = 0 to String.length s - 1 do
|
2010-01-22 04:48:24 -08:00
|
|
|
if s.[i] = c then incr count
|
2003-11-24 13:20:51 -08:00
|
|
|
done;
|
|
|
|
!count
|
|
|
|
|
|
|
|
let escape_n s c n =
|
|
|
|
let remain = ref n in
|
|
|
|
let len = String.length s in
|
|
|
|
let b = Buffer.create (len + n) in
|
|
|
|
for i = 0 to len - 1 do
|
2010-01-22 04:48:24 -08:00
|
|
|
if s.[i] = c && !remain > 0 then
|
|
|
|
(
|
|
|
|
Printf.bprintf b "\\%c" c;
|
|
|
|
decr remain
|
|
|
|
)
|
|
|
|
else
|
|
|
|
Buffer.add_char b s.[i]
|
2003-11-24 13:20:51 -08:00
|
|
|
done;
|
|
|
|
Buffer.contents b
|
|
|
|
|
|
|
|
let escape_code s =
|
|
|
|
let open_brackets = count s '[' in
|
|
|
|
let close_brackets = count s ']' in
|
|
|
|
if open_brackets > close_brackets then
|
2010-01-22 04:48:24 -08:00
|
|
|
escape_n s '[' (open_brackets - close_brackets)
|
2003-11-24 13:20:51 -08:00
|
|
|
else
|
2010-01-22 04:48:24 -08:00
|
|
|
if close_brackets > open_brackets then
|
|
|
|
escape_n s ']' (close_brackets - open_brackets)
|
|
|
|
else
|
|
|
|
s
|
2003-11-24 13:20:51 -08:00
|
|
|
|
|
|
|
let escape_raw s =
|
|
|
|
let len = String.length s in
|
|
|
|
let b = Buffer.create len in
|
|
|
|
for i = 0 to len - 1 do
|
2010-01-22 04:48:24 -08:00
|
|
|
match s.[i] with
|
|
|
|
'[' | ']' | '{' | '}' ->
|
|
|
|
Printf.bprintf b "\\%c" s.[i]
|
|
|
|
| c ->
|
|
|
|
Buffer.add_char b c
|
2003-11-24 13:20:51 -08:00
|
|
|
done;
|
|
|
|
Buffer.contents b
|
|
|
|
|
|
|
|
let p = Printf.bprintf
|
|
|
|
|
|
|
|
let rec p_text b t =
|
|
|
|
List.iter (p_text_element b) t
|
|
|
|
|
|
|
|
and p_list b l =
|
|
|
|
List.iter
|
2010-01-22 04:48:24 -08:00
|
|
|
(fun t -> p b "{- " ; p_text b t ; p b "}\n")
|
|
|
|
l
|
2003-11-24 13:20:51 -08:00
|
|
|
|
|
|
|
and p_text_element b = function
|
|
|
|
| Raw s -> p b "%s" (escape_raw s)
|
|
|
|
| Code s -> p b "[%s]" (escape_code s)
|
|
|
|
| CodePre s -> p b "{[%s]}" s
|
|
|
|
| Verbatim s -> p b "{v %s v}" s
|
|
|
|
| Bold t -> p b "{b " ; p_text b t ; p b "}"
|
|
|
|
| Italic t -> p b "{i " ; p_text b t ; p b "}"
|
|
|
|
| Emphasize t -> p b "{e " ; p_text b t ; p b "}"
|
|
|
|
| Center t -> p b "{C " ; p_text b t ; p b "}"
|
|
|
|
| Left t -> p b "{L " ; p_text b t ; p b "}"
|
|
|
|
| Right t -> p b "{R " ; p_text b t ; p b "}"
|
|
|
|
| List l -> p b "{ul\n"; p_list b l; p b "}"
|
|
|
|
| Enum l -> p b "{ol\n"; p_list b l; p b "}"
|
2006-01-04 08:55:50 -08:00
|
|
|
| Newline -> p b "\n"
|
2003-11-24 13:20:51 -08:00
|
|
|
| Block t -> p_text b t
|
|
|
|
| Title (n, l_opt, t) ->
|
2010-01-22 04:48:24 -08:00
|
|
|
p b "{%d%s "
|
|
|
|
n
|
|
|
|
(match l_opt with
|
|
|
|
None -> ""
|
|
|
|
| Some s -> ":"^s
|
|
|
|
);
|
|
|
|
p_text b t ;
|
|
|
|
p b "}"
|
2003-11-24 13:20:51 -08:00
|
|
|
| Latex s -> p b "{%% %s%%}" s
|
|
|
|
| Link (s,t) ->
|
2010-01-22 04:48:24 -08:00
|
|
|
p b "{{:%s}" s;
|
|
|
|
p_text b t ;
|
|
|
|
p b "}"
|
2009-12-18 03:52:23 -08:00
|
|
|
| Ref (name, kind_opt, text_opt) ->
|
|
|
|
begin
|
|
|
|
p b "%s{!%s%s}"
|
|
|
|
(match text_opt with None -> "" | Some _ -> "{")
|
|
|
|
(match kind_opt with
|
|
|
|
None -> ""
|
|
|
|
| Some k ->
|
|
|
|
let s =
|
|
|
|
match k with
|
|
|
|
RK_module -> "module"
|
|
|
|
| RK_module_type -> "modtype"
|
|
|
|
| RK_class -> "class"
|
|
|
|
| RK_class_type -> "classtype"
|
|
|
|
| RK_value -> "val"
|
|
|
|
| RK_type -> "type"
|
|
|
|
| RK_exception -> "exception"
|
|
|
|
| RK_attribute -> "attribute"
|
|
|
|
| RK_method -> "method"
|
|
|
|
| RK_section _ -> "section"
|
2012-07-26 12:21:54 -07:00
|
|
|
| RK_recfield -> "recfield"
|
|
|
|
| RK_const -> "const"
|
2009-12-18 03:52:23 -08:00
|
|
|
in
|
|
|
|
s^":"
|
|
|
|
)
|
|
|
|
name;
|
|
|
|
match text_opt with
|
|
|
|
None -> ()
|
|
|
|
| Some t -> p_text b t; p b "}"
|
|
|
|
end
|
2003-11-24 13:20:51 -08:00
|
|
|
| Superscript t -> p b "{^" ; p_text b t ; p b "}"
|
|
|
|
| Subscript t -> p b "{_" ; p_text b t ; p b "}"
|
2006-01-04 08:55:50 -08:00
|
|
|
| Module_list l ->
|
2010-01-22 04:48:24 -08:00
|
|
|
p b "{!modules:";
|
|
|
|
List.iter (fun s -> p b " %s" s) l;
|
|
|
|
p b "}"
|
|
|
|
| Index_list ->
|
|
|
|
p b "{!indexlist}"
|
|
|
|
| Custom (s,t) ->
|
|
|
|
p b "{%s " s;
|
|
|
|
p_text b t;
|
|
|
|
p b "}"
|
2010-03-08 08:54:13 -08:00
|
|
|
| Target (target, code) ->
|
|
|
|
p b "{%%%s: %s}" target (escape_raw code)
|
2006-01-04 08:55:50 -08:00
|
|
|
|
2003-11-24 13:20:51 -08:00
|
|
|
let string_of_text s =
|
|
|
|
let b = Buffer.create 256 in
|
|
|
|
p_text b s;
|
|
|
|
Buffer.contents b
|
2006-01-04 08:55:50 -08:00
|
|
|
|
2002-03-27 08:20:32 -08:00
|
|
|
end
|