Skip to content

Commit

Permalink
refactor createoutputfiles with promise functions
Browse files Browse the repository at this point in the history
  • Loading branch information
acestronautical committed Feb 22, 2024
1 parent e3009f0 commit 8c387bf
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 138 deletions.
247 changes: 112 additions & 135 deletions src/book.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ export class Book {
async createoutputfiles(isPreview) {
const previewFrame = document.getElementById('pdf');
previewFrame.style.display = 'none';
let resultPDF = null;
let previewPdf = null;

// create a directory named after the input pdf and fill it with
// the signatures
Expand All @@ -316,124 +316,126 @@ export class Book {
this.format == 'standardsig' ||
this.format == 'customsig'
) {
const generateAggregate = this.print_file != 'signatures';
const generateSignatures = this.print_file != 'aggregated';
const side1PageNumbers = new Set(
this.rearrangedpages.reduce((accumulator, currentValue) => {
const pageNums = currentValue[0].map((pageInfo) => pageInfo.info);
return accumulator.concat(pageNums);
}, [])
);
const [pdf0PageNumbers, pdf1PageNumbers] =
!generateAggregate || this.duplex
? [null, null]
: [
Array.from(Array(this.managedDoc.getPageCount()).keys()).map((p) => {
return side1PageNumbers.has(p) ? p : 'b';
}),
Array.from(Array(this.managedDoc.getPageCount()).keys()).map((p) => {
return !side1PageNumbers.has(p) ? p : 'b';
}),
];
const [aggregatePdf0, embeddedPages0] = generateAggregate
? await this.embedPagesInNewPdf(this.managedDoc, pdf0PageNumbers)
: [null, null];
const [aggregatePdf1, embeddedPages1] =
generateAggregate && !this.duplex
? await this.embedPagesInNewPdf(this.managedDoc, pdf1PageNumbers)
: [null, null];
const forLoop = async () => {
for (let i = 0; i < this.rearrangedpages.length; i++) {
const signature = this.rearrangedpages[i];
console.log(signature);
const sigName = `${this.filename}_signature${i}`;
const [sigFront, sigBack] = await this.createSignatures({
pageIndexDetails: signature,
id: generateSignatures ? `${this.filename}_signature${i}` : null,
isDuplex: this.duplex,
fileList: this.filelist,
// Only generate the first signature for preview
const pagesArr = isPreview ? this.rearrangedpages.slice(0, 1) : this.rearrangedpages;
const signatures = [{}];
const makeSignatures = async () => {
const tasks = pagesArr.map(async (pages, i) => {
console.log(pages);
signatures[i] = { name: `${this.filename}_signature${i}` };
[signatures[i].front, signatures[i].back] = await this.createSignatures({
pageIndexDetails: pages,
});
});
await Promise.all(tasks);
};
await makeSignatures();

// always duplex for preview
if (this.duplex || isPreview) {
const duplexSignatures = async () => {
const tasks = signatures.map(async (sig, i) => {
signatures[i].duplex = await interleavePages(sig.front, sig.back);
signatures[i].back = signatures[i].front = null;
});
await Promise.all(tasks);
};
await duplexSignatures();
previewPdf = signatures[0].duplex;
}

if (this.duplex) {
// collate
const sig = await interleavePages(sigFront, sigBack);

if (generateSignatures) {
await sig.save().then((pdfBytes) => {
this.zip.file(`signatures/${sigName}_duplex`, pdfBytes);
});
}
if (this.print_file != 'aggregated' && !isPreview) {
const saveSignatures = async () => {
const tasks = signatures.map(async (sig) => {
await sig.front?.save().then((pdfBytes) => {
this.zip.file(`signatures/${sig.name}_side1.pdf`, pdfBytes);
});
await sig.back?.save().then((pdfBytes) => {
this.zip.file(`signatures/${sig.name}_side2.pdf`, pdfBytes);
});
await sig.duplex?.save().then((pdfBytes) => {
this.zip.file(`signatures/${sig.name}_duplex.pdf`, pdfBytes);
});
});
await Promise.all(tasks);
};
await saveSignatures();
}

if (generateAggregate) {
const copiedPages = await aggregatePdf0.copyPages(sig, sig.getPageIndices());
copiedPages.forEach((page) => aggregatePdf0.addPage(page));
}
} else {
if (generateSignatures) {
await sigFront.save().then((pdfBytes) => {
this.zip.file(`signatures/${sigName}_side1`, pdfBytes);
});
await sigBack.save().then((pdfBytes) => {
this.zip.file(`signatures/${sigName}_side2`, pdfBytes);
});
if (this.print_file != 'signatures' && !isPreview) {
const saveAggregate = async () => {
const aggregate = {
front: !this.duplex ? await PDFDocument.create() : null,
back: !this.duplex ? await PDFDocument.create() : null,
duplex: this.duplex ? await PDFDocument.create() : null,
};
for (const sig of signatures) {
// Adding pages to aggregate PDFs has to be done in order, not with promises
if (aggregate.front) {
const copiedPages = await aggregate.front.copyPages(
sig.front,
sig.front.getPageIndices()
);
copiedPages.forEach((page) => aggregate.front.addPage(page));
}

if (generateAggregate) {
const copiedPagesFront = await aggregatePdf0.copyPages(
sigFront,
sigFront.getPageIndices()
if (aggregate.back) {
const copiedPages = await aggregate.back.copyPages(
sig.back,
sig.back.getPageIndices()
);
copiedPagesFront.forEach((page) => aggregatePdf0.addPage(page));

const copiedPagesBack = await aggregatePdf1.copyPages(
sigBack,
sigBack.getPageIndices()
copiedPages.forEach((page) => aggregate.back.addPage(page));
}
if (aggregate.duplex) {
const copiedPages = await aggregate.duplex.copyPages(
sig.duplex,
sig.duplex.getPageIndices()
);
copiedPagesBack.forEach((page) => aggregatePdf1.addPage(page));
copiedPages.forEach((page) => aggregate.duplex.addPage(page));
}
}
}
};
await forLoop();

if (aggregatePdf1 != null) {
await aggregatePdf1.save().then((pdfBytes) => {
if (!isPreview) this.zip.file(`${this.filename}_typeset_side2.pdf`, pdfBytes);
});
}
if (aggregatePdf0 != null) {
await aggregatePdf0.save().then((pdfBytes) => {
if (!isPreview)
this.zip.file(
this.duplex ? `${this.filename}_typeset.pdf` : `${this.filename}_typeset_side1.pdf`,
pdfBytes
);
});
if (aggregate.front) {
await aggregate.front.save().then((pdfBytes) => {
this.zip.file(`${this.filename}_typeset_side1.pdf`, pdfBytes);
});
}
if (aggregate.back) {
await aggregate.back.save().then((pdfBytes) => {
this.zip.file(`${this.filename}_typeset_side2.pdf`, pdfBytes);
});
}
if (aggregate.duplex) {
await aggregate.duplex.save().then((pdfBytes) => {
this.zip.file(`${this.filename}_typeset.pdf`, pdfBytes);
});
}
};
await saveAggregate();
}

var rotationMetaInfo =
(this.paper_rotation_90 ? 'paper_rotated' : '') +
(this.source_rotation == 'none' ? '' : `_${this.source_rotation}`);
this.filename = `${origFileName}${rotationMetaInfo}`;
} else if (this.format == 'a9_3_3_4') {
resultPDF = await this.buildSheets(this.filename, this.book.a9_3_3_4_builder());
previewPdf = await this.buildSheets(this.filename, this.book.a9_3_3_4_builder());
} else if (this.format == 'a10_6_10s') {
resultPDF = await this.buildSheets(this.filename, this.book.a10_6_10s_builder());
previewPdf = await this.buildSheets(this.filename, this.book.a10_6_10s_builder());
} else if (this.format == 'a_4_8s') {
resultPDF = await this.buildSheets(this.filename, this.book.a_4_8s_builder());
previewPdf = await this.buildSheets(this.filename, this.book.a_4_8s_builder());
} else if (this.format == 'a_3_6s') {
resultPDF = await this.buildSheets(this.filename, this.book.a_3_6s_builder());
previewPdf = await this.buildSheets(this.filename, this.book.a_3_6s_builder());
} else if (this.format == 'A7_2_16s') {
resultPDF = await this.buildSheets(this.filename, this.book.a7_2_16s_builder());
previewPdf = await this.buildSheets(this.filename, this.book.a7_2_16s_builder());
} else if (this.format == '1_3rd') {
resultPDF = await this.buildSheets(this.filename, this.book.page_1_3rd_builder());
previewPdf = await this.buildSheets(this.filename, this.book.page_1_3rd_builder());
} else if (this.format == '8_zine') {
resultPDF = await this.buildSheets(this.filename, this.book.page_8_zine_builder());
previewPdf = await this.buildSheets(this.filename, this.book.page_8_zine_builder());
}
console.log('Attempting to generate preview for ', resultPDF);
console.log('Attempting to generate preview for ', previewPdf);

if (resultPDF != null) {
const pdfDataUri = await resultPDF.saveAsBase64({ dataUri: true });
const viewerPrefs = resultPDF.catalog.getOrCreateViewerPreferences();
if (previewPdf != null) {
const pdfDataUri = await previewPdf.saveAsBase64({ dataUri: true });
const viewerPrefs = previewPdf.catalog.getOrCreateViewerPreferences();
viewerPrefs.setHideToolbar(false);
viewerPrefs.setHideMenubar(false);
viewerPrefs.setHideWindowUI(false);
Expand Down Expand Up @@ -508,11 +510,7 @@ export class Book {
block_end += offset;
}

if (printSignatures) {
await outPDF.save().then((pdfBytes) => {
this.zip.file(`signatures/${config.outname}`, pdfBytes);
});
}
return outPDF;
}
/**
*
Expand Down Expand Up @@ -588,42 +586,21 @@ export class Book {
* PDF builder base function for Classic (non-Wacky) layouts. Called by [createoutputfiles]
*
* @param {Object} config
* @param {PageInfo[][]|PageInfo[]} config.pageIndexDetails : a nested list of objects.
* @param config.embeddedPages : list of lists of embedded pages from source document ( [0] for duplex & front, [1] for backs -- value is null if no aggregate printing enabled)
* @param {string} config.id : string dentifier for signature file name (null if no signature files to be generated)
* @param {boolean} config.isDuplex : boolean
* @param {string[]} config.fileList : list of filenames for sig filename to be added to (modifies list)
* @param {PageInfo[][]} config.pageIndexDetails : a nested list of objects.
*/
async createSignatures(config) {
const pages = config.pageIndexDetails;
// duplex printers print both sides of the sheet,
if (config.isDuplex) {
const outduplex = printSignatures ? `${config.id}_duplex.pdf` : null;
await this.writepages({
outname: outduplex,
pageList: pages[0],
back: false,
alt: true,
});
config.fileList[config.index] = outduplex;
} else {
// for non-duplex printers we have two files, print the first, flip
// the sheets over, then print the second
const outname1 = printSignatures ? `${config.id}_side1.pdf` : null;
const outname2 = printSignatures ? `${config.id}_side2.pdf` : null;

await this.writepages({
outname: outname1,
pageList: pages[0],
back: false,
alt: false,
});
const pdfBack = await this.writepages({
pageList: pages[1],
back: true,
alt: false,
});
return [pdfFront, pdfBack];
const pdfFront = await this.writepages({
pageList: pages[0],
back: false,
alt: false,
});
const pdfBack = await this.writepages({
pageList: pages[1],
back: true,
alt: false,
});
return [pdfFront, pdfBack];
}

bundleSettings() {
Expand Down
13 changes: 10 additions & 3 deletions src/utils/pdf.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,21 @@ import { PDFDocument } from 'pdf-lib';
export async function interleavePages(pdfA, pdfB) {
const mergedPdf = await PDFDocument.create();
const pageCount = Math.max(pdfA.getPageCount(), pdfB.getPageCount());
const promises = [];

for (let i = 0; i < pageCount; i++) {
const pageA = pdfA.getPage(i);
if (pageA) mergedPdf.addPage((await mergedPdf.copyPages(pdfA, [i]))[0]);
const pageAPromise = pdfA.getPage(i);
const pageBPromise = pdfB.getPage(i);

promises.push(pageAPromise, pageBPromise);

const pageB = pdfB.getPage(i);
const [pageA, pageB] = await Promise.all([pageAPromise, pageBPromise]);

if (pageA) mergedPdf.addPage((await mergedPdf.copyPages(pdfA, [i]))[0]);
if (pageB) mergedPdf.addPage((await mergedPdf.copyPages(pdfB, [i]))[0]);
}

await Promise.all(promises); // Wait for all page retrieval promises to resolve
return mergedPdf;
}

Expand Down

0 comments on commit 8c387bf

Please sign in to comment.