basilisp.pprint¶
Pretty Printing¶
Pretty printing built-in data structures is as easy as a call to pprint.
(require '[basilisp.pprint :as pprint])
(pprint/pprint (range 30))
The output can be configured using a number of different control variables, which are expressed as dynamic Vars.
You can pretty print the last result from the REPL using the pp convenience macro.
As an alternative, the write API enables a more ergonomic API for configuring the printer using keyword arguments rather than dynamic Vars.
(pprint/write (ns-interns 'basilisp.pprint) :sort-keys true)
;; {*current-length* #'basilisp.pprint/*current-length*
;; ...
;; write-out #'basilisp.pprint/write-out}
Custom Pretty Print Dispatch Function¶
The default dispatch function is simple-dispatch which can print most builtin Basilisp types.
Using the builtin macros and utilities, it is possible to create a custom dispatch function.
Pretty Printing Concepts¶
The pretty printing algorithm used in basilisp.pprint is based on the XP algorithm defined in Richard Water’s 1989 paper “XP: A Common Lisp Pretty Printing System” as adapted in Clojure’s pprint by Tom Faulhaber.
There are three basic concepts in the XP algorithm which are necessary in order to create a custom dispatch function.
Logical blocks are groups of output that should be treated as a single unit by the pretty printer. Logical blocks can nest, so one logical block may contain 0 or more other logical blocks. For example, a vector may contain a map; the vector would be a logical block and the map would also be a logical block.
simple-dispatcheven treats key/value pairs in associative type outputs as a logical block, so they are printed on the same line whenever possible.A dispatch function can emit a logical block using the
pprint-logical-blockmacro.Conditional newlines can be emitted anywhere a newline may need inserted into the output stream. Newlines can be one of 3 different types which hints to the pretty printer when a newline should be emitted.
Dispatch functions can emit newlines in any supported style using the
pprint-newlinefunction.:linearstyle newlines should be emitted whenever the enclosing logical block does not fit on a single line. Note that if any linear newline is emitted in a block, every linear newline will be emitted in that block.:mandatorystyle newlines are emitted in all cases.:miserstyle newlines are emitted only when the output will occur in the “miser” region as defined by*print-miser-width*. This allows additional newlines to be emitted as the output nests closer to the right margin.
Indentation commands indicate how indentation of subsequent lines in a logical block should be defined. Indentation may be defined relative to either the starting column of the current logical block or to the current column of the output.
Dispatch functions can control indentation using the
pprint-indentfunction.
Pretty printing is most useful for viewing large, nested structures in a more human-friendly way.
To that end, dispatch functions wishing to print any collection may want to use the print-length-loop macro to loop over the output, respecting the basilisp.core/*print-length* setting.
Dispatch functions which may need to be called on nested elements should use write-out to ensure that basilisp.core/*print-level* is respected.
Scalar values can be printed with basilisp.core/pr or just written directly to *out*.
Unimplemented Features¶
The following features from clojure.pprint are not currently implemented:
:fillnewlinescode-dispatchfor printing codecl-format
References¶
Tom Faulhaber et al.;
clojure.pprint(API, Documentation)Oppen, Derek; "Prettyprinting"; October 1980
Waters, Richard; "XP: A Common Lisp Pretty Printing System"; March 1989
API¶
- dynamic Var *print-base*[source]¶
The base used for printing integer literals and rationals.
Default is 10.
- dynamic Var *print-miser-width*[source]¶
The text column number to start using miser style.
Not all dispatch functions support using a miser style, so the effect of this value depends on the value of
*print-pprint-dispatch*.Default is 40. May be set to
nilto disable.
- dynamic Var *print-pprint-dispatch*[source]¶
The dispatch function used for pretty printing.
Default is
simple-dispatch.
- dynamic Var *print-pretty*[source]¶
If bound to
true, calls towritewill use pretty printing.Default is
false, butpprintbinds the value totrue.
- dynamic Var *print-radix*[source]¶
If bound to
true, integers and rationals will be printed with a radix prefix. For bases 2, 8, and 16 the prefix will be#b,#oand#xrespectively. All other bases will be specified as#XXrwhereXXis the decimal value of*print-base*.Default is
false.
- dynamic Var *print-right-margin*[source]¶
The soft upper limit for the length of the right margin.
Default is 72.
- dynamic Var *print-sort-keys*[source]¶
If bound to
true, associative collections will be printed in sorted order by their keys.Default is
false.
- dynamic Var *print-suppress-namespaces*[source]¶
If
true, suppress printing symbol namespaces. This may be useful when printing macroexpansions.Default is
nil.
- protocolPrettyWriter[source]¶
Protocol defining a writer type for pretty printing with the XP algorithm.
Callers should generally not be calling
PrettyWriterprotocol methods directly, but should instead call the other helper functions and macros directly.
- fn (get-pretty-writer writer)[source]¶
- fn (get-pretty-writer writer max-columns)
Return a pretty writer instance which satisfies
PrettyWriterand which is also anio.TextIOBase.The current state can be fetched using
basilisp.core/deref.
- fn (pprint object)[source]¶
- fn (pprint object writer)
Pretty print
objectto thewritersubject to the bindings of the pretty printing control variables.If no
writeris given, the value bound tobasilisp.core/*out*is used.
- fn (pprint-indent relative-to offset)[source]¶
Configure the indent of
offsetcharacters relative to an anchor at this point in the pretty print output.relative-tomust be one of the following keywords::current, meaning that the indent offset is relative to the current column when the indent token is encountered:block, meaning that the indent offset is relative to the starting column of the current logical block
- macro (pprint-logical-block & body)[source]¶
Macro for grouping logical elements together in
pprintoutputs.
- fn (pprint-newline kind)[source]¶
Emit a newline to the output buffer.
kindmust be one of the following keywords::linear, which will be emitted as newlines only if the the logical block doesn’t fit on one line:mandatory, which the pretty writer will emit in all cases:miser, which will emit a newline whenever the output column is in the miser region, as configured by*print-miser-width*
- macro (print-length-loop bindings & body)[source]¶
loop-like macro which loops at mostbasilisp.core/*print-length*times, which is often useful when defining custom pretty-printing functions.
- fn (print-table rows)[source]¶
- fn (print-table ks rows)
Print a collection of maps as a table to the buffer currently bound to
basilisp.core/*out*.If there is at least one element in
rows, a header row will be printed followed by a single divider row followed by a line for each element inrows.If no keys are given (as
ks), then use the keys returned from the first element inrows(as by(keys (first rows))). Note that in this case, the order of headers in the resulting table is based on the order of keys returned bybasilisp.core/keys.
- fn (set-pprint-dispatch function)[source]¶
Set the root value of
*print-pprint-dispatch*tofunction.By default, the root value is
simple-dispatch.
- macro (with-pprint-dispatch function & body)[source]¶
Convenience macro for setting the
*print-pprint-dispatch*while executing the body.
- fn (write object & {:as opts})[source]¶
Pretty print
objectas bypprint, but options may be specified as keyword arguments rather than dynamic Vars.The supported keyword arguments are listed below with their corresponding dynamic Var:
:basecorresponds to*print-base*:dispatchcorresponds to*print-pprint-dispach*:lengthcorresponds tobasilisp.core/*print-length*:levelcorresponds tobasilisp.core/*print-level*:prettycorresponds to*print-pretty*:radixcorresponds to*print-radix*:miser-widthcorresponds to*print-miser-width*:right-margincorresponds to*print-right-margin*:sort-keyscorresponds to*print-sort-keys:streamcorresponds to thewriterargument ofpprint:suppress-namespacescorresponds to*print-suppress-namespaces*
- fn (write-out object)[source]¶
Write
objecttobasilisp.core/*out*, respecting the current bindings of the pretty printing control variables.*out*should be a pretty writer (as returned byget-pretty-writer).This function is intended to be called from within pretty print dispatch functions which already have pretty print control variables correctly set up.
Note
This function performs cycle detection on input values.