Copy link to clipboard
Copied
I am making a script which will:
1) Open a folder of Illustrator files
2) Open each file in the folder (these files are called the source files)
3) Select all the contents of the source file
4) Copy the contents of the source file
5) Paste these contents into a target file as a new layer
6) Ensure the new layer has the same name as the old source file
However, I don't know how to tell Illustrator where my target file is. How can I do this?
Also, when I paste, how can I turn off paste rembers layers. (So the layers get pasted into the new layer that has the same name as the old document).
Here is my code:
// JavaScript Document
//Set up vairaibles
var destDoc, sourceDoc, sourceFolder;
// Select the source folder.
sourceFolder = Folder.selectDialog('Select the folder with Illustrator files that you want to mere into one', '~');
// If a valid folder is selected
if (sourceFolder != null) {
files = new Array();
// Get all files matching the pattern
files = sourceFolder.getFiles();
if (files.length > 0) {
// Get the destination to save the files
destDoc = document.selectDialog('Select the final saved document', '~');
for (i = 0; i < files.length; i++) {
sourceDoc = app.open(files); // returns the document object
var myLayers = sourceDoc.layers; // All layers in Active Document
//Go through all layers of source document and copy artwork
for (i = 0; i < myLayers.length; i++) {
myLayers.hasSelectedArtwork = true;
};
with(sourceDoc) {
var count = pageItems.length;
for (var i = 0; i < count; i++) {
pageItems.selected = true;
}
redraw();
copy();
for (var i = 0; i < count; i++) {
pageItems.selected = false;
}
}
//Create a new title variable that has the title of the source document
var title = sourceDoc.name;
var title = title.substring(0, title.length - 4); //(remove extension from name)
//Close the Source Document
sourceDoc.close(SaveOptions.DONOTSAVECHANGES);
//Open the Destination Document and create a new layer in it that is named after the title variation
var newLayer = destDoc.layers.add();
newLayer.name = title;
//Paste into this new layer
destDoc = app.paste();
}
}
else {
alert('No matching files found');
}
}
Thanks in advance for any help
Edit: Also, when pasting, how can I paste in place instead of just pasting.
Copy link to clipboard
Copied
After looking at other scripts, I have found that you don't need to specify a target document, as you can just create a new document that will hold all the source layers, by using
destDoc = app.documents.add();
I have put that line in my code. When I run the script, the contents of the first source document are pasted in the new document and it works perfectly.
However, when it moves to the second source document, I get this error message:
Error 21: undefined is not an object.
Line: 50
-> var newLayer = destDoc.layers.add();
I am not sure why it should work with the first source document and not the other ones.
I would appreciate any pointers.
Here is my full script:
// JavaScript Document
//Set up vairaibles
var destDoc, sourceDoc, sourceFolder;
// Select the source folder.
sourceFolder = Folder.selectDialog('Select the folder with Illustrator files that you want to mere into one', '~');
destDoc = app.documents.add();
// If a valid folder is selected
if (sourceFolder != null) {
files = new Array();
// Get all files matching the pattern
files = sourceFolder.getFiles();
if (files.length > 0) {
// Get the destination to save the files
for (i = 0; i < files.length; i++) {
sourceDoc = app.open(files); // returns the document object
var myLayers = sourceDoc.layers; // Select All layers in Active Document
//Go through all layers of source document and copy artwork
for (i = 0; i < myLayers.length; i++) {
myLayers.hasSelectedArtwork = true;
};
with(sourceDoc) {
var count = pageItems.length;
for (var i = 0; i < count; i++) {
pageItems.selected = true;
}
redraw();
copy();
for (var i = 0; i < count; i++) {
pageItems.selected = false;
}
}
//Create a new title variable that has the title of the source document
var title = sourceDoc.name;
var title = title.substring(0, title.length - 4); //(remove extension from name)
//Close the Source Document
sourceDoc.close(SaveOptions.DONOTSAVECHANGES);
//Open the Destination Document and create a new layer in it that is named after the title variation
var newLayer = destDoc.layers.add();
newLayer.name = title;
//Paste into this new layer
destDoc = app.paste();
}
}
else {
alert('No matching files found');
}
}
Copy link to clipboard
Copied
If I change this line of code:
//Open the Destination Document and create a new layer in it that is named after the title variation
var newLayer = destDoc.layers.add();
newLayer.name = title;
//Paste into this new layer
destDoc = app.paste();
to this:
//Open the Destination Document and create a new layer in it that is named after the title variation
newLayer = destDoc.layers.add();
newLayer.name = title;
//Paste into this new layer
newLayer = app.paste();
then I don't get the error message.
However, it runs on the first source file. But then it endlessly just pastes the second source file in the destination document (I.e. it doesn't move onto any of the other source file). It just endlessly pastes and so I have to force quit!
How can I get it to move onto the next file.
Copy link to clipboard
Copied
Howdy big_smile,
You are doing a great job at answering your own question, it seems! 😉 Glancing at your post and (of course) not knowing what your original (source) docs look like, one thought occurred to me early on... might it not be easier to 1) open the source document, 2) save it under a new name, then just flatten your atwork and save? It seems to me that would save a lot of work...
I'm recently doing more ID scripting so that's where my head is, but would it be worth considering?
-TT
Copy link to clipboard
Copied
@ThinkingThings, Thanks for the reply!
I have over 60 illustrator files per project (and 20 projects in total) and I need to combine them into a single Illustrator file. I don't quite follow how flattening the artwork will help (especially as the final file needs to have 60 layers (so each of the 60 files is on a seperate layer in the main document).
Thanks in advance for any guidance you can offer!
Copy link to clipboard
Copied
I've found this script that is similar to what I need except it places the source files (Instead of copying & pasting them)
http://kelsocartography.com/blog/?p=2047
I've tried going over it but I am not sure how to adapt it to make it copy and paste instead of place.
Thanks for any help anyone can offer!
Copy link to clipboard
Copied
I have over 60 illustrator files per project (and 20 projects in total) and I need to combine them into a single Illustrator file.
Ah, okay -- I didn't know that part, although it may still be advantageous (at least in my mind) to have a flattened version of the source file that you could then place or copy into your new single document. The notion of flattening the artwork simply "flattens" all layers to a single layer. I am assuming there is scripting support for the flattening feature. To see how this works, simply create two shapes (or whatever) and put one shape on one layer and the second shape on the second layer. Now go to the menu dropdown of the Layers panel and choose "Flatten Artwork" and you will see everything go to one layer, which you could rename the layer at that point (per your instructions), save the file to a new name like "OldFileName_Flattened.ai". Do that for all 60 files, then create a script to place (if you want to retain the ability to chgange the source and have the changes manifested in the new composite file) or probably place and embed (again I am speaking hypothetically here as I don't remember the scripting support availability). See I started out in AI and now do that as well as ID, but my head is in ID, as I mentioned before. Virtually EVERYTHING is available in ID to script, whereas AI is somewhat limited. But I am sure that you could find a way, even if it is through actions or DoMenus.
What do you think?
-TT
PS: (edit) I also script in .NET (a rare commodity) and prefer to avoid JS (a bad idea admittedly) which may also be why I may sound a little vague and lacking on scripting details, although I am happy to help.
Copy link to clipboard
Copied
Hi Thanks for your help. The only problem with placing a file is that you can't edit* the layers in the target document. If I can copy and paste it via the script, it would be better, because I can then edit the layers after they have been placed.
*I know you can click on edit original, but its not as easy as being able to edit a non-placed file (as when the original is opened, you can see all the other layers in the target file).
Copy link to clipboard
Copied
study this script, I do more or less the same thing with pdf pages
Copy link to clipboard
Copied
Thanks CarlosCanto! In the link you posted, the script is hosted on fileswap, but the link is broken.
There's a real world Illustrator link, but it is an Apple script app (and mine is JS), so I can't study it.
Thanks for any help you can offer!
Copy link to clipboard
Copied
there's a newer link deeper into the same post, I also posted a link in the real world site about a week ago, go to the last comment.
Copy link to clipboard
Copied
Thanks CarlosCanto!
I went over your script (which is very impressive, Btw, especially the UI for the dialogue box).
However, I am not sure how it relates to my use case, as I am trying to combine multiple seperate illustrator files into one, where as your script takes single PDF pages and combines them into one.
Is there a specific aspect you had in mind.
Thanks for any help!
Copy link to clipboard
Copied
I have been studying this script. It is similar to what I need except it places the source files (Instead of copying & pasting them)
http://kelsocartography.com/blog/?p=204
I have adapted the script to my needs and it works perfectly, except it has the same problem as before: It pastes the first source file, but then it endlessly starts pasting the second source file (in a loop) and so I have to force quit.
So my new question is, when looping through files how can you get illustrator to move on the next one?
The original kelsocartography had this line:
thisPlacedItem = newLayer.placedItems.add()
thisPlacedItem.file = imageList;
I belive this line is what makes Illustrator move onto the next file, but I am not sure how to adapt it to my code.
Here is my code so far:
function getFolder() {
return Folder.selectDialog('Please select the folder to be imported:', Folder('~'));
}
function importFolderAsLayers(selectedFolder) {
// if a folder was selected continue with action, otherwise quit
var myDocument;
if (selectedFolder) {
myDocument = app.documents.add();
var firstImageLayer = true;
var newLayer;
var thisPlacedItem;
// create document list from files in selected folder
var documentList = selectedFolder.getFiles();
for (var i = 0; i < documentList.length; i++) {
// open each document in file list
if (documentList instanceof File) {
// get the file name
var fName = documentList.name.toLowerCase();
var sourceDoc = app.open(documentList); // returns the document object
var myLayers = sourceDoc.layers; // Select All layers in Active Document
//Go through all layers of source document and copy artwork
for (i = 0; i < myLayers.length; i++) {
myLayers.hasSelectedArtwork = true;
};
with(sourceDoc) {
var count = pageItems.length;
for (var i = 0; i < count; i++) {
pageItems.selected = true;
}
redraw();
copy();
for (var i = 0; i < count; i++) {
pageItems.selected = false;
}
}
//Create a new title variable that has the title of the source document
var title = sourceDoc.name;
var title = title.substring(0, title.length - 4); //(remove extension from name)
//Close the Source Document
// check for supported file formats
if ((fName.indexOf(".eps") == -1)) {
continue;
} else {
if (firstImageLayer) {
newLayer = myDocument.layers[0];
firstImageLayer = false;
} else {
newLayer = myDocument.layers.add();
}
// Give the layer the name of the image file
newLayer.name = fName.substring(0, fName.indexOf("."));
// Place the image on the artboard
sourceDoc.close(SaveOptions.DONOTSAVECHANGES);
//Paste into this new layer
newLayer = app.paste();
}
}
}
if (firstImageLayer) {
// alert("The action has been cancelled.");
// display error message if no supported documents were found in the designated folder
alert("Sorry, but the designated folder does not contain any recognized image formats.\n\nPlease choose another folder.");
myDocument.close();
importFolderAsLayers(getFolder());
}
} else {
// alert("The action has been cancelled.");
// display error message if no supported documents were found in the designated folder
alert("Rerun the script and choose a folder with images.");
//importFolderAsLayers(getFolder());
}
}
// Start the script off
importFolderAsLayers(getFolder());
Copy link to clipboard
Copied
don't worry about the whole picture, use only the "concept" of a small part and adapt it to your needs
I open a pdf page (you open an ai)
I copy the contents (you, same)
I paste to destination (you, same)
I close pdf page (you, close ai)
I open next pdf page (you, open next ai)
Copy link to clipboard
Copied
I got this working! The Solution was to use a function (see below).
Could someone explain to me why a function is needed, as I don't understand. Thanks!
Also, is it possible for the script to turn off "Paste Remembers Layers" and then restore the option to its previous setting?
Thanks!
// JavaScript Document
//Set up vairaibles
var destDoc, sourceDoc, sourceFolder, newLayer;
// Select the source folder.
sourceFolder = Folder.selectDialog('Select the folder with Illustrator files that you want to mere into one', '~');
destDoc = app.documents.add();
// If a valid folder is selected
if (sourceFolder != null) {
files = new Array();
// Get all files matching the pattern
files = sourceFolder.getFiles(/\.(ai|eps|pdf)$/i);
if (files.length > 0) {
// Get the destination to save the files
for (i = 0; i < files.length; i++) {
doSomething(i);
}
}
else {
alert('No matching files found');
}
}
function doSomething(i) {
sourceDoc = app.open(files); // returns the document object
var myLayers = sourceDoc.layers; // Select All layers in Active Document
//Go through all layers of source document and copy artwork
for (i = 0; i < myLayers.length; i++) {
myLayers.hasSelectedArtwork = true;
};
with(sourceDoc) {
var count = pageItems.length;
for (var i = 0; i < count; i++) {
pageItems.selected = true;
}
redraw();
copy();
for (var i = 0; i < count; i++) {
pageItems.selected = false;
}
}
//Create a new title variable that has the title of the source document
var title = sourceDoc.name;
var title = title.substring(0, title.length - 4); //(remove extension from name)
//Close the Source Document
sourceDoc.close(SaveOptions.DONOTSAVECHANGES);
//Open the Destination Document and create a new layer in it that is named after the title variation
newLayer = destDoc.layers.add();
newLayer.name = title;
//Paste into this new layer
newLayer = app.paste();
}
Copy link to clipboard
Copied
Has anyone managed to modify this script so that the copied elements are pasted in place? Right now they're all pasted in the center of the new document.
Copy link to clipboard
Copied
@Kirkcp Illustrator has a function called Paste in Place, but I don't know how to use that in a script.
Copy link to clipboard
Copied
Thanks for posting this. I added an unlock everything to it. I think it worked. I heard it can take a long time if there are many items.
//Unlock all page items
getInfoC = app.activeDocument.pageItems;
for ( a = 0; a < getInfoC.length; a++ )
{
try {
getInfoC4 = getInfoC;
getInfoC4.locked = false;
} catch (e) {}
}