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

New color group whit script ?

Explorer ,
Jun 16, 2023 Jun 16, 2023

Hello everyone, I tried to show with the pictures

what I want to do with the script.

Is there someone who can help me with this?

1-) Select all in layer

2-) New Color Group

3-) Add name for new color group.With default settings.

4-)And result like this

Untitled-1-01.jpg

TOPICS
How-to , Scripting
477
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

Community Expert , Jun 16, 2023 Jun 16, 2023

Hi,

Try following version

var doc = app.activeDocument;
for (var l = 0; l < doc.layers.length; l++) {
    app.executeMenuCommand('deselectall');
    var _layer = doc.layers[l];
    _layer.hasSelectedArtwork = true;
    addColorGroup();

}

function addColorGroup() {
    var actionStr = [
        "/version 3",
        "/name [ 5",
        "	5365742031",
        "]",
        "/isOpen 1",
        "/actionCount 1",
        "/action-1 {",
        "	/name [ 9",
        "		416464436f6c6f7273",
        
...
Translate
Adobe
Community Expert ,
Jun 16, 2023 Jun 16, 2023

Hi,

Try following version

var doc = app.activeDocument;
for (var l = 0; l < doc.layers.length; l++) {
    app.executeMenuCommand('deselectall');
    var _layer = doc.layers[l];
    _layer.hasSelectedArtwork = true;
    addColorGroup();

}

function addColorGroup() {
    var actionStr = [
        "/version 3",
        "/name [ 5",
        "	5365742031",
        "]",
        "/isOpen 1",
        "/actionCount 1",
        "/action-1 {",
        "	/name [ 9",
        "		416464436f6c6f7273",
        "	]",
        "	/keyIndex 0",
        "	/colorIndex 0",
        "	/isOpen 0",
        "	/eventCount 1",
        "	/event-1 {",
        "		/useRulersIn1stQuadrant 0",
        "		/internalName (ai_plugin_swatches)",
        "		/localizedName [ 8",
        "			5377617463686573",
        "		]",
        "		/isOpen 1",
        "		/isOn 1",
        "		/hasDialog 1",
        "		/showDialog 0",
        "		/parameterCount 1",
        "		/parameter-1 {",
        "			/key 1835363957",
        "			/showInPalette 4294967295",
        "			/type (enumerated)",
        "			/name [ 15",
        "				4e657720436f6c6f722047726f7570",
        "			]",
        "			/value 17",
        "		}",
        "	}",
        "}",
        ""
    ].join("\n");

    var actionFileDestStr = Folder.desktop + "/MyAction.aia";
    var actionFile = File(actionFileDestStr);
    actionFile.open('w');
    actionFile.write(actionStr);
    actionFile.close();
    app.loadAction(actionFile);
    app.doScript("AddColors", "Set 1");
    actionFile.remove();
    app.unloadAction("Set 1", '');
}
Best regards
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
Explorer ,
Jun 16, 2023 Jun 16, 2023

It's perfect. exactly as I want.
thanks

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 ,
Jun 16, 2023 Jun 16, 2023

Hi @Goldberg_1453, just before posting this I see that you already have @Charu Rajput's excellent and efficient answer and probably don't need my long-winded contribution.

 

However, our two scripts take very different approaches, and will have different results depending on your exact situation. For example, I think that Charu's script has the advantage of including more than just the first fill and stroke colors (ie. complex appearances) because it executes built-in menu commands, whereas my script does everything through the scripting DOM. Anyway, on the chance that you—or someone else coming here—would benefit from seeing my different approach, here it is, mostly based on functions I have written beforehand.

- Mark

/**
 * Collects colors from selected items, and
 * populates a swatch group with those colors.
 * Notes:
 * - IMPORTANT: can only work with an item's *basic*
 *   appearance, meaning its first fillColor and strokeColor.
 * @author m1b
 * @discussion https://community.adobe.com/t5/illustrator-discussions/new-color-group-whit-script/m-p/13871446
 */
(function () {

    var settings = {
        colorGroupName: 'My Color Group',
        showResults: true,
        showUI: true,
    };

    var colorGroupName = settings.colorGroupName,
        doc = app.activeDocument,
        items = itemsInsideGroupItems(doc.selection);

    if (items.length == 0) {
        alert('Please select one or more page items and try again.');
        return;
    }

    if (
        settings.showUI
        && !(colorGroupName = prompt('Enter name for color group:', colorGroupName))
    )
        return;

    var results = makeSwatchGroupFromItemsColors(items, doc, colorGroupName);

    if (settings.showResults)
        alert('Collected ' + results.addedColorsCount + ' colors.');

})();


/**
 * Creates a new SwatchGroup populated with
 * colors derived from the supplied items.
 * Note: function will *duplicate* existing
 * global or spot colors and spot tints.
 * @author m1b
 * @version 2023-06-17
 * @param {Array<PageItem>} items - Illustrator page items.
 * @param {Document} doc - the Illustrator Document to convert.
 * @param {String} name - the name of the new SwatchGroup.
 */
function makeSwatchGroupFromItemsColors(items, doc, name) {

    var colorables = [],
        colorablesCounter = 0,
        addedColorsCounter = 0,
        alreadyProcessed = {};

    // get the basic colorables
    for (var i = 0; i < items.length; i++)
        colorables = colorables.concat(getBasicColorablesFromItem(doc, items[i]));

    colorablesCounter += colorables.length;

    // make the swatch group
    var swatchGroup = getByName(doc.swatchGroups, name);
    if (!swatchGroup) {
        swatchGroup = doc.swatchGroups.add();
        swatchGroup.name = name;
    }

    for (var i = 0; i < colorables.length; i++) {

        var col = colorables[i].color,
            id = stringify(col);

        if (alreadyProcessed[id])
            continue;
        else
            alreadyProcessed[id] = true;

        var sw = doc.swatches.add();
        sw.color = col;
        swatchGroup.addSwatch(sw);
        addedColorsCounter++;

    }

    return {
        colorableCount: colorablesCounter,
        addedColorsCount: addedColorsCounter,
    };

};



/**
 * Returns array of swatches or colors
 * found in fill or stroke of page item.
 * @author m1b
 * @version 2022-10-11
 * @param {PageItem} item - an Illustrator page item.
 * @returns {Object} -  {fillColors: Array<Color>, strokeColors: Array<Color>}
 */
function getBasicColorablesFromItem(doc, item) {

    if (item == undefined)
        throw Error('getBasicColorablesFromItem: No `item` supplied.');

    var colorables = [];

    // collect all the colorables
    if (item.constructor.name == 'PathItem') {
        colorables = colorables.concat(getBasicColorables(item));
    }

    else if (
        item.constructor.name == 'CompoundPathItem'
        && item.pathItems
    ) {
        colorables = colorables.concat(getBasicColorables(item.pathItems[0]));
    }

    else if (
        item.constructor.name == 'RasterItem'
    ) {
        // only way to get the raster item's color
        var originalSelection = doc.selection;
        doc.selection = [item];
        colorables.push({
            color: doc.defaultFillColor,
            colorize: item,
        });
        doc.selection = originalSelection;
    }

    else if (
        item.constructor.name == 'TextFrame'
        && item.textRanges
    ) {
        var ranges = getTextStyleRanges(item.textRange, ['fillColor', 'strokeColor']);
        for (var i = ranges.length - 1; i >= 0; i--)
            colorables = colorables.concat(getBasicColorables(ranges[i]));
    }

    else if (item.constructor.name == 'GroupItem') {
        for (var i = 0; i < item.pageItems.length; i++)
            colorables = colorables.concat(getBasicColorables(item.pageItems[i]));

    }

    return colorables;

};



/**
 * Returns array of colorable things.
 * @date 2023-04-20
 * @param {PageItem} item - an Illustrator page item.
 * @returns {Array<Object>}
 */
function getBasicColorables(item) {

    var colorables = [],
        noColor = "[NoColor]";

    if (
        item.hasOwnProperty('fillColor')
        && item.fillColor != noColor
        && (
            !item.hasOwnProperty('filled')
            || item.filled == true
        )
        && item.fillColor != undefined
    )
        colorables.push({
            color: item.fillColor,
            fillColor: item
        });

    if (
        item.hasOwnProperty('strokeColor')
        && item.strokeColor != noColor
        && (
            !item.hasOwnProperty('stroked')
            || item.stroked == true
        )
        && item.strokeColor != undefined
    )
        colorables.push({
            color: item.strokeColor,
            strokeColor: item
        });

    return colorables;

};


/**
 * Returns an array of TextRanges,
 * determined by mapping changes
 * in supplied keys. For example,
 * supplying the 'fillColor' key
 * will return ranges divided when
 * the text's fillColor changes.
 * @author m1b
 * @version 2023-04-26
 * @param {TextRange} textRange - an Illustrator TextRange.
 * @param {Array<String>} keys - an array of keys to match, eg ['fillColor'].
 */
function getTextStyleRanges(textRange, keys) {

    if (
        textRange == undefined
        || textRange.constructor.name != 'TextRange'
    )
        throw Error('getTextStyleRanges: bad `textRange` supplied.');

    if (
        keys == undefined
        || keys.constructor.name != 'Array'
    )
        throw Error('getTextStyleRanges: bad `textRange` supplied.');

    // check keys are valid
    for (var j = 0; j < keys.length; j++)
        if (!textRange.characterAttributes.hasOwnProperty(keys[j]))
            throw Error('getTextStyleRanges: bad key supplied ("' + keys[j] + '")');

    var ranges = [],
        start = 0,
        currentValues = {};

    charactersLoop:
    for (var i = 0; i < textRange.length; i++) {

        var tr = textRange.textRanges[i],
            matches = true;

        // check each key
        keysLoop:
        for (var j = 0; j < keys.length; j++) {

            if (i == 0)
                currentValues[keys[j]] = tr.characterAttributes[keys[j]];

            else if (stringify(tr.characterAttributes[keys[j]]) !== stringify(currentValues[keys[j]])) {
                matches = false;
                break keysLoop;
            }
        }

        currentValues[keys[j]] = tr.characterAttributes[keys[j]];

        if (
            i == textRange.length - 1
            || !matches
        ) {
            // start a new range
            var newTextRange = textRange.textRanges[start];
            newTextRange.end = i == textRange.length - 1 ? i + 1 : i;
            ranges.push(newTextRange);
            start = i;
        }

    }

    return ranges;

};


/**
 * Stringify tailored for the purpose
 * of identifying identical Swatches.
 * @author m1b
 * @version 2023-04-26
 * @param {Object} obj - the object to stringify.
 * @returns {String}
 */
function stringify(obj) {

    var str = obj.toString();

    for (var key in obj) {

        if (!obj.hasOwnProperty(key))
            continue;

        if (
            key == 'spot'
            || key == 'color'
        )
            str += stringify(obj[key]);

        else
            str += obj[key];

    }

    return str;

};


/**
 * Returns array containing items, including
 * items found inside GroupItems
 * @author m1b
 * @version 2022-05-23
 * Example usage:
 * var items = itemsInsideGroupItems(doc.selection, ['PathItem', 'CompoundPathItem']);
 * @param {Array<PageItem>} items - array or collection of Illustrator page items.
 * @param {String|Array<String>} [typenames] - item constructor names to target (default: target all typenames).
 * @param {Number} [level] - recursion level (private parameter).
 * @returns {Array<PathItem>} the path items found.
 */
function itemsInsideGroupItems(items, typenames, level) {

    try {

        if (level == undefined)
            level = 0;

        var found = [];

        for (var i = 0; i < items.length; i++) {

            var item = items[i];

            if (
                item.uuid == undefined
                || item.parent.typename == 'CompoundPathItem'
            )
                continue;

            if (item.typename == 'GroupItem') {
                found = found.concat(itemsInsideGroupItems(item.pageItems, typenames, level + 1));
            }

            else if (typenames === undefined || itemIsType(item, typenames)) {
                found.push(item);
            }

        }

        return found;

    } catch (err) {
        alert('itemsInsideGroupItems: ' + err)
    }

};


/**
 * Returns true if item.typename
 * matches any of the typenames supplied.
 * @param {PageItem} item - an Illustrator page item.
 * @param {String|Array<String>} typenames - the typenames to check against.
 * @returns {Boolean}
 */
function itemIsType(item, typenames) {

    if (!typenames.constructor.name == 'Array')
        typenames = [typenames];

    var matched = false;
    for (var i = 0; i < typenames.length; i++) {
        if (typenames[i] == item.typename) {
            matched = true;
            break;
        }
    }

    return matched;

};


/**
 * Gets a thing by name from array of named things.
 * @param {Array<any>} things - array of named things.
 * @param {String} name - the name to look for.
 * @returns {Any} - the found thing.
 */
function getByName(things, name) {
    for (var i = 0; i < things.length; i++)
        if (things[i].name == name)
            return things[i];
};

 

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 ,
Jun 18, 2023 Jun 18, 2023
LATEST

@m1b - Thank you, We shoould always have second approach to do things, you never know what section of code give you something new.. 🙂

Best regards
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