Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixing in progress.

  • Loading branch information...
commit e5a7bcca3e127bcd9a40af145117a1fe15ea89c3 1 parent d40c887
Kanen Flowers authored

Showing 1 changed file with 66 additions and 71 deletions. Show diff stats Hide diff stats

  1. +66 71 csv.lsp
137 csv.lsp
... ... @@ -1,62 +1,57 @@
1   -;; @module CSV
2   -;; @author Jeff Ober <jeffober@gmail.com>, Kanen Flowers <kanendosei@gmail.com>
3   -;; @version 1.1
4   -;; @location http://static.artfulcode.net/newlisp/csv.lsp
5   -;; @package http://static.artfulcode.net/newlisp/csv.qwerty
6   -;; @description Functions for parsing CSV files (updated for newlisp 10)
7   -;; <h4>Version history</h4>
8   -;; <b>1.1</b>
9   -;; &bull; fixed incompatibilities with newlisp 10
10   -;;
11   -;; <b>1.0</b>
12   -;; &bull; initial release
  1 +; @module CSV
  2 +; @author Jeff Ober <jeffober@gmail.com>, Kanen Flowers <kanendosei@gmail.com>
  3 +; @version 1.2
  4 +; @location https://raw.github.com/kanendosei/artful-newlisp/master/csv.lsp
  5 +;
  6 +; @description Functions for parsing CSV files (updated for newlisp 10)
  7 +;
