import { PDFDocument, PDFPage } from 'pdf-lib'; export async function organizePages( snapshot: string | Uint8Array | ArrayBuffer, operation: "CUSTOM_PAGE_ORDER" | "REVERSE_ORDER" | "DUPLEX_SORT" | "BOOKLET_SORT" | "ODD_EVEN_SPLIT" | "REMOVE_FIRST" | "REMOVE_LAST" | "REMOVE_FIRST_AND_LAST", customOrderString: string): Promise { const pdfDoc = await PDFDocument.load(snapshot); let subDocument = await PDFDocument.create(); const copiedPages = await subDocument.copyPages(pdfDoc, pdfDoc.getPageIndices()); const pageCount = pdfDoc.getPages().length; switch (operation) { case "CUSTOM_PAGE_ORDER": console.log("Custom Order"); const pageOrderArray = parseCustomPageOrder(customOrderString, pageCount); console.log(pageOrderArray); const customOrderedPages = pageOrderArray.map((pageIndex) => copiedPages[pageIndex]); customOrderedPages.forEach((page) => subDocument.addPage(page)); break; case "REVERSE_ORDER": const reversedPages: PDFPage[] = []; for (let i = pageCount - 1; i >= 0; i--) { reversedPages.push(copiedPages[i]); } reversedPages.forEach((page) => subDocument.addPage(page)); break; case 'DUPLEX_SORT': //TODO: Needs to be checked by someone who knows more about duplex printing. const duplexPages: PDFPage[] = []; const half = (pageCount + 1) / 2 for (let i = 1; i <= half; i++) { duplexPages.push(copiedPages[i - 1]); if (i <= pageCount - half) { duplexPages.push(copiedPages[pageCount - i]); } } duplexPages.forEach((page) => subDocument.addPage(page)); break; case 'BOOKLET_SORT': const bookletPages: PDFPage[] = []; for (let i = 0; i < pageCount / 2; i++) { bookletPages.push(copiedPages[i]); bookletPages.push(copiedPages[pageCount - i - 1]); } bookletPages.forEach((page) => subDocument.addPage(page)); break; case 'ODD_EVEN_SPLIT': const oddPages: PDFPage[] = []; const evenPages: PDFPage[] = []; for (let i = 0; i < pageCount; i++) { if (i % 2 === 0) { evenPages.push(copiedPages[i]); } else { oddPages.push(copiedPages[i]); } } oddPages.forEach((page) => subDocument.addPage(page)); evenPages.forEach((page) => subDocument.addPage(page)); break; case 'REMOVE_FIRST': pdfDoc.removePage(0); subDocument = pdfDoc; break; case 'REMOVE_LAST': pdfDoc.removePage(pageCount - 1); subDocument = pdfDoc; break; case 'REMOVE_FIRST_AND_LAST': pdfDoc.removePage(0); pdfDoc.removePage(pageCount - 2); subDocument = pdfDoc; break; default: throw new Error("Operation not supported"); break; } return subDocument.save(); }; function parseCustomPageOrder(customOrder: string, pageCount: number) { const pageOrderArray: number[] = []; const ranges = customOrder.split(','); ranges.forEach((range) => { if (range.includes('-')) { const [start, end] = range.split('-').map(Number); for (let i = start; i <= end; i++) { pageOrderArray.push(i - 1); } } else if (range.includes('n')) { const [even, odd] = range.split('n').map(Number); for (let i = 1; i <= pageCount; i++) { if (i % 2 === 0) { pageOrderArray.push((i * even) - 1); } else { pageOrderArray.push((i * odd) - 1); } } } else { pageOrderArray.push(Number(range) - 1); } }); return pageOrderArray; }