Skip to content

Commit dcd0560

Browse files
authored
Experimental command to format code blocks embedded in docstrings (#7598)
* add experimental command to format code blocks embedded in docstrings * normalize whitespace better * fix offset lines calculation * fix tests * format Stdlib_Result.resi with the new docstrings formatter * just output the filename without the full path for now * fix * disable color in docstring format tests since it breaks in different environments in CI * better approach than a new env variable * more tweaks to not make more changes to docstrings than needed * do not edit anything if we didnt have any code blocks * use cmarkit for transforming codeblocks * add to opam file * add to dune-project * make markdown code block formatter work on markdown files as well * restructure args * refactor * add transform for assertEqual -> == in code blocks * change printer to make width optional * explicit cmarkit * add note about --transform-assert-equal * support more rescript lang tags * support resi code blocks as well * add missing help text * changelog
1 parent a8d8562 commit dcd0560

29 files changed

+751
-50
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
1313
# 12.0.0-beta.1 (Unreleased)
1414

15+
#### :rocket: New Feature
16+
17+
- Add experimental command to `rescript-tools` for formatting all ReScript code blocks in markdown. Either in a markdown file directly, or inside of docstrings in ReScript code. https://github.com/rescript-lang/rescript/pull/7598
18+
1519
# 12.0.0-alpha.15
1620

1721
#### :boom: Breaking Change

analysis/src/Commands.ml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,17 +282,13 @@ let format ~path =
282282
~filename:path
283283
in
284284
if List.length diagnostics > 0 then ""
285-
else
286-
Res_printer.print_implementation
287-
~width:Res_multi_printer.default_print_width ~comments structure
285+
else Res_printer.print_implementation ~comments structure
288286
else if Filename.check_suffix path ".resi" then
289287
let {Res_driver.parsetree = signature; comments; diagnostics} =
290288
Res_driver.parsing_engine.parse_interface ~for_printer:true ~filename:path
291289
in
292290
if List.length diagnostics > 0 then ""
293-
else
294-
Res_printer.print_interface ~width:Res_multi_printer.default_print_width
295-
~comments signature
291+
else Res_printer.print_interface ~comments signature
296292
else ""
297293

298294
let diagnosticSyntax ~path =

analysis/src/CreateInterface.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ let printSignature ~extractor ~signature =
102102
Printtyp.reset_names ();
103103
let sigItemToString (item : Outcometree.out_sig_item) =
104104
item |> Res_outcome_printer.print_out_sig_item_doc
105-
|> Res_doc.to_string ~width:Res_multi_printer.default_print_width
105+
|> Res_doc.to_string ~width:Res_printer.default_print_width
106106
in
107107

108108
let genSigStrForInlineAttr lines attributes id vd =

analysis/src/Xform.ml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,6 @@ let parseImplementation ~filename =
855855
let structure = [Ast_helper.Str.eval ~loc:expr.pexp_loc expr] in
856856
structure
857857
|> Res_printer.print_implementation
858-
~width:Res_multi_printer.default_print_width
859858
~comments:(comments |> filterComments ~loc:expr.pexp_loc)
860859
|> Utils.indent range.start.character
861860
in
@@ -864,14 +863,12 @@ let parseImplementation ~filename =
864863
let structure = [item] in
865864
structure
866865
|> Res_printer.print_implementation
867-
~width:Res_multi_printer.default_print_width
868866
~comments:(comments |> filterComments ~loc:item.pstr_loc)
869867
|> Utils.indent range.start.character
870868
in
871869
let printStandaloneStructure ~(loc : Location.t) structure =
872870
structure
873871
|> Res_printer.print_implementation
874-
~width:Res_multi_printer.default_print_width
875872
~comments:(comments |> filterComments ~loc)
876873
in
877874
(structure, printExpr, printStructureItem, printStandaloneStructure)
@@ -891,7 +888,7 @@ let parseInterface ~filename =
891888
(item : Parsetree.signature_item) =
892889
let signature_item = [item] in
893890
signature_item
894-
|> Res_printer.print_interface ~width:Res_multi_printer.default_print_width
891+
|> Res_printer.print_interface
895892
~comments:(comments |> filterComments ~loc:item.psig_loc)
896893
|> Utils.indent range.start.character
897894
in

compiler/ml/location.ml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -231,24 +231,29 @@ let error_of_exn exn =
231231

232232
(* taken from https://github.com/rescript-lang/ocaml/blob/d4144647d1bf9bc7dc3aadc24c25a7efa3a67915/parsing/location.ml#L380 *)
233233
(* This is the error report entry point. We'll replace the default reporter with this one. *)
234-
let rec default_error_reporter ?(src = None) ppf {loc; msg; sub} =
234+
let rec default_error_reporter ?(custom_intro = None) ?(src = None) ppf
235+
{loc; msg; sub} =
235236
setup_colors ();
236237
(* open a vertical box. Everything in our message is indented 2 spaces *)
237238
(* If src is given, it will display a syntax error after parsing. *)
238239
let intro =
239-
match src with
240-
| Some _ -> "Syntax error!"
241-
| None -> "We've found a bug for you!"
240+
match (custom_intro, src) with
241+
| Some intro, _ -> intro
242+
| None, Some _ -> "Syntax error!"
243+
| None, None -> "We've found a bug for you!"
242244
in
243245
Format.fprintf ppf "@[<v>@, %a@, %s@,@]"
244246
(print ~src ~message_kind:`error intro)
245247
loc msg;
246-
List.iter (Format.fprintf ppf "@,@[%a@]" (default_error_reporter ~src)) sub
248+
List.iter
249+
(Format.fprintf ppf "@,@[%a@]" (default_error_reporter ~custom_intro ~src))
250+
sub
247251
(* no need to flush here; location's report_exception (which uses this ultimately) flushes *)
248252

249253
let error_reporter = ref default_error_reporter
250254

251-
let report_error ?(src = None) ppf err = !error_reporter ~src ppf err
255+
let report_error ?(custom_intro = None) ?(src = None) ppf err =
256+
!error_reporter ~custom_intro ~src ppf err
252257

253258
let error_of_printer loc print x = errorf ~loc "%a@?" print x
254259

@@ -276,7 +281,8 @@ let rec report_exception_rec n ppf exn =
276281
match error_of_exn exn with
277282
| None -> reraise exn
278283
| Some `Already_displayed -> ()
279-
| Some (`Ok err) -> fprintf ppf "@[%a@]@." (report_error ~src:None) err
284+
| Some (`Ok err) ->
285+
fprintf ppf "@[%a@]@." (report_error ~custom_intro:None ~src:None) err
280286
with exn when n > 0 -> report_exception_rec (n - 1) ppf exn
281287

282288
let report_exception ppf exn = report_exception_rec 5 ppf exn

compiler/ml/location.mli

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,28 @@ val register_error_of_exn : (exn -> error option) -> unit
103103
a location, a message, and optionally sub-messages (each of them
104104
being located as well). *)
105105

106-
val report_error : ?src:string option -> formatter -> error -> unit
107-
108-
val error_reporter : (?src:string option -> formatter -> error -> unit) ref
106+
val report_error :
107+
?custom_intro:string option ->
108+
?src:string option ->
109+
formatter ->
110+
error ->
111+
unit
112+
113+
val error_reporter :
114+
(?custom_intro:string option ->
115+
?src:string option ->
116+
formatter ->
117+
error ->
118+
unit)
119+
ref
109120
(** Hook for intercepting error reports. *)
110121

111-
val default_error_reporter : ?src:string option -> formatter -> error -> unit
122+
val default_error_reporter :
123+
?custom_intro:string option ->
124+
?src:string option ->
125+
formatter ->
126+
error ->
127+
unit
112128
(** Original error reporter for use in hooks. *)
113129

114130
val report_exception : formatter -> exn -> unit

compiler/syntax/src/res_diagnostics.ml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,13 @@ let explain t =
131131

132132
let make ~start_pos ~end_pos category = {start_pos; end_pos; category}
133133

134-
let print_report diagnostics src =
134+
let print_report ?(custom_intro = None) ?(formatter = Format.err_formatter)
135+
diagnostics src =
135136
let rec print diagnostics src =
136137
match diagnostics with
137138
| [] -> ()
138139
| d :: rest ->
139-
Location.report_error ~src:(Some src) Format.err_formatter
140+
Location.report_error ~custom_intro ~src:(Some src) formatter
140141
Location.
141142
{
142143
loc =
@@ -147,12 +148,12 @@ let print_report diagnostics src =
147148
};
148149
(match rest with
149150
| [] -> ()
150-
| _ -> Format.fprintf Format.err_formatter "@.");
151+
| _ -> Format.fprintf formatter "@.");
151152
print rest src
152153
in
153-
Format.fprintf Format.err_formatter "@[<v>";
154+
Format.fprintf formatter "@[<v>";
154155
print (List.rev diagnostics) src;
155-
Format.fprintf Format.err_formatter "@]@."
156+
Format.fprintf formatter "@]@."
156157

157158
let unexpected token context = Unexpected {token; context}
158159

compiler/syntax/src/res_diagnostics.mli

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,9 @@ val message : string -> category
2222

2323
val make : start_pos:Lexing.position -> end_pos:Lexing.position -> category -> t
2424

25-
val print_report : t list -> string -> unit
25+
val print_report :
26+
?custom_intro:string option ->
27+
?formatter:Format.formatter ->
28+
t list ->
29+
string ->
30+
unit

compiler/syntax/src/res_multi_printer.ml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
let default_print_width = 100
2-
31
(* print res files to res syntax *)
42
let print_res ~ignore_parse_errors ~is_interface ~filename =
53
if is_interface then (
@@ -9,7 +7,7 @@ let print_res ~ignore_parse_errors ~is_interface ~filename =
97
if parse_result.invalid then (
108
Res_diagnostics.print_report parse_result.diagnostics parse_result.source;
119
if not ignore_parse_errors then exit 1);
12-
Res_printer.print_interface ~width:default_print_width
10+
Res_printer.print_interface ~width:Res_printer.default_print_width
1311
~comments:parse_result.comments parse_result.parsetree)
1412
else
1513
let parse_result =
@@ -18,7 +16,7 @@ let print_res ~ignore_parse_errors ~is_interface ~filename =
1816
if parse_result.invalid then (
1917
Res_diagnostics.print_report parse_result.diagnostics parse_result.source;
2018
if not ignore_parse_errors then exit 1);
21-
Res_printer.print_implementation ~width:default_print_width
19+
Res_printer.print_implementation ~width:Res_printer.default_print_width
2220
~comments:parse_result.comments parse_result.parsetree
2321
[@@raises exit]
2422

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
val default_print_width : int [@@live]
2-
31
(* Interface to print source code to res.
42
* Takes a filename called "input" and returns the corresponding formatted res syntax *)
53
val print : ?ignore_parse_errors:bool -> string -> string [@@dead "+print"]

0 commit comments

Comments
 (0)