Skip to main content
brian_p_dts
Community Expert
Community Expert
August 25, 2023
Question

JSX - How to reference swatch in a loaded swatch library in an AIT?

  • August 25, 2023
  • 1 reply
  • 285 views

Hi all, I want to set up AITs with preloaded swatch libraries. Is there a way to reference those swathes without having to copy the swatches over into the main doc swatch library programmatically? 

 

I did set up a routine to do that, but, while it works sometimes, occassionally I get a PARM error. This is the routine I'm using; instead of loading the ASE, I am loading the swatch ai file ("theFile"). To reference the existing swatch library, I've tried just a regular activeDocument.swatches.getByName("theName"), where the ait is the active doc, as well as app.documents.getByName("libraryname").swatches.getByName("theName"), both of which yield No Such Element.

//open the swatch library and return its swatches
var openSwatches = function(doc, theFile) {
    //var openOpt = new OpenOptions();
    //  get swatches
    var sd = app.open(theFile);
    var sws = sd.swatches;
    var i = sws.length;
    var a = []; //array of swatch names to return
    var s, ns, cs;
    while(i--) {
        s = sws[i];
        //skip default swatches
        if(s.name == "[Registration]" || s.name == "[None]"){
            continue;
        }
        //remove the swatch if it exists already
        try {
            cs = doc.swatches.getByName(s.name);
            cs.remove();
        } catch(e)  {}
        //do spots
        if (s.color.typename === "SpotColor") {
            ns = doc.spots.add();            
            ns.color = s.color.spot.color;
            ns.colorType = ColorModel.SPOT;

        }
        //do nonspots
        else {
            ns = doc.swatches.add();            
            ns.color= s.color;
        }
        ns.name = s.name;
        a.push(ns.name);
    }
    sd.close(SaveOptions.DONOTSAVECHANGES);
}

 

1 reply

m1b
Community Expert
Community Expert
August 25, 2023

Hi @brian_p_dts, looking at your code I don't see any obvious things. The first suggestion I'd make is to move the swatches into a normal array before doing anything with them. That can resolve some types of reference issues.

- Mark

 

P.S. I tried another approach, just for fun, which moves all the swatches in one go, by moving a group of colored rectangles across. Note this only moves swatches, not non-global colors (all the colors come across in the rectangles, but you'd have to add an extra bit of code to add them as swatches). Here is my experiment:

 

/**
 * Copy swatches from a source document to a target document.
 * Experimental: the idea here is to color a bunch of rectangles
 * and then move them all (in a group) to the target document.
 * @author m1b
 * @discussion https://community.adobe.com/t5/illustrator-discussions/jsx-how-to-reference-swatch-in-a-loaded-swatch-library-in-an-ait/m-p/14035836
 */
(function () {

    // my demo documents:
    // doc1 has a bunch of PANTONE spot colours
    var doc1 = '~/Desktop/demo3.ai';
    // doc2 has no colours
    var doc2 = app.documents.getByName('demo2.ai');

    // example filter: ignore [none]|[registration]
    var filter = function (swatch) {
        return swatch.name[0] != '[';
    };

    // try it out
    copySwatches(doc1, doc2, filter);
    app.activeDocument = doc2;

})();



/**
 * Move swatches from `sourceDocument` into `targetDocument`;
 * If sourceDocument is a File or path, then will open document
 * and close after copying the swatches.
 * @author m1b
 * @version 2023-08-25
 * @param {Document|File|String} sourceDocument - an Illustrator Document, File or path to a file.
 * @param {Document} targetDocument - an Illustrator Document.
 * @param {Function} filter - function that copies swatch when returns true;
 */
function copySwatches(sourceDocument, targetDocument, filter) {

    var closeSourceDocument = false;

    if (sourceDocument.constructor.name == 'String')
        sourceDocument = File(sourceDocument);

    if (
        sourceDocument.constructor.name == 'File'
        && sourceDocument.exists
    ) {
        closeSourceDocument = true;
        sourceDocument = app.open(sourceDocument);
    }

    if (sourceDocument.constructor.name !== 'Document')
        return;

    var group = sourceDocument.activeLayer.groupItems.add(),
        bounds = [0, 0, 10, 10];

    sourceDocument.defaultFilled = false;
    sourceDocument.defaultStroked = false;

    var swatches = [];

    // make a normal array
    for (var i = 0; i < sourceDocument.swatches.length; i++)
        swatches[i] = sourceDocument.swatches[i];

    // add colours to rectangles
    for (var i = 0; i < swatches.length; i++) {

        if (
            filter == undefined
            || filter(swatches[i])
        ) {
            sourceDocument.defaultFillColor = swatches[i].color;
            makeRectanglePathItem(group, bounds);
        }

    }

    try {

        // duplicate the rectangles to the target document
        var dup = group.duplicate(targetDocument.activeLayer, ElementPlacement.PLACEATEND);
        dup.remove();

    }

    catch (error) { }

    finally {

        if (closeSourceDocument)
            sourceDocument.close(SaveOptions.DONOTSAVECHANGES);

    }

};

/**
 * Draws and returns a rectangle path item.
 * @author m1b
 * @version 2023-08-24
 * @param {Document} container - an Illustrator Document.
 * @param {Array<Number>} rect - [L, T, R, B].
 * @returns {PathItem}
 */
function makeRectanglePathItem(container, rect) {

    var left = rect[0],
        top = rect[1],
        right = rect[2],
        bottom = rect[3];

    var newPath = container.pathItems.add();
    newPath.setEntirePath([
        [left, top],
        [right, top],
        [right, bottom],
        [left, bottom],
    ]);
    newPath.closed = true;

    return newPath;

};

Edit 2023-08-25: fixed typo. Added a path style doc reference.