OCaml HTML5 parser/serialiser based on Python's JustHTML
1(* CSS selector AST types *)
2
3type simple_selector_type =
4 | Type_tag
5 | Type_id
6 | Type_class
7 | Type_universal
8 | Type_attr
9 | Type_pseudo
10
11type simple_selector = {
12 selector_type : simple_selector_type;
13 name : string option;
14 operator : string option;
15 value : string option;
16 arg : string option;
17}
18
19type compound_selector = {
20 selectors : simple_selector list;
21}
22
23type complex_selector = {
24 parts : (string option * compound_selector) list;
25 (* List of (combinator, compound_selector) pairs.
26 First element has combinator = None *)
27}
28
29type selector_list = {
30 selectors : complex_selector list;
31}
32
33type selector =
34 | Simple of simple_selector
35 | Compound of compound_selector
36 | Complex of complex_selector
37 | List of selector_list
38
39(* Constructors *)
40let make_simple selector_type ?name ?operator ?value ?arg () =
41 { selector_type; name; operator; value; arg }
42
43let make_compound (selectors : simple_selector list) : compound_selector = { selectors }
44
45let make_complex parts : complex_selector = { parts }
46
47let make_list (selectors : complex_selector list) : selector_list = { selectors }
48
49(* Pretty printers *)
50let pp_simple_selector_type fmt = function
51 | Type_tag -> Format.pp_print_string fmt "tag"
52 | Type_id -> Format.pp_print_string fmt "id"
53 | Type_class -> Format.pp_print_string fmt "class"
54 | Type_universal -> Format.pp_print_string fmt "universal"
55 | Type_attr -> Format.pp_print_string fmt "attr"
56 | Type_pseudo -> Format.pp_print_string fmt "pseudo"
57
58let pp_simple_selector fmt s =
59 Format.fprintf fmt "%a" pp_simple_selector_type s.selector_type;
60 Option.iter (Format.fprintf fmt "(%s)") s.name;
61 Option.iter (Format.fprintf fmt "[%s]") s.operator;
62 Option.iter (Format.fprintf fmt "=%S") s.value;
63 Option.iter (Format.fprintf fmt "(%s)") s.arg
64
65let pp_compound_selector fmt (c : compound_selector) =
66 Format.pp_print_list ~pp_sep:(fun fmt () -> Format.pp_print_char fmt ' ')
67 pp_simple_selector fmt c.selectors
68
69let pp_complex_selector fmt c =
70 let pp_part fmt (comb, compound) =
71 Option.iter (Format.fprintf fmt " %s ") comb;
72 pp_compound_selector fmt compound
73 in
74 List.iter (pp_part fmt) c.parts
75
76let pp_selector_list fmt l =
77 Format.pp_print_list ~pp_sep:(fun fmt () -> Format.pp_print_string fmt ", ")
78 pp_complex_selector fmt l.selectors
79
80let pp fmt = function
81 | Simple s -> pp_simple_selector fmt s
82 | Compound c -> pp_compound_selector fmt c
83 | Complex c -> pp_complex_selector fmt c
84 | List l -> pp_selector_list fmt l