Search code examples
clojureoutputpretty-print

How to use pprint-newline properly?


I am trying to print a sequence such that neither the whole sequence is printed on one line, nor is each element of the sequence printed on its own line. E.g.

[10 11 12 13 14 15 16 17 18 19
 20 21 22 23 24 25 26 27 28 29]

I found pprint-newline in the documentation which indicates that allows me to determine how the newline gets printed. Unfortunately, I cannot find any examples on how it is to be used in conjunction with pprint, and the doc string doesn't to offer much insight:

-------------------------
clojure.pprint/pprint-newline
([kind])
  Print a conditional newline to a pretty printing stream. kind specifies if the 
newline is :linear, :miser, :fill, or :mandatory. 

This function is intended for use when writing custom dispatch functions.

Output is sent to *out* which must be a pretty printing writer.

pprint specifies an optional second argument for the writer, which is by default set to *out*. However, I am not sure how to 'send' pprint-writer to *out* in this case, e.g. something like the example below doesn't appear to work

(clojure.pprint/pprint [1 2 3 4] (*out* (clojure.pprint/pprint-newline :miser)))

Solution

  • While Guillermo explained how to change the dispatch for pretty-printing in general, if all you want to do is printing one collection differently, that's possible, too.

    For example, using cl-format (after (use '[clojure.pprint :as pp)):

    (binding [pp/*print-pretty* true
              pp/*print-miser-width* nil
              pp/*print-right-margin* 10]
      (pp/cl-format true "~<[~;~@{~a~^ ~:_~}~;]~:>~%" '[foo bar baz quux]))
    

    Set *print-right-margin* as you wish.

    You don't have to use format for this. The format directives can be translated to their respective pretty-printer functions, if you want. Explanation of the format string: ~< and ~:> establish a logical block. Inside the block, there are three sections separated by ~;. The first and last section are your prefix and suffix, while the elements are printed in the middle section, using ~@{ and ~}. For each element, the element is printed using ~a, followed by a space, if needed, and a conditional fill-style newline.

    (In CL, the format string could be simplified to "~<[~;~@{~a~^ ~}~;]~:@>~%", but that doesn't seem to work in Clojure 1.5.)