Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap arrays using an hov box only if they contain only simple elements. #142

Merged
merged 3 commits into from
Jun 8, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

### Fixed

- Fix pretty-printing behavior for lists/objects inside lists (#141, @c-cube)
- Fix pretty-printing behavior for lists/objects inside lists (@c-cube
#141, @mjambon #142)

## 2.0.0

Expand Down
61 changes: 60 additions & 1 deletion lib/pretty.ml
Original file line number Diff line number Diff line change
@@ -1,8 +1,59 @@
(*
Pretty-print JSON data in an attempt to maximize readability.

1. What fits on one line stays on one line.
2. What doesn't fit on one line gets printed more vertically so as to not
exceed a reasonable page width, if possible.

Arrays containing only simple elements ("atoms") are pretty-printed with
end-of-line wrapping like ordinary text:

[
"hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello",
"hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello"
]

Other arrays are printed either horizontally or vertically depending
on whether they fit on a single line:

[ { "hello": "world" }, { "hello": "world" }, { "hello": "world" } ]

or

[
{ "hello": "world" },
{ "hello": "world" },
{ "hello": "world" },
{ "hello": "world" }
]
*)

let pp_list sep ppx out l =
let pp_sep out () = Format.fprintf out "%s@ " sep in
Format.pp_print_list ~pp_sep ppx out l

let is_atom (x: [> t]) =
match x with
| `Null
| `Bool _
| `Int _
| `Float _
| `String _
| `Intlit _
| `Floatlit _
| `Stringlit _
| `List []
| `Assoc []
| `Tuple []
| `Variant (_, None) -> true
| `List _
| `Assoc _
| `Tuple _
| `Variant (_, Some _) -> false

let is_atom_list l =
List.for_all is_atom l

let rec format ~inside_box std (out:Format.formatter) (x:t) : unit =
match x with
| `Null -> Format.pp_print_string out "null"
Expand Down Expand Up @@ -33,7 +84,15 @@ let rec format ~inside_box std (out:Format.formatter) (x:t) : unit =
| `List [] -> Format.pp_print_string out "[]"
| `List l ->
if not inside_box then Format.fprintf out "@[<hov2>";
Format.fprintf out "[@;<1 0>@[<hov>%a@]@;<1 -2>]" (pp_list "," (format ~inside_box:false std)) l;
if is_atom_list l then
(* use line wrapping like we would do for a paragraph of text *)
Format.fprintf out "[@;<1 0>@[<hov>%a@]@;<1 -2>]"
(pp_list "," (format ~inside_box:false std)) l
else
(* print the elements horizontally if they fit on the line,
otherwise print them in a column *)
Format.fprintf out "[@;<1 0>@[<hv>%a@]@;<1 -2>]"
(pp_list "," (format ~inside_box:false std)) l;
if not inside_box then Format.fprintf out "@]";
| `Assoc [] -> Format.pp_print_string out "{}"
| `Assoc l ->
Expand Down
41 changes: 32 additions & 9 deletions test/pretty/atd.expected.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
[
{ "r1": "testing" }, { "r2": [ "Some", 2 ] }, { "r2": "None" },
{ "r3": [ "Some", 3 ] }, {}, { "r4": true }, { "r5": [ "Some", 5 ] }, {},
{ "r6": 6 }, {}, { "r7": -1000 }, { "r8": [ 1, 2, 3 ] }, [ "foo", "bar" ],
[], null, [ 1, 2, 3 ], 99, { "foo": 7, "bar": 8, "baz": 43 },
{ "foo2": 5, "bar2": 6, "baz2": 41, "42": 42 }, [ 100, "foo" ],
[ 100, 200, 42 ], [ 100, 200, -1 ],
{ "r1": "testing" },
{ "r2": [ "Some", 2 ] },
{ "r2": "None" },
{ "r3": [ "Some", 3 ] },
{},
{ "r4": true },
{ "r5": [ "Some", 5 ] },
{},
{ "r6": 6 },
{},
{ "r7": -1000 },
{ "r8": [ 1, 2, 3 ] },
[ "foo", "bar" ],
[],
null,
[ 1, 2, 3 ],
99,
{ "foo": 7, "bar": 8, "baz": 43 },
{ "foo2": 5, "bar2": 6, "baz2": 41, "42": 42 },
[ 100, "foo" ],
[ 100, 200, 42 ],
[ 100, 200, -1 ],
[
"V1", "v22", [ "V3", "testing" ], [ "V44", 255 ], [ "V5", "None" ],
[ "V5", [ "Some", true ] ] ], { "v2": "A" }, { "v2": [ "B", 100 ] },
[ "C1", [ "C2", true ], [ "C2", false ] ], [ 50, 30, -1, 400 ]
"V1",
"v22",
[ "V3", "testing" ],
[ "V44", 255 ],
[ "V5", "None" ],
[ "V5", [ "Some", true ] ] ],
mjambon marked this conversation as resolved.
Show resolved Hide resolved
{ "v2": "A" },
{ "v2": [ "B", 100 ] },
[ "C1", [ "C2", true ], [ "C2", false ] ],
[ 50, 30, -1, 400 ]
]