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
open Printf
type inline =
[ `Text of string
| `Code of string ]
type block = [ `Paragraph of inline list | `Pre of string ]
type doc = [ `Text of block list ]
let parse_text loc s =
try `Text (Atd_doc_lexer.parse_string s : block list)
with e ->
failwith (Printf.sprintf "%s:\nInvalid format for doc.text %S:\n%s"
(Atd_ast.string_of_loc loc) s (Printexc.to_string e))
let get_doc loc an : doc option =
Atd_annot.get_field
(fun s -> Some (Some (parse_text loc s))) None ["doc"] "text" an
let html_escape buf s =
String.iter (
function
'<' -> Buffer.add_string buf "<"
| '>' -> Buffer.add_string buf ">"
| '&' -> Buffer.add_string buf "&"
| '"' -> Buffer.add_string buf """
| c -> Buffer.add_char buf c
) s
let print_inline buf = function
`Text s -> html_escape buf s
| `Code s -> bprintf buf "<code>%a</code>" html_escape s
let html_of_doc (`Text blocks) =
let buf = Buffer.create 300 in
bprintf buf "\n<div class=\"atd-doc\">\n";
List.iter (
function
`Paragraph l ->
Buffer.add_string buf "<p>\n";
List.iter (print_inline buf) l;
Buffer.add_string buf "\n</p>\n"
| `Pre s ->
Buffer.add_string buf "<pre>\n";
html_escape buf s;
Buffer.add_string buf "</pre>\n"
) blocks;
bprintf buf "\n</div>\n";
Buffer.contents buf