Tidied up 'To Table' operation, adding better CSV parsing support.
This commit is contained in:
parent
8fc5f59647
commit
8556bdcdeb
@ -737,37 +737,43 @@ const Utils = {
|
|||||||
* Parses CSV data and returns it as a two dimensional array or strings.
|
* Parses CSV data and returns it as a two dimensional array or strings.
|
||||||
*
|
*
|
||||||
* @param {string} data
|
* @param {string} data
|
||||||
|
* @param {string[]} [cellDelims=[","]]
|
||||||
|
* @param {string[]} [lineDelims=["\n", "\r"]]
|
||||||
* @returns {string[][]}
|
* @returns {string[][]}
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* // returns [["head1", "head2"], ["data1", "data2"]]
|
* // returns [["head1", "head2"], ["data1", "data2"]]
|
||||||
* Utils.parseCSV("head1,head2\ndata1,data2");
|
* Utils.parseCSV("head1,head2\ndata1,data2");
|
||||||
*/
|
*/
|
||||||
parseCSV: function(data) {
|
parseCSV: function(data, cellDelims=[","], lineDelims=["\n", "\r"]) {
|
||||||
|
|
||||||
let b,
|
let b,
|
||||||
ignoreNext = false,
|
next,
|
||||||
|
renderNext = false,
|
||||||
inString = false,
|
inString = false,
|
||||||
cell = "",
|
cell = "",
|
||||||
line = [],
|
line = [],
|
||||||
lines = [];
|
lines = [];
|
||||||
|
|
||||||
|
// Remove BOM, often present in Excel CSV files
|
||||||
|
if (data.length && data[0] === "\uFEFF") data = data.substr(1);
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
b = data[i];
|
b = data[i];
|
||||||
if (ignoreNext) {
|
next = data[i+1] || "";
|
||||||
|
if (renderNext) {
|
||||||
cell += b;
|
cell += b;
|
||||||
ignoreNext = false;
|
renderNext = false;
|
||||||
} else if (b === "\\") {
|
} else if (b === "\\") {
|
||||||
cell += b;
|
renderNext = true;
|
||||||
ignoreNext = true;
|
|
||||||
} else if (b === "\"" && !inString) {
|
} else if (b === "\"" && !inString) {
|
||||||
inString = true;
|
inString = true;
|
||||||
} else if (b === "\"" && inString) {
|
} else if (b === "\"" && inString) {
|
||||||
inString = false;
|
if (next === "\"") renderNext = true;
|
||||||
} else if (b === "," && !inString) {
|
else inString = false;
|
||||||
|
} else if (!inString && cellDelims.indexOf(b) >= 0) {
|
||||||
line.push(cell);
|
line.push(cell);
|
||||||
cell = "";
|
cell = "";
|
||||||
} else if ((b === "\n" || b === "\r") && !inString) {
|
} else if (!inString && lineDelims.indexOf(b) >= 0) {
|
||||||
line.push(cell);
|
line.push(cell);
|
||||||
cell = "";
|
cell = "";
|
||||||
lines.push(line);
|
lines.push(line);
|
||||||
|
@ -67,7 +67,6 @@ const Categories = [
|
|||||||
"Encode text",
|
"Encode text",
|
||||||
"Decode text",
|
"Decode text",
|
||||||
"Swap endianness",
|
"Swap endianness",
|
||||||
"To Table",
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -183,6 +182,7 @@ const Categories = [
|
|||||||
"To Lower case",
|
"To Lower case",
|
||||||
"Add line numbers",
|
"Add line numbers",
|
||||||
"Remove line numbers",
|
"Remove line numbers",
|
||||||
|
"To Table",
|
||||||
"Reverse",
|
"Reverse",
|
||||||
"Sort",
|
"Sort",
|
||||||
"Unique",
|
"Unique",
|
||||||
|
@ -616,26 +616,22 @@ const OperationConfig = {
|
|||||||
},
|
},
|
||||||
"To Table": {
|
"To Table": {
|
||||||
module: "Default",
|
module: "Default",
|
||||||
description: "Renders data as a table. Data can be split on different characters and output as a HTML or ASCII table with optional header row.",
|
description: "Data can be split on different characters and rendered as an HTML or ASCII table with an optional header row.<br><br>Supports the CSV (Comma Separated Values) file format by default. Change the cell delimiter argument to <code>\\t</code> to support TSV (Tab Separated Values) or <code>|</code> for PSV (Pipe Separated Values).<br><br>You can enter as many delimiters as you like. Each character will be treat as a separate possible delimiter.",
|
||||||
inputType: "string",
|
inputType: "string",
|
||||||
outputType: "html",
|
outputType: "html",
|
||||||
highlight: false,
|
|
||||||
highlightReverse: false,
|
|
||||||
manualBake: false,
|
|
||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
name: "Select separator",
|
name: "Cell delimiters",
|
||||||
type: "populateOption",
|
type: "binaryShortString",
|
||||||
value: ToTable.SEPARATORS,
|
|
||||||
target: 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Separator",
|
|
||||||
type: "string",
|
|
||||||
value: ","
|
value: ","
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "First row header?",
|
name: "Row delimiters",
|
||||||
|
type: "binaryShortString",
|
||||||
|
value: "\\n\\r"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Make first row header",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: false
|
value: false
|
||||||
},
|
},
|
||||||
|
@ -2,19 +2,14 @@
|
|||||||
* ToTable operations.
|
* ToTable operations.
|
||||||
*
|
*
|
||||||
* @author Mark Jones [github.com/justanothermark]
|
* @author Mark Jones [github.com/justanothermark]
|
||||||
|
* @copyright Crown Copyright 2018
|
||||||
|
* @license Apache-2.0
|
||||||
|
*
|
||||||
* @namespace
|
* @namespace
|
||||||
*/
|
*/
|
||||||
|
import Utils from "../Utils.js";
|
||||||
|
|
||||||
const ToTable = {
|
const ToTable = {
|
||||||
/**
|
|
||||||
* @constant
|
|
||||||
* @default
|
|
||||||
*/
|
|
||||||
SEPARATORS: [
|
|
||||||
{name: "Comma", value: ","},
|
|
||||||
{name: "Tab", value: "\\t"},
|
|
||||||
{name: "Pipe", value: "|"},
|
|
||||||
{name: "Custom", value: ""}
|
|
||||||
],
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
@ -25,6 +20,7 @@ const ToTable = {
|
|||||||
"HTML"
|
"HTML"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To Table operation.
|
* To Table operation.
|
||||||
*
|
*
|
||||||
@ -33,42 +29,26 @@ const ToTable = {
|
|||||||
* @returns {html}
|
* @returns {html}
|
||||||
*/
|
*/
|
||||||
runToTable: function (input, args) {
|
runToTable: function (input, args) {
|
||||||
let separator = args[1];
|
const [cellDelims, rowDelims, firstRowHeader, format] = args;
|
||||||
let firstRowHeader = args[2];
|
|
||||||
let format = args[3];
|
|
||||||
let tableData = [];
|
|
||||||
|
|
||||||
// If the separator contains any tabs, convert them to tab characters.
|
|
||||||
separator = separator.replace("\\t", "\t");
|
|
||||||
|
|
||||||
// Process the input into a nested array of elements.
|
// Process the input into a nested array of elements.
|
||||||
let rows = input.split("\n");
|
const tableData = Utils.parseCSV(input, cellDelims.split(""), rowDelims.split(""));
|
||||||
rows.forEach(function(element) {
|
|
||||||
if (separator === "") {
|
if (!tableData.length) return "";
|
||||||
tableData.push([element]);
|
|
||||||
} else {
|
|
||||||
tableData.push(element.split(separator));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Render the data in the requested format.
|
// Render the data in the requested format.
|
||||||
let output = "";
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case "ASCII":
|
case "ASCII":
|
||||||
output = asciiOutput(tableData);
|
return asciiOutput(tableData);
|
||||||
break;
|
case "HTML":
|
||||||
|
|
||||||
default:
|
default:
|
||||||
output = htmlOutput(tableData);
|
return htmlOutput(tableData);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Outputs an array of data as an ASCII table.
|
* Outputs an array of data as an ASCII table.
|
||||||
*
|
*
|
||||||
* @param {Array[]} tableData
|
* @param {string[][]} tableData
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
function asciiOutput(tableData) {
|
function asciiOutput(tableData) {
|
||||||
@ -137,6 +117,9 @@ const ToTable = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Outputs a table of data as a HTML table.
|
* Outputs a table of data as a HTML table.
|
||||||
|
*
|
||||||
|
* @param {string[][]} tableData
|
||||||
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
function htmlOutput(tableData) {
|
function htmlOutput(tableData) {
|
||||||
// Start the HTML output with suitable classes for styling.
|
// Start the HTML output with suitable classes for styling.
|
||||||
|
Loading…
Reference in New Issue
Block a user