Skip to content

Commit 47b0645

Browse files
committed
Move rewrap_paragraph to the shared Doc module
1 parent 96a2648 commit 47b0645

File tree

3 files changed

+60
-50
lines changed

3 files changed

+60
-50
lines changed

atd/src/doc.ml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,49 @@ let html_of_doc blocks =
194194
) blocks;
195195
bprintf buf "\n</div>\n";
196196
Buffer.contents buf
197+
198+
let split_on_blank =
199+
let rex = Re.Pcre.regexp {|[ \t\r\n]+|} in
200+
fun str ->
201+
Re.Pcre.split ~rex str
202+
|> (* make sure to ignore leading and trailing whitespace *)
203+
List.filter (function "" -> false | _ -> true)
204+
205+
let concatenate_into_lines ~max_length (words : string list) : string list =
206+
let max_length = max 0 max_length in
207+
let buf = Buffer.create max_length in
208+
let finish_line () =
209+
let line = Buffer.contents buf in
210+
Buffer.clear buf;
211+
line
212+
in
213+
let rec make_lines orig_words =
214+
match orig_words with
215+
| [] -> [finish_line ()]
216+
| word :: words ->
217+
let word_len = String.length word in
218+
let len = Buffer.length buf in
219+
if len = 0 then (
220+
(* The word may be longer than 'max_length'. Putting it on its
221+
own line is the best we can do without hyphenating it. *)
222+
Buffer.add_string buf word;
223+
make_lines words
224+
)
225+
else
226+
(* Add the word to the current line only if it fits. *)
227+
let new_len = len + 1 + word_len in
228+
if new_len <= max_length then (
229+
bprintf buf " %s" word;
230+
make_lines words
231+
)
232+
else
233+
(* The new word doesn't fit on the current line. Start a new one. *)
234+
let line = finish_line () in
235+
line :: make_lines orig_words
236+
in
237+
make_lines words
238+
239+
let rewrap_paragraph ~max_length strs =
240+
strs
241+
|> List.concat_map split_on_blank
242+
|> concatenate_into_lines ~max_length

atd/src/doc.mli

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,16 @@ val get_doc : Ast.loc -> Ast.annot -> doc option
6969

7070
(** Convert parsed doc into HTML. *)
7171
val html_of_doc : doc -> string
72+
73+
(** Rewrap a paragraph of text.
74+
75+
This generic utility concatenates a list of strings
76+
into lines where the "words" (any sequence of non-whitespace characters)
77+
are separated by a single space character. Each line will not exceed
78+
[max_length] bytes unless a word is longer than this maximum length.
79+
80+
The input is a list of lines but may also be an unsplit multiline
81+
paragraph provided as [[paragraph]]. The result is a list of lines that
82+
are not newline-terminated.
83+
*)
84+
val rewrap_paragraph : max_length:int -> string list -> string list

atdpy/src/lib/Codegen_doc.ml

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -18,57 +18,9 @@ let make_ocamldoc_block = function
1818
List (("", "", "", plist), atoms)
1919
*)
2020

21-
open Printf
2221
open Atd
2322
open Indent
2423

25-
let split_on_blank =
26-
let rex = Re.Pcre.regexp {|[ \t]+|} in
27-
fun str ->
28-
Re.Pcre.split ~rex str
29-
30-
(* Concatenate a list of strings ("words") into lines where the words
31-
are separated by a single space character. Each line will not exceed
32-
'max_length' bytes unless a word is longer than this. *)
33-
let concatenate_into_lines ~max_length (words : string list) : string list =
34-
let max_length = max 0 max_length in
35-
let buf = Buffer.create max_length in
36-
let finish_line () =
37-
let line = Buffer.contents buf in
38-
Buffer.clear buf;
39-
line
40-
in
41-
let rec make_lines orig_words =
42-
match orig_words with
43-
| [] -> [finish_line ()]
44-
| word :: words ->
45-
let word_len = String.length word in
46-
let len = Buffer.length buf in
47-
if len = 0 then (
48-
(* The word may be longer than 'max_length'. Putting it on its
49-
own line is the best we can do without hyphenating it. *)
50-
Buffer.add_string buf word;
51-
make_lines words
52-
)
53-
else
54-
(* Add the word to the current line only if it fits. *)
55-
let new_len = len + 1 + word_len in
56-
if new_len <= max_length then (
57-
bprintf buf " %s" word;
58-
make_lines words
59-
)
60-
else
61-
(* The new word doesn't fit on the current line. Start a new one. *)
62-
let line = finish_line () in
63-
line :: make_lines orig_words
64-
in
65-
make_lines words
66-
67-
let rewrap_paragraph ~max_length str =
68-
str
69-
|> split_on_blank
70-
|> concatenate_into_lines ~max_length
71-
7224
let docstring_escape str =
7325
(* TODO *)
7426
str
@@ -101,8 +53,7 @@ let translate_block ~max_length (block : Doc.block) : Indent.node list =
10153
| Paragraph elements ->
10254
elements
10355
|> List.map translate_inline_element
104-
|> String.concat ""
105-
|> rewrap_paragraph ~max_length
56+
|> Doc.rewrap_paragraph ~max_length
10657
|> List.map (fun line -> Line line)
10758

10859
let make_unquoted_multiline_docstring

0 commit comments

Comments
 (0)