Shepherd School of Music Programs

Convert print formatted InDesign files to view-able PDFs 

The Shepherd School of Music was in need of a solution to change large batches of working InDesign files to easily view-able PDFs. The original InDesign files were designed to be printed, folded and stapled as program literature for concerts. In order to create an electronic version the user would have to open the InDesign file, re-format the content, re-order the pages and export to PDF. This is very time consuming and because there are hundreds of new programs every semester, an automated process is needed. An Adobe extendscript written in Javascript was used to speed things up.

The InDesign file was originally formatted as 2 letter sized pages with content on either side. The InDesign file is duplex printed as a single sheet of paper with ink on the front and back. The duplex print is then folded over into a bi-fold program. Below is the printed and folded single sheet of paper:

The Before image is the original InDesign file. Notice the pink highlights signifying missing fonts. The After is the result of the batch script:

If you do not have the scripts installed, copy and paste the complete script located later in this post and save it with the above name + .jsx under C:\Program Files\Adobe\Adobe InDesign CC 2017\Scripts\Scripts Panel\Samples\JavaScript. To use the script, open InDesign. Click Windows>Utilities>Scripts. Under Application>Javascript you will find “Shepherd_School_Bifold” and “Shepherd_School_Tri” scripts. Double click the appropriate script, type in the desired file prefix for new files, check options and then choose the folder containing all of your Bi-fold or Tri-fold files. Avoid clicking cancel. If script is cancelled before executing, options and file prefixes will be undefined.

The conversion presented a challenge because the InDesign file is only 2 pages yet the program is comprised of 4 separate sections (6 for Tri-fold). The solution was to duplicate each of the 2 InDesign pages to 4 total pages and then resize the width of each page from a relative anchor point. Below are the steps:

Bi-fold Duplicate Pages:
Duplicates every page

function duplicateSpreads(){
    app.activeWindow.zoom(ZoomOptions.FIT_PAGE);
    var myDocument = app.activeDocument;
    var Length = app.activeDocument.pages.length;
    //loop through pages and duplicate
for(myCounter = 0; myCounter<Length; myCounter ++){
    //page to be duplicated, the *2 multiplier will skip the already duplicated page
    var pageToDup = app.activeDocument.pages[myCounter*2];
    //sets active page
    app.activeWindow.activePage = myDocument.pages.item(myCounter*2);
    //duplicate page at a location after itself
    pageToDup.duplicate (LocationOptions.AFTER, app.layoutWindows[0].activePage);
 }
}

Result:

 

Bi-fold Resize Pages:

Half the width of each page from an anchor point to the left or right depending on page number. A portion of this code was taken from one of Adobe’s example scripts AdjustLayout.jsx installed with InDesign

function changePageSize(){
 for(myCounter = 0; myCounter<app.activeDocument.pages.length; myCounter++){
 var myDocument = app.activeDocument;
 var myPages = myDocument.pages;
 if(myCounter % 2 == 0){
 //Page is an even page. The page's width will be cut in half to exclude the right side
 myPages.item(myCounter).resize(CoordinateSpaces.INNER_COORDINATES,
 AnchorPoint.LEFT_CENTER_ANCHOR,
 ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY,
 [.5, 1]);
 }
 else{
 //Page is an odd page. The page's width will be cut in half to exclude the left side
 myPages.item(myCounter).resize(CoordinateSpaces.INNER_COORDINATES,
 AnchorPoint.RIGHT_CENTER_ANCHOR,
 ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY,
 [.5,1]);
 }
 }
}

Result:

 

Reorder Pages:

Move the final page to be the first page.

function reOrderPages(){
    //get final page
    var LengthMinusOne = (app.activeDocument.pages.length) - 1;
    //move final page before first page
    app.activeDocument.pages[LengthMinusOne].move(LocationOptions.BEFORE, app.activeDocument.pages[0]);  
}

Result:

 

Remove Empty Pages:

Delete pages that contain no items.

