Copy link to clipboard
Copied
I'm working on a script that would make it impossible to export a PDF unless there are no preflight errors.
I've done this by creating a startup script that has an eventlistener that will run the script after the export option has been chosen, but before the export save dialog begins. The script works in two ways: if preflight is off, an alert pops up saying "turn it on". If preflight is on, it determines if there are 0 errors, and if so, proceeds to export... if not, displays an error.
The code is here:
#targetengine "session"
main();
function main(){
var beforeExport = app.menuActions.itemByName ( "$ID/Export..." ).addEventListener ( "beforeInvoke", checkJob );
function checkJob(myEvent){
if(app.activeDocument.preflightOptions.preflightOff == true){
alert('Hey, turn your preflight on!');
exit(0);
}else{
var my_profile = app.preflightProfiles.firstItem();
var my_process = app.preflightProcesses.add(app.activeDocument, my_profile);
my_process.waitForProcess();
results = my_process.processResults;
var myTest = results.indexOf("None");
if (myTest == 0)
{
//alert ("No errors found");
}
else
{
alert ("Errors found");
}
};
}
}
However, there are two improvements I'm struggling to make and I'm looking for suggestions:
1) After an alert (meaning preflight wasn't on or it wasn't free of errors) I'd like the export dialog to stop completely, but at the moment the error dialogs will appear but the export continues on regardless. Is there a way to do this?
2) The variable "my_profile" I'm having trouble assigning it to the profile that is selected by the end-user. I've tried selectedIndex and been through the list here InDesign ExtendScript API (12.0) but can't seem to get the end-user selected profile. The one I settled on for the above script was the first item that shows up in the end-user list.
Can anyone suggest any solutions or workarounds that may assist me with this script?
Many thanks
Colin
...#targetengine "onExport"
main();
function main(){
var beforeExport = app.menuActions.itemByName ( "$ID/Export..." ).addEventListener ( "beforeInvoke", checkJob );
function checkJob(myEvent){
if(app.activeDocument.preflightOptions.preflightOff == true){
alert('Hey, turn your preflight on!');
myEvent.preventDefault();
myEvent.stopPropagation();
exit(0);
}else{
var my_profile = app.preflightProfiles.firstItem();
var my_process = app.preflightProcess
Copy link to clipboard
Copied
#targetengine "onExport"
main();
function main(){
var beforeExport = app.menuActions.itemByName ( "$ID/Export..." ).addEventListener ( "beforeInvoke", checkJob );
function checkJob(myEvent){
if(app.activeDocument.preflightOptions.preflightOff == true){
alert('Hey, turn your preflight on!');
myEvent.preventDefault();
myEvent.stopPropagation();
exit(0);
}else{
var my_profile = app.preflightProfiles.firstItem();
var my_process = app.preflightProcesses.add(app.activeDocument, my_profile);
my_process.waitForProcess();
results = my_process.processResults;
var myTest = results.indexOf("None");
if (myTest == 0)
{
//alert ("No errors found");
}
else
{
alert ("Errors found");
}
};
}
}
Use
myEvent.preventDefault();
myEvent.stopPropagation();
HTH
Loic
Copy link to clipboard
Copied
Thank you Loic, that did the trick for that issue.
I still have an issue concerning that was the second part of my two-part question, and that was:
The one I settled on for the original script was the first item that shows up in the end-user list, but if the user changes profile while they're working on the job, the profile that the original script referred to was the profile that was at the top of the list when the document was opened.
Nevertheless, this first solution is very helpful and I can continue improving the script in other ways.
Thank you very much.
Colin
Copy link to clipboard
Copied
I've worked out the second part of the problem. I didn't need to add a preflight process, just use the one that was selected i.e.
var my_process = app.preflightProcesses[0];
Here is the full code, should anyone want to make the lives of their designers more frustrating by making them conform to using the preflight profiles! Sure, they can cheat and use the [Basic] profile, but the script can be adjusted to ensure that staff are using a specifically named preset.
#targetengine "session"
main();
function main(){
var beforeExport = app.menuActions.itemByName ( "$ID/Export..." ).addEventListener ( "beforeInvoke", checkJob );
function checkJob(myEvent){
if(app.activeDocument.preflightOptions.preflightOff == true){
alert('You have not preflighted your artwork.\rPlease preflight your artwork using the preflight panel before trying again.');
app.panels.itemByName("$ID/kPreflightUIPaletteName").visible = true;
app.activeDocument.preflightOptions.preflightOff = false;
myEvent.preventDefault();
myEvent.stopPropagation();
exit(0);
}else{
var my_process = app.preflightProcesses[0];
results = my_process.processResults;
var myTest = results.indexOf("None");
if (myTest == 0)
{
}
else
{
alert ('This artwork contains preflight errors.\rPlease resolve these errors using the preflight panel and try again.');
app.panels.itemByName("$ID/kPreflightUIPaletteName").visible = true;
myEvent.preventDefault();
myEvent.stopPropagation();
exit(0);
}
};
}
}
Hey, why stop there... why not include printing as well? Add this line after line 4:
var beforePrint = app.menuActions.itemByName ( "$ID/kPrint" ).addEventListener ( "beforeInvoke", checkJob );
Copy link to clipboard
Copied
Nope, nope, nope... as usual I have it completely wrong.
To include the beforePrint would be the following code:
var beforePrint = app.menuActions.itemByName ( "$ID/Print..." ).addEventListener ( "beforeInvoke", checkJob ); |
The code that I had to choose whatever preflight was selected fails the moment the preflight On checkbox is clicked, so the following code is INCORRECT:
- var my_process = app.preflightProcesses[0];
So that leaves me in the same circumstances I was in before, that is I need the script to determine whatever preflight was selected previously - use that... but I can't call it by it's name because I've no idea what the name of the preflight could be. So using a solution like this:
var process = app.preflightProcesses.add(myDocument, profile);
process.waitForProcess();
results = process.processResults;
won't work because the profile variable isn't a fixed name, but whatever the client has selected when preflighting their document.
Sorry to keep yapping on about this but I was so close!
Copy link to clipboard
Copied
Did you ever figure this out?
I am in the middle of scripting something similar, and I've discovered this code to come up with the current preflight name:
app.activeDocument.preflightOptions.preflightWorkingProfile;
So what this means is you can use the currently selected preflight profile, without having to know what it is named ahead of time. Here is a simple function I wrote (based on yours) that simply executes a preflight check, and displays a simple alert of the errors:
function checkPreflight() {
if (app.activeDocument.preflightOptions.preflightOff) {
// Preflight is off, do something
} else {
// Preflight is on
var myDoc = app.activeDocument;
var preflightName = myDoc.preflightOptions.preflightWorkingProfile; // Get the currently selected preflight profile name
var myProfile = myDoc.preflightProfiles.item(preflightName); // Get the profile itself using the name derived above
var myPreflight = app.preflightProcesses.add(myDoc, myProfile); // Set the preflight var
myPreflight.waitForProcess(); // Don't process the results until it has finished running
var results = myPreflight.aggregatedResults; // Store the results in a variable
if (results == "None") {
alert('No preflight errors'); // Self explanatory
} else {
alert('Preflight errors found - ' + results); // This needs some love formatting-wise
}
}
}
I'm really curious if you ever solved this, or if you had any other insights along these lines we could learn from
Thanks!
-Jimmy
Copy link to clipboard
Copied
Hello there.
At the time of writing this post, little progress was made with the script. I'd posted several videos on my youtube channel featuring the script in action, along with an article on my website about it plus a call-to-action to download the script via my contact page, and the results were disappointing. InDesignSecrets has provided a link to the original article in their February 2018 round-up but it would appear that apart from my own employer, the "care-factor" of a compulsory preflight is quite low.
Circular Software offer a better (albeit paid) solution called Greenlight.
Copy link to clipboard
Copied
ah yes, good to know. The script I'm working on is still giving me some fits understanding the results of the preflight, but specifically the part you were looking for (capturing the currently selected preflight profile) seems capable of being done with
myDoc.preflightOptions.preflightWorkingProfile;
I don't know how to comprehensively stop exporting to PDF in all cases, as my script only notifies the user of two things: if an invalid profile is being used, and if it passed or failed - it then directs the user to look at the preflight panel to understand what is wrong. I also log in the console the error, but that's more for me than the users who will use this script.
My objective is different than yours was, as I don't want to prevent an export of a PDF, I simply want to alert the user that there is an error, and they can decide for themselves if they want to keep the PDF they exported, or fix the errors and export another one.
Here's what I have now:
function checkPreflight() {
if (app.activeDocument.preflightOptions.preflightOff) {
// Preflight is off, do something
} else {
// Preflight is on
var myDoc = app.activeDocument;
var preflightName = myDoc.preflightOptions.preflightWorkingProfile; // Get the currently selected preflight profile name
var myProfile = myDoc.preflightProfiles.item(preflightName); // Get the profile itself using the name derived above
if (!myProfile.isValid) {
alert('Invalid preflight profile is active');
} else {
var myPreflight = app.preflightProcesses.add(myDoc, myProfile); // Set the preflight var
myPreflight.waitForProcess(); // Don't process the results until it has finished running
var results = myPreflight.aggregatedResults[2]; // Store the results in a variable
if (results.length == 0) {
//alert('No preflight errors'); // Self explanatory
} else {
alert('Preflight errors found - check preflight menu for errors'); // This needs some love formatting-wise
for (x in results) {
$.writeln('[' + x + "]\t" + results
); }
}
}
}
return true;
}
I return true because I want to call it inside an if statement to display any error messages prior to exporting the PDF and covering up the message with the PDF itself.
Here's how I call the function:
if(checkPreflight()) { myDoc.exportFile(ExportFormat.pdfType, filePath, false, pdfPreset); }