UNPKG

@beenotung/tslib

Version:
250 lines (249 loc) 7.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.COMMA = exports.DOUBLE_QUOTE = exports.SINGLE_QUOTE = void 0; exports.from_csv = from_csv; exports.to_csv = to_csv; exports.regular_csv = regular_csv; exports.csv_to_json = csv_to_json; exports.json_to_csv_titles = json_to_csv_titles; exports.json_to_csv = json_to_csv; exports.csv_to_table_text = csv_to_table_text; exports.SINGLE_QUOTE = "'"; exports.DOUBLE_QUOTE = '"'; exports.COMMA = ','; function from_csv(s, separator = exports.COMMA, delimiter = exports.DOUBLE_QUOTE) { // to remove control char if got from network s = s.trim(); const rows = []; let cols = []; let col = ''; let i = 0; const n = s.length; for (; i < n;) { const c = s[i]; i++; switch (c) { case separator: cols.push(col); col = ''; break; case '\r': if (s[i] !== '\n') { col += c; } break; case '\n': cols.push(col); col = ''; rows.push(cols); cols = []; break; default: if (col.length === 0 && c === delimiter) { for (; i < n;) { const c = s[i]; i++; if (c === delimiter) { if (s[i] === delimiter) { /* the content is delimiter */ col += delimiter; i++; } else { /* the content has ends */ break; } } else { /* the content is not delimiter */ col += c; } } break; } col += c; } } const last_char = s[n - 1]; if (last_char !== '\n') { // not terminated by new line, auto feed a newline if (col.length > 0 || last_char === separator || last_char === delimiter) { cols.push(col); } if (cols.length > 0) { rows.push(cols); } } return rows; } function to_csv(rows, separator = exports.COMMA, delimiter = exports.DOUBLE_QUOTE) { const res = []; for (const cols of rows) { let first = true; for (const col of cols) { if (first) { first = false; } else { res.push(separator); } if (col.indexOf('\n') === -1 && col.indexOf(delimiter) === -1 && col.indexOf(separator) === -1) { res.push(col); } else { res.push(delimiter); for (const c of col || '') { if (c === delimiter) { res.push(delimiter, delimiter); } else { res.push(c); } } res.push(delimiter); } } res.push('\r\n'); } return res.join(''); } function regular_csv(rows) { /** * to make each rows with same number of columns * for to_csv() to insert ending commas * */ let maxCol = 0; rows.forEach(cols => (maxCol = Math.max(maxCol, cols.length))); rows.forEach(cols => { for (let i = cols.length; i < maxCol; i++) { cols.push(); } }); } function csv_to_json(rows, titles) { if (!titles) { rows = rows.slice(); titles = rows.shift() || []; } const n = titles.length; return rows.map(cols => { const res = {}; for (let i = 0; i < n; i++) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion res[titles[i]] = cols[i]; } return res; }); } function json_to_csv_titles(xs) { const titles = []; const titleCache = {}; /* build title list */ for (const x of xs) { for (const title of Object.keys(x)) { if (!titleCache[title]) { titleCache[title] = true; titles.push(title); } } } return titles; } function json_to_csv(xs, titles = json_to_csv_titles(xs)) { const rows = [titles]; const n = titles.length; for (const x of xs) { const cols = new Array(n).fill(''); rows.push(cols); for (let i = 0; i < n; i++) { let col = x[titles[i]]; if (col === null || col === undefined) { col = ''; } else { col = String(col); } cols[i] = col; } } return rows; } function to_width(s, len, repeatChar) { const diff = len - s.length; if (diff > 0) { s += repeatChar.repeat(diff / repeatChar.length); s += repeatChar.slice(0, len - s.length); } return s; } function csv_to_table_text(rows, options) { if (rows.length === 0) { return ''; } let col_separator = ' '; let header_line_char = '-'; let show_total = false; let line_edge_start = ''; let line_edge_end = ''; let min_col_width = 0; if (options) { if (options.col_separator) { col_separator = options.col_separator; } if (options.header_line_char) { header_line_char = options.header_line_char; } if (options.show_total) { show_total = options.show_total; } if (options.min_col_width) { min_col_width = options.min_col_width; } if (options.markdown) { col_separator = ' | '; header_line_char = '-'; line_edge_start = '| '; line_edge_end = ' |'; min_col_width = Math.max(min_col_width, 3); } } const n = rows[0].length; const lengths = new Array(n).fill(0); for (const cols of rows) { for (let i = 0; i < n; i++) { const col = cols[i]; if (col) { lengths[i] = Math.max(lengths[i], col.length, min_col_width); } } } const titles = rows[0]; const contents = rows.slice(1); let acc = ''; // headers acc += line_edge_start; acc += titles.map((s, i) => to_width(s, lengths[i], ' ')).join(col_separator); acc += line_edge_end; acc += '\n'; // symbol row under headers acc += line_edge_start; acc += titles .map((s, i) => to_width('', lengths[i], header_line_char)) .join(col_separator); acc += line_edge_end; acc += '\n'; // content rows acc += contents .map(cols => line_edge_start + cols.map((s, i) => to_width(s, lengths[i], ' ')).join(col_separator) + line_edge_end) .join('\n'); if (show_total) { acc += '\n'; acc += '\n'; acc += 'total: ' + contents.length; } return acc; }