@@ -25,10 +25,6 @@ include Mustache_types
2525module List = ListLabels
2626module String = StringLabels
2727
28- module Infix = struct
29- let (^) y x = Concat [x; y]
30- end
31-
3228module Json = struct
3329 type value =
3430 [ `Null
@@ -45,9 +41,6 @@ module Json = struct
4541 let value: t -> value = fun t -> (t :> value )
4642end
4743
48- let parse_lx = Mustache_parser. mustache Mustache_lexer. mustache
49- let of_string s = parse_lx (Lexing. from_string s)
50-
5144let escape_html s =
5245 let b = Buffer. create (String. length s) in
5346 String. iter ( function
@@ -60,8 +53,48 @@ let escape_html s =
6053 ) s ;
6154 Buffer. contents b
6255
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
6598 | String s ->
6699 Format. pp_print_string fmt s
67100
@@ -88,45 +121,14 @@ let rec pp fmt = function
88121 | Concat s ->
89122 List. iter (pp fmt) s
90123
91- let to_formatter = pp
92-
93124let to_string x =
94125 let b = Buffer. create 0 in
95126 let fmt = Format. formatter_of_buffer b in
96127 pp fmt x ;
97128 Format. pp_print_flush fmt () ;
98129 Buffer. contents b
99130
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. *)
130132
131133module Lookup = struct
132134 let scalar ?(strict =true ) = function
@@ -172,8 +174,8 @@ module Lookup = struct
172174
173175end
174176
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
177179 let rec render ' m (js : Json.value ) = match m with
178180
179181 | String s ->
@@ -211,9 +213,131 @@ let render_fmt ?(strict=true) (fmt : Format.formatter) (m : t) (js : Json.t) =
211213
212214 in render' m (Json. value js)
213215
214- let render ?(strict =true ) (m : t ) (js : Json.t ) =
216+ let render ?(strict =true ) (m : No_locs. t ) (js : Json.t ) =
215217 let b = Buffer. create 0 in
216218 let fmt = Format. formatter_of_buffer b in
217219 render_fmt ~strict fmt m js ;
218220 Format. pp_print_flush fmt () ;
219221 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