Recently Written · git

CSV

Convert CSV (in a reader macro, or in a file) in to Lisp lists.

git clone https://github.com/equwal/CSV

Log | Files | Refs


commit 6deca0d81e38d24fe7cd0bc062a53c1ff4d6818c
Spenser Truex <spensertruexonline@gmail.com>
2019-01-07 12:21:23 -0800

Fix quoting bug and homepage on README.

 README.md | 36 +-----------------------------------
 csv.lisp  | 19 ++++++++++++-------
 2 files changed, 13 insertions(+), 42 deletions(-)
diff --git a/README.md b/README.md
index 14d6964..0b725e0 100644
--- a/README.md
+++ b/README.md
@@ -1,36 +1,2 @@
-[homepage](http://spensertruex.com/CSV.html)
+[Go to the homepage.](http://spensertruex.com/CSV.html)
 
-# CSV
-Defines a lisp reader to read is CSV:
-
-`#!field,field,field!#`
-
-which is used to read in CSV files with `slurp`:
-
-`(slurp #p"example.csv")`
-
-and the result is a list:
-
-``` common-lisp
-CL-USER> (csv:slurp #p"example.csv")
-("example" "csv" "list" "result" "like" " this")
-```
-
-This program invokes the lisp reader, making it:
-1) Potentially risky to use if the input it not trusted.
-2) Resource intensive for medium to large files (>5MB).
-
-Use with care.
-
-# Features:
-Supports escaping quotes the CSV way, with quad quotes:
-csv   -> lisp
-`""""`->`"\""`
-
-# Installation
-Use ASDF:
-
-``` common-lisp
-CL-USER> (asdf:load-system :csv)
-T
-```
diff --git a/csv.lisp b/csv.lisp
index 7665baf..4e610d7 100644
--- a/csv.lisp
+++ b/csv.lisp
@@ -45,12 +45,13 @@
                    (inner (subseq str (1+ res)) (push (subseq str 0 res) acc!))))))
     (inner str nil)))
 (make-reader my-csv (stream #\# #\!)
-  (do ((prev #1= (read-char stream nil nil) curr)
-       (curr #1# #1#)
-       (str (make-array 0 :adjustable t :element-type 'character)
-	    (switches prev curr str)))
-      ((and (char= curr #\#)
-            (char= prev #\!)) (splice (switches nil nil str)))))
+  (macrolet ((once (&body body) ``',,@body))
+    (do ((prev #1= (read-char stream nil nil) curr)
+	 (curr #1# #1#)
+	 (str (make-array 0 :adjustable t :element-type 'character)
+	      (switches prev curr str)))
+	((and (char= curr #\#)
+              (char= prev #\!)) (once (splice (switches nil nil str)))))))
 (defun read-to-string (stream)
   (with-output-to-string (s)
     (dolines (line stream)
@@ -60,6 +61,10 @@
   "Read in a CSV file to string. Resource intensive."
   (with-open-file (s path)
     (concatenate 'string "#!" (read-to-string s) "!#")))
+(defun dequote (list)
+  (if (eql 'quote (car list))
+      (cadr list)
+      list))
 (defun slurp (path)
   "Read in a CSV file to list. Resource intensive."
-  (read-from-string (slurp-csv path)))
+  (dequote (read-from-string (slurp-csv path))))