Skip to content

Commit 89dd2cf

Browse files
committed
more improvements
1 parent 0774ce6 commit 89dd2cf

File tree

1 file changed

+125
-81
lines changed

1 file changed

+125
-81
lines changed

src/markdown/generator.ml

+125-81
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,48 @@ open Odoc_document
22
open Types
33
open Doctree
44

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
646
type t =
7-
| Inline of string list
847
| Block of t list
948
| Concat of t list
1049
| Break
@@ -54,13 +93,16 @@ module Markup = struct
5493

5594
let string s = String s
5695

96+
let block' ts = Block ts
97+
98+
let inline' l = List.map (fun s -> string s) l |> concat
99+
57100
let str fmt = Format.ksprintf (fun s -> string s) fmt
58101

59102
let escaped fmt = Format.ksprintf (fun s -> string s) fmt
60103

61104
let rec pp fmt t =
62105
match t with
63-
| Inline s -> Format.fprintf fmt "%s" (String.concat "" s)
64106
| Block b ->
65107
let inner = function
66108
| [] -> ()
@@ -77,7 +119,7 @@ module Markup = struct
77119
within backtick, and the spaces before and after the backticks for
78120
clarity on what should be enclosed in backticks. For example,
79121
"type nums = [ | `One | `Two ]" would be rendered as "``|`````Monday`` "
80-
if the spaces were not there.
122+
if the spaces were missing.
81123
*)
82124
| Backticks -> Format.fprintf fmt " `` "
83125
| Nbsp -> Format.fprintf fmt "  "
@@ -103,93 +145,89 @@ let style (style : style) content =
103145
| `Superscript -> string "<sup>" ++ content
104146
| `Subscript -> string "<sub>" ++ content
105147

106-
(*I'm not sure if `make_hashes` is the best name to use! *)
107148
let make_hashes n = String.make n '#'
108149

109150
type args = { generate_links : bool ref }
110151

111152
let args = { generate_links = ref true }
112153

113-
let rec source_code (s : Source.t) =
154+
let rec source_code (s : Source.t) nbsp =
114155
match s with
115156
| [] -> noop
116157
| h :: t -> (
158+
let continue s = if s = [] then concat [] else source_code s nbsp in
117159
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)
121163

122-
and inline (l : Inline.t) =
164+
and inline (l : Inline.t) nbsp =
123165
match l with
124166
| [] -> noop
125167
| i :: rest -> (
168+
let continue i = if i = [] then noop else inline i nbsp in
126169
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)
144182
| Entity e ->
145183
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
149187
| Link (href, content) ->
150188
if !(args.generate_links) then
151189
match content with
152190
| [] -> noop
153191
| i :: rest ->
154192
(match i.desc with
155193
| Text _ ->
156-
open_sq_bracket ++ inline content ++ close_sq_bracket
194+
open_sq_bracket ++ continue content ++ close_sq_bracket
157195
++ 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
162200
| InternalLink (Resolved (link, content)) ->
163201
if !(args.generate_links) then
164202
match link.page.parent with
165-
| Some _ -> inline content ++ inline rest
203+
| Some _ -> continue content ++ continue rest
166204
| None ->
167-
open_sq_bracket ++ inline content ++ close_sq_bracket
205+
open_sq_bracket ++ continue content ++ close_sq_bracket
168206
++ open_parenthesis
169207
++ 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
173211
| 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)
176214

177-
let rec block (l : Block.t) =
215+
let rec block (l : Block.t) nbsp =
178216
match l with
179217
| [] -> noop
180218
| 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
182220
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
185223
| List (list_typ, l) ->
186224
let f n b =
187225
let bullet =
188226
match list_typ with
189227
| Unordered -> escaped "- "
190228
| Ordered -> str "%d. " (n + 1)
191229
in
192-
bullet ++ block b ++ break
230+
bullet ++ block b nbsp ++ break
193231
in
194232
list ~sep:break (List.mapi f l) ++ continue rest
195233
| Description _ ->
@@ -199,16 +237,14 @@ let rec block (l : Block.t) =
199237
| _ -> Stop_and_keep)
200238
in
201239
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
204242
break ++ str "@" ++ key ++ str " : " ++ def ++ break ++ break
205243
in
206244
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
210246
| Verbatim content ->
211-
space ++ space ++ space ++ str "%s" content ++ continue rest
247+
space ++ space ++ space ++ space ++ str "%s" content ++ continue rest
212248
| Raw_markup t -> raw_markup t ++ continue rest)
213249

214250
let expansion_not_inlined url = not (Link.should_inline url)
@@ -224,10 +260,9 @@ let take_code l =
224260
in
225261
(c, rest)
226262

227-
let heading { Heading.label; level; title } =
263+
let heading { Heading.label; level; title } nbsp =
228264
let level =
229265
match level with
230-
(*TODO: We may want to create markup type for these! *)
231266
| 1 -> make_hashes 1
232267
| 2 -> make_hashes 2
233268
| 3 -> make_hashes 3
@@ -238,34 +273,37 @@ let heading { Heading.label; level; title } =
238273
(* We can be sure that h6 will never be exceded! *)
239274
in
240275
match label with
241-
| Some _ -> (
276+
| Some l -> (
277+
(*TODO: Improve this! ! *)
242278
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
246282

247283
let inline_subpage = function
248284
| `Inline | `Open | `Default -> true
249285
| `Closed -> false
250286

251287
let item_prop nbsp = string (make_hashes 6) ++ space ++ nbsp
252288

253-
let rec documented_src (l : DocumentedSrc.t) nbsp =
289+
let rec documented_src (l : DocumentedSrc.t) nbsp nbsp' =
254290
match l with
255291
| [] -> noop
256292
| 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
258296
match line with
259297
| Code _ ->
260298
let c, rest = take_code l in
261-
source_code c ++ continue rest
299+
source_code c nbsp' ++ continue rest
262300
| Alternative alt -> (
263301
match alt with
264302
| Expansion { expansion; url; _ } ->
265303
if expansion_not_inlined url then
266304
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')
269307
| Subpage p -> subpage p.content nbsp ++ continue rest
270308
| Documented _ | Nested _ ->
271309
let lines, _, rest =
@@ -277,11 +315,11 @@ let rec documented_src (l : DocumentedSrc.t) nbsp =
277315
| _ -> Stop_and_keep)
278316
in
279317
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
281319
let content =
282320
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'
285323
in
286324
let anchor = match anchor with Some a -> a.anchor | None -> "" in
287325
break ++ break ++ anchor' anchor ++ break ++ item_prop nbsp
@@ -297,29 +335,35 @@ and subpage { title = _; header = _; items; url = _ } nbsp =
297335
in
298336
surround @@ item nbsp content
299337

300-
and item nbsp (l : Item.t list) : Markup.t =
338+
and item nbsp' (l : Item.t list) : Markup.t =
301339
match l with
302340
| [] -> noop
303341
| 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
305345
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
308348
| 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
312354
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
314356
++ doc ++ continue rest
315357
| Include
316358
{ attr = _; anchor = _; content = { summary; status; content }; doc }
317359
->
318360
let d =
319-
if inline_subpage status then item nbsp content
361+
if inline_subpage status then item nbsp' content
320362
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'
323367
in
324368
d ++ continue rest)
325369

@@ -339,9 +383,9 @@ and page generate_links ({ Page.header; items; url; _ } as p) =
339383
let header = Shift.compute ~on_sub header in
340384
let items = Shift.compute ~on_sub items in
341385
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 ]
345389
@ subpages)
346390

347391
let rec subpage subp =

0 commit comments

Comments
 (0)