function delEmptyPages(){
       var myDocument = app.activeDocument;
       var myPages = myDocument.pages;  
    for(myCounter = 0; myCounter<app.activeDocument.pages.length; myCounter++){  
        if(myPages[myCounter].pageItems.length==0){  
            myPages[myCounter].remove();  
            }  
        }  
}

Result:

Save to PDF and an optional InDesign file:

Lastly, to save a lightweight pdf and the option of saving the newly edited InDesign file as a separate file:

 

var myFolder = Folder.selectDialog("Select Indesign Folder");  
var myIndsnFiles = myFolder.getFiles("*.indd");  
var PDFfolderLocation = myFolder + "/PDF";
var editINDfloderLocation = myFolder + "/Edited_InDesign_Files";
//create a PDF folder 
var pdfFolder = new Folder(PDFfolderLocation);
    if (!pdfFolder.exists)
        pdfFolder.create();
//if save InDesign option was chosen, create Indesign Folder
if (saveInDesOption == true){
        var InDFolder = new Folder(editINDfloderLocation);
        if (!InDFolder.exists)
            InDFolder.create();     
            }
//main portion of script, loop through batch of original files, execute functions and save new result
for(myCounter=0; myCounter<myIndsnFiles.length; myCounter++)  
{  
    app.open(myIndsnFiles[myCounter]); 
    replaceMissFont();
    duplicateSpreads();
    changePageSize();
    reOrderPages();
    delEmptyPages();
    var docName = app.activeDocument.name;
    var docNamePDF = (app.activeDocument.name.replace(".indd",".pdf"));
    //edited InDesign file name  
    var newName = editINDfloderLocation + "/" + myPrefix + docName;
    //final pdf file name
    var newPDFName = PDFfolderLocation + "/" + myPrefix + docNamePDF;
    //save PDF
    app.activeDocument.exportFile(ExportFormat.pdfType, File(newPDFName),false);
    //if InDesign file option chose, save new .indd file
    if (saveInDesOption == true){
        app.activeDocument.save(new File(newName));
        }
    app.activeDocument.close();  
    }  

Result:

Notice the correct fonts and the single pages


 

The entire Bi-fold Script

Below is the entire script. The first portion is the dialog box UI and later a function to replace a missing font. The font name is hard coded so that function is not useful outside of this project.

 

    //dialog box UI
    var myLabelWidth = 100;
	var myDialog = app.dialogs.add({name:"BiFold"});
	with(myDialog){
		with(dialogColumns.add()){
			with(borderPanels.add()){
				staticTexts.add({staticLabel:"Document Details:"});
				with(dialogColumns.add()){					
                        var saveInDesCheckbox = checkboxControls.add({staticLabel:"Save edited Indesign Files", checkedState:false});
				}
			}
			with(borderPanels.add()){
				with(dialogColumns.add()){
					with(dialogRows.add()){
						with(dialogColumns.add()){
							staticTexts.add({staticLabel:"File Prefix:", minWidth:myLabelWidth});
						}
						with(dialogColumns.add()){
							var myPrefixEntry = textEditboxes.add({editContents:"000edit", minWidth:180});
						}
					}
                }
            }
            }
        }
	myReturn = myDialog.show();
	if (myReturn == true){
		//Get control values from the dialog box.
         var saveInDesOption = saveInDesCheckbox.checkedState;
		var myPrefix = myPrefixEntry.editContents;
		//Remove the dialog box from memory.
		myDialog.destroy();
	}
	else{
		//Remove the dialog box from memory.
		myDialog.destroy();
	}
//turn off user interaction so InDesign warnings don't interrupt script
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
function  replaceMissFont(){
app.findTextPreferences = NothingEnum.nothing;
app.changeTextPreferences = NothingEnum.nothing;
app.findTextPreferences.appliedFont = "Times New Roman PS";
app.changeTextPreferences.appliedFont = "Times New Roman";
app.activeDocument.changeText();
}
function duplicateSpreads(){
    app.activeWindow.zoom(ZoomOptions.FIT_PAGE);
   var myDocument = app.activeDocument;
   var Length = app.activeDocument.pages.length;
for(myCounter = 0; myCounter<Length; myCounter ++){
    var pageToDup = app.activeDocument.pages[myCounter*2];
    app.activeWindow.activePage = myDocument.pages.item(myCounter*2);
    pageToDup.duplicate (LocationOptions.AFTER, app.layoutWindows[0].activePage);
 }
}

