Added ToTable operation to output data as ASCII or HTML tables.
parent
cb66508b8a
commit
e2af3c78e7
|
@ -67,6 +67,7 @@ const Categories = [
|
||||||
"Encode text",
|
"Encode text",
|
||||||
"Decode text",
|
"Decode text",
|
||||||
"Swap endianness",
|
"Swap endianness",
|
||||||
|
"To Table",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,6 +37,7 @@ import SeqUtils from "../operations/SeqUtils.js";
|
||||||
import Shellcode from "../operations/Shellcode.js";
|
import Shellcode from "../operations/Shellcode.js";
|
||||||
import StrUtils from "../operations/StrUtils.js";
|
import StrUtils from "../operations/StrUtils.js";
|
||||||
import Tidy from "../operations/Tidy.js";
|
import Tidy from "../operations/Tidy.js";
|
||||||
|
import ToTable from "../operations/ToTable.js";
|
||||||
import Unicode from "../operations/Unicode.js";
|
import Unicode from "../operations/Unicode.js";
|
||||||
import URL_ from "../operations/URL.js";
|
import URL_ from "../operations/URL.js";
|
||||||
|
|
||||||
|
@ -613,6 +614,38 @@ const OperationConfig = {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"To Table": {
|
||||||
|
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.",
|
||||||
|
inputType: "string",
|
||||||
|
outputType: "html",
|
||||||
|
highlight: false,
|
||||||
|
highlightReverse: false,
|
||||||
|
manualBake: false,
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "Select separator",
|
||||||
|
type: "populateOption",
|
||||||
|
value: ToTable.SEPARATORS,
|
||||||
|
target: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Separator",
|
||||||
|
type: "string",
|
||||||
|
value: ","
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "First row header?",
|
||||||
|
type: "boolean",
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Format",
|
||||||
|
type: "option",
|
||||||
|
value: ToTable.FORMATS
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"From Hex": {
|
"From Hex": {
|
||||||
module: "Default",
|
module: "Default",
|
||||||
description: "Converts a hexadecimal byte string back into its raw value.<br><br>e.g. <code>ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a</code> becomes the UTF-8 encoded string <code>Γειά σου</code>",
|
description: "Converts a hexadecimal byte string back into its raw value.<br><br>e.g. <code>ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a</code> becomes the UTF-8 encoded string <code>Γειά σου</code>",
|
||||||
|
|
|
@ -27,6 +27,7 @@ import Rotate from "../../operations/Rotate.js";
|
||||||
import SeqUtils from "../../operations/SeqUtils.js";
|
import SeqUtils from "../../operations/SeqUtils.js";
|
||||||
import StrUtils from "../../operations/StrUtils.js";
|
import StrUtils from "../../operations/StrUtils.js";
|
||||||
import Tidy from "../../operations/Tidy.js";
|
import Tidy from "../../operations/Tidy.js";
|
||||||
|
import ToTable from "../../operations/ToTable.js";
|
||||||
import Unicode from "../../operations/Unicode.js";
|
import Unicode from "../../operations/Unicode.js";
|
||||||
import UUID from "../../operations/UUID.js";
|
import UUID from "../../operations/UUID.js";
|
||||||
import XKCD from "../../operations/XKCD.js";
|
import XKCD from "../../operations/XKCD.js";
|
||||||
|
@ -163,6 +164,7 @@ OpModules.Default = {
|
||||||
"Mean": Arithmetic.runMean,
|
"Mean": Arithmetic.runMean,
|
||||||
"Median": Arithmetic.runMedian,
|
"Median": Arithmetic.runMedian,
|
||||||
"Standard Deviation": Arithmetic.runStdDev,
|
"Standard Deviation": Arithmetic.runStdDev,
|
||||||
|
"To Table": ToTable.runToTable,
|
||||||
"Windows Filetime to UNIX Timestamp": Filetime.runFromFiletimeToUnix,
|
"Windows Filetime to UNIX Timestamp": Filetime.runFromFiletimeToUnix,
|
||||||
"UNIX Timestamp to Windows Filetime": Filetime.runToFiletimeFromUnix,
|
"UNIX Timestamp to Windows Filetime": Filetime.runToFiletimeFromUnix,
|
||||||
"XKCD Random Number": XKCD.runRandomNumber,
|
"XKCD Random Number": XKCD.runRandomNumber,
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
import Utils from "../Utils.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ToTable operations.
|
||||||
|
*
|
||||||
|
* @author Mark Jones [github.com/justanothermark]
|
||||||
|
* @namespace
|
||||||
|
*/
|
||||||
|
const ToTable = {
|
||||||
|
/**
|
||||||
|
* @constant
|
||||||
|
* @default
|
||||||
|
*/
|
||||||
|
SEPARATORS: [
|
||||||
|
{name: "Comma", value:","},
|
||||||
|
{name: "Tab", value: escape("\t")},
|
||||||
|
{name: "Pipe", value: "|"},
|
||||||
|
{name: "Custom", value: ""}
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constant
|
||||||
|
* @default
|
||||||
|
*/
|
||||||
|
FORMATS: [
|
||||||
|
'ASCII',
|
||||||
|
'HTML'
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To Table operation.
|
||||||
|
*
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {html}
|
||||||
|
*/
|
||||||
|
runToTable: function (input, args) {
|
||||||
|
let separator = args[1];
|
||||||
|
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.
|
||||||
|
let rows = input.split('\n');
|
||||||
|
rows.forEach(function(element) {
|
||||||
|
if (separator == '') {
|
||||||
|
tableData.push([element]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tableData.push(element.split(separator));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Render the data in the requested format.
|
||||||
|
let output = '';
|
||||||
|
switch (format) {
|
||||||
|
case 'ASCII':
|
||||||
|
output = asciiOutput(tableData);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
output = htmlOutput(tableData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs an array of data as an ASCII table.
|
||||||
|
*
|
||||||
|
* @param {Array[]} tableData
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function asciiOutput(tableData) {
|
||||||
|
const horizontalBorder = '-';
|
||||||
|
const verticalBorder = '|';
|
||||||
|
const crossBorder = '+';
|
||||||
|
|
||||||
|
let output = '';
|
||||||
|
let longestCells = [];
|
||||||
|
|
||||||
|
// Find longestCells value per column to pad cells equally.
|
||||||
|
tableData.forEach(function(row, index) {
|
||||||
|
row.forEach(function(cell, cellIndex) {
|
||||||
|
if (longestCells[cellIndex] == undefined || cell.length > longestCells[cellIndex]) {
|
||||||
|
longestCells[cellIndex] = cell.length;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Calculate the complete row length. This is the length of the
|
||||||
|
// longest cell for each column plus 3 characters per cell
|
||||||
|
// (1 padding each side of the value and 1 for the cell border)
|
||||||
|
// plus 1 for the final cell border.
|
||||||
|
let rowLength = (longestCells.length * 3) + 1;
|
||||||
|
longestCells.forEach(function(celllongestCells) {
|
||||||
|
rowLength += celllongestCells;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add the top border of the table to the output.
|
||||||
|
output += outputHorizontalBorder(longestCells);
|
||||||
|
|
||||||
|
// If the first row is a header, remove the row from the data and
|
||||||
|
// add it to the output with another horizontal border.
|
||||||
|
if (firstRowHeader) {
|
||||||
|
let row = tableData.shift();
|
||||||
|
output += outputRow(row, longestCells);
|
||||||
|
output += outputHorizontalBorder(longestCells);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the rest of the table rows.
|
||||||
|
tableData.forEach(function(row, index) {
|
||||||
|
output += outputRow(row, longestCells);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close the table with a final horizontal border.
|
||||||
|
output += outputHorizontalBorder(longestCells);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs a row of correctly padded cells.
|
||||||
|
*/
|
||||||
|
function outputRow(row, longestCells) {
|
||||||
|
let rowOutput = verticalBorder;
|
||||||
|
row.forEach(function(cell, index) {
|
||||||
|
rowOutput += ' ' + cell + ' '.repeat(longestCells[index] - cell.length) + ' ' + verticalBorder;
|
||||||
|
});
|
||||||
|
rowOutput += '\n';
|
||||||
|
return rowOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs a horizontal border with a different character where
|
||||||
|
* the horizontal border meets a vertical border.
|
||||||
|
*/
|
||||||
|
function outputHorizontalBorder(longestCells) {
|
||||||
|
let rowOutput = crossBorder;
|
||||||
|
longestCells.forEach(function(cellLength) {
|
||||||
|
rowOutput += horizontalBorder.repeat(cellLength + 2) + crossBorder;
|
||||||
|
});
|
||||||
|
rowOutput += '\n';
|
||||||
|
return rowOutput;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs a table of data as a HTML table.
|
||||||
|
*/
|
||||||
|
function htmlOutput(tableData) {
|
||||||
|
// Start the HTML output with suitable classes for styling.
|
||||||
|
let output = "<table class='table table-hover table-condensed table-bordered table-nonfluid'>";
|
||||||
|
|
||||||
|
// If the first row is a header then put it in <thead> with <th> cells.
|
||||||
|
if (firstRowHeader) {
|
||||||
|
let row = tableData.shift();
|
||||||
|
output += "<thead>";
|
||||||
|
output += outputRow(row, 'th');
|
||||||
|
output += "</thead>";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output the rest of the rows in the <tbody>.
|
||||||
|
output += "<tbody>";
|
||||||
|
tableData.forEach(function(row, index) {
|
||||||
|
output += outputRow(row, 'td');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close the body and table elements.
|
||||||
|
output += "</tbody></table>";
|
||||||
|
return output;
|
||||||
|
|
||||||
|
function outputRow(row, cellType) {
|
||||||
|
let output = "<tr>";
|
||||||
|
row.forEach(function(cell) {
|
||||||
|
output += "<" + cellType + ">" + cell + "</" + cellType + ">";
|
||||||
|
});
|
||||||
|
output += "</tr>";
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ToTable;
|
Loading…
Reference in New Issue