@@ -29,7 +29,8 @@ defmodule Inspect.Opts do
29
29
30
30
* `:pretty` - if set to true enables pretty printing, defaults to false.
31
31
32
- * `:width` - defaults to the 80 characters.
32
+ * `:width` - defaults to the 80 characters, used when pretty is true or
33
+ when printing to IO devices.
33
34
"""
34
35
35
36
defstruct structs: true ,
@@ -66,8 +67,8 @@ defmodule Inspect.Algebra do
66
67
elements together and render them:
67
68
68
69
iex> doc = Inspect.Algebra.concat(Inspect.Algebra.empty, "foo")
69
- iex> Inspect.Algebra.pretty (doc, 80)
70
- "foo"
70
+ iex> Inspect.Algebra.format (doc, 80)
71
+ [ "foo"]
71
72
72
73
The functions `nest/2`, `space/2` and `line/2` help you put the
73
74
document together into a rigid structure. However, the document
@@ -77,15 +78,15 @@ defmodule Inspect.Algebra do
77
78
render it:
78
79
79
80
iex> doc = Inspect.Algebra.glue("a", " ", "b")
80
- iex> Inspect.Algebra.pretty (doc, 80)
81
- "a b"
81
+ iex> Inspect.Algebra.format (doc, 80)
82
+ ["a", " ", "b"]
82
83
83
84
Notice the break was represented as is, because we haven't reached
84
85
a line limit. Once we do, it is replaced by a newline:
85
86
86
87
iex> doc = Inspect.Algebra.glue(String.duplicate("a", 20), " ", "b")
87
- iex> Inspect.Algebra.pretty (doc, 10)
88
- "aaaaaaaaaaaaaaaaaaaa\nb"
88
+ iex> Inspect.Algebra.format (doc, 10)
89
+ [ "aaaaaaaaaaaaaaaaaaaa", "\n", "b"]
89
90
90
91
Finally, this module also contains Elixir related functions, a bit
91
92
tied to Elixir formatting, namely `surround/3` and `surround_many/5`.
@@ -190,9 +191,10 @@ defmodule Inspect.Algebra do
190
191
try do
191
192
Process . put ( :inspect_trap , true )
192
193
res = Inspect.Map . inspect ( map , opts )
194
+ formatted = IO . iodata_to_binary ( format ( res , :infinity ) )
193
195
raise ArgumentError ,
194
196
"Got #{ inspect e . __struct__ } with message " <>
195
- "\" #{ Exception . message ( e ) } \" while inspecting #{ pretty ( res , opts . width ) } "
197
+ "\" #{ Exception . message ( e ) } \" while inspecting #{ formatted } "
196
198
after
197
199
Process . delete ( :inspect_trap )
198
200
end
@@ -224,9 +226,9 @@ defmodule Inspect.Algebra do
224
226
225
227
## Examples
226
228
227
- iex> doc = Inspect.Algebra.concat "Tasteless ", "Artosis "
228
- iex> Inspect.Algebra.pretty (doc, 80)
229
- "TastelessArtosis"
229
+ iex> doc = Inspect.Algebra.concat "hello ", "world "
230
+ iex> Inspect.Algebra.format (doc, 80)
231
+ ["hello", "world"]
230
232
231
233
"""
232
234
@ spec concat ( t , t ) :: doc_cons
@@ -250,8 +252,8 @@ defmodule Inspect.Algebra do
250
252
## Examples
251
253
252
254
iex> doc = Inspect.Algebra.nest(Inspect.Algebra.glue("hello", "world"), 5)
253
- iex> Inspect.Algebra.pretty (doc, 5)
254
- "hello\n world"
255
+ iex> Inspect.Algebra.format (doc, 5)
256
+ [ "hello", " \n ", " world"]
255
257
256
258
"""
257
259
@ spec nest ( t , non_neg_integer ) :: doc_nest
@@ -275,15 +277,15 @@ defmodule Inspect.Algebra do
275
277
Let's glue two docs together with a break and then render it:
276
278
277
279
iex> doc = Inspect.Algebra.glue("a", " ", "b")
278
- iex> Inspect.Algebra.pretty (doc, 80)
279
- "a b"
280
+ iex> Inspect.Algebra.format (doc, 80)
281
+ ["a", " ", "b"]
280
282
281
283
Notice the break was represented as is, because we haven't reached
282
284
a line limit. Once we do, it is replaced by a newline:
283
285
284
286
iex> doc = Inspect.Algebra.glue(String.duplicate("a", 20), " ", "b")
285
- iex> Inspect.Algebra.pretty (doc, 10)
286
- "aaaaaaaaaaaaaaaaaaaa\nb"
287
+ iex> Inspect.Algebra.format (doc, 10)
288
+ [ "aaaaaaaaaaaaaaaaaaaa", "\n", "b"]
287
289
288
290
"""
289
291
@ spec break ( binary ) :: doc_break
@@ -326,10 +328,10 @@ defmodule Inspect.Algebra do
326
328
...> "B"
327
329
...> )
328
330
...> ))
329
- iex> Inspect.Algebra.pretty (doc, 80)
330
- "Hello, A B"
331
- iex> Inspect.Algebra.pretty (doc, 6)
332
- "Hello,\nA B"
331
+ iex> Inspect.Algebra.format (doc, 80)
332
+ [ "Hello,", " ", "A", " ", "B"]
333
+ iex> Inspect.Algebra.format (doc, 6)
334
+ [ "Hello,", "\n", "A", " ", "B"]
333
335
334
336
"""
335
337
@ spec group ( t ) :: doc_group
@@ -343,8 +345,8 @@ defmodule Inspect.Algebra do
343
345
## Examples
344
346
345
347
iex> doc = Inspect.Algebra.space "Hughes", "Wadler"
346
- iex> Inspect.Algebra.pretty (doc, 80)
347
- "Hughes Wadler"
348
+ iex> Inspect.Algebra.format (doc, 80)
349
+ [ "Hughes", " ", " Wadler"]
348
350
349
351
"""
350
352
@ spec space ( t , t ) :: doc_cons
@@ -356,8 +358,8 @@ defmodule Inspect.Algebra do
356
358
## Examples
357
359
358
360
iex> doc = Inspect.Algebra.line "Hughes", "Wadler"
359
- iex> Inspect.Algebra.pretty (doc, 80)
360
- "Hughes\nWadler"
361
+ iex> Inspect.Algebra.format (doc, 80)
362
+ [ "Hughes", "\n", "Wadler"]
361
363
362
364
"""
363
365
@ spec line ( t , t ) :: doc_cons
@@ -373,8 +375,8 @@ defmodule Inspect.Algebra do
373
375
iex> doc = Inspect.Algebra.folddoc(doc, fn(x,y) ->
374
376
...> Inspect.Algebra.concat [x, "!", y]
375
377
...> end)
376
- iex> Inspect.Algebra.pretty (doc, 80)
377
- "A!B"
378
+ iex> Inspect.Algebra.format (doc, 80)
379
+ ["A", "!", "B"]
378
380
379
381
"""
380
382
@ spec folddoc ( [ t ] , ( ( t , t ) -> t ) ) :: t
@@ -394,8 +396,8 @@ defmodule Inspect.Algebra do
394
396
## Examples
395
397
396
398
iex> doc = Inspect.Algebra.surround "[", Inspect.Algebra.glue("a", "b"), "]"
397
- iex> Inspect.Algebra.pretty (doc, 3)
398
- "[a \n b]"
399
+ iex> Inspect.Algebra.format (doc, 3)
400
+ ["[", "a", " \n ", "b", "]"]
399
401
400
402
"""
401
403
@ spec surround ( binary , t , binary ) :: t
@@ -411,15 +413,15 @@ defmodule Inspect.Algebra do
411
413
## Examples
412
414
413
415
iex> doc = Inspect.Algebra.surround_many("[", Enum.to_list(1..5), "]", :infinity, &Integer.to_string(&1))
414
- iex> Inspect.Algebra.pretty (doc, 5)
416
+ iex> Inspect.Algebra.format (doc, 5) |> IO.iodata_to_binary
415
417
"[1,\n 2,\n 3,\n 4,\n 5]"
416
418
417
419
iex> doc = Inspect.Algebra.surround_many("[", Enum.to_list(1..5), "]", 3, &Integer.to_string(&1))
418
- iex> Inspect.Algebra.pretty (doc, 20)
420
+ iex> Inspect.Algebra.format (doc, 20) |> IO.iodata_to_binary
419
421
"[1, 2, 3, ...]"
420
422
421
423
iex> doc = Inspect.Algebra.surround_many("[", Enum.to_list(1..5), "]", 3, &Integer.to_string(&1), "!")
422
- iex> Inspect.Algebra.pretty (doc, 20)
424
+ iex> Inspect.Algebra.format (doc, 20) |> IO.iodata_to_binary
423
425
"[1! 2! 3! ...]"
424
426
425
427
"""
@@ -460,50 +462,50 @@ defmodule Inspect.Algebra do
460
462
defp decrement ( counter ) , do: counter - 1
461
463
462
464
@ doc """
463
- The pretty printing function.
465
+ The formatting function.
464
466
465
467
Takes the maximum width and a document to print as its arguments
466
- and returns the string representation of the best layout for the
468
+ and returns an IO data representation of the best layout for the
467
469
document to fit in the given width.
468
470
"""
469
- @ spec pretty ( t , non_neg_integer | :infinity ) :: binary
471
+ @ spec format ( t , non_neg_integer | :infinity ) :: binary
472
+ def format ( d , w ) do
473
+ format ( w , 0 , [ { 0 , default_mode ( w ) , doc_group ( d ) } ] )
474
+ end
475
+
476
+ @ doc false
470
477
def pretty ( d , w ) do
471
- sdoc = format w , 0 , [ { 0 , default_mode ( w ) , doc_group ( d ) } ]
472
- render ( sdoc )
478
+ format ( d , w ) |> IO . iodata_to_binary
473
479
end
474
480
475
481
defp default_mode ( :infinity ) , do: :flat
476
482
defp default_mode ( _ ) , do: :break
477
483
478
- # Rendering and internal helpers
479
-
480
484
# Record representing the document mode to be rendered: flat or broken
481
485
@ typep mode :: :flat | :break
482
486
483
- @ doc false
484
487
@ spec fits? ( integer , [ { integer , mode , t } ] ) :: boolean
485
- def fits? ( w , _ ) when w < 0 , do: false
486
- def fits? ( _ , [ ] ) , do: true
487
- def fits? ( _ , [ { _ , _ , :doc_line } | _ ] ) , do: true
488
- def fits? ( w , [ { _ , _ , :doc_nil } | t ] ) , do: fits? ( w , t )
489
- def fits? ( w , [ { i , m , doc_cons ( x , y ) } | t ] ) , do: fits? ( w , [ { i , m , x } | [ { i , m , y } | t ] ] )
490
- def fits? ( w , [ { i , m , doc_nest ( x , j ) } | t ] ) , do: fits? ( w , [ { i + j , m , x } | t ] )
491
- def fits? ( w , [ { i , _ , doc_group ( x ) } | t ] ) , do: fits? ( w , [ { i , :flat , x } | t ] )
492
- def fits? ( w , [ { _ , _ , s } | t ] ) when is_binary ( s ) , do: fits? ( ( w - byte_size s ) , t )
493
- def fits? ( w , [ { _ , :flat , doc_break ( s ) } | t ] ) , do: fits? ( ( w - byte_size s ) , t )
494
- def fits? ( _ , [ { _ , :break , doc_break ( _ ) } | _ ] ) , do: true
488
+ defp fits? ( w , _ ) when w < 0 , do: false
489
+ defp fits? ( _ , [ ] ) , do: true
490
+ defp fits? ( _ , [ { _ , _ , :doc_line } | _ ] ) , do: true
491
+ defp fits? ( w , [ { _ , _ , :doc_nil } | t ] ) , do: fits? ( w , t )
492
+ defp fits? ( w , [ { i , m , doc_cons ( x , y ) } | t ] ) , do: fits? ( w , [ { i , m , x } | [ { i , m , y } | t ] ] )
493
+ defp fits? ( w , [ { i , m , doc_nest ( x , j ) } | t ] ) , do: fits? ( w , [ { i + j , m , x } | t ] )
494
+ defp fits? ( w , [ { i , _ , doc_group ( x ) } | t ] ) , do: fits? ( w , [ { i , :flat , x } | t ] )
495
+ defp fits? ( w , [ { _ , _ , s } | t ] ) when is_binary ( s ) , do: fits? ( ( w - byte_size s ) , t )
496
+ defp fits? ( w , [ { _ , :flat , doc_break ( s ) } | t ] ) , do: fits? ( ( w - byte_size s ) , t )
497
+ defp fits? ( _ , [ { _ , :break , doc_break ( _ ) } | _ ] ) , do: true
495
498
496
- @ doc false
497
499
@ spec format ( integer | :infinity , integer , [ { integer , mode , t } ] ) :: [ binary ]
498
- def format ( _ , _ , [ ] ) , do: [ ]
499
- def format ( w , _ , [ { i , _ , :doc_line } | t ] ) , do: [ indent ( i ) | format ( w , i , t ) ]
500
- def format ( w , k , [ { _ , _ , :doc_nil } | t ] ) , do: format ( w , k , t )
501
- def format ( w , k , [ { i , m , doc_cons ( x , y ) } | t ] ) , do: format ( w , k , [ { i , m , x } | [ { i , m , y } | t ] ] )
502
- def format ( w , k , [ { i , m , doc_nest ( x , j ) } | t ] ) , do: format ( w , k , [ { i + j , m , x } | t ] )
503
- def format ( w , k , [ { i , m , doc_group ( x ) } | t ] ) , do: format ( w , k , [ { i , m , x } | t ] )
504
- def format ( w , k , [ { _ , _ , s } | t ] ) when is_binary ( s ) , do: [ s | format ( w , ( k + byte_size s ) , t ) ]
505
- def format ( w , k , [ { _ , :flat , doc_break ( s ) } | t ] ) , do: [ s | format ( w , ( k + byte_size s ) , t ) ]
506
- def format ( w , k , [ { i , :break , doc_break ( s ) } | t ] ) do
500
+ defp format ( _ , _ , [ ] ) , do: [ ]
501
+ defp format ( w , _ , [ { i , _ , :doc_line } | t ] ) , do: [ indent ( i ) | format ( w , i , t ) ]
502
+ defp format ( w , k , [ { _ , _ , :doc_nil } | t ] ) , do: format ( w , k , t )
503
+ defp format ( w , k , [ { i , m , doc_cons ( x , y ) } | t ] ) , do: format ( w , k , [ { i , m , x } | [ { i , m , y } | t ] ] )
504
+ defp format ( w , k , [ { i , m , doc_nest ( x , j ) } | t ] ) , do: format ( w , k , [ { i + j , m , x } | t ] )
505
+ defp format ( w , k , [ { i , m , doc_group ( x ) } | t ] ) , do: format ( w , k , [ { i , m , x } | t ] )
506
+ defp format ( w , k , [ { _ , _ , s } | t ] ) when is_binary ( s ) , do: [ s | format ( w , ( k + byte_size s ) , t ) ]
507
+ defp format ( w , k , [ { _ , :flat , doc_break ( s ) } | t ] ) , do: [ s | format ( w , ( k + byte_size s ) , t ) ]
508
+ defp format ( w , k , [ { i , :break , doc_break ( s ) } | t ] ) do
507
509
k = k + byte_size ( s )
508
510
509
511
if w == :infinity or fits? ( w - k , t ) do
@@ -515,10 +517,4 @@ defmodule Inspect.Algebra do
515
517
516
518
defp indent ( 0 ) , do: @ newline
517
519
defp indent ( i ) , do: @ newline <> :binary . copy ( " " , i )
518
-
519
- @ doc false
520
- @ spec render ( [ binary ] ) :: binary
521
- def render ( sdoc ) do
522
- IO . iodata_to_binary sdoc
523
- end
524
520
end
0 commit comments