OCaml HTML5 parser/serialiser based on Python's JustHTML
1(** Base checker module for HTML5 conformance checking. *)
2
3module type S = sig
4 type state
5
6 val create : unit -> state
7 val reset : state -> unit
8
9 val start_element :
10 state ->
11 element:Element.t ->
12 Message_collector.t ->
13 unit
14
15 val end_element :
16 state ->
17 tag:Tag.element_tag ->
18 Message_collector.t ->
19 unit
20
21 val characters : state -> string -> Message_collector.t -> unit
22 val end_document : state -> Message_collector.t -> unit
23end
24
25type t = (module S)
26
27(** No-operation checker implementation. *)
28module Noop = struct
29 type state = unit
30
31 let create () = ()
32 let reset () = ()
33
34 let start_element () ~element:_ _ = ()
35 let end_element () ~tag:_ _ = ()
36 let characters () _ _ = ()
37 let end_document () _ = ()
38end
39
40let noop () = (module Noop : S)
41
42(** Input signature for Make functor *)
43module type Input = sig
44 type state
45 val create : unit -> state
46 val reset : state -> unit
47 val start_element : state -> element:Element.t -> Message_collector.t -> unit
48 val end_element : state -> tag:Tag.element_tag -> Message_collector.t -> unit
49 val characters : (state -> string -> Message_collector.t -> unit) option
50 val end_document : (state -> Message_collector.t -> unit) option
51end
52
53(** Functor to create a checker with default implementations for optional callbacks *)
54module Make (I : Input) : S with type state = I.state = struct
55 type state = I.state
56
57 let create = I.create
58 let reset = I.reset
59 let start_element = I.start_element
60 let end_element = I.end_element
61
62 let characters = match I.characters with
63 | Some f -> f
64 | None -> fun _ _ _ -> ()
65
66 let end_document = match I.end_document with
67 | Some f -> f
68 | None -> fun _ _ -> ()
69end
70
71(** Create a checker from individual callback functions.
72 This eliminates the boilerplate module wrapper at the end of each checker. *)
73let make
74 (type s)
75 ~(create : unit -> s)
76 ~(reset : s -> unit)
77 ~(start_element : s -> element:Element.t -> Message_collector.t -> unit)
78 ~(end_element : s -> tag:Tag.element_tag -> Message_collector.t -> unit)
79 ?(characters : (s -> string -> Message_collector.t -> unit) option)
80 ?(end_document : (s -> Message_collector.t -> unit) option)
81 () : t =
82 (module struct
83 type state = s
84 let create = create
85 let reset = reset
86 let start_element = start_element
87 let end_element = end_element
88 let characters = match characters with
89 | Some f -> f
90 | None -> fun _ _ _ -> ()
91 let end_document = match end_document with
92 | Some f -> f
93 | None -> fun _ _ -> ()
94 end : S)