/* * 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};