function changePageSize(){
 for(myCounter = 0; myCounter<app.activeDocument.pages.length; myCounter++){
        var myDocument = app.activeDocument;
        var myPages = myDocument.pages;
        if(myCounter % 2 == 0){
            //Page is an even page.
            myPages.item(myCounter).resize(CoordinateSpaces.INNER_COORDINATES,
            AnchorPoint.LEFT_CENTER_ANCHOR,
            ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY,
            [.5, 1]);
        }
        else{
            //Page is an odd page.
            myPages.item(myCounter).resize(CoordinateSpaces.INNER_COORDINATES,
            AnchorPoint.RIGHT_CENTER_ANCHOR,
            ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY,
            [.5,1]);
        }
    }
}

function reOrderPages(){
    var LengthMinusOne = (app.activeDocument.pages.length) - 1;
    app.activeDocument.pages[LengthMinusOne].move(LocationOptions.BEFORE, app.activeDocument.pages[0]);  
}
function delEmptyPages(){
       var myDocument = app.activeDocument;
       var myPages = myDocument.pages;  
    for(myCounter = 0; myCounter<app.activeDocument.pages.length; myCounter++){  
        if(myPages[myCounter].pageItems.length==0){  
            myPages[myCounter].remove();  
            }  
        }  
}
var myFolder = Folder.selectDialog("Select Indesign Folder");  
var myIndsnFiles = myFolder.getFiles("*.indd");  
var PDFfolderLocation = myFolder + "/PDF";
var editINDfloderLocation = myFolder + "/Edited_InDesign_Files";
var pdfFolder = new Folder(PDFfolderLocation);
    if (!pdfFolder.exists)
        pdfFolder.create();
if (saveInDesOption == true){
        var InDFolder = new Folder(editINDfloderLocation);
        if (!InDFolder.exists)
            InDFolder.create();     
            }
for(finalCounter=0; finalCounter<myIndsnFiles.length; finalCounter++)  
{  
    app.open(myIndsnFiles[finalCounter]); 
    replaceMissFont();
    duplicateSpreads();
    changePageSize();
    reOrderPages();
    delEmptyPages();
    var docName = app.activeDocument.name;
    var docNamePDF = (app.activeDocument.name.replace(".indd",".pdf"));  
    var newName = editINDfloderLocation + "/" + myPrefix + docName;
    var newPDFName = PDFfolderLocation + "/" + myPrefix + docNamePDF;
    app.activeDocument.exportFile(ExportFormat.pdfType, File(newPDFName),false);
    if (saveInDesOption == true){
        app.activeDocument.save(new File(newName));
        }
    app.activeDocument.close();  
    }  
 app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;

TriFold script

Original InDesign File:

Result after script:

The Trifold script makes use of % modulus operator to determine every first, second and third page for the resize page function. There is also a checkbox in the initial dialog box that provides the option of moving an “Acknowledgements” page directly after the cover page. Below are some of the major differences:

Tri-fold Duplicate Pages function:

Duplicate pages.

function duplicateSpreads(){
    app.activeWindow.zoom(ZoomOptions.FIT_PAGE);
   var myDocument = app.activeDocument;
   var Length = app.activeDocument.pages.length;
for(myCounter = 0; myCounter<Length; myCounter ++){
    var pageToDup = app.activeDocument.pages[myCounter*3];
    app.activeWindow.activePage = myDocument.pages.item(myCounter*3);
    pageToDup.duplicate (LocationOptions.AFTER, app.layoutWindows[0].activePage);
    pageToDup.duplicate (LocationOptions.AFTER, app.layoutWindows[0].activePage);
 }
}

Tri-fold Resize Pages function:

