@@ -2,9 +2,48 @@ open Odoc_document
2
2
open Types
3
3
open Doctree
4
4
5
- module Markup = struct
5
+ module Markup : sig
6
+ type t
7
+
8
+ val noop : t
9
+
10
+ val break : t
11
+
12
+ val nbsp : t
13
+
14
+ val space : t
15
+
16
+ val backticks : t
17
+
18
+ val open_sq_bracket : t
19
+
20
+ val close_sq_bracket : t
21
+
22
+ val ( ++ ) : t -> t -> t
23
+
24
+ val concat : t list -> t
25
+
26
+ val inline' : string list -> t
27
+
28
+ val block' : t list -> t
29
+
30
+ val list : ?sep : t -> t list -> t
31
+
32
+ val anchor' : string -> t
33
+
34
+ val string : string -> t
35
+
36
+ val str : ('a , unit , string , t ) format4 -> 'a
37
+
38
+ val escaped : ('a , unit , string , t ) format4 -> 'a
39
+
40
+ val open_parenthesis : t
41
+
42
+ val close_parenthesis : t
43
+
44
+ val pp : Format .formatter -> t -> unit
45
+ end = struct
6
46
type t =
7
- | Inline of string list
8
47
| Block of t list
9
48
| Concat of t list
10
49
| Break
@@ -54,13 +93,16 @@ module Markup = struct
54
93
55
94
let string s = String s
56
95
96
+ let block' ts = Block ts
97
+
98
+ let inline' l = List. map (fun s -> string s) l |> concat
99
+
57
100
let str fmt = Format. ksprintf (fun s -> string s) fmt
58
101
59
102
let escaped fmt = Format. ksprintf (fun s -> string s) fmt
60
103
61
104
let rec pp fmt t =
62
105
match t with
63
- | Inline s -> Format. fprintf fmt " %s" (String. concat " " s)
64
106
| Block b ->
65
107
let inner = function
66
108
| [] -> ()
@@ -77,7 +119,7 @@ module Markup = struct
77
119
within backtick, and the spaces before and after the backticks for
78
120
clarity on what should be enclosed in backticks. For example,
79
121
"type nums = [ | `One | `Two ]" would be rendered as "``|`````Monday`` "
80
- if the spaces were not there .
122
+ if the spaces were missing .
81
123
*)
82
124
| Backticks -> Format. fprintf fmt " `` "
83
125
| Nbsp -> Format. fprintf fmt " "
@@ -103,93 +145,89 @@ let style (style : style) content =
103
145
| `Superscript -> string " <sup>" ++ content
104
146
| `Subscript -> string " <sub>" ++ content
105
147
106
- (* I'm not sure if `make_hashes` is the best name to use! *)
107
148
let make_hashes n = String. make n '#'
108
149
109
150
type args = { generate_links : bool ref }
110
151
111
152
let args = { generate_links = ref true }
112
153
113
- let rec source_code (s : Source.t ) =
154
+ let rec source_code (s : Source.t ) nbsp =
114
155
match s with
115
156
| [] -> noop
116
157
| h :: t -> (
158
+ let continue s = if s = [] then concat [] else source_code s nbsp in
117
159
match h with
118
- | Source. Elt i -> inline i ++ source_code t
119
- | Tag (None, s ) -> source_code s ++ source_code t
120
- | Tag (Some _ , s ) -> source_code s ++ source_code t)
160
+ | Source. Elt i -> inline i nbsp ++ continue t
161
+ | Tag (None, s ) -> continue s ++ continue t
162
+ | Tag (Some _ , s ) -> continue s ++ continue t)
121
163
122
- and inline (l : Inline.t ) =
164
+ and inline (l : Inline.t ) nbsp =
123
165
match l with
124
166
| [] -> noop
125
167
| i :: rest -> (
168
+ let continue i = if i = [] then noop else inline i nbsp in
126
169
match i.desc with
127
- | Text "" -> inline rest
128
- | Text _ ->
129
- let l, _, rest =
130
- Doctree.Take. until l ~classify: (function
131
- | { Inline. desc = Text s ; _ } -> (
132
- match s with
133
- | "end" ->
134
- Accum
135
- [
136
- break ++ space
137
- ++ string (make_hashes 6 )
138
- ++ space ++ nbsp ++ string s;
139
- ]
140
- | _ -> Accum [ str " %s" s ])
141
- | _ -> Stop_and_keep )
142
- in
143
- concat l ++ inline rest
170
+ | Text "" -> continue rest
171
+ | Text s -> (
172
+ match s with
173
+ | "end" ->
174
+ break ++ string (make_hashes 6 ) ++ space ++ nbsp ++ string s
175
+ | _ ->
176
+ let l, _, rest =
177
+ Doctree.Take. until l ~classify: (function
178
+ | { Inline. desc = Text s ; _ } -> Accum [ str " %s" s ]
179
+ | _ -> Stop_and_keep )
180
+ in
181
+ concat l ++ continue rest)
144
182
| Entity e ->
145
183
let x = entity e in
146
- x ++ inline rest
147
- | Styled (sty , content ) -> style sty (inline content) ++ inline rest
148
- | Linebreak -> break ++ inline rest
184
+ x ++ continue rest
185
+ | Styled (sty , content ) -> style sty (continue content) ++ continue rest
186
+ | Linebreak -> break ++ continue rest
149
187
| Link (href , content ) ->
150
188
if ! (args.generate_links) then
151
189
match content with
152
190
| [] -> noop
153
191
| i :: rest ->
154
192
(match i.desc with
155
193
| Text _ ->
156
- open_sq_bracket ++ inline content ++ close_sq_bracket
194
+ open_sq_bracket ++ continue content ++ close_sq_bracket
157
195
++ open_parenthesis ++ string href ++ close_parenthesis
158
- ++ inline rest
159
- | _ -> inline content ++ inline rest)
160
- ++ inline rest
161
- else inline content ++ inline rest
196
+ ++ continue rest
197
+ | _ -> continue content ++ continue rest)
198
+ ++ continue rest
199
+ else continue content ++ continue rest
162
200
| InternalLink (Resolved (link , content )) ->
163
201
if ! (args.generate_links) then
164
202
match link.page.parent with
165
- | Some _ -> inline content ++ inline rest
203
+ | Some _ -> continue content ++ continue rest
166
204
| None ->
167
- open_sq_bracket ++ inline content ++ close_sq_bracket
205
+ open_sq_bracket ++ continue content ++ close_sq_bracket
168
206
++ open_parenthesis
169
207
++ string (make_hashes 1 ^ link.anchor)
170
- ++ close_parenthesis ++ inline rest
171
- else inline content ++ inline rest
172
- | InternalLink (Unresolved content ) -> inline content ++ inline rest
208
+ ++ close_parenthesis ++ continue rest
209
+ else continue content ++ continue rest
210
+ | InternalLink (Unresolved content ) -> continue content ++ continue rest
173
211
| Source content ->
174
- backticks ++ source_code content ++ backticks ++ inline rest
175
- | Raw_markup t -> raw_markup t ++ inline rest)
212
+ backticks ++ source_code content nbsp ++ backticks ++ continue rest
213
+ | Raw_markup t -> raw_markup t ++ continue rest)
176
214
177
- let rec block (l : Block.t ) =
215
+ let rec block (l : Block.t ) nbsp =
178
216
match l with
179
217
| [] -> noop
180
218
| b :: rest -> (
181
- let continue r = if r = [] then noop else break ++ block r in
219
+ let continue r = if r = [] then noop else break ++ block r nbsp in
182
220
match b.desc with
183
- | Inline i -> inline i ++ continue rest
184
- | Paragraph i -> inline i ++ break ++ break ++ continue rest
221
+ | Inline i -> inline i nbsp ++ continue rest
222
+ | Paragraph i -> inline i nbsp ++ break ++ break ++ continue rest
185
223
| List (list_typ , l ) ->
186
224
let f n b =
187
225
let bullet =
188
226
match list_typ with
189
227
| Unordered -> escaped " - "
190
228
| Ordered -> str " %d. " (n + 1 )
191
229
in
192
- bullet ++ block b ++ break
230
+ bullet ++ block b nbsp ++ break
193
231
in
194
232
list ~sep: break (List. mapi f l) ++ continue rest
195
233
| Description _ ->
@@ -199,16 +237,14 @@ let rec block (l : Block.t) =
199
237
| _ -> Stop_and_keep )
200
238
in
201
239
let f i =
202
- let key = inline i.Description. key in
203
- let def = block i.Description. definition in
240
+ let key = inline i.Description. key nbsp in
241
+ let def = block i.Description. definition nbsp in
204
242
break ++ str " @" ++ key ++ str " : " ++ def ++ break ++ break
205
243
in
206
244
list ~sep: break (List. map f descrs) ++ continue rest
207
- | Source content -> source_code content ++ continue rest
208
- (* TODO: I'm not sure if indenting using spaces is the better way, or
209
- creating an indent constructor*)
245
+ | Source content -> source_code content nbsp ++ continue rest
210
246
| Verbatim content ->
211
- space ++ space ++ space ++ str " %s" content ++ continue rest
247
+ space ++ space ++ space ++ space ++ str " %s" content ++ continue rest
212
248
| Raw_markup t -> raw_markup t ++ continue rest)
213
249
214
250
let expansion_not_inlined url = not (Link. should_inline url)
@@ -224,10 +260,9 @@ let take_code l =
224
260
in
225
261
(c, rest)
226
262
227
- let heading { Heading. label; level; title } =
263
+ let heading { Heading. label; level; title } nbsp =
228
264
let level =
229
265
match level with
230
- (*TODO: We may want to create markup type for these! * )
231
266
| 1 -> make_hashes 1
232
267
| 2 -> make_hashes 2
233
268
| 3 -> make_hashes 3
@@ -238,34 +273,37 @@ let heading { Heading.label; level; title } =
238
273
(* We can be sure that h6 will never be exceded! *)
239
274
in
240
275
match label with
241
- | Some _ -> (
276
+ | Some l -> (
277
+ (* TODO: Improve this! ! *)
242
278
match level with
243
- | "#" -> string level ++ (space ++ inline title)
244
- | _ -> string level ++ (space ++ inline title ++ break ++ str " ---" ))
245
- | None -> string level ++ space ++ inline title
279
+ | "#" -> string level ++ str " :%s " l ++ (space ++ inline title nbsp )
280
+ | _ -> string level ++ (space ++ inline title nbsp ++ break ++ str " ---" ))
281
+ | None -> string level ++ space ++ inline title nbsp
246
282
247
283
let inline_subpage = function
248
284
| `Inline | `Open | `Default -> true
249
285
| `Closed -> false
250
286
251
287
let item_prop nbsp = string (make_hashes 6 ) ++ space ++ nbsp
252
288
253
- let rec documented_src (l : DocumentedSrc.t ) nbsp =
289
+ let rec documented_src (l : DocumentedSrc.t ) nbsp nbsp' =
254
290
match l with
255
291
| [] -> noop
256
292
| line :: rest -> (
257
- let continue r = documented_src r nbsp in
293
+ let continue l =
294
+ if l = [] then concat [] else documented_src l nbsp nbsp'
295
+ in
258
296
match line with
259
297
| Code _ ->
260
298
let c, rest = take_code l in
261
- source_code c ++ continue rest
299
+ source_code c nbsp' ++ continue rest
262
300
| Alternative alt -> (
263
301
match alt with
264
302
| Expansion { expansion; url; _ } ->
265
303
if expansion_not_inlined url then
266
304
let c, rest = take_code l in
267
- source_code c ++ continue rest
268
- else documented_src expansion nbsp)
305
+ source_code c nbsp' ++ continue rest
306
+ else documented_src expansion nbsp nbsp' )
269
307
| Subpage p -> subpage p.content nbsp ++ continue rest
270
308
| Documented _ | Nested _ ->
271
309
let lines, _, rest =
@@ -277,11 +315,11 @@ let rec documented_src (l : DocumentedSrc.t) nbsp =
277
315
| _ -> Stop_and_keep )
278
316
in
279
317
let f (content , doc , (anchor : Odoc_document.Url.t option )) =
280
- let doc = match doc with [] -> noop | doc -> block doc in
318
+ let doc = match doc with [] -> noop | doc -> block doc nbsp in
281
319
let content =
282
320
match content with
283
- | `D code -> inline code
284
- | `N l -> documented_src l nbsp
321
+ | `D code -> inline code nbsp
322
+ | `N l -> documented_src l nbsp nbsp'
285
323
in
286
324
let anchor = match anchor with Some a -> a.anchor | None -> " " in
287
325
break ++ break ++ anchor' anchor ++ break ++ item_prop nbsp
@@ -297,29 +335,35 @@ and subpage { title = _; header = _; items; url = _ } nbsp =
297
335
in
298
336
surround @@ item nbsp content
299
337
300
- and item nbsp (l : Item.t list ) : Markup.t =
338
+ and item nbsp' (l : Item.t list ) : Markup.t =
301
339
match l with
302
340
| [] -> noop
303
341
| i :: rest -> (
304
- let continue r = if r = [] then noop else break ++ break ++ item nbsp r in
342
+ let continue r =
343
+ if r = [] then noop else break ++ break ++ item nbsp' r
344
+ in
305
345
match i with
306
- | Text b -> block b ++ continue rest
307
- | Heading h -> break ++ heading h ++ break ++ continue rest
346
+ | Text b -> block b nbsp' ++ continue rest
347
+ | Heading h -> break ++ heading h nbsp' ++ break ++ continue rest
308
348
| Declaration { attr = _ ; anchor; content; doc } ->
309
- let nbsp' = nbsp ++ nbsp ++ nbsp in
310
- let decl = documented_src content (nbsp ++ nbsp') in
311
- let doc = match doc with [] -> noop | doc -> block doc ++ break in
349
+ let nbsp'' = nbsp ++ nbsp ++ nbsp ++ nbsp in
350
+ let decl = documented_src content (nbsp' ++ nbsp'') nbsp' in
351
+ let doc =
352
+ match doc with [] -> noop | doc -> block doc nbsp' ++ break
353
+ in
312
354
let anchor = match anchor with Some x -> x.anchor | None -> " " in
313
- anchor' anchor ++ break ++ item_prop nbsp ++ decl ++ break ++ break
355
+ anchor' anchor ++ break ++ item_prop nbsp' ++ decl ++ break ++ break
314
356
++ doc ++ continue rest
315
357
| Include
316
358
{ attr = _; anchor = _; content = { summary; status; content }; doc }
317
359
->
318
360
let d =
319
- if inline_subpage status then item nbsp content
361
+ if inline_subpage status then item nbsp' content
320
362
else
321
- let s = source_code summary in
322
- match doc with [] -> s | doc -> s ++ break ++ break ++ block doc
363
+ let s = source_code summary nbsp' in
364
+ match doc with
365
+ | [] -> s
366
+ | doc -> s ++ break ++ break ++ block doc nbsp'
323
367
in
324
368
d ++ continue rest)
325
369
@@ -339,9 +383,9 @@ and page generate_links ({ Page.header; items; url; _ } as p) =
339
383
let header = Shift. compute ~on_sub header in
340
384
let items = Shift. compute ~on_sub items in
341
385
let subpages = subpages p generate_links in
342
- Block
343
- ([ Inline (Link. for_printing url) ]
344
- @ [ item nbsp header ++ item nbsp items ]
386
+ block'
387
+ ([ inline' (Link. for_printing url) ]
388
+ @ [ item (str " " ) header ++ item (str " " ) items ]
345
389
@ subpages)
346
390
347
391
let rec subpage subp =
0 commit comments