     (catch IllegalArgumentException ex
       false)))
 
-(defn- ->printable-row [row-data]
-  (letfn [(make-readable [val]
-            (if (readable-form? val)
-              val
-              (->UnreadableForm (str val)  (str (.getName (class val))))))]
-    (zipmap (map make-readable (keys row-data))
-            (map make-readable (vals row-data)))))
+(defprotocol ToPrintable
+  (->printable-form [o]
+    "Converts object into a printable form by returning an UnreadableForm
+    representation of it (or its constituent parts if it can't be
+    serialized.)"))
+
+(extend-protocol ToPrintable
+  incanter.core.Dataset
+  (->printable-form [ds]
+    (make-dataset (map ->printable-form (:rows ds))
+                  (map ->printable-form (:column-names ds))))
+
+  java.util.Map
+  (->printable-form [form]
+    (letfn [(make-readable [val]
+              (if (readable-form? val)
+                val
+                (unreadable-form val)))]
+      (zipmap (map make-readable (keys form))
+              (map make-readable (vals form)))))
+
+  java.lang.Object
+  (->printable-form [form]
+    (if (readable-form? form)
+      form
+      (unreadable-form form)))
+
+  nil
+  (->printable-form [nl]
+    nil))
 
 (defn preview-graph
   "Takes a dataset a function built via grafter.tabular/graph-fn and a row

  "Tool support for rendering previews of grafter.tabular graph-fn templates
  with values from datasets."
  (:require [clojure.walk]
            [clojure.edn :as edn]))

(defn- symbolize-keys [m]
  (zipmap (map (comp symbol name) (keys m)) (vals m)))

   (let [form (:grafter.tabular/template (meta graphf))
         bindings (first (second form))
         body-forms (drop 2 form)
         printable-row-data (->printable-form (nth (:rows dataset) row nil))
         subs (substitution-map bindings printable-row-data)]

     {:bindings bindings :row printable-row-data :template
