OCaml HTML5 parser/serialiser based on Python's JustHTML
1(** Validation messages with typed error codes. *)
2
3type severity = Error | Warning | Info
4
5type location = {
6 line : int;
7 column : int;
8 end_line : int option;
9 end_column : int option;
10 system_id : string option;
11}
12
13type error_code =
14 | Parse_error of Html5rw.Parse_error_code.t
15 | Conformance_error of Error_code.t
16
17type t = {
18 severity : severity;
19 message : string;
20 error_code : error_code;
21 location : location option;
22 element : string option;
23 attribute : string option;
24 extract : string option;
25}
26
27let make_location ~line ~column ?end_line ?end_column ?system_id () =
28 { line; column; end_line; end_column; system_id }
29
30(** Create a message from a conformance error code *)
31let of_conformance_error ?location ?element ?attribute ?extract error_code =
32 let severity = match Error_code.severity error_code with
33 | Error_code.Error -> Error
34 | Error_code.Warning -> Warning
35 | Error_code.Info -> Info
36 in
37 {
38 severity;
39 message = Error_code.to_message error_code;
40 error_code = Conformance_error error_code;
41 location;
42 element;
43 attribute;
44 extract;
45 }
46
47(** Create a message from a parse error code *)
48let of_parse_error ?location ?element ?attribute ?extract ~message code =
49 {
50 severity = Error; (* Parse errors are always errors *)
51 message;
52 error_code = Parse_error code;
53 location;
54 element;
55 attribute;
56 extract;
57 }
58
59let error_code_to_string = function
60 | Parse_error code -> Html5rw.Parse_error_code.to_string code
61 | Conformance_error code -> Error_code.code_string code
62
63let severity_to_string = function
64 | Error -> "error"
65 | Warning -> "warning"
66 | Info -> "info"
67
68let pp_severity fmt severity =
69 Format.pp_print_string fmt (severity_to_string severity)
70
71let pp_location fmt loc =
72 (match loc.system_id with
73 | Some sid -> Format.fprintf fmt "%s:" sid
74 | None -> ());
75 Format.fprintf fmt "%d:%d" loc.line loc.column;
76 match (loc.end_line, loc.end_column) with
77 | Some el, Some ec when el = loc.line && ec > loc.column ->
78 Format.fprintf fmt "-%d" ec
79 | Some el, Some ec when el > loc.line ->
80 Format.fprintf fmt "-%d:%d" el ec
81 | _ -> ()
82
83let pp fmt msg =
84 (match msg.location with
85 | Some loc ->
86 pp_location fmt loc;
87 Format.fprintf fmt ": "
88 | None -> ());
89 pp_severity fmt msg.severity;
90 Format.fprintf fmt " [%s]" (error_code_to_string msg.error_code);
91 Format.fprintf fmt ": %s" msg.message;
92 (match msg.element with
93 | Some elem -> Format.fprintf fmt " (element: %s)" elem
94 | None -> ());
95 match msg.attribute with
96 | Some attr -> Format.fprintf fmt " (attribute: %s)" attr
97 | None -> ()
98
99let to_string msg =
100 let buf = Buffer.create 256 in
101 let fmt = Format.formatter_of_buffer buf in
102 pp fmt msg;
103 Format.pp_print_flush fmt ();
104 Buffer.contents buf