From 1647500abe94fe0e9e12a75c37835aa75058297b Mon Sep 17 00:00:00 2001 From: Ivaylo Dankolov Date: Wed, 2 Apr 2014 02:49:16 +0300 Subject: [PATCH] Extended the annotate form to handle printing annotate: should now include the standard output of the evaluation for every ; => form on a new line following it. --- src/lectures/annotate.clj | 43 +++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/lectures/annotate.clj b/src/lectures/annotate.clj index 458f963..0499e30 100644 --- a/src/lectures/annotate.clj +++ b/src/lectures/annotate.clj @@ -20,18 +20,25 @@ (eval '(do (ns lectures.sandbox) (def placeholder-values (atom {})) + (def placeholder-outputs (atom {})) (defmacro store-result [number & body] `(try - (let [value# (do ~@body)] - (swap! ~'lectures.sandbox/placeholder-values assoc ~number value#) - value#) + (let [output# (new java.io.StringWriter)] + (binding [*out* output#] + (let [value# (do ~@body)] + + (swap! ~'lectures.sandbox/placeholder-values assoc ~number value#) + (swap! ~'lectures.sandbox/placeholder-outputs + assoc ~number (str output#)) + value#))) (catch Throwable e# (swap! ~'lectures.sandbox/placeholder-values assoc ~number e#) nil))))) (eval (read-string code))) - (let [result (eval '@lectures.sandbox/placeholder-values)] + (let [result (eval '@lectures.sandbox/placeholder-values) + outputs (eval '@lectures.sandbox/placeholder-outputs)] (remove-ns 'lectures.sandbox) - result))) + {:values result, :outputs outputs}))) (defn- placeholder->str [value] @@ -39,12 +46,30 @@ Throwable (str (-> value class .getName) ": " (.getMessage value)) (pr-str value))) +(defn- prettify-output + [output] + (->> output + str/split-lines + (map (partial str "; ")) + (str/join "\n") + (str ";; OUTPUT:\n"))) + + (defn- replace-placeholders - [code placeholders] - (str/replace code #"(?m)\{(\d+)\}$" #(-> % second Integer. placeholders placeholder->str))) + [code placeholders outputs] + (str/replace code #"(?m)\{(\d+)\}$" + (fn [[_ match]] + (let [id (Integer. match) + value-string (-> id + placeholders + placeholder->str) + output (outputs id)] + (if (not-empty output) + (str value-string "\n" (prettify-output output)) + value-string))))) (defn annotate [code] (let [code (assign-placeholders code) - values (eval-placeholders code)] - (replace-placeholders code values))) + {:keys [values outputs]} (eval-placeholders code)] + (replace-placeholders code values outputs)))