Shorten width to 1/3rd width of each page from an anchor point to the left, right or center depending on page number.

function changePageSize(){
 for(myCounter = 0; myCounter<app.activeDocument.pages.length; myCounter++){
        var myDocument = app.activeDocument;
        var myPages = myDocument.pages;
        if(myCounter % 3 == 0){
            //Page is divisable by 3.
            myPages.item(myCounter).resize(CoordinateSpaces.INNER_COORDINATES,
            AnchorPoint.LEFT_CENTER_ANCHOR,
            ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY,
            [.33, 1]);
        }
        else if(myCounter % 3 == 1){
            //Page has remainder of 1 after dividing by 3.
            myPages.item(myCounter).resize(CoordinateSpaces.INNER_COORDINATES,
            AnchorPoint.CENTER_ANCHOR,
            ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY,
            [.33,1]);
        }
        else if(myCounter % 3 == 2){
            //Page has remainder of 2 after dividing by 3.
            myPages.item(myCounter).resize(CoordinateSpaces.INNER_COORDINATES,
            AnchorPoint.RIGHT_CENTER_ANCHOR,
            ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY,
            [.33,1]);
        }
    }
}

Lastly, a couple of lines to move the Acknowledgements page directly after the title page:

In a tri-fold, after the viewer opens the cover, the next page immediately in view is the back side of the program folded in. A typical case is an “Acknowledgements”  page which the view see after opening. This needs to be the second page of the PDF version.

function moveAknowledgePage(){
    var LengthMinusTwo = (app.activeDocument.pages.length) - 2;
    app.activeDocument.pages[LengthMinusTwo].move(LocationOptions.AFTER, app.activeDocument.pages[0]);  
}

Below is the entire Tri-fold script:

 var myLabelWidth = 100;
 var myDialog = app.dialogs.add({name:"TriFold"});
 with(myDialog){
 with(dialogColumns.add()){
 with(borderPanels.add()){
 staticTexts.add({staticLabel:"Document Details:"});
 with(dialogColumns.add()){ 
 var AknowCheckbox = checkboxControls.add({staticLabel:"Aknowledgements Page", checkedState:false});
 var saveInDesCheckbox = checkboxControls.add({staticLabel:"Save edited Indesign Files", checkedState:false});
 }
 }
 with(borderPanels.add()){
 with(dialogColumns.add()){
 with(dialogRows.add()){
 with(dialogColumns.add()){
 staticTexts.add({staticLabel:"File Prefix:", minWidth:myLabelWidth});
 }
 with(dialogColumns.add()){
 var myPrefixEntry = textEditboxes.add({editContents:"000edit", minWidth:180});
 }
 }
 }
 }
 }
 }
 myReturn = myDialog.show();
 if (myReturn == true){
 //Get control values from the dialog box.
 var myAknow = AknowCheckbox.checkedState;
 var saveInDesOption = saveInDesCheckbox.checkedState;
 var myPrefix = myPrefixEntry.editContents;
 //Remove the dialog box from memory.
 myDialog.destroy();
 }
 else{
 //Remove the dialog box from memory.
 myDialog.destroy();
 }

app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
function replaceMissFont(){
app.findTextPreferences = NothingEnum.nothing;
app.changeTextPreferences = NothingEnum.nothing;
app.findTextPreferences.appliedFont = "Times New Roman PS";
app.changeTextPreferences.appliedFont = "Times New Roman";
app.activeDocument.changeText();
}
function duplicateSpreads(){
 app.activeWindow.zoom(ZoomOptions.FIT_PAGE);
 var myDocument = app.activeDocument;
 var Length = app.activeDocument.pages.length;
for(myCounter = 0; myCounter < Length; myCounter ++){
 var pageToDup = app.activeDocument.pages[myCounter*3];
 app.activeWindow.activePage = myDocument.pages.item(myCounter*3);
 pageToDup.duplicate (LocationOptions.AFTER, app.layoutWindows[0].activePage);
 pageToDup.duplicate (LocationOptions.AFTER, app.layoutWindows[0].activePage);
 }
}

