comparison hexagram-6ae12361157c/hexagram/jquery.tsv.js @ 0:1407e3634bcf draft default tip

Uploaded r11 from test tool shed.
author adam-novak
date Tue, 22 Oct 2013 14:17:59 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1407e3634bcf
1 /**
2 * jQuery-tsv (jQuery Plugin)
3 *
4 * Inspired by jQuery-csv by Evan Plaice.
5 *
6 * Copyright 2012 by Bob Kerns
7 *
8 * This software is licensed as free software under the terms of the MIT License:
9 * http://www.opensource.org/licenses/mit-license.php
10 */
11
12 (function ($) {
13 // Make sure we have a copy, not original, of $.tsv.options.
14 function copyOptions(options) {
15 return $.extend({__copy: true}, options);
16 }
17 // Default the options.
18 function tsvOptions(options) {
19 if (options) {
20 if (options.__defaults_applied) {
21 return options;
22 }
23 return $.extend(copyOptions($.tsv.options), options);
24 }
25 return copyOptions($.tsv.options);
26 }
27
28 function tsvColumn(options, index) {
29 var opts = tsvOptions(options);
30 return String(opts.columns ? opts.columns[index] : index);
31 }
32
33 function tsvColumns(options, top) {
34 if (options.columns) {
35 return options.columns;
36 } else {
37 var cols = Object.keys(top || {}).sort();
38 options.columns = cols;
39 return cols;
40 }
41 }
42
43 $.tsv = {
44 version: "0.957",
45 /**
46 * The default set of options. It is not recommended to change these, as the impact will be global
47 */
48 options: {
49 /**
50 * If supplied, a function to format a value on output.
51 * The returned value is used in the output instead of the supplied value.
52 * If not supplied, it is simply converted to a string.
53 *
54 * @param value the value to be formatted.
55 * @param the options
56 * @param colnum the column number
57 * @param colname the column name, if known, or the column number as a string.
58 * @param rownum the row number
59 * @returns the value, formatted
60 */
61 formatValue: null,
62 /**
63 * If supplied, a function to parse or canonicalize a value on input.
64 * The returned value is used in place of the input.
65 *
66 * @param value the value to be formatted.
67 * @param the options
68 * @param colnum the column number
69 * @param colname the column name, if known, or the column number as a string.
70 * @param rownum the row number
71 * @returns the value, parsed
72 */
73 parseValue: null,
74 /**
75 * The character sequence to use to separate lines.
76 */
77 lineSeparator: "\n",
78 /** A RegExp to recognize line separators */
79 lineSplitter: /\r?\n/,
80 /** The character sequence to use to separate values. */
81 valueSeparator: "\t",
82 /** A RegExp to recognize value separators. */
83 valueSplitter: /\t/,
84 /**
85 * If supplied, a function of one argument to convert a row to an object.
86 *
87 * @param row an array of values, e.g. ["1", "2", "3.14"]
88 * @param options { columns: ["id", "count", "price"] }
89 * @returns e.g. {id: "1", count: "2", price: "3.14"}
90 */
91 arrayToObject: null,
92 /**
93 * If supplied, a function of one argument to convert an object to a row. Typically, this will implement a variant
94 * of the contract for $.tsv.objectToArray.
95 *
96 * @param object an object to be converted to a row, e.g. {id: "1", count: "2", price: "3.14"}
97 * @param options { columns: ["id", "count", "price"] }
98 * @returns an array of values, e.g. ["1", "2", "3.14"]. Typically these would be ordered by options.column
99 */
100 objectToArray: null,
101 /**
102 * If true, when converting from an array of objects to a TSV string, include the column names as the
103 * first line. For most purposes, you won't want to override this, but if you're working with tables in sections,
104 * for example, you'd want to suppress this for the latter segments.
105 *
106 * But you are strongly encouraged to use column names whenever possible, especially if you work with objects.
107 */
108 includeHeader: true,
109 /**
110 * The starting row number, not counting the header, if any (which is always numbered -1).
111 * This can be useful for computing subranges of a table, or appending to a table.
112 */
113 startRownum: 0,
114 // An internal flag, to avoid multiple defaulting steps.
115 // values are true, if it is this default, or 'copy'.
116 ___defaults_applied: true,
117 extend: $.extend
118 },
119
120 /**
121 * Parse one value. This can be overridden in the options.
122 * @param value the string to parse
123 * @param options optional: { parseValue: <substitute function> }
124 * @param colnum the column number
125 * @param colname the column name, if known, or the column number as a string.
126 * @param rownum the row number
127 * @returns the string
128 */
129 parseValue: function parseValue(value, options, colnum, colname, rownum) {
130 var opts = tsvOptions(options);
131 if (opts.parseValue) {
132 // We have an override; use that instead.
133 return options.parseValue(value, opts, colnum, colname, rownum);
134 }
135 return value;
136 },
137
138 /**
139 * Format one value. This can be overridden in the options.
140 * @param value the value to format
141 * @param options optional: { formatValue: <substitute function> }
142 * @param colnum the column number
143 * @param colname the column name, if known, or the column number as a string.
144 * @param rownum the row number
145 */
146 formatValue: function formatValue(value, options, rownum, colnum, colname, rownum) {
147 var opts = tsvOptions(options);
148 if (opts.formatValue) {
149 // We have an override; use that instead.
150 return options.formatValue(value, opts, colnum, colname, rownum);
151 }
152 return String(value);
153 },
154
155 /**
156 * $.tsv.toArray(line, options) parses one line of TSV input into an array of values.
157 * @param line A line with values separated by single tab characters, e.g. "11\t12\t13"
158 * @param options optional: { valueSplitter: /\t/, parseValue: <a function to parse each value>}
159 * @param rownum optional: the row number (defaults to 0);
160 * @returns an array of values, e.g. ["11" "12", "13"]
161 */
162 toArray: function toArray(line, options, rownum) {
163 var opts = tsvOptions(options);
164 var valueSplitter = opts.valueSplitter;
165 rownum = rownum || 0;
166 var colnum = 0;
167 function doValue(val) {
168 var c = colnum++;
169 return $.tsv.parseValue(val, opts, c, tsvColumn(opts, c), rownum);
170 }
171 return line.split(valueSplitter).map(doValue);
172 },
173
174 /**
175 * $.tsv.fromArray(row, options) returns one line of TSV input from an array of values.
176 * @param array an array of values, e.g. ["11" "12", "13"]
177 * @param options optional: { valueSeparator: "\t", formatValue: <a function to format each value>}
178 * @param rownum optional: the row number (defaults to 0);
179 * @returns A line with values separated by single tab characters, e.g. "11\t12\t13"
180 */
181 fromArray: function fromArray(array, options, rownum) {
182 var opts = tsvOptions(options);
183 var valueSeparator = opts.valueSeparator;
184 var colnum = 0;
185 function doValue(val) {
186 var c = colnum++;
187 return $.tsv.formatValue(val, opts, c, tsvColumn(c), rownum);
188 }
189 return array.map(doValue).join(valueSeparator);
190 },
191
192 /**
193 * $.tsv.toArrays(tsv, options) returns an array of arrays, one per line, each containing values from one row.
194 * @param tsv a tab-separated-values input, e.g. "11\t\12\t13\n21\t22\t23"
195 * @param options optional: { valueSplitter: /\t/, lineSplitter: /\r?\n/, parseValue: <a function to parse each value> }
196 * @returns an array of arrays, e.g. [["11", "12", "13"], ["21", "22", "23"]]
197 */
198 toArrays: function toArrays(tsv, options) {
199 var opts = tsvOptions(options);
200 var lines = tsv.split(opts.lineSplitter);
201 var rownum = opts.startRownum || 0;
202 return lines.map(function doLine(line) {
203 return $.tsv.toArray(line, opts, rownum++);
204 });
205 },
206
207 /**
208 * $.tsv.fromArrays(array, options) returns a TSV string representing the array of row arrays.
209 * @param array an array of arrays of values. To produce valid TSV, all the arrays should be of the same length.
210 * @param options optional: { valueSeparator: "\t", lineSeparator: "\n", columns: ["c1", "c2", "c3"], formatValue: <a function to format each value> }
211 * @returns An tsv string, e.g. "c1\tc2\tc3\n11\t\12\t13\n21\t22\t23"
212 */
213 fromArrays: function fromArrays(array, options) {
214 var opts = tsvOptions(options);
215 var first = array.length ? array[0] : [];
216 var cols = tsvColumns(opts, first);
217 var rownum = opts.startRownum || 0;
218 var header = opts.includeHeader ? $.tsv.fromArray(cols, opts, -1) : undefined;
219 function doRow(row) {
220 return $.tsv.fromArray(row, opts, rownum++);
221 }
222 var rtemp = array.map(doRow);
223 if (header) {
224 rtemp.unshift(header);
225 }
226 return rtemp.join(opts.lineSeparator);
227 },
228
229 /**
230 * $.tsv.arrayToObject(row, options) returns an object whose fields are named in options.columns, and
231 * whose values come from the corresponding position in row (an array of values in the same order).
232 *
233 * If the columns are not supplied, "0", "1", etc. will be used.
234 * @param row the values, e.g. ["v1", "v2"]
235 * @param options optional: { columns: ["name1", "name2"], rowToObject: <optional conversion function to call instead> }
236 * @param rownum optional: the row number
237 * @returns an object derived from the elements of the row.
238 */
239 arrayToObject: function arrayToObject(row, options, rownum) {
240 var opts = tsvOptions(options);
241 rownum = rownum || 0;
242 var columns = tsvColumns(opts, row);
243 if (opts.arrayToObject) {
244 // We have an override; use that instead.
245 return opts.arrayToObject(row, opts, rownum);
246 }
247 var dict = {};
248 for (var j = 0; j < columns.length; j++) {
249 dict[columns[j]] = row[j];
250 }
251 return dict;
252 },
253
254 /**
255 * $.tsv.arraysToObjects(array, options) returns an array of objects, derived from the array.
256 * The array must either have the first row be column names, or columns: ["name1", "name2", ...] must be supplied
257 * in the options.
258 * @param array an array of arrays of values. [ ["name1", "name2" ...],? ["val1", "val2" ...] ...]
259 * @param options optional: { columns: ["name1", "name2", ...] }
260 * @returns An array of objects, [ { name1: val1, name2: val2 ... } ... ]
261 */
262 arraysToObjects: function arraysToObjects(array, options) {
263 var opts = tsvOptions(options);
264 if (! opts.columns) {
265 opts.columns = array.shift();
266 }
267 var rownum = opts.startRownum || 0;
268 return array.map(function convert(row) {
269 return $.tsv.arrayToObject(row, opts, rownum++);
270 });
271 },
272
273 /**
274 * $.tsv.toObjects(tsv, options) returns an array of objects from a tsv string.
275 * The string must either have the first row be column names, or columns: ["name1", "name2", ...] must be supplied
276 * in the options.
277 *
278 * @param A TSV string, e.g. "val1\tval2..." or "name1\tname2...\n\val1\val2..."
279 * @param options optional: { columns ["name1", "name2" ...] }
280 * @returns an array of objects, e.g. [ {name1: val1, name2: val2 ...} ...]
281 */
282 toObjects: function toObjects(tsv, options) {
283 var opts = tsvOptions(options);
284 return $.tsv.arraysToObjects($.tsv.toArrays(tsv, opts), opts);
285 },
286
287 /**
288 * $.tsv.objectToArray(obj, options) Convert one object to an array representation for storing as a TSV line.
289 *
290 * @param obj an object to convert to an array representations, e.g. { name1: "val1", name2: "val2" ... }
291 * @param options optional: { columns: ["name1", "name2"], objectToArray: <a function to use instead> }
292 * @param rownum optional: the row number
293 * @result an array, e.g. ["val1", "val2"]
294 */
295 objectToArray: function objectToArray(obj, options, rownum) {
296 var opts = tsvOptions(options);
297 var columns = tsvColumns(opts, obj);
298 rownum = rownum || 0;
299 if (opts.objectToArray) {
300 // We have an override; use that instead.
301 return opts.objectToArray(obj, opts, rownum);
302 }
303 var row = [];
304 for (var j = 0; j < columns.length; j++) {
305 row.push(obj[columns[j]]);
306 }
307 return row;
308 },
309
310 /**
311 * $.tsv.objectsToArrays(array, options) converts an array of objects into an array of row arrays.
312 *
313 * @param array An array of objects, e.g. [ { name1: "val1", name2: "val2", ...} ...]
314 * @param options { columns: ["name1", "name2"...], includeHeaders: true, objectToArray: <optional function to convert each object> }
315 */
316 objectsToArrays: function objectsToArrays(array, options) {
317 var opts = tsvOptions(options);
318 var rownum = options.startRownum;
319 var result = array.map(function convert(obj) {
320 return $.tsv.objectToArray(obj, opts, rownum++);
321 });
322 return result;
323 },
324
325 fromObject: function fromObject(array, options) {
326 var opts = tsvOptions(options);
327 return $.tsv.fromArray($.tsv.objectToArray(array, opts), opts);
328 },
329
330 /**
331 * $.tsv.fromObjects(array, options) converts an array of objects into a tsv string.
332 *
333 * @param array An array of objects, e.g. [ { name1: "val1", name2: "val2", ...} ...]
334 * @param options { columns: ["name1", "name2"...], includeHeaders: true, objectToArray: <optional function to convert each object> }
335 */
336 fromObjects: function fromObjects(array, options) {
337 var opts = tsvOptions(options);
338 var first = array.length ? array[0] : {};
339 // Calculate the columns while we still have the original objects. This is being called for side-effect!
340 tsvColumns(opts, first);
341 return $.tsv.fromArrays($.tsv.objectsToArrays(array, opts), opts);
342 },
343
344 extend: $.extend
345 };
346 // Compatibility with initial release.
347 $.tsv.parseRow = $.tsv.toArray;
348 $.tsv.parseRows = $.tsv.toArrays;
349 $.tsv.parseObject = $.tsv.toObject;
350 $.tsv.parseObjects = $.tsv.toObjects;
351 $.tsv.formatValue = $.tsv.formatValue;
352 $.tsv.formatRow = $.tsv.fromArray;
353 $.tsv.formatRows = $.tsv.fromArrays;
354 $.tsv.formatObject = $.tsv.fromObject;
355 $.tsv.formatObjects = $.tsv.fromObjects;
356
357 })(jQuery);