Copy link to clipboard
Copied
Hey everyone- I am currently running Illustrator CS5 on Windows 7 using extendscript. My issue is this:
When testing this script on any Windows machine, my script runs as it should but when I try to run it on a Mac using Illustrator CS4, the PDFs save as they should, but the Illustrator file doesn't. The folder contains the PDFs but no Illustrator. I'm currently using CS5 and the IllustratorSaveOptions specify to save as a CS4 file. Any help would be appreciated. I've seen other posts showing IllustratorSaveOptions that had "+ 'ai'" and "+ '.pdf'" at the end of the file string. Could that have anything to do with it? The most important part of the script is towards the bottom. Here is my script:
#target illustrator
var myDoc = activeDocument;
var dateFormat = function () {
var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
timezoneClip = /[^-+\dA-Z]/g,
pad = function (val, len) {
val = String(val);
len = len || 2;
while (val.length < len) val = "0" + val;
return val;
};
// Regexes and supporting functions are cached through closure
return function (date, mask, utc) {
var dF = dateFormat;
// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
mask = date;
date = undefined;
}
// Passing date through Date applies Date.parse, if necessary
date = date ? new Date(date) : new Date;
if (isNaN(date)) throw SyntaxError("invalid date");
mask = String(dF.masks[mask] || mask || dF.masks["default"]);
// Allow setting the utc argument via the mask
if (mask.slice(0, 4) == "UTC:") {
mask = mask.slice(4);
utc = true;
}
var _ = utc ? "getUTC" : "get",
d = date[_ + "Date"](),
D = date[_ + "Day"](),
m = date[_ + "Month"](),
y = date[_ + "FullYear"](),
H = date[_ + "Hours"](),
M = date[_ + "Minutes"](),
s = date[_ + "Seconds"](),
L = date[_ + "Milliseconds"](),
o = utc ? 0 : date.getTimezoneOffset(),
flags = {
d: d,
dd: pad(d),
ddd: dF.i18n.dayNames
dddd: dF.i18n.dayNames[D + 7],
m: m + 1,
mm: pad(m + 1),
mmm: dF.i18n.monthNames
mmmm: dF.i18n.monthNames[m + 12],
yy: String(y).slice(2),
yyyy: y,
h: H % 12 || 12,
hh: pad(H % 12 || 12),
H: H,
HH: pad(H),
M: M,
MM: pad(M),
s: s,
ss: pad(s),
l: pad(L, 3),
L: pad(L > 99 ? Math.round(L / 10) : L),
t: H < 12 ? "a" : "p",
tt: H < 12 ? "am" : "pm",
T: H < 12 ? "A" : "P",
TT: H < 12 ? "AM" : "PM",
Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
};
return mask.replace(token, function ($0) {
return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
});
};
}();
// Some common format strings
dateFormat.masks = {
"default": "ddd mmm dd yyyy HH:MM:ss",
shortDate: "m/d/yy",
mediumDate: "mmm d, yyyy",
longDate: "mmmm d, yyyy",
fullDate: "dddd, mmmm d, yyyy",
shortTime: "h:MM TT",
mediumTime: "h:MM:ss TT",
longTime: "h:MM:ss TT Z",
isoDate: "yyyy-mm-dd",
isoTime: "HH:MM:ss",
isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};
// Internationalization strings
dateFormat.i18n = {
dayNames: [
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
],
monthNames: [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
]
};
// For convenience...
Date.prototype.format = function (mask, utc) {
return dateFormat(this, mask, utc);
};
var now = new Date();
var now_format = now.format("mmddyy");
/*with (myDoc) {
for (var i = textFrames.length-1; i >= 0; i--) {
textFrames.createOutline();
}
alert('Done…');
}
*/
function outlineDocText( ) {
if ( app.documents.length == 0 ) return;
var myDoc = app.activeDocument;
recurseLayers( myDoc.layers );
};
outlineDocText();
function recurseLayers( objArray ) {
for ( var i = 0; i < objArray.length; i++ ) {
// Record previous value with conditional change
var l = objArray.locked;
if ( l ) objArray.locked = false;
// Record previous value with conditional change
var v = objArray.visible;
if ( !v ) objArray.visible = true;
outlineText( objArray.textFrames );
// Recurse the contained layer collection
if ( objArray.layers.length > 0 ) {
recurseLayers( objArray.layers )
}
// Recurse the contained group collection
if ( objArray.groupItems.length > 0 ) {
recurseGroups( objArray.groupItems )
}
// Return to previous values
objArray.locked = l;
objArray.visible = v;
}
};
function recurseGroups( objArray ) {
for ( var i = 0; i < objArray.length; i++ ) {
// Record previous value with conditional change
var l = objArray.locked;
if ( l ) objArray.locked = false;
// Record previous value with conditional change
var h = objArray.hidden;
if ( h ) objArray.hidden = false;
outlineText( objArray.textFrames );
// Recurse the contained group collection
if ( objArray.groupItems.length > 0 ) {
recurseGroups( objArray.groupItems )
}
// Return to previous values
objArray.locked = l;
objArray.hidden = h;
}
};
function outlineText( objArray ) {
// Reverse this loop as it brakes the indexing
for ( var i = objArray.length-1; i >= 0; i-- ) {
// Record previous value with conditional change
var l = objArray.locked;
if ( l ) objArray.locked = false;
// Record previous value with conditional change
var h = objArray.hidden;
if ( h ) objArray.hidden = false;
var g = objArray.createOutline( );
// Return new group to previous Text Frame values
g.locked = l;
g.hidden = h;
}
};
var myPermission =confirm ("Are you sure you're ready to save?","","Save Script Execution")
if (myPermission){
var myFileName = prompt ("Enter Filename","");
if (myFileName){
var destFolder = Folder.selectDialog('Select which folder to save to Katie:');
}
else
alert ("Save cancelled");
}
if (destFolder) {
/*Save as Illustrator CS4*/
var IFile = new File(destFolder + '/' + myFileName);
var ISave = new IllustratorSaveOptions();
with (ISave){
compatibility = Compatibility.ILLUSTRATOR14;
}
/*Save as standard PDF*/
var IPreset = '[Illustrator Default]'
var pdfSave = new PDFSaveOptions();
var pdfFile = new File(destFolder + '/' + myFileName);
with (pdfSave){
pDFPreset = IPreset;
viewAfterSaving = false;
compatibility = PDFCompatibility.ACROBAT5;
}
/*Save as smallest PDF*/
var SmallestPDF = '[Smallest File Size]';
var pdfSaveOpts = new PDFSaveOptions();
var pdfFileCompressed = new File(destFolder + '/' + myFileName +'%2e' + now_format);
with (pdfSaveOpts){
compatibility = PDFCompatibility.ACROBAT5;
pDFPreset = SmallestPDF;
viewAfterSaving = false;
}
destFolder.execute()
myDoc.saveAs (IFile, ISave)
myDoc.saveAs(pdfFile, pdfSave)
myDoc.saveAs(pdfFileCompressed, pdfSaveOpts)
}
else {
alert("Save cancelled!")
}
It's NOT the case of the file system showing the file correctly… It is saved to the requested location… You are just overwriting it with the standard PDF… The supplied paths you defined are the same… Here I have just made a change to your code…
...var myDoc = app.activeDocument; // Just so I can ignore the rest of the code…
var myPermission =confirm ("Are you sure you're ready to save?","","Save Script Execution")
if (myPermission){
var myFileName = prompt ("Enter Filename","");
if (myFileName){
var dest
Copy link to clipboard
Copied
Ignore the file suffix/extension you see in some other scripts… Its a cheat… An *.ai file is based closely on the *.pdf so im some cases its indended to fool the OS or other apps/devices such as ipad… You should suffix your file correctly if this is NOT your intent…
Copy link to clipboard
Copied
But could this keep the AI file from showing up on a MAC system if they weren't suffixed in the script? I'm not trying to cheat or confuse the system. I want to save an AI as an AI and a PDF as a PDF. My intent is to get it to work and keep it functional and that was just an idea of why it might not be working.
I'm trying to figure out why this script would work perfectly in Windows with all saved files appearing correctly in the chosen folder, but the PDFs only showing up in the MAC. IllustratorSaveOptions(Extendscript) should work the same across both platforms, correct?
Copy link to clipboard
Copied
It's NOT the case of the file system showing the file correctly… It is saved to the requested location… You are just overwriting it with the standard PDF… The supplied paths you defined are the same… Here I have just made a change to your code…
var myDoc = app.activeDocument; // Just so I can ignore the rest of the code…
var myPermission =confirm ("Are you sure you're ready to save?","","Save Script Execution")
if (myPermission){
var myFileName = prompt ("Enter Filename","");
if (myFileName){
var destFolder = Folder.selectDialog('Select which folder to save to Katie:');
}
else
alert ("Save cancelled");
}
if (destFolder) {
/*Save as Illustrator CS4*/
var IFile = new File(destFolder + '/' + myFileName + '.ai' ); // Now unique
var ISave = new IllustratorSaveOptions();
with (ISave){
compatibility = Compatibility.ILLUSTRATOR14;
}
/*Save as standard PDF*/
var IPreset = '[Illustrator Default]'
var pdfSave = new PDFSaveOptions();
var pdfFile = new File(destFolder + '/' + myFileName + '.pdf' ); // Ditto here
with (pdfSave){
pDFPreset = IPreset;
viewAfterSaving = false;
compatibility = PDFCompatibility.ACROBAT5;
}
/*Save as smallest PDF*/
var SmallestPDF = '[Smallest File Size]';
var pdfSaveOpts = new PDFSaveOptions();
var pdfFileCompressed = new File(destFolder + '/' + myFileName +'%2e' + 'now_format' + '.pdf' ); // This was just un-string your variable…
with (pdfSaveOpts){
compatibility = PDFCompatibility.ACROBAT5;
pDFPreset = SmallestPDF;
viewAfterSaving = false;
}
destFolder.execute()
myDoc.saveAs (IFile, ISave)
myDoc.saveAs(pdfFile, pdfSave)
myDoc.saveAs(pdfFileCompressed, pdfSaveOpts)
}
else {
alert("Save cancelled!")
}
Copy link to clipboard
Copied
Hey Muppet, thanks for the input. It seems like that will work. I will have to try it today at work and see how it goes. Another question: How would I go about wrapping this in a function so that at this point -
else
alert ("Save cancelled"); the script would totally stop. I'm doing alot of my debugging in ESTK, and when I hit the cancel button, this alert does pop up, but the script keeps running. It seems like that would end up wasting alot of memory. The only answer I've seen on other forums is to use RETURN to end the script, and it has to have a function. Thanks in advance!
Copy link to clipboard
Copied
Yeah… For AI, ID & PS I wrap everything in function calls so that I can just return; and end the script… ID does have a exit(); but as its the only app with this I just stick to what I use everywhere else… Keeps all my variables from being global too… I usually do stuff like
function doStuff() {
if ( app.documents.length == 0 ) { return; }
// Set up function variables if there is a doc
var doc, count, etc;
// Do the rest of my stuff
};
doStuff();
I don't let anyone know they just cancelled… Surely they know that already…?
Copy link to clipboard
Copied
I guess you're right on letting them now they cancelled. I'll pull that from my script. I'll give all of this a shot in a bit. Thanks again.
Copy link to clipboard
Copied
You are the master of muppets! Once again, you came through with the right answer. Thanks!! It works like a charm.
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more