Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Javascript to duplicate artboard and items to other open docs

Contributor ,
Aug 11, 2022 Aug 11, 2022

Hi all,

I'm piecing together a script to duplicate the chosen artboard and its contents to another document. I've ALMOST got it working.

If I separate the script, the artboard duplication works, and the item duplication works. But when I try and combine the two scripts together, it doesn't select the items on the source artboard and fails. That's probably quite easy to solve...BUT...

...what I'd really like it to do is to duplicate the source artboard and its selection to ALL OTHER open documents. All except the source doc. 

Do you think that's possible?

Any guidance would be great. J

/// PART 1 ///
//DIALOG - Get artboard number from user
var input = prompt("Enter artboard # to duplicate", "0");
    var sourceIndex = input - 1;
        
var doc = app.activeDocument;
var ABs = doc.artboards;
ABs.setActiveArtboardIndex(sourceIndex);
doc.selectObjectsOnActiveArtboard();

/// PART 2 ///
// COPY THAT ARTBOARD TO ANOTHER DOC
var sourceDoc = app.documents[0]; // get source doc
var destDoc = app.documents[1]; // get dest doc
 
ABs = sourceDoc.artboards[sourceIndex]; // get source artboard
ABsRect = ABs.artboardRect; // get Rectangle
ABsNames = ABs.name; // get Name
ABsInfo = [ABsRect, ABsNames]; // get Rectangle and Name
sourceDoc.selection = null; // deselect
sourceDoc.artboards.setActiveArtboardIndex(sourceIndex); // activate source artboard
             
addArtboards(destDoc, ABsInfo); // create artboard in dest doc

// create artboards in destination doc, using the info in absInfo (abRect, Name)
function addArtboards(doc, absInfo) {
    var destDoc = doc;
    destDoc.activate();
        var newAB = destDoc.artboards.add(ABsInfo[0]);
        newAB.name = ABsInfo[1];
    }

/// PART 3 ///
// COPY THE SOURCE ARTBOARD'S ITEMS TO DESINTATION DOC
var newItem;
sourceDoc = app.documents[1];
sourceDoc.selectObjectsOnActiveArtboard();
var sourceDoc = app.activeDocument.selection;
if (sourceDoc.length > 0) {
// Create a new document and move the selected items to it. var destDoc = app.documents.add();
var destDoc = app.documents[1];
if (sourceDoc.length > 0) {
for (var i = 0; i < sourceDoc.length; i++) {
sourceDoc[i].selected = false;
newItem = sourceDoc[i].duplicate(destDoc, ElementPlacement.PLACEATEND);
}
} else {
sourceDoc.selected = false;
newItem = sourceDoc.parent.duplicate(destDoc, ElementPlacement.PLACEATEND);
}
} else {
  alert("Please select one or more art objects");
}

 

TOPICS
Scripting
966
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guide , Aug 11, 2022 Aug 11, 2022

See if this works.  Please note that I've not extensively tested it.  I've made three changes.  The first two are after block comments (/* ... */).  First is assigning the source items to an array, so as to duplicate from the array in part 3 without referencing the source document and its changing index.  Second is iterating the documents from 1 onwards (i.e. all but the source document), calling addArtboards() each time.  Third is putting part 3 in a function to be called in the same loop as ad

...
Translate
Adobe
Guide ,
Aug 11, 2022 Aug 11, 2022

See if this works.  Please note that I've not extensively tested it.  I've made three changes.  The first two are after block comments (/* ... */).  First is assigning the source items to an array, so as to duplicate from the array in part 3 without referencing the source document and its changing index.  Second is iterating the documents from 1 onwards (i.e. all but the source document), calling addArtboards() each time.  Third is putting part 3 in a function to be called in the same loop as addArtboards().

 

/// PART 1 ///
// DIALOG - Get artboard number from user
var input = prompt("Enter artboard # to duplicate", "0");
var sourceIndex = input - 1;
var doc = app.activeDocument;
var ABs = doc.artboards;
doc.selection = null;
ABs.setActiveArtboardIndex(sourceIndex);  // make source artboard active
doc.selectObjectsOnActiveArtboard();  // select items on source artboard

/// PART 2 ///
// COPY THAT ARTBOARD TO ANOTHER DOC
var sourceDoc = app.activeDocument; // get source doc
AB = sourceDoc.artboards[sourceIndex]; // get source artboard
ABRect = AB.artboardRect; // get rectangle
ABName = AB.name; // get name
ABInfo = [ABRect, ABName]; // get rectangle and name
/*
  assign source items (selected items on source artboard from part 1) to array, 
  so as to duplicate from array in part 3 without referencing source document
*/
var sourceItems = [];
for (var i = 0; i < sourceDoc.selection.length; i++) {
    sourceItems.push(sourceDoc.selection[i]);
}
app.selection = null;
/*
  iterate documents from 1 onwards (i.e. all but source document),
  calling addArtboards() and copySourceItems() each time 
*/
for (var i = 1; i < app.documents.length; i++) {
    addArtboards(app.documents[i], ABInfo);
    copySourceItems(app.activeDocument);
    app.selection = null;
}
// create artboard in dest doc, using the info in ABInfo (ABRect, ABName)
function addArtboards(destDoc, abInfo) {
    destDoc.activate();
    var newAB = destDoc.artboards.add(abInfo[0]);
    newAB.name = abInfo[1];
}

/// PART 3 ///
// COPY THE SOURCE ARTBOARD'S ITEMS TO DESINTATION DOC
function copySourceItems(destDoc1) {
    for (var j = 0; j < sourceItems.length; j++) {
        sourceItems[j].duplicate(destDoc1, ElementPlacement.PLACEATEND);
    }
}

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 11, 2022 Aug 11, 2022

