mdtabeditor/public/serialize_table.mjs

120 lines
2.7 KiB
JavaScript

/*
* str: string
*
* Returns a string
*/
function escapeItem(str) {
return str.replaceAll(/(\\*)\|/g, function(match, backslashes) {
if (backslashes.length % 2 === 0) {
backslashes += "\\";
}
return backslashes + "|";
});
}
/*
* escapedColumns: array of objects
* escapedRow: array of string
*
* Returns a string
*/
function writeRow(escapedColumns, escapedRow) {
let res = "";
for (let i = 0; i < escapedColumns.length; i++) {
let escapedColumn = escapedColumns[i];
let escapedItem = escapedRow[i];
res += `| ${escapedItem}${" ".repeat(escapedColumn.maxLength - escapedItem.length)} `;
}
res += "|";
return res;
}
/*
* escapedColumns: array of objects
*
* Returns a string
*/
function writeHeader(escapedColumns) {
let headerRow = [];
let delimiterRow = [];
for (let escapedColumn of escapedColumns) {
headerRow.push(escapedColumn.text);
let delimiter = "";
if (escapedColumn.leftAligned) {
delimiter += ":";
}
delimiter += "-".repeat(escapedColumn.maxLength - escapedColumn.leftAligned - escapedColumn.rightAligned);
if (escapedColumn.rightAligned) {
delimiter += ":";
}
delimiterRow.push(delimiter);
}
return writeRow(escapedColumns, headerRow) + "\n" + writeRow(escapedColumns, delimiterRow);
}
/*
* column: object
* rows: array of array of strings
* headerIndex: integer
*
* Returns an integer
*/
function calculateColumnLength(column, rows, columnIndex) {
let length = Math.max(column.text.length, 3);
for (let row of rows) {
let item = row[columnIndex];
if (item.length > length) {
length = item.length;
}
}
return length;
}
/*
* table: object
*
* Returns a string
*/
function serializeTable(table) {
let escapedColumns = [];
let escapedRows = [];
for (let column of table.columns) {
escapedColumns.push({
text: escapeItem(column.text),
leftAligned: column.leftAligned,
rightAligned: column.rightAligned
});
}
for (let row of table.rows) {
let escapedRow = [];
for (let item of row) {
escapedRow.push(escapeItem(item));
}
escapedRows.push(escapedRow);
}
for (let i = 0; i < escapedColumns.length; i++) {
escapedColumns[i].maxLength = calculateColumnLength(escapedColumns[i], escapedRows, i);
}
let res = writeHeader(escapedColumns);
for (let escapedRow of escapedRows) {
res += "\n" + writeRow(escapedColumns, escapedRow);
}
return res;
}
// XXX: perhaps calculateColumnLength could be placed somewhere else?
export {serializeTable, calculateColumnLength};