Source file attributes.ml
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
let parse loc (language, element_name) attributes =
let (module Reflected) =
Namespace.get language in
let parse_prefixed prefix name =
let length = String.length prefix in
let is_prefixed =
try String.sub name 0 length = prefix
with Invalid_argument _ -> false
in
if not is_prefixed then None
else Some (String.sub name length (String.length name - length))
in
let parse_attribute (labeled, regular) ((_, local_name), value) =
let tyxml_name = Name_convention.attrib local_name in
let test_labeled (e, a, _) = e = element_name && a = local_name in
let test_blacklisted (a, _, _) = a = tyxml_name in
let test_renamed (_, a, es) = a = local_name && List.mem element_name es in
let unknown () =
Common.error loc "Unknown attribute in %s element: %s"
(Common.lang language) local_name
in
match Common.find test_labeled Reflected.labeled_attributes with
| Some (_, label, parser) ->
let e =
match parser language loc local_name value with
| None ->
Common.error loc
"Internal error: labeled attribute %s without an argument" label
| Some e -> e
in
(Labelled label, e)::labeled, regular
| None ->
if List.exists test_blacklisted Reflected.renamed_attributes then
unknown ()
else
let parse_prefixed_attribute tag tyxml_name =
let parser =
try List.assoc tyxml_name Reflected.attribute_parsers
with Not_found ->
Common.error loc "Internal error: no parser for %s" tyxml_name
in
let identifier = Common.make ~loc language tyxml_name in
let tag = Common.string loc tag in
let e =
match parser language loc local_name value with
| Some e' -> [%expr [%e identifier] [%e tag] [%e e']] [@metaloc loc]
| None ->
Common.error loc "Internal error: no expression for %s"
tyxml_name
in
labeled, e::regular
in
match parse_prefixed "data-" local_name,
parse_prefixed "aria-" local_name
with
| Some tag, _ -> parse_prefixed_attribute tag "a_user_data"
| _, Some tag -> parse_prefixed_attribute tag "a_aria"
| None, None ->
let tyxml_name =
match Common.find test_renamed Reflected.renamed_attributes with
| Some (name, _, _) -> name
| None -> tyxml_name
in
let parser =
try List.assoc tyxml_name Reflected.attribute_parsers
with Not_found -> unknown ()
in
let identifier = Common.make ~loc language tyxml_name in
let e =
match parser language loc local_name value with
| None -> identifier
| Some e' -> [%expr [%e identifier] [%e e']] [@metaloc loc]
in
labeled, e::regular
in
let labeled, regular =
List.fold_left parse_attribute ([], []) attributes in
if regular = [] then List.rev labeled
else
let regular =
Labelled "a",
Common.list loc (List.rev regular)
in
List.rev (regular::labeled)