-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMarkdown Table.js
More file actions
36 lines (35 loc) · 1.75 KB
/
Markdown Table.js
File metadata and controls
36 lines (35 loc) · 1.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Converts csv, tsv or markdown table into pretty markdown table format.
function pre(str) {
const list = str.trim().replace(/^(\r?\n)+$/g, "\n").split("\n").map(v => v.replace(/^\||\|$/g, ""));
const delimiter = [`|`, `\t`, `","`, `,`].find(v => list[0].split(v).length > 1);
if (delimiter === `|`) {
// If input text is markdown table format, removes header separator.
list.splice(1, 1);
}
const tableElements = list.map(record => record.split(delimiter).map(v => v.trim()));
const calcBytes = (character) => {
let length = 0;
for (let i = 0; i < character.length; i++) {
const c = character.charCodeAt(i);
// Multibyte handling
(c >= 0x0 && c < 0x81) || (c === 0xf8f0) || (c >= 0xff61 && c < 0xffa0) || (c >= 0xf8f1 && c < 0xf8f4) ? length += 1 : length += 2;
}
return length;
};
const columnMaxLengthList = tableElements[0].map((v, i) => i).reduce((map, columnIndex) => {
let maxLength = 0;
tableElements.forEach(record => maxLength < calcBytes(record[columnIndex]) ? maxLength = calcBytes(record[columnIndex]) : null);
if (maxLength === 1) {
// Avoids markdown header line becomes only ":" ( ":-" is correct. ).
maxLength = 2;
}
map[columnIndex] = maxLength;
return map;
}, {})
const formattedTableElements = tableElements.map(record => record.map((value, columnIndex) => value + "".padEnd(columnMaxLengthList[columnIndex] - calcBytes(value), " ")));
const headerValues = formattedTableElements.shift();
const tableLine = headerValues.map(v => "".padStart(calcBytes(v), "-").replace(/^./, ":"));
formattedTableElements.unshift(tableLine);
formattedTableElements.unshift(headerValues);
return formattedTableElements.map(record => "| " + record.join(" | ") + " |").join("\n");
}