13 8
14 9 (context 'CSV)
15 10
16 11 (setq *quote-char* "\"")
17 12 (setq *delimiter* ",")
18 13
19   -(define (regex-token-quoted-string delimiter quote-char)
  14 +(define (CSV:regex-token-quoted-string delimiter quote-char)
20 15 (format "^(%s((?:[^%s]|%s%s)+?)%s)(%s|$)"
21 16 quote-char
22 17 quote-char
23 18 quote-char
24 19 quote-char
25   - quote-char
  20 + quote-char
26 21 delimiter))
27 22
28   -(define (regex-token-atom delimiter quote-char)
  23 +(define (CSV:regex-token-atom delimiter quote-char)
29 24 (format "^([^%s%s]+?)(?:%s|$)"
30 25 quote-char
31 26 delimiter
32 27 delimiter))
33 28
34   -(define (regex-token-empty delimiter)
  29 +(define (CSV:regex-token-empty delimiter)
35 30 (format "^%s(?:%s|$)"
36 31 delimiter
37 32 delimiter))
38 33
39   -;; @syntax (CSV:make-row-parser <str-delimiter> <str-quote-char>)
40   -;; @param <str-delimiter> column delimiter
41   -;; @param <str-quote-char> character denoting quoted strings
42   -;; <p>Returns a lambda that is able to parse a single row of CSV text.
43   -;; The created function returns a list of column values.</p>
44   -;; @example
45   -;; (setq parser (CSV:make-row-parser "," "\""))
46   -;; => parser function
47   -;;
48   -;; (parser "foo,bar,baz,bat")
49   -;; => ("foo" "bar" "baz" "bat")
50   -;;
51   -;; (setq parser (CSV:make-row-parser "|" "\""))
52   -;; => parser function
53   -;;
54   -;; (parser "foo|bar|baz|bat")
55   -;; => ("foo" "bar" "baz" "bat")
  34 +; @syntax (CSV:make-row-parser <str-delimiter> <str-quote-char>)
  35 +; @param <str-delimiter> column delimiter
  36 +; @param <str-quote-char> character denoting quoted strings
  37 +; <p>Returns a lambda that is able to parse a single row of CSV text.
  38 +; The created function returns a list of column values.</p>
  39 +; @example
  40 +; (setq parser (CSV:make-row-parser "," "\""))
  41 +; => parser function
  42 +;;
  43 +; (parser "foo,bar,baz,bat")
  44 +; => ("foo" "bar" "baz" "bat")
  45 +;;
  46 +; (setq parser (CSV:make-row-parser "|" "\""))
  47 +; => parser function
  48 +;;
  49 +; (parser "foo|bar|baz|bat")
  50 +; => ("foo" "bar" "baz" "bat")
56 51
57 52 (setq re-chars "|[]{}()<>?\^$*+!:.")
58 53
59   -(define (make-row-parser delimiter quote-char)
  54 +(define (CSV:make-row-parser delimiter quote-char)
60 55 (if (find delimiter re-chars) (setq delimiter (string "\\" delimiter)))
61 56 (if (find quote-char re-chars) (setq quote-char (string "\\" quote-char)))
62 57 (letex ((re1 (regex-comp (regex-token-quoted-string delimiter quote-char)))
@@ -75,36 +70,36 @@
75 70 (true '())))))
76 71 (parser line))))))
77 72
78   -;; @syntax (CSV:parse-string <str-text> [<str-delimiter> [<str-quote-char>]])
79   -;; @param <str-text> the text to be parsed
80   -;; @param <str-delimiter> column delimiter
81   -;; @param <str-quote-char> character denoting quoted strings
82   -;; <p>Parses a string of text as a CSV file. Returns a list with one element
83   -;; for each line; each element is a list of column values for each line in the
84   -;; text.</p>
  73 +; @syntax (CSV:parse-string <str-text> [<str-delimiter> [<str-quote-char>]])
  74 +; @param <str-text> the text to be parsed
  75 +; @param <str-delimiter> column delimiter
  76 +; @param <str-quote-char> character denoting quoted strings
  77 +; <p>Parses a string of text as a CSV file. Returns a list with one element
  78 +; for each line; each element is a list of column values for each line in the
  79 +; text.</p>
85 80
86 81 (setq EOL-re (regex-comp "\n|\r"))
87 82
88   -(define (parse-string str (delimiter *delimiter*) (quote-char *quote-char*))
  83 +(define (CSV:parse-string str (delimiter *delimiter*) (quote-char *quote-char*))
89 84 "Parses an entire string into a nested list of rows."
90 85 (map (make-row-parser delimiter quote-char)
91 86 (parse str EOL-re 0x10000)))
92 87
93   -;; @syntax (CSV:parse-file <str-file> [<str-delimiter> [<str-quote-char>]])
94   -;; @param <str-file> the file to be read and parsed
95   -;; @param <str-delimiter> column delimiter
96   -;; @param <str-quote-char> character denoting quoted strings
97   -;; <p>Parses a CSV text file. Returns a list with one element
98   -;; for each line; each element is a list of column values for each line in the
99   -;; text. <parse-file> parses line by line, rather than processing the entire
100   -;; string at once, and is therefore more efficient than <parse-file>.</p>
101   -;; <p><b>Note:</b> at least some versions of MS Excel use a single \r for
102   -;; line endings, rather than a line feed or both. newLISP's read-line will
103   -;; only treat \n or \r\n as line endings. If all columns are lumped into one
104   -;; flat list, this may be the culprit. In this case, use <parse-string> with
105   -;; <read-file> instead as the best alternative.</p>
106   -
107   -(define (parse-file path (delimiter *delimiter*) (quote-char *quote-char*))
  88 +; @syntax (CSV:parse-file <str-file> [<str-delimiter> [<str-quote-char>]])
  89 +; @param <str-file> the file to be read and parsed
  90 +; @param <str-delimiter> column delimiter
  91 +; @param <str-quote-char> character denoting quoted strings
  92 +; <p>Parses a CSV text file. Returns a list with one element
  93 +; for each line; each element is a list of column values for each line in the
  94 +; text. <parse-file> parses line by line, rather than processing the entire
  95 +; string at once, and is therefore more efficient than <parse-file>.</p>
  96 +; <p><b>Note:</b> at least some versions of MS Excel use a single \r for
  97 +; line endings, rather than a line feed or both. newLISP's read-line will
  98 +; only treat \n or \r\n as line endings. If all columns are lumped into one
  99 +; flat list, this may be the culprit. In this case, use <parse-string> with
  100 +; <read-file> instead as the best alternative.</p>
  101 +
  102 +(define (CSV:parse-file path (delimiter *delimiter*) (quote-char *quote-char*))
108 103 (let ((f (open path "r"))
109 104 (parser (make-row-parser delimiter quote-char))
110 105 (rows '())
@@ -114,28 +109,28 @@
114 109 (close f)
115 110 rows))
116 111
117   -;; @syntax (CSV:list->row <list-cols> <str-delimiter> <str-quote-char>)
118   -;; @param <str-delimiter> column delimiter; defaults to ","
119   -;; @param <str-quote-char> character denoting quoted strings; defaults to "\""
120   -;; @param <str-quote-char> character denoting quoted strings
121   -;; <p>Generates one row of CSV data from the values in <list-cols>. Non-numeric
122   -;; elements are treated as quoted strings.</p>
  112 +; @syntax (CSV:list->row <list-cols> <str-delimiter> <str-quote-char>)
  113 +; @param <str-delimiter> column delimiter; defaults to ","
  114 +; @param <str-quote-char> character denoting quoted strings; defaults to "\""
  115 +; @param <str-quote-char> character denoting quoted strings
  116 +; <p>Generates one row of CSV data from the values in <list-cols>. Non-numeric
  117 +; elements are treated as quoted strings.</p>
123 118
124   -(define (list->row lst (delimiter *delimiter*) (quote-char *quote-char*), (buff ""))
  119 +(define (CSV:list->row lst (delimiter *delimiter*) (quote-char *quote-char*), (buff ""))
125 120 (dolist (elt lst)
126 121 (write-buffer buff (if (number? elt) (string elt)
127 122 (format "%s%s%s" quote-char (string elt) quote-char)))
128 123 (write-buffer buff ","))
129 124 buff)
130 125
131   -;; @syntax (CSV:list->csv <list-rows> <str-delimiter> <str-quote-char> <str-eol>)
132   -;; @param <list-rows> list of row sets (each is a list of values)
133   -;; @param <str-delimiter> column delimiter; defaults to ","
134   -;; @param <str-quote-char> character denoting quoted strings; defaults to "\""
135   -;; @param <str-eol> end of line character; defaults to "\n"
136   -;; <p>Generates CSV string of a list of column value sets.</p>
  126 +; @syntax (CSV:list->csv <list-rows> <str-delimiter> <str-quote-char> <str-eol>)
  127 +; @param <list-rows> list of row sets (each is a list of values)
  128 +; @param <str-delimiter> column delimiter; defaults to ","
  129 +; @param <str-quote-char> character denoting quoted strings; defaults to "\""
  130 +; @param <str-eol> end of line character; defaults to "\n"
  131 +; <p>Generates CSV string of a list of column value sets.</p>
137 132
138   -(define (list->csv lst (delimiter *delimiter*) (quote-char *quote-char*) (eol-str "\n"))
  133 +(define (CSV:list->csv lst (delimiter *delimiter*) (quote-char *quote-char*) (eol-str "\n"))
139 134 (join (map (fn (r) (list->row r delimiter quote-char)) lst) eol-str))
140 135
141 136 (context MAIN)

0 comments on commit e5a7bcc

Please sign in to comment.
Something went wrong with that request. Please try again.