ruricolist / serapeum

Utilities beyond Alexandria
MIT License
425 stars 42 forks source link

How about a "pretty-print-hash-table" ? A proposal. #75

Closed vindarel closed 3 years ago

vindarel commented 3 years ago

Hello,

I don't see such a function. It would be useful to have.

What about the following, which I adapted from Rutils, but in this version without pprint-indent which was messing the terminal output (it's fine on Slime):

(defparameter *current-pprint-indentation* 1)

(defun print-hash-table (ht &optional (stream *standard-output*))
  "Pretty print hash-table HT to STREAM."
  ;; We use *current-pprint-indentation* instead of the built-in pprint-indent and friends
  ;; because printing in the terminal prints too many tabs and too many lines in-between elements.
  (let ((*print-pretty* t)
        (i 0))
    (pprint-logical-block (stream nil)
      (format stream "~&")
      (format stream "~vt" *current-pprint-indentation*)
      (princ "(dict " stream)
      (unless (eq (hash-table-test ht) 'equal)
        (princ #\' stream)
        (princ (hash-table-test ht) stream))
      (incf *current-pprint-indentation*)
      (format stream "~vt" *current-pprint-indentation*)
      (block nil
        (maphash (lambda (k v)
                   (format stream "~&")
                   (when (and *print-length* (> (incf i) *print-length*))
                     (princ "..." stream)
                     (return))
                   (when (and k (listp k))
                     (princ #\' stream))
                   (if (typep k 'hash-table)
                       (print-hash-table k stream)
                       (format stream "~vt~s" *current-pprint-indentation* k))
                   (princ " " stream)
                   (when (and v (listp v))
                     (princ #\' stream))
                   (if (typep v 'hash-table)
                       (print-hash-table v stream)
                       (format stream "~s" v)))
                 ht))
      (decf *current-pprint-indentation*)
      (format stream "~vt" *current-pprint-indentation*)
      (format stream "~&")
      (format stream "~vt) " *current-pprint-indentation*)))
  ht)
(dict 'eql :a 1 :c '(3 three) :d (dict :e "e"))

 (dict 'EQL 
  :A 1
  :C '(3 THREE)
  :D 
  (dict  
   :E "e" 
  )  
 ) 
(gethash :c (read-from-string "
 (dict 'EQL 
  :A 1
  :C '(3 THREE)
  :D 
  (dict  
   :E "e" 
  )  
 ) "))
(3 THREE)
T
ruricolist commented 3 years ago

This seems like a good idea. What license is Rutils under?

vindarel commented 3 years ago

:licence "3-clause MIT licence"

ruricolist commented 3 years ago

I would be interested in this if you would care to make a pull request. (Although I would prefer pretty-print-hash-table as the name.)