Skip to content

Instantly share code, notes, and snippets.

@cuibonobo
Last active December 23, 2020 18:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cuibonobo/69d063f9a9a412dd8cf1a925c444ef14 to your computer and use it in GitHub Desktop.
Save cuibonobo/69d063f9a9a412dd8cf1a925c444ef14 to your computer and use it in GitHub Desktop.
Change the order of the pages in a PDF to create a booklet using mutool.
/*
Usage:
mutool run booklet.js input.pdf output.pdf
*/
function copyPage(dstDoc, srcDoc, pageNumber, graftMap) {
var srcPage = srcDoc.findPage(pageNumber - 1);
var dstPage = dstDoc.newDictionary();
dstPage.Type = dstDoc.newName("Page");
if (srcPage.MediaBox){
dstPage.MediaBox = graftMap.graftObject(srcPage.MediaBox);
}
if (srcPage.Rotate){
dstPage.Rotate = graftMap.graftObject(srcPage.Rotate);
}
if (srcPage.Resources){
dstPage.Resources = graftMap.graftObject(srcPage.Resources);
}
if (srcPage.Contents){
dstPage.Contents = graftMap.graftObject(srcPage.Contents);
}
dstDoc.insertPage(-1, dstDoc.addObject(dstPage));
}
function getPageOrder(outputLength) {
var outputPages = [];
for (var i = 0; i < outputLength; i++) {
if (outputPages.indexOf(i + 1) >= 0) {
break;
}
if (i % 2 == 0) {
outputPages.push(outputLength - i);
outputPages.push(i + 1);
} else {
outputPages.push(i + 1);
outputPages.push(outputLength - i);
}
}
return outputPages;
};
function getBookLength(srcDoc) {
var inputPages = srcDoc.countPages();
var outputSheets = Math.floor(inputPages / 4);
var outputMod = inputPages % 4;
if (outputMod != 0) {
outputSheets += 1;
}
return outputSheets * 4;
};
function padPages(srcDoc, desiredLength) {
var examplePage = srcDoc.loadPage(0);
var inputPages = srcDoc.countPages();
if (inputPages < desiredLength) {
var padLength = desiredLength - inputPages;
var blankPage = srcDoc.addPage(examplePage.bound(), 0, null, null);
for (var i = 0; i < padLength; i++) {
srcDoc.insertPage(-1, blankPage);
}
}
return srcDoc;
};
function createBooklet() {
var inputFile = scriptArgs[0];
var outputFile = scriptArgs[1];
var inputDoc = new PDFDocument(inputFile);
var outputDoc = new PDFDocument();
var bookLength = getBookLength(inputDoc);
var outputPages = getPageOrder(bookLength);
inputDoc = padPages(inputDoc, bookLength);
var graftMap = outputDoc.newGraftMap();
for (var i = 0; i < outputPages.length; i++) {
copyPage(outputDoc, inputDoc, outputPages[i], graftMap);
}
outputDoc.save(outputFile);
};
if (scriptArgs.length < 2) {
print("usage: mutool run booklet.js input.pdf output.pdf");
} else {
createBooklet();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment