I have following function that display ASCII table
function ascii_table(array, header) {
if (!array.length) {
return '';
}
var lengths = array[0].map(function(_, i) {
var col = array.map(function(row) {
if (row[i] != undefined) {
return row[i].length;
} else {
return 0;
}
});
return Math.max.apply(Math, col);
});
array = array.map(function(row) {
return '| ' + row.map(function(item, i) {
var size = item.length;
if (size < lengths[i]) {
item += new Array(lengths[i]-size+1).join(' ');
}
return item;
}).join(' | ') + ' |';
});
var sep = '+' + lengths.map(function(length) {
return new Array(length+3).join('-');
}).join('+') + '+';
if (header) {
return sep + '\n' + array[0] + '\n' + sep + '\n' +
array.slice(1).join('\n') + '\n' + sep;
} else {
return sep + '\n' + array.join('\n') + '\n' + sep;
}
}
the problem is when the cell contain new line I end up with something like this:
+---------------------+--------+-------+-----+-------------------------------+------------+---------------------+
| date | nick | email | www | comment | ip | avatar |
+---------------------+--------+-------+-----+-------------------------------+------------+---------------------+
| 2016-01-27 21:11:10 | stefan | kanev | | dsfdsfsd
sdfsdf
sdfsdf
sdfdsf | 1308240552 | avatars/default.png |
+---------------------+--------+-------+-----+-------------------------------+------------+---------------------+
What should I change in my function to produce the result like this:
+---------------------+--------+-------+-----+----------+------------+---------------------+
| date | nick | email | www | comment | ip | avatar |
+---------------------+--------+-------+-----+----------+------------+---------------------+
| 2016-01-27 21:11:10 | stefan | kanev | | dsfdsfsd | 1308240552 | avatars/default.png |
| | | | | sdfsdf | | |
| | | | | sdfsdf | | |
| | | | | sdfdsf | | |
+---------------------+--------+-------+-----+----------+------------+---------------------+
You could modify the table and add the new rows to the table before before rendering it:
function ascii_table(array, header) {
if (!array.length) {
return '';
}
//added
for (var i = array.length - 1; i >= 0; i--) {
var row = array[i];
var stacks = [];
for (var j = 0; j < row.length; j++) {
var newLines = row[j].split("\n");
row[j] = newLines.shift();
stacks.push(newLines);
}
var newRowsCount = stacks.reduce(function(a, b) {
return a.length > b.length ? a : b;
}).length;
for (var k = newRowsCount - 1; k >= 0; k--) {
array.splice(i + 1, 0, stacks.map(function(stackColumn) {
return stackColumn[k] || "";
}));
}
}
//added
var lengths = array[0].map(function(_, i) {
var col = array.map(function(row) {
if (row[i] != undefined) {
return row[i].length;
} else {
return 0;
}
});
return Math.max.apply(Math, col);
});
array = array.map(function(row) {
return '| ' + row.map(function(item, i) {
var size = item.length;
if (size < lengths[i]) {
item += new Array(lengths[i] - size + 1).join(' ');
}
return item;
}).join(' | ') + ' |';
});
var sep = '+' + lengths.map(function(length) {
return new Array(length + 3).join('-');
}).join('+') + '+';
if (header) {
return sep + '\n' + array[0] + '\n' + sep + '\n' +
array.slice(1).join('\n') + '\n' + sep;
} else {
return sep + '\n' + array.join('\n') + '\n' + sep;
}
}
Output:
+---------------------+------+--------+-----+------------------+------------+---------------------+
| date | nick | email | www | comment | ip | avatar |
+---------------------+------+--------+-----+------------------+------------+---------------------+
| 2016-01-28 11:40:59 | lol | lol@lo | | nocomment | 1844311719 | avatars/default.png |
| | | l.fr | | lol | | |
| | | | | lol | | |
| | | | | lol | | |
| 2016-01-10 15:13:59 | ehs | what | | ente rm comment. | 1423172924 | avatars/default.png |
+---------------------+------+--------+-----+------------------+------------+---------------------+
(Added a new line in one email cell, to test new lines in multiple columns).
This can be done without any modification of your code by expanding your array
-- adding one new row for each extra line of the comment. The first row would be the same as before -- except that the comment cell contains only the first line of the comment. Every additional line would contain empty cells -- except the comment cell, which would contain that comment line.
I'd break out most of the functions for readability, but to keep with your coding style, it might look like this:
array = array.reduce(function (carry, originalRow) {
var commentLines = originalRow[4].split(/\n/g);
var rows = commentLines.map(function (commentLine, rowIndex) {
var newRow = originalRow.map(function (originalCellContent, columnIndex) {
var cellContent = '';
if (rowIndex === 0) {
cellContent = originalCellContent;
}
if (columnIndex === 4) {
cellContent = commentLine;
}
return cellContent;
});
carry.push(newRow);
});
return carry;
}, []);
A fork of your fiddle is here, with this code added.
Here it is: https://jsfiddle.net/zww557sh/1/
function ascii_table(array, header) {
if (!array.length) {
return '';
}
var lengths = array[0].map(function(_, i) {
var col = array.map(function(row) {
if (row[i] != undefined) {
return row[i].length;
} else {
return 0;
}
});
return Math.max.apply(Math, col);
});
array = array.map(function(row, r) {
// let's split the table cells to lines
var cols = row.map(function(item, i){
return item.split("\n")
});
// and calculate the max column-height in this row
var maxH = (cols.reduce(function(i,j){return i.length > j.length ? i : j})).length;
// here we manually build the string that will represent
// this row of the table, including the "multi-line" cells
var rowStr = "";
// loop until the maximum cell height in this row
for (h=0;h<maxH;h++) {
rowStr += "| ";
// loop on all the cells
for (c=0;c<cols.length;c++) {
if (c>0) rowStr += " | ";
// item is the h'th in column c, but it might
// be non existing, then we use ""
var item = cols[c][h] || "";
var size = item.length;
// here we use the same padding
if (size < lengths[c]) {
item += new Array(lengths[c]-size+1).join(' ');
}
rowStr += item;
}
rowStr += " |";
if (h<maxH-1) rowStr += "\n";
}
return rowStr;
});
var sep = '+' + lengths.map(function(length) {
return new Array(length+3).join('-');
}).join('+') + '+';
if (header) {
return sep + '\n' + array[0] + '\n' + sep + '\n' +
array.slice(1).join('\n') + '\n' + sep;
} else {
return sep + '\n' + array.join('\n') + '\n' + sep;
}
}
Output:
+---------------------+------+------------+-----+-----------------------+------------+---------------------+
| date | nick | email | www | comment | ip | avatar |
+---------------------+------+------------+-----+-----------------------+------------+---------------------+
| 2016-01-28 11:40:59 | lol | lol@lol.fr | | nocomment | 1844311719 | avatars/default.png |
| | | | | lol | | |
| | | | | lol | | |
| | | | | lol | | |
| 2016-01-10 15:13:59 | ehs | what | | ente rm comment. | 1423172924 | avatars/default.png |
+---------------------+------+------------+-----+-----------------------+------------+---------------------+
来源:https://stackoverflow.com/questions/35047522/ascii-table-where-field-can-have-newlines