annotate src/clojure/contrib/pprint/column_writer.clj @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
rev   line source
rlm@10 1 ;;; column_writer.clj -- part of the pretty printer for Clojure
rlm@10 2
rlm@10 3 ;; by Tom Faulhaber
rlm@10 4 ;; April 3, 2009
rlm@10 5 ;; Revised to use proxy instead of gen-class April 2010
rlm@10 6
rlm@10 7 ; Copyright (c) Tom Faulhaber, Dec 2008. All rights reserved.
rlm@10 8 ; The use and distribution terms for this software are covered by the
rlm@10 9 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
rlm@10 10 ; which can be found in the file epl-v10.html at the root of this distribution.
rlm@10 11 ; By using this software in any fashion, you are agreeing to be bound by
rlm@10 12 ; the terms of this license.
rlm@10 13 ; You must not remove this notice, or any other, from this software.
rlm@10 14
rlm@10 15 ;; This module implements a column-aware wrapper around an instance of java.io.Writer
rlm@10 16
rlm@10 17 (ns clojure.contrib.pprint.column-writer
rlm@10 18 (:import
rlm@10 19 [clojure.lang IDeref]
rlm@10 20 [java.io Writer]))
rlm@10 21
rlm@10 22 (def *default-page-width* 72)
rlm@10 23
rlm@10 24 (defn- get-field [^Writer this sym]
rlm@10 25 (sym @@this))
rlm@10 26
rlm@10 27 (defn- set-field [^Writer this sym new-val]
rlm@10 28 (alter @this assoc sym new-val))
rlm@10 29
rlm@10 30 (defn get-column [this]
rlm@10 31 (get-field this :cur))
rlm@10 32
rlm@10 33 (defn get-line [this]
rlm@10 34 (get-field this :line))
rlm@10 35
rlm@10 36 (defn get-max-column [this]
rlm@10 37 (get-field this :max))
rlm@10 38
rlm@10 39 (defn set-max-column [this new-max]
rlm@10 40 (dosync (set-field this :max new-max))
rlm@10 41 nil)
rlm@10 42
rlm@10 43 (defn get-writer [this]
rlm@10 44 (get-field this :base))
rlm@10 45
rlm@10 46 (defn- write-char [^Writer this ^Integer c]
rlm@10 47 (dosync (if (= c (int \newline))
rlm@10 48 (do
rlm@10 49 (set-field this :cur 0)
rlm@10 50 (set-field this :line (inc (get-field this :line))))
rlm@10 51 (set-field this :cur (inc (get-field this :cur)))))
rlm@10 52 (.write ^Writer (get-field this :base) c))
rlm@10 53
rlm@10 54 (defn column-writer
rlm@10 55 ([writer] (column-writer writer *default-page-width*))
rlm@10 56 ([writer max-columns]
rlm@10 57 (let [fields (ref {:max max-columns, :cur 0, :line 0 :base writer})]
rlm@10 58 (proxy [Writer IDeref] []
rlm@10 59 (deref [] fields)
rlm@10 60 (write
rlm@10 61 ([^chars cbuf ^Integer off ^Integer len]
rlm@10 62 (let [^Writer writer (get-field this :base)]
rlm@10 63 (.write writer cbuf off len)))
rlm@10 64 ([x]
rlm@10 65 (condp = (class x)
rlm@10 66 String
rlm@10 67 (let [^String s x
rlm@10 68 nl (.lastIndexOf s (int \newline))]
rlm@10 69 (dosync (if (neg? nl)
rlm@10 70 (set-field this :cur (+ (get-field this :cur) (count s)))
rlm@10 71 (do
rlm@10 72 (set-field this :cur (- (count s) nl 1))
rlm@10 73 (set-field this :line (+ (get-field this :line)
rlm@10 74 (count (filter #(= % \newline) s)))))))
rlm@10 75 (.write ^Writer (get-field this :base) s))
rlm@10 76
rlm@10 77 Integer
rlm@10 78 (write-char this x)
rlm@10 79 Long
rlm@10 80 (write-char this x))))))))