[ANN] Announcing AutoPrettyPrinting.jl

Hey everyone. I’m happy to announce AutoPrettyPrinting.jl v0.1, which makes generating data-dependent pretty printing code a (relative) breeze. This package makes use of the excellent PrettyPrinting.jl, along with some sane-ish layouting logic, to automatically choose, at object printing runtime, between a compact horizontal layout (for sufficiently small objects) and a more expansive vertical layout. It supports assigning different layout-generating code to different MIME-types, so that, e.g., your pretty printing code doesn’t have to overwrite external types that define their own Base.show methods for MIME"text/plain" types.

Using the @def_pprint macro, simple + complicated types will now print out nicely

julia> using AutoPrettyPrinting

julia> struct A 
           key1::Int 
           key2::String
       end

julia> @def_pprint mime_types="text/plain" base_show=true A

julia> a = A(10, "abcd")
A(key1 = 10, key2 = abcd)

This package was written with composition in mind, so that types composed of other types registered with this package “just work”

julia> struct B 
           data::Vector{A}
       end

julia> @def_pprint mime_types="text/plain" base_show=true B 

julia> b = B([A(i, "a"^i) for i in 1:2])
B(data = [A(key1 = 1, key2 = a), A(key1 = 2, key2 = aa)])

And when the objects themselves are too big to be printed nicely on a single line, the vertical layout for these objects is used.


julia> b = B([A(i, "a"^i) for i in 1:10])
B(
  data = [
           A(key1 = 1, key2 = a)
           A(key1 = 2, key2 = aa)
           A(key1 = 3, key2 = aaa)
           A(key1 = 4, key2 = aaaa)
           A(key1 = 5, key2 = aaaaa)
           A(key1 = 6, key2 = aaaaaa)
           A(key1 = 7, key2 = aaaaaaa)
           A(key1 = 8, key2 = aaaaaaaa)
           A(key1 = 9, key2 = aaaaaaaaa)
           A(key1 = 10, key2 = aaaaaaaaaa)
         ]
)

And if you want more control over how your objects are rendered, you can use the @custom_tile macro

julia> struct D 
           value::Int
       end

julia> @custom_tile mime_types="text/plain" base_show=true D => AutoPrettyPrinting.literal("CustomD $(_obj_.value^2)")

julia> d = D(10)
CustomD 100

Happy pretty printing!

30 Likes

This looks great! I’ve wanted prettier default printing for structs and especially NamedTuples in Base for a while now. Love to see efforts in this space!

10 Likes

@curtd thank you for sharing this, it can save a lot of copy/paste in large projects.

Can you please comment on the current dependencies of AutoPrettyPrinting.jl? Can we reduce the list?

1 Like

Probably not unfortunately! As far as the dependencies go,

  • Dates and Sockets standard libraries are just there to provide pretty printing for types in those standard libraries.
  • MacroUtilities provides the expression parsing for the various macros in the package
  • PrecompileTools is standard for providing package precompilation
  • ScopedValues provides the ability to change the generated layout dynamically, and
  • PrettyPrinting does the actual heavy lifting of printing the objects

And there are package extensions for TimeZones and Dictionaries, for including those types into this framework.

2 Likes

Does it mean that the package is pirating the Base types, redefining their show methods?

Thanks for explaining the dependencies!

Couldn’t you use package extension for this as well? Just like for TimeZones and Dictionaries?

2 Likes

I remember trying that when I was developing the package but, as I recall, Julia kept complaining to me when I was trying to run precompilation workloads in the extensions. Possibly it’s because they’re stdlibs, possibly I did something wrong, I’m not sure. I’ll have another look at it when I have some time.

3 Likes

Nope, no type piracy here. There’s just the repr_pretty function and the PPrintContext type to pretty print types, and tools for defining Base.show using this machinery for your own types.

1 Like

That’s a known bug in Julia, Strange "missing from cache"/"does not support precompilation"/... errors · Issue #52132 · JuliaLang/julia · GitHub. Should be fixed in some upcoming new version.

1 Like