0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-08 11:52:44 +00:00

Drastic simplification of SpanTables via better regex

Thanks @ericscheid for finding a good regex!
This commit is contained in:
Trevor Buckner
2021-08-13 14:38:43 -04:00
parent 9726fb5666
commit 9dc6d2532a

View File

@@ -369,53 +369,28 @@ const getTableCell = (text, cell, type, align)=>{
}; };
const splitCells = (tableRow, count, prevRow = [])=>{ const splitCells = (tableRow, count, prevRow = [])=>{
// trim any excessive pipes at start of row const cells = [...tableRow.matchAll(/(?:[^|\\]|\\.?)+(?:\|+|$)/g)].map((x)=>x[0]);
tableRow = tableRow.replace(/^\|+(?=\|)/, '')
.replace(/(\|)(\|*)/g, (match, p1, p2, offset, str)=>{
let escaped = false,
curr = offset;
while (--curr >= 0 && str[curr] === '\\') escaped = !escaped;
if(escaped) {
// odd number of slashes means | is escaped
// so apply a space after to separate from unescaped pipes
return `${p1} ${p2}`;
} else {
// add space before unescaped | to distinguish it from an escaped pipe
return ` ${p1}${p2}`;
}
});
tableRow = ` ${tableRow}`;
// Split into cells by matching anything that ends with space followed by pipes // Remove first/last cell in a row if whitespace only and no leading/trailing pipe
const cells = [...tableRow.matchAll(/[^\|].*?(?: \|+|$)/g)].map((x)=>{ if(!cells[0]?.trim()) { cells.shift(); }
if(x[0].slice(-2) == ' |') //Cut off the added space too if only one pipe if(!cells[cells.length - 1]?.trim()) { cells.pop(); }
return x[0].slice(0, -2);
else {
return x[0].slice(0, -1);
}
});
// First/last cell in a row cannot be empty if it has no leading/trailing pipe
if(!cells[0].trim()) { cells.shift(); }
if(!cells[cells.length - 1].trim()) { cells.pop(); }
let numCols = 0; let numCols = 0;
let i = 0; let i, j, trimmedCell, prevCell, prevCols;
for (; i < cells.length; i++) { for (i = 0; i < cells.length; i++) {
const trimmedCell = cells[i].split(/ \|+$/)[0]; trimmedCell = cells[i].split(/\|+$/)[0];
cells[i] = { cells[i] = {
rowspan : 1, rowspan : 1,
colspan : Math.max(cells[i].length - trimmedCell.length, 1), colspan : Math.max(cells[i].length - trimmedCell.length, 1),
text : trimmedCell.trim().replace(/\\\|/g, '|') text : trimmedCell.trim().replace(/\\\|/g, '|')
// trim whitespace and display escaped pipes as normal character // display escaped pipes as normal character
}; };
// Handle Rowspan // Handle Rowspan
if(trimmedCell.slice(-1) == '^' && prevRow.length) { if(trimmedCell.slice(-1) == '^' && prevRow.length) {
// Find matching cell in previous row // Find matching cell in previous row
let prevCols = 0; prevCols = 0;
let j, prevCell;
for (j = 0; j < prevRow.length; j++) { for (j = 0; j < prevRow.length; j++) {
prevCell = prevRow[j]; prevCell = prevRow[j];
if((prevCols == numCols) && (prevCell.colspan == cells[i].colspan)) { if((prevCols == numCols) && (prevCell.colspan == cells[i].colspan)) {