function changePageSize(){
 for(myCounter = 0; myCounter <app.activeDocument.pages.length; myCounter++){
 var myDocument = app.activeDocument;
 var myPages = myDocument.pages;
 if(myCounter % 3 == 0){
 //Page is divisable by 3.
 myPages.item(myCounter).resize(CoordinateSpaces.INNER_COORDINATES,
 AnchorPoint.LEFT_CENTER_ANCHOR,
 ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY,
 [.33, 1]);
 }
 else if(myCounter % 3 == 1){
 //Page has remainder of 1 after dividing by 3.
 myPages.item(myCounter).resize(CoordinateSpaces.INNER_COORDINATES,
 AnchorPoint.CENTER_ANCHOR,
 ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY,
 [.33,1]);
 }
 else if(myCounter % 3 == 2){
 //Page has remainder of 2 after dividing by 3.
 myPages.item(myCounter).resize(CoordinateSpaces.INNER_COORDINATES,
 AnchorPoint.RIGHT_CENTER_ANCHOR,
 ResizeMethods.MULTIPLYING_CURRENT_DIMENSIONS_BY,
 [.33,1]);
 }
 }
}

function reOrderPages(){
 var LengthMinusOne = (app.activeDocument.pages.length) - 1;
 app.activeDocument.pages[LengthMinusOne].move(LocationOptions.BEFORE, app.activeDocument.pages[0]); 
}
function moveAknowledgePage(){
 var LengthMinusTwo = (app.activeDocument.pages.length) - 2;
 app.activeDocument.pages[LengthMinusTwo].move(LocationOptions.AFTER, app.activeDocument.pages[0]); 
}
function delEmptyPages(){
 var myDocument = app.activeDocument;
 var myPages = myDocument.pages; 
 for(myCounter = 0; myCounter <app.activeDocument.pages.length; myCounter++){ 
 if(myPages[myCounter].pageItems.length==0){ 
 myPages[myCounter].remove(); 
 } 
 } 
}
var myFolder = Folder.selectDialog("Select Indesign Folder"); 
var myIndsnFiles = myFolder.getFiles("*.indd"); 
var PDFfolderLocation = myFolder + "/PDF";
var editINDfloderLocation = myFolder + "/Edited_InDesign_Files";
var pdfFolder = new Folder(PDFfolderLocation);
 if (!pdfFolder.exists)
 pdfFolder.create();
if (saveInDesOption == true){
 var InDFolder = new Folder(editINDfloderLocation);
 if (!InDFolder.exists)
 InDFolder.create(); 
 }
for(finalCounter=0; finalCounter<myIndsnFiles.length; finalCounter++) 
{ 
 app.open(myIndsnFiles[finalCounter]); 
 replaceMissFont();
 duplicateSpreads();
 changePageSize();
 reOrderPages();
 if (myAknow == true){
 moveAknowledgePage();
 }
 delEmptyPages();
 var docName = app.activeDocument.name;
 var docNamePDF = (app.activeDocument.name.replace(".indd",".pdf")); 
 var newName = editINDfloderLocation + "/" + myPrefix + docName;
 var newPDFName = PDFfolderLocation + "/" + myPrefix + docNamePDF;
 app.activeDocument.exportFile(ExportFormat.pdfType, File(newPDFName),false);
 if (saveInDesOption == true){
 app.activeDocument.save(new File(newName));
 }
 app.activeDocument.close(); 
 } 
 app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;

Issues and Improvements:

If the script is canceled before executing, the options and file name prefix dialog will be lost. This may have something to do with not wrapping the dialog box portion of the script in a function or some kind of scope issue. Restarting InDesign will get this dialog back.

For any DMC student assistant: Currently the duplicated content of the edited InDesign remains, making the file nearly 2x the size for Bifold and 3x the size for Trifold. I’m sure there is a way for InDesign to detect items outside of the pasteboard for deletion. I will leave this open for a DMCer to implement a solution.

The Remove Pages function does not delete every page on some tri-fold inDesign files. This one is a mystery.