Skip to content

fixed issue 1231 #1391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 82 additions & 12 deletions src/gen-tables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,21 +297,40 @@ export function getSlidesForTableRows(tableRows: TableCell[][] = [], tableProps:

// STEP 6: **MAIN** Iterate over rows, add table content, create new slides as rows overflow
let newTableRowSlide: TableRowSlide = { rows: [] as TableRow[] }
// activeRowSpans stores rowspan state.
// key is column index, cell is the spanning cell, remaining means how many more rows to span the cell
const activeRowSpans: Map<number, { activeRowIndex: number; cell: TableCell; remaining: number; }> = new Map()
tableRows.forEach((row, iRow) => {
// A: Row variables
const rowCellLines: TableCell[] = []
let maxCellMarTopEmu = 0
let maxCellMarBtmEmu = 0
let activeCellIndex = 0

// B: Create new row in data model, calc `maxCellMar*`
let currTableRow: TableRow = []
row.forEach(cell => {
for (let columnIndex = 0; columnIndex < numCols; ++columnIndex) {
const activeRowSpan = activeRowSpans.get(columnIndex)

const cell = activeRowSpan && activeRowSpan.activeRowIndex < iRow ? activeRowSpan.cell : row[activeCellIndex++]
if (!activeRowSpan && cell.options.rowspan) {
activeRowSpans.set(columnIndex, {
activeRowIndex: iRow,
cell,
remaining: cell.options.rowspan,
})
}

currTableRow.push({
_type: SLIDE_OBJECT_TYPES.tablecell,
text: [],
options: cell.options,
})

if (activeRowSpan && activeRowSpan.activeRowIndex < iRow) {
continue
}

/** FUTURE: DEPRECATED:
* - Backwards-Compat: Oops! Discovered we were still using points for cell margin before v3.8.0 (UGH!)
* - We cant introduce a breaking change before v4.0, so...
Expand All @@ -327,15 +346,20 @@ export function getSlidesForTableRows(tableRows: TableCell[][] = [], tableProps:
if (cell.options?.margin && cell.options.margin[2] && inch2Emu(cell.options.margin[2]) > maxCellMarBtmEmu) maxCellMarBtmEmu = inch2Emu(cell.options.margin[2])
else if (tableProps?.margin && tableProps.margin[2] && inch2Emu(tableProps.margin[2]) > maxCellMarBtmEmu) maxCellMarBtmEmu = inch2Emu(tableProps.margin[2])
}
})
}

// C: Calc usable vertical space/table height. Set default value first, adjust below when necessary.
calcSlideTabH()
emuTabCurrH += maxCellMarTopEmu + maxCellMarBtmEmu // Start row height with margins
if (tableProps.verbose && iRow === 0) console.log(`| SLIDE [${tableRowSlides.length}]: emuSlideTabH ...... = ${(emuSlideTabH / EMU).toFixed(1)} `)

// D: --==[[ BUILD DATA SET ]]==-- (iterate over cells: split text into lines[], set `lineHeight`)
row.forEach((cell, iCell) => {
activeCellIndex = 0
for (let columnIndex = 0; columnIndex < numCols; ++columnIndex) {
const activeRowSpan = activeRowSpans.get(columnIndex)

const cell = activeRowSpan && activeRowSpan.activeRowIndex < iRow ? activeRowSpan.cell : row[activeCellIndex++]

const newCell: TableCell = {
_type: SLIDE_OBJECT_TYPES.tablecell,
_lines: null,
Expand All @@ -355,17 +379,17 @@ export function getSlidesForTableRows(tableRows: TableCell[][] = [], tableProps:
newCell.options.autoPageCharWeight = tableProps.autoPageCharWeight ? tableProps.autoPageCharWeight : null

// E-3: **MAIN** Parse cell contents into lines based upon col width, font, etc
let totalColW = tableProps.colW[iCell]
let totalColW = tableProps.colW[columnIndex]
if (cell.options.colspan && Array.isArray(tableProps.colW)) {
totalColW = tableProps.colW.filter((_cell, idx) => idx >= iCell && idx < idx + cell.options.colspan).reduce((prev, curr) => prev + curr)
totalColW = tableProps.colW.filter((_cell, idx) => idx >= columnIndex && idx < idx + cell.options.colspan).reduce((prev, curr) => prev + curr)
}

// E-4: Create lines based upon available column width
newCell._lines = parseTextToLines(cell, totalColW, false)
newCell._lines = activeRowSpan && activeRowSpan.activeRowIndex < iRow ? [] : parseTextToLines(cell, totalColW, false)

// E-5: Add cell to array
rowCellLines.push(newCell)
})
}

/** E: --==[[ PAGE DATA SET ]]==--
* Add text one-line-a-time to this row's cells until: lines are exhausted OR table height limit is hit
Expand Down Expand Up @@ -408,6 +432,24 @@ export function getSlidesForTableRows(tableRows: TableCell[][] = [], tableProps:
let currCellIdx = 0
let emuLineMaxH = 0
let isDone = false

function flushCurrentRowToSlide(tableSlide: TableRowSlide, rowToAdd: TableRow) {
const tableHeaderRowsCount = (tableProps.addHeaderToEach || tableProps.autoPageRepeatHeader) && tableProps._arrObjTabHeadRows ? tableProps._arrObjTabHeadRows.length : 0
/*
* this fixed ISSUE#1231. When row span to auto created slides, first row doesn't have enough columns
* and thus table rows in auto generated slides don't align correctly
*/
if (tableSlide.rows.length === tableHeaderRowsCount) {
tableSlide.rows.push(rowToAdd)
} else {
const rowsToAdd = rowToAdd.filter((_, idx) => {
const activeSpan = activeRowSpans.get(idx)
return !(activeSpan && activeSpan.activeRowIndex < iRow)
})
tableSlide.rows.push(rowsToAdd)
}
}

while (!isDone) {
const srcCell: TableCell = rowCellLines[currCellIdx]
let tgtCell: TableCell = currTableRow[currCellIdx] // NOTE: may be redefined below (a new row may be created, thus changing this value)
Expand All @@ -427,7 +469,7 @@ export function getSlidesForTableRows(tableRows: TableCell[][] = [], tableProps:
}

// A: add current row slide or it will be lost (only if it has rows and text)
if (currTableRow.length > 0 && currTableRow.map(cell => cell.text.length).reduce((p, n) => p + n) > 0) newTableRowSlide.rows.push(currTableRow)
if (currTableRow.length > 0 && currTableRow.map(cell => cell.text.length).reduce((p, n) => p + n) > 0) flushCurrentRowToSlide(newTableRowSlide, currTableRow)

// B: add current slide to Slides array
tableRowSlides.push(newTableRowSlide)
Expand All @@ -438,7 +480,25 @@ export function getSlidesForTableRows(tableRows: TableCell[][] = [], tableProps:

// D: reset working/curr row
currTableRow = []
row.forEach(cell => currTableRow.push({ _type: SLIDE_OBJECT_TYPES.tablecell, text: [], options: cell.options }))
activeCellIndex = 0
for (let columnIndex = 0; columnIndex < numCols; ++columnIndex) {
const activeRowSpan = activeRowSpans.get(columnIndex)

const cell = activeRowSpan && activeRowSpan.activeRowIndex < iRow ? activeRowSpan.cell : row[activeCellIndex++]

currTableRow.push({
_type: SLIDE_OBJECT_TYPES.tablecell,
text: [],
options: {
...cell.options,
...(cell.options.rowspan
? {
rowspan: activeRowSpan.remaining,
}
: {}),
},
})
}

// E: Calc usable vertical space/table height now as we may still be in the same row and code above ("C: Calc usable vertical space/table height.") calc may now be invalid
calcSlideTabH()
Expand Down Expand Up @@ -477,18 +537,28 @@ export function getSlidesForTableRows(tableRows: TableCell[][] = [], tableProps:
}

// 5: increase table height by the curr line height (if we're on the last column)
if (currCellIdx === rowCellLines.length - 1) emuTabCurrH += emuLineMaxH
if (currCellIdx === numCols - 1) emuTabCurrH += emuLineMaxH

// 6: advance column/cell index (or circle back to first one to continue adding lines)
currCellIdx = currCellIdx < rowCellLines.length - 1 ? currCellIdx + 1 : 0
currCellIdx = currCellIdx < numCols - 1 ? currCellIdx + 1 : 0

// 7: done?
const brent = rowCellLines.map(cell => cell._lines.length).reduce((prev, next) => prev + next)
if (brent === 0) isDone = true
}

// F: Flush/capture row buffer before it resets at the top of this loop
if (currTableRow.length > 0) newTableRowSlide.rows.push(currTableRow)
if (currTableRow.length > 0) flushCurrentRowToSlide(newTableRowSlide, currTableRow)

// update activeRowSpans
const rowSpanColumns = Array.from(activeRowSpans.keys())
rowSpanColumns.forEach(columnIndex => {
const rowSpan = activeRowSpans.get(columnIndex)
rowSpan.remaining--
if (rowSpan.remaining === 0) {
activeRowSpans.delete(columnIndex)
}
})

if (tableProps.verbose) {
console.log(
Expand Down