@@ -25,10 +25,6 @@ include Mustache_types
25
25
module List = ListLabels
26
26
module String = StringLabels
27
27
28
- module Infix = struct
29
- let (^) y x = Concat [x; y]
30
- end
31
-
32
28
module Json = struct
33
29
type value =
34
30
[ `Null
@@ -45,9 +41,6 @@ module Json = struct
45
41
let value: t -> value = fun t -> (t :> value )
46
42
end
47
43
48
- let parse_lx = Mustache_parser. mustache Mustache_lexer. mustache
49
- let of_string s = parse_lx (Lexing. from_string s)
50
-
51
44
let escape_html s =
52
45
let b = Buffer. create (String. length s) in
53
46
String. iter ( function
@@ -60,8 +53,48 @@ let escape_html s =
60
53
) s ;
61
54
Buffer. contents b
62
55
63
- let rec pp fmt = function
64
-
56
+ (* Utility functions that allow converting between the ast with locations and
57
+ without locations. *)
58
+
59
+ let dummy_loc =
60
+ { Locs. loc_start = Lexing. dummy_pos;
61
+ Locs. loc_end = Lexing. dummy_pos }
62
+
63
+ let rec erase_locs { Locs. desc; _ } =
64
+ erase_locs_desc desc
65
+ and erase_locs_desc = function
66
+ | Locs. String s -> No_locs. String s
67
+ | Locs. Escaped s -> No_locs. Escaped s
68
+ | Locs. Section s -> No_locs. Section (erase_locs_section s)
69
+ | Locs. Unescaped s -> No_locs. Unescaped s
70
+ | Locs. Partial s -> No_locs. Partial s
71
+ | Locs. Inverted_section s -> No_locs. Inverted_section (erase_locs_section s)
72
+ | Locs. Concat l -> No_locs. Concat (List. map erase_locs l)
73
+ | Locs. Comment s -> No_locs. Comment s
74
+ and erase_locs_section { Locs. name; Locs. contents } =
75
+ { No_locs. name; No_locs. contents = erase_locs contents }
76
+
77
+ let rec add_dummy_locs t =
78
+ { Locs. loc = dummy_loc;
79
+ Locs. desc = add_dummy_locs_desc t }
80
+ and add_dummy_locs_desc = function
81
+ | No_locs. String s -> Locs. String s
82
+ | No_locs. Escaped s -> Locs. Escaped s
83
+ | No_locs. Section s -> Locs. Section (add_dummy_locs_section s)
84
+ | No_locs. Unescaped s -> Locs. Unescaped s
85
+ | No_locs. Partial s -> Locs. Partial s
86
+ | No_locs. Inverted_section s ->
87
+ Locs. Inverted_section (add_dummy_locs_section s)
88
+ | No_locs. Concat l -> Locs. Concat (List. map add_dummy_locs l)
89
+ | No_locs. Comment s -> Locs. Comment s
90
+ and add_dummy_locs_section { No_locs. name; No_locs. contents } =
91
+ { Locs. name; Locs. contents = add_dummy_locs contents }
92
+
93
+ (* Printing: defined on the ast without locations. *)
94
+
95
+ let rec pp fmt =
96
+ let open No_locs in
97
+ function
65
98
| String s ->
66
99
Format. pp_print_string fmt s
67
100
@@ -88,45 +121,14 @@ let rec pp fmt = function
88
121
| Concat s ->
89
122
List. iter (pp fmt) s
90
123
91
- let to_formatter = pp
92
-
93
124
let to_string x =
94
125
let b = Buffer. create 0 in
95
126
let fmt = Format. formatter_of_buffer b in
96
127
pp fmt x ;
97
128
Format. pp_print_flush fmt () ;
98
129
Buffer. contents b
99
130
100
- let rec fold ~string ~section ~escaped ~unescaped ~partial ~comment ~concat t =
101
- let go = fold ~string ~section ~escaped ~unescaped ~partial ~comment ~concat in
102
- match t with
103
- | String s -> string s
104
- | Escaped s -> escaped s
105
- | Unescaped s -> unescaped s
106
- | Comment s -> comment s
107
- | Section { name; contents } ->
108
- section ~inverted: false name (go contents)
109
- | Inverted_section { name; contents } ->
110
- section ~inverted: true name (go contents)
111
- | Concat ms ->
112
- concat (List. map ms ~f: go)
113
- | Partial p -> partial p
114
-
115
- let raw s = String s
116
- let escaped s = Escaped s
117
- let unescaped s = Unescaped s
118
- let section n c = Section { name = n ; contents = c }
119
- let inverted_section n c = Inverted_section { name = n ; contents = c }
120
- let partial s = Partial s
121
- let concat t = Concat t
122
- let comment s = Comment s
123
-
124
- let rec expand_partials =
125
- let section ~inverted =
126
- if inverted then inverted_section else section
127
- in
128
- fun partial ->
129
- fold ~string: raw ~section ~escaped ~unescaped ~partial ~comment ~concat
131
+ (* Rendering: defined on the ast without locations. *)
130
132
131
133
module Lookup = struct
132
134
let scalar ?(strict =true ) = function
@@ -172,8 +174,8 @@ module Lookup = struct
172
174
173
175
end
174
176
175
- let render_fmt ?(strict =true ) (fmt : Format.formatter ) (m : t ) (js : Json.t ) =
176
-
177
+ let render_fmt ?(strict =true ) (fmt : Format.formatter ) (m : No_locs. t ) (js : Json.t ) =
178
+ let open No_locs in
177
179
let rec render ' m (js : Json.value ) = match m with
178
180
179
181
| String s ->
@@ -211,9 +213,131 @@ let render_fmt ?(strict=true) (fmt : Format.formatter) (m : t) (js : Json.t) =
211
213
212
214
in render' m (Json. value js)
213
215
214
- let render ?(strict =true ) (m : t ) (js : Json.t ) =
216
+ let render ?(strict =true ) (m : No_locs. t ) (js : Json.t ) =
215
217
let b = Buffer. create 0 in
216
218
let fmt = Format. formatter_of_buffer b in
217
219
render_fmt ~strict fmt m js ;
218
220
Format. pp_print_flush fmt () ;
219
221
Buffer. contents b
222
+
223
+ (* Parsing: produces an ast with locations. *)
224
+
225
+ let parse_lx : Lexing.lexbuf -> Locs.t =
226
+ Mustache_parser. mustache Mustache_lexer. mustache
227
+
228
+ let of_string s = parse_lx (Lexing. from_string s)
229
+
230
+ (* Packing up everything in two modules of similar signature:
231
+ [With_locations] and [Without_locations].
232
+ *)
233
+
234
+ module With_locations = struct
235
+ include Locs
236
+
237
+ let dummy_loc = dummy_loc
238
+ let parse_lx = parse_lx
239
+ let of_string = of_string
240
+
241
+ let pp fmt x = pp fmt (erase_locs x)
242
+ let to_formatter = pp
243
+
244
+ let to_string x = to_string (erase_locs x)
245
+
246
+ let render_fmt ?strict fmt m js =
247
+ render_fmt ?strict fmt (erase_locs m) js
248
+
249
+ let render ?strict m js =
250
+ render ?strict (erase_locs m) js
251
+
252
+ let rec fold ~string ~section ~escaped ~unescaped ~partial ~comment ~concat t =
253
+ let go = fold ~string ~section ~escaped ~unescaped ~partial ~comment ~concat in
254
+ let { desc; loc } = t in
255
+ match desc with
256
+ | String s -> string ~loc s
257
+ | Escaped s -> escaped ~loc s
258
+ | Unescaped s -> unescaped ~loc s
259
+ | Comment s -> comment ~loc s
260
+ | Section { name; contents } ->
261
+ section ~loc ~inverted: false name (go contents)
262
+ | Inverted_section { name; contents } ->
263
+ section ~loc ~inverted: true name (go contents)
264
+ | Concat ms ->
265
+ concat ~loc (List. map ms ~f: go)
266
+ | Partial p -> partial ~loc p
267
+
268
+ module Infix = struct
269
+ let (^) t1 t2 = { desc = Concat [t1; t2]; loc = dummy_loc }
270
+ end
271
+
272
+ let raw ~loc s = { desc = String s; loc }
273
+ let escaped ~loc s = { desc = Escaped s; loc }
274
+ let unescaped ~loc s = { desc = Unescaped s; loc }
275
+ let section ~loc n c =
276
+ { desc = Section { name = n; contents = c };
277
+ loc }
278
+ let inverted_section ~loc n c =
279
+ { desc = Inverted_section { name = n; contents = c };
280
+ loc }
281
+ let partial ~loc s = { desc = Partial s; loc }
282
+ let concat ~loc t = { desc = Concat t; loc }
283
+ let comment ~loc s = { desc = Comment s; loc }
284
+
285
+ let rec expand_partials =
286
+ let section ~loc ~inverted =
287
+ if inverted then inverted_section ~loc else section ~loc
288
+ in
289
+ fun partial ->
290
+ fold ~string: raw ~section ~escaped ~unescaped ~partial ~comment ~concat
291
+ end
292
+
293
+ module Without_locations = struct
294
+ include No_locs
295
+
296
+ let parse_lx lexbuf = erase_locs (parse_lx lexbuf)
297
+ let of_string s = erase_locs (of_string s)
298
+
299
+ let pp = pp
300
+ let to_formatter = pp
301
+
302
+ let to_string = to_string
303
+
304
+ let rec fold ~string ~section ~escaped ~unescaped ~partial ~comment ~concat t =
305
+ let go = fold ~string ~section ~escaped ~unescaped ~partial ~comment ~concat in
306
+ match t with
307
+ | String s -> string s
308
+ | Escaped s -> escaped s
309
+ | Unescaped s -> unescaped s
310
+ | Comment s -> comment s
311
+ | Section { name; contents } ->
312
+ section ~inverted: false name (go contents)
313
+ | Inverted_section { name; contents } ->
314
+ section ~inverted: true name (go contents)
315
+ | Concat ms ->
316
+ concat (List. map ms ~f: go)
317
+ | Partial p -> partial p
318
+
319
+ module Infix = struct
320
+ let (^) y x = Concat [x; y]
321
+ end
322
+
323
+ let raw s = String s
324
+ let escaped s = Escaped s
325
+ let unescaped s = Unescaped s
326
+ let section n c = Section { name = n ; contents = c }
327
+ let inverted_section n c = Inverted_section { name = n ; contents = c }
328
+ let partial s = Partial s
329
+ let concat t = Concat t
330
+ let comment s = Comment s
331
+
332
+ let rec expand_partials =
333
+ let section ~inverted =
334
+ if inverted then inverted_section else section
335
+ in
336
+ fun partial ->
337
+ fold ~string: raw ~section ~escaped ~unescaped ~partial ~comment ~concat
338
+ end
339
+
340
+ (* Include [Without_locations] at the toplevel, to preserve backwards
341
+ compatibility of the API. *)
342
+
343
+ include Without_locations
0 commit comments