OCaml HTML5 parser/serialiser based on Python's JustHTML
1(** Typed error codes for HTML5 validation messages.
2
3 This module defines a comprehensive variant type for all validation errors,
4 ensuring exact message matching with the Nu HTML Validator test suite. *)
5
6(** Severity level of a validation message *)
7type severity = Error | Warning | Info
8
9(** Typed error codes with associated data *)
10type t =
11 (* Attribute Errors *)
12 | Attr_not_allowed_on_element of { attr: string; element: string }
13 | Attr_not_allowed_here of { attr: string }
14 | Attr_not_allowed_when of { attr: string; element: string; condition: string }
15 | Missing_required_attr of { element: string; attr: string }
16 | Missing_required_attr_one_of of { element: string; attrs: string list }
17 | Bad_attr_value of { element: string; attr: string; value: string; reason: string }
18 | Bad_attr_value_generic of { message: string }
19 | Duplicate_id of { id: string }
20 | Data_attr_invalid_name of { reason: string }
21 | Data_attr_uppercase
22
23 (* Element Errors *)
24 | Obsolete_element of { element: string; suggestion: string }
25 | Obsolete_attr of { element: string; attr: string; suggestion: string option }
26 | Obsolete_global_attr of { attr: string; suggestion: string }
27 | Element_not_allowed_as_child of { child: string; parent: string }
28 | Unknown_element of { name: string }
29 | Element_must_not_be_descendant of { element: string; attr: string option; ancestor: string }
30 | Missing_required_child of { parent: string; child: string }
31 | Missing_required_child_one_of of { parent: string; children: string list }
32 | Missing_required_child_generic of { parent: string }
33 | Element_must_not_be_empty of { element: string }
34 | Stray_start_tag of { tag: string }
35 | Stray_end_tag of { tag: string }
36 | End_tag_for_void_element of { tag: string }
37 | Self_closing_non_void
38 | Text_not_allowed of { parent: string }
39
40 (* Child Restrictions *)
41 | Div_child_of_dl_bad_role
42 | Li_bad_role_in_menu
43 | Li_bad_role_in_tablist
44 | Li_bad_role_in_list
45
46 (* ARIA Errors *)
47 | Unnecessary_role of { role: string; element: string; reason: string }
48 | Bad_role of { element: string; role: string }
49 | Aria_must_not_be_specified of { attr: string; element: string; condition: string }
50 | Aria_must_not_be_used of { attr: string; element: string; condition: string }
51 | Aria_should_not_be_used of { attr: string; role: string }
52 | Aria_hidden_on_body
53 | Img_empty_alt_with_role
54 | Checkbox_button_needs_aria_pressed
55 | Tab_without_tabpanel
56 | Multiple_main_visible
57 | Discarding_unrecognized_role of { token: string }
58
59 (* Required Attribute/Element Conditions *)
60 | Img_missing_alt
61 | Img_missing_src_or_srcset
62 | Option_empty_without_label
63 | Bdo_missing_dir
64 | Bdo_dir_auto
65 | Base_missing_href_or_target
66 | Base_after_link_script
67 | Link_missing_href
68 | Link_as_requires_preload
69 | Link_imagesrcset_requires_as_image
70 | Img_ismap_needs_a_href
71 | Sizes_without_srcset
72 | Imagesizes_without_imagesrcset
73 | Srcset_w_without_sizes
74 | Source_missing_srcset
75 | Source_needs_media_or_type
76 | Picture_missing_img
77 | Map_id_name_mismatch
78 | List_attr_requires_datalist
79 | Input_list_not_allowed
80 | Label_too_many_labelable
81 | Label_for_id_mismatch
82 | Role_on_label_ancestor
83 | Role_on_label_for
84 | Aria_label_on_label_for
85 | Input_value_constraint of { constraint_type: string }
86 | Summary_missing_role
87 | Summary_missing_attrs
88 | Summary_role_not_allowed
89 | Autocomplete_webauthn_on_select
90 | Commandfor_invalid_target
91
92 (* Parse Errors *)
93 | Forbidden_codepoint of { codepoint: int }
94 | Char_ref_control of { codepoint: int }
95 | Char_ref_non_char of { codepoint: int; astral: bool }
96 | Char_ref_unassigned
97 | Char_ref_zero
98 | Char_ref_out_of_range
99 | Numeric_char_ref_carriage_return
100 | End_of_file_with_open_elements
101 | No_element_in_scope of { tag: string }
102 | End_tag_implied_open_elements of { tag: string }
103 | Start_tag_in_table of { tag: string }
104 | Bad_start_tag_in of { tag: string; context: string }
105
106 (* Table Errors *)
107 | Table_row_no_cells of { row: int }
108 | Table_cell_overlap
109 | Table_cell_spans_rowgroup
110 | Table_column_no_cells of { column: int; element: string }
111
112 (* Language/Internationalization *)
113 | Missing_lang_attr
114 | Wrong_lang of { detected: string; declared: string; suggested: string }
115 | Missing_dir_rtl of { language: string }
116 | Wrong_dir of { language: string; declared: string }
117 | Xml_lang_without_lang
118 | Xml_lang_lang_mismatch
119
120 (* Unicode Normalization *)
121 | Not_nfc of { replacement: string }
122
123 (* Multiple h1 *)
124 | Multiple_h1
125 | Multiple_autofocus
126
127 (* Import Maps *)
128 | Importmap_invalid_json
129 | Importmap_invalid_root
130 | Importmap_imports_not_object
131 | Importmap_empty_key
132 | Importmap_non_string_value
133 | Importmap_key_trailing_slash
134 | Importmap_scopes_not_object
135 | Importmap_scopes_values_not_object
136 | Importmap_scopes_invalid_url
137 | Importmap_scopes_value_invalid_url
138
139 (* Style Element *)
140 | Style_type_invalid
141
142 (* Headingoffset *)
143 | Headingoffset_invalid
144
145 (* Media Attribute *)
146 | Media_empty
147 | Media_all
148
149 (* SVG/MathML specific *)
150 | Svg_deprecated_attr of { attr: string; element: string }
151 | Missing_required_svg_attr of { element: string; attr: string }
152
153 (* Generic/Fallback *)
154 | Generic of { message: string }
155
156(** Get the severity level for an error code *)
157val severity : t -> severity
158
159(** Get a short code string for categorization *)
160val code_string : t -> string
161
162(** Convert error code to exact Nu validator message string *)
163val to_message : t -> string
164
165(** Format a string with curly quotes *)
166val q : string -> string