PrettyPrint.jl is a library for easy pretty printing in Julia.
It does not aim to provide very high extensibility and customizations(but still very rich), instead, it targets extreme simplicity and 99% use cases when pretty printing is needed.
99% users exclusively use 2 functions pprintln
and pformat
.
pprint(io::IO, data)::Nothing
pformat(data)::String
pprintln
: add a newline afterpprint
There are other pprint libraries in Julia ecosystem, some of which are more extensible but might not very user-friendly, while some takes an opposite approach.
- GarishPrint.jl: An opinioned pretty printing package for Julia objects. Only export a
pprint
. - PrettyPrinting.jl: Julia library for optimal formatting of composite data structures. Highly extensible and support pretty-printing a wide range of builtin data types.
- PrettyNumbers: Pretty print numbers in Julia.
Choose the one that fits your use.
v0.1
APIs broke because I didn't find a good approach to emit deprecation warnings when adding method overloads incorrectly. Only in this way can I prevent users continuously using pprint_impl(io, data, indent, newline) = ...
.
A pp extension method implementation change to pp_impl(io, data, indent)
instead of pprint_impl(io, data, indent, newline)
.
Besides, the new API pp_impl
should return an integer indicating the final indentation level.
Example:
function PrettyPrint.pp_impl(io, data::MyData, indent::Int)
s = "<" * repr(data) * ">"
print(io, s)
return length(s) + indent
end
pkg> add PrettyPrint
using PrettyPrint
struct S1
i :: Int
f :: Float64
end
struct S2
s :: Vector{String}
s1 :: S1
end
data = S2(
["114514", "as we can"],
S1(42, 9.96)
)
pprintln(data) # or println(pformat(data))
produces
S2(
s=["114514", "as we can"],
s1=S1(i=42, f=9.96),
)
using PrettyPrint
struct Account
username :: String
password :: String
end
@info :before_extension
pprint(
[Account("van", "gd"), Account("thautwarm", "996icu")]
)
println()
PrettyPrint.pp_impl(io, account::Account, indent::Int) = print(io, "Account($(account.username))")
@info :after_extension
pprint(
[Account("van", "gd"), Account("thautwarm", "996icu")]
)
println()
produces
[ Info: before_extension
[
Account(username="van", password="gd"),
Account(username="thautwarm", password="996icu"),
]
[ Info: after_extension
[
Account(van),
Account(thautwarm),
]
- Vector
- Tuple
- Set
- String
- Nothing
- Dict
Any other datatypes are also supported with a default pp_impl
.
pprint([1, 2, 3])
# => [1, 2, 3]
pprint([Account("van", "gd")])
# [
Account(username="van", password="gd")
# ]
What's the difference?
Because PrettyPrint.is_simple_t(Int) == true
while PrettyPrint.is_simple_t(Account) == false
.
If you want to have the following effect:
struct K
a :: Int
end
pprint([K(1), K(2)])
# [
# K(a=1,),
# K(a=2,),
# ]
do this
PrettyPrint.is_simple_t(::Type{K}) = true
# [K(a=1,), K(a=2,)]
If you want to pp data via repr
instead of recursively pretty printing, try
struct X
a
b
end
pprint(X([1, 2], 1))
# X(
# a = [1, 2],
# b = 1
# )
PrettyPrint.is_atom_t(::Type{X}) = true
pprint(X([1, 2], 1))
# X([1, 2], 1)
This is not strict, but you can adjust the column length of PrettyPrint.jl by
PrettyPrint.MaxIndentExpected[] = 42