That's perfect. Thank you once again for helping me out of a jam.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 11, 2022 Aug 11, 2022

Nice work Femke. We basically produced the exact same thing, and made the same kind of changes. But i decided to build it from scratch and you beat me to the punch by 19 minutes. 😉

 

One thing i did differently was to create a "transport group" so that all of the art gets transferred into the dest document at once. Otherwise things can proceed quite slowly if there's lots of complex art being copied one by one. Plus, if there's a LOT of art, you could run out of undo states and not be able to revert the file back to how it was before you ran the script. using a transport group ensures minimal undo states used by the script and makes for easy reverting.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Aug 11, 2022 Aug 11, 2022

@Disposition_Dev  I just did a bit of rejigging to make the OP's script work as they intended.  Your "transport group" idea is very nice. 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 11, 2022 Aug 11, 2022

that's what i intended to do as well.. but i kept thinking of edge cases for which to create error handling  and before i knew it i had rewritten it all. lol. it's easier for me to work in my own variable naming conventions than to read/edit someone else's.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 11, 2022 Aug 11, 2022

Try this out. 

 

https://github.com/wdjsdev/public_illustrator_scripts/blob/master/duplicate_artboard_to_all_open_doc...

 

 

 

// what I'd really like it to do is to duplicate the source artboard 
// and its selection to ALL OTHER open documents. All except the source doc. 

//Script Description: Duplicate user selected artboard to all open documents
//Script high level functionality:
    //Script propmpts user to input artboard number to duplicate
    //the bounds of the artboard are logged
    //the artwork is duplicated into a "transport group".
        //if you copy the items individually, Illustrator creates an "undo state" for each item.
        //this can be annoying if you need to undo, becuase you could potentially run out of
        //available undo states and not be able to get back to the original state.
        //by grouping all the art that will be transferred, only one undo state is created,
        //and the art can easily be ungrouped and manipulated however you want after it's been duplicated
        //to the dest document.
    //for each open document (sans the source document)
        //activate document
        //create new artboard matching the artboardRect from the source document
        //duplicate the transfer group from the source document to the new artboard
            //and place it in a new layer named "imported artwork"
    //remove the transport group from the source document
    //end script



//author: William Dowling
//email: illustrator.dev.pro@gmail.com
//github: https://www.github.com/wdjsdev
//this project on github: https://github.com/wdjsdev/public_illustrator_scripts/blob/master/duplicate_artboard_to_all_open_docs.js
//linkedin: https://www.linkedin.com/in/william-dowling-4537449a/
//Adobe Discussion Forum Post that initiated this: https://community.adobe.com/t5/illustrator-discussions/javascript-to-duplicate-artboard-and-items-to-other-open-docs/td-p/13129047

//*******//

//Did you find this useful? Would you like to buy me a cup (or a pot) of coffee to say thanks?
//paypal.me/illustratordev
//<3

//Do you have some work to do, but you have more money than time/skill?
//Send me an email or a dm! I'll see what we can do to help each other..

//*******//
function duplicateArtboardToAllOpenDocuments()
{
    if(!app.documents.length)
    {
        alert("Please open at least 2 documents first, then try again.");
    }
    var doc = app.activeDocument;
    var ab = doc.artboards;
    var userChoice = prompt("Which artboard do you want to duplicate?", "1");

    if(!userChoice)
    {
        return;
    }
    if(userChoice < 1 || userChoice > ab.length)
    {
        alert("Invalid artboard number");
        return;
    }

    userChoice -= 1; //convert to zero-based index

    var abToDuplicate = ab[userChoice];
    var abDupRect = abToDuplicate.artboardRect;
    ab.setActiveArtboardIndex(userChoice);
    doc.selection = null;
    doc.selectObjectsOnActiveArtboard();
    
    //build a group of the selection to make it easier/faster/more efficient
    //to transfer the selection to all other open documents
    //you can ungroup this in the dest document here in the code if you want to
    var transportGroup = doc.groupItems.add();
    for (var s = doc.selection.length - 1; s >= 0; s--) {
        doc.selection[s].duplicate(transportGroup);
    }

    //loop all open documents and duplicate the transportGroup to each one, except the source document
    //destLay is a new layer in the dest document that will be used to place the transportGroup
    //to prevent runtime errors if the top layer is locked/hidden/inaccessible.
    //this layer can be removed from here in the code and you can simply move() the transportGroup
    //to wherever you want it to be in the dest document.
    
    var docsArray = [];

    //build an array of all open documents except the source document, which is app.documents[0]
    for (var d = app.documents.length - 1; d >= 1; d--) {
        docsArray.push(app.documents[d]);
    }

    //process each document in the array
    for(var d=0;d<docsArray.length;d++)
    {
       processDoc(docsArray[d]);
    }

    //remove the transport group from the source document
    transportGroup.remove();


    //reset the app.coordinate system to whatever it was before the script ran
    // app.coordinateSystem = prevCoordSystem;




    function processDoc(destDoc)
    {
        destDoc = docsArray[d];
        destDoc.activate();
        var destAb = destDoc.artboards.add(abDupRect);
        //move artboard by assigning it a new artboardRect
        //keep track of the distance the artboard moves, then
        //apply the same transformation to the artGroup
        
        
        var destLay = destDoc.layers.add();
        destLay.name = "imported artwork";
        var destArt = transportGroup.duplicate(destDoc);
        destArt.moveToBeginning(destLay);
    }
}
duplicateArtboardToAllOpenDocuments();

 

 

 

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 11, 2022 Aug 11, 2022
LATEST

Thanks for your alternate solution. It does indeed run quite a bit faster and I'll save it for later use.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines