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

InDesign script to randomly apply color swatches to text characters

New Here ,
Apr 19, 2024 Apr 19, 2024

Currently working in InDesign cc2022.

I found this older thread that seems like the exact thing I need, but the code didn't work for me.

 

https://community.adobe.com/t5/indesign-discussions/script-random-colours-on-letters/td-p/7073766

TOPICS
How to , Scripting
1.8K
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 , Apr 24, 2024 Apr 24, 2024

Hi @Paperback Pat, okay so on private message you've added a couple of new parts: (1) target a paragraph style, and (2) specify and a color order with no repetitions. By supplying a demo document (I've attached it here for anyone to follow along) you've also confirmed that you only want colors from a specific color group. That's enough information for me to configure the script. I'll list it again, rather than update the original one, because this also has the extra function `getTexts` which is

...
Translate
Community Expert ,
Apr 19, 2024 Apr 19, 2024

Forum migration stripped iterators a while back. In the last line, it should read "chars[i]" at the start of the line, without quotes. I think that's the only change needed. 

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
New Here ,
Apr 19, 2024 Apr 19, 2024

Thank you so much, that worked!

 

Same as the OP from the link above, I wonder how to limit this to a Color Group within Swatches.

 

Any ideas?

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 ,
Apr 20, 2024 Apr 20, 2024

Any ideas?

 

Hi @Paperback Pat , The OP wanted to skip the default Paper, None, Black, and Registration swatches—you could do that like this:

 

var tf = app.activeDocument.selection[0];
var chars = tf.characters.everyItem().getElements();
var col = app.activeDocument.swatches.length-1;
var c
for (var i=0; i<chars.length; i++){
    c = app.activeDocument.swatches[Math.floor((Math.random() * col) + 1)]
    if (c.name!="Black" || c.name!="Paper" || c.name!="Registration"|| c.name!="None") {
        chars[i].fillColor=c
    } 
}

 

 

Or to use a group you could do this where "MyGroup" is the name of the group you want to use:

 
var cg = app.activeDocument.colorGroups.itemByName("MyGroup").colorGroupSwatches.everyItem().getElements()
var tf = app.activeDocument.selection[0];
var chars = tf.characters.everyItem().getElements();
var col = cg.length-1;
var c
for (var i=0; i<chars.length; i++){
    c = cg[Math.floor((Math.random() * col) + 1)]
    chars[i].fillColor = c.swatchItemRef
}
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 ,
Apr 20, 2024 Apr 20, 2024

@Paperback Pat I wrote a function `getDocumentColors` for getting colors from a document. I think this will be handy for many cases. It gives option for including and excluding both Swatches and ColorGroups, or a filter option.

 

Also the `colorCharacters` function is a bit flexible by way of using custom characterPicker or colorPicker functions as parameters. But you can ignore all those details if not relevent to your situation. Just try it out.

 

Let me know if it helps, or isn't quite working the way you want—there's a good chance it'll be easy to adjust.

- Mark

/**
 * @file Color Characters.js
 *
 * There are two working parts to this script:
 *
 *   1. `getDocumentColors` function, which will collect colors
 *      from the document based on the parameters specified; and
 *
 *   2. `colorCharacters` function, which assigns the colors
 *      from (1) to the characters of the selected items.
 *
 * See function documentation below for info.
 *
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/indesign-script-to-randomly-apply-color-swatches-to-text-characters/m-p/14567096
 */
function main() {

    if (0 === app.documents.length)
        return alert('Please select some text and try again.');

    var doc = app.activeDocument,

        colors = getDocumentColors({

            doc: doc,
            // includeSwatches: ['C=100 M=0 Y=0 K=0', 'C=0 M=100 Y=0 K=0'],
            excludeSwatches: ['None', 'Registration', 'Paper'],
            // includeColorGroups: ['MyWantedColorGroup'],
            // excludeColorGroups: ['MyUnwantedColorGroup'],
            // filter: function (swatchName) { return /^PANTONE/.test(swatchName) },

        });

    if (0 === colors.length)
        return alert('No colors were found with the current options.');

    // do the coloring
    colorCharacters(doc.selection, colors);

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Color Characters');


/**
 * Returns an array of colors from a document.
 * ----------------------------------------------
 * General usage notes:
 *   - leave `includeSwatches` undefined to use every swatch
 *   - using `filter` will override all other parameters.
 * ----------------------------------------------
 * Example 1 - Get all swatches, except some:
 *
 *   var colors = getDocumentColors({
 *       doc: doc,
 *       excludeSwatches: ['None', 'Registration', 'Paper'],
 *   });
 * ----------------------------------------------
 * Example 3 - Get all swatches in a color group:
 *
 *   var colors = getDocumentColors({
 *       doc: doc,
 *       includeColorGroup: 'My Favourite Colours',
 *   });
 * ----------------------------------------------
 * Example 2 - Get all swatches with name starting "PANTONE":
 *
 *   var colors = getDocumentColors({
 *       doc: doc,
 *       filter: function (swatchName) {
 *         return /^PANTONE/.test(swatchName);
 *       },
 *   });
 * ----------------------------------------------
 * @author m1b
 * @version 2024-04-20
 * @param {Object} options
 * @param {Array<String>} [options.includeSwatches] - swatch names to specifically include (default: include all swatches).
 * @param {Array<String>} [options.excludeSwatches] - swatch names to specifically exclude (default: no exclusions).
 * @param {Array<String>} [options.includeColorGroups] - color group names to specifically include (default: include all color groups).
 * @param {Array<String>} [options.excludeColorGroups] - color group names to specifically exclude (default: no exclusions).
 * @param {Function} [options.filter] - function that returns true to include swatch (default: no filter).
 * @returns {Array<Color>}
 */
function getDocumentColors(options) {

    options = options || {};

    var doc = options.doc || app.activeDocument,
        includeSwatches = options.includeSwatches || [],
        excludeSwatches = options.excludeSwatches || [],
        includeColorGroups = options.includeColorGroups || [],
        excludeColorGroups = options.excludeColorGroups || [],
        filter = options.filter;

    const INCLUDE_ALL_SWATCHES = (
        0 === includeColorGroups.length
        && 0 === includeSwatches.length
        && undefined == filter
    );

    var allSwatches = doc.colorGroups.everyItem().colorGroupSwatches.everyItem().swatchItemRef,
        swatches = [];

    for (var i = 0, sw; i < allSwatches.length; i++) {

        sw = allSwatches[i];

        if (undefined != filter) {
            // include according to filter function
            if (filter(sw.name))
                swatches.push(sw);
            else
                continue;
        }

        if (
            getThing(excludeSwatches, undefined, sw.name)
            || getThing(excludeColorGroups, undefined, sw.parentColorGroup.name)
        )
            // ignore specifically-excluded swatch
            continue;

        if (

            // include all swatches by default
            INCLUDE_ALL_SWATCHES

            // include swatch in specific color group
            || getThing(includeColorGroups, undefined, sw.parentColorGroup.name)

            // include specific swatch
            || getThing(includeSwatches, undefined, sw.name)

        )
            swatches.push(sw);

    }

    return swatches;

};

/**
 * Assigns fill color to selected text randomly.
 * ----------------------------------------------
 * Example `colorIndexPicker` functions:
 *
 *    function cycler(ch, index, max) {
 *        // return the next value, in order, cycling
 *        return index % max;
 *    };
 *
 * ----------------------------------------------
 * Example `characterPicker` functions:
 *
 *    function pickHalfCharacters() {
 *        return Math.random() < 0.5;
 *    }
 *
 *    function pickEveryNthCharacter(ch, index) {
 *        var n = 2;
 *        return (index + 1) % n === 0;
 *    }
 * ----------------------------------------------
 * @author m1b
 * @version 2024-04-20
 * @param {Array|Collection<TextFrame|Text>} things - array or collection of DOM object's with characters.
 * @param {Array<Color|null>} colors - array of colors to use.
 * @param {Function} [colorIndexPicker] - function that determines which color to use (default: pick random color).
 * @param {Function} [characterPicker] - function that determines if a character is colored (default: pick every character).
 */
function colorCharacters(things, colors, colorIndexPicker, characterPicker) {

    colorIndexPicker = colorIndexPicker || defaultColorPicker;
    characterPicker = characterPicker || defaultCharacterpPicker;

    for (var i = 0, characters; i < things.length; i++) {

        if (!things[i].hasOwnProperty('characters'))
            continue;

        if (things[i].hasOwnProperty('pageItems'))
            colorCharacters(things[i].pageItems, colors, colorIndexPicker, characterPicker);

        if (things[i].hasOwnProperty('tables'))
            colorCharacters(things[i].tables.everyItem().cells, colors, colorIndexPicker, characterPicker);

        if (things[i].hasOwnProperty('footnotes'))
            colorCharacters(things[i].footnotes, colors, colorIndexPicker, characterPicker);

        characters = things[i].characters;

        characterLoop:
        for (var j = 0, r, len = characters.length; j < len; j++) {

            if (!characterPicker(characters[j], j, len - 1))
                continue characterLoop;

            r = colorIndexPicker(characters[j], j, colors.length);
            characters[j].fillColor = colors[r];

        }

    }

    function defaultColorPicker(ch, index, max) {
        return Math.floor(Math.random() * max);
    };

    function defaultCharacterpPicker() {
        return true;
    };

};

/**
 * Returns a thing with a `key` matching `value`.
 * If `key` is undefined, evaluate the object itself.
 * @author m1b
 * @version 2024-04-20
 * @param {Array|Collection} things - the things to look through.
 * @param {String} [key] - the property name (default: undefined).
 * @param {*} value - the value to match.
 * @returns {*}
 */
function getThing(things, key, value) {

    for (var i = 0, obj; i < things.length; i++)
        if ((undefined == key ? things[i] : thing[i][key]) == value)
            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
New Here ,
Apr 22, 2024 Apr 22, 2024

I very much appreciate the feedback, @m1b @rob day 

I wasn't able to get any of these working well. Please keep in mind, I'm not a programmer. I was able to create a script off of the following code that works, but I'd like to limit it the swatches to a color group of 5 colors, that it randomly, and even (ideally) applies.

@m1b – I couldn't get any of your scripts to run for me. Not sure what I'm doing wrong, but it also didn't return any errors, just didn't affect the colors or provide any feedback.

 

@rob day – I was able to get yours to run, but the results were

 

I think I'm getting some of the brackets wrong when I input your codes. Would it be possible to receive the full code to copy/paste, so that I'm not missing the correct beginining/end brackets?

 

This is the original code that @brian_p_dts  helped with that's working, but I need to limit or exclude certain swatches.

 

Also, being able to undo the entire script sequence could be helpful?

 

(function(){

var tf=app.activeDocument.selection[0];
var chars=tf.characters.everyItem().getElements();
var col=app.activeDocument.swatches.length-1;

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

var rand=Math.floor((Math.random() * col) + 1);

chars[i].fillColor=app.activeDocument.swatches[rand];
}
}());

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
New Here ,
Apr 22, 2024 Apr 22, 2024

@rob day - to complete my incomplete thought above. I was able to get your scripts to run, but they didn't work as expected. The first script still included Paper, None, Black, and Registration colors.

 

The second script did limit to a color group of 5 colors, however it only applied 4 of those 5 colors and not very randomly. 

 

Thanks for the all the ideas, but so far no bullseyes.

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 ,
Apr 22, 2024 Apr 22, 2024

The first script still included Paper, None, Black, and Registration colors.

 

Sorry, I should have checked–the || need to be &&:

 

Before:

Screen Shot 43.png

 

After:

Screen Shot 42.png

 

This lets you undo:

 

function randomFill(){
    var tf = app.activeDocument.selection[0];
    var chars = tf.characters.everyItem().getElements();
    var col = app.activeDocument.swatches.length-1;
    var c
    for (var i=0; i<chars.length; i++){
        c = app.activeDocument.swatches[Math.floor((Math.random() * col) + 1)]
        if (c.name!="Black" && c.name!="Paper" && c.name!="Registration" && c.name!="None") {
            chars[i].fillColor=c;
        } 
    }
}

app.doScript(randomFill, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Random Character Colors');

 

 

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
New Here ,
Apr 22, 2024 Apr 22, 2024

I appreciate this @rob day – the undo works great!

Still getting Black in the results, though. I'm not getting Paper, Registration, or None, but still getting black ...

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 ,
Apr 22, 2024 Apr 22, 2024

Right, sorry again, I got caught up in editing the code from the post you linked to.

 

If the random color is one of the colors you are trying to skip it just leaves the character with its starting color—Black in your case. You’ll need to create a custom array of colors:

 

Screen Shot 44.png

 

function randomFill(){
    var tf = app.activeDocument.selection[0];
    var chars = tf.characters.everyItem().getElements();
    var c = app.activeDocument.swatches.everyItem().getElements();
    var ca = [];
    for (var i = 0; i < c.length; i++){
        if (c[i].name!="Black" && c[i].name!="Paper" && c[i].name!="Registration" && c[i].name!="None") {
            ca.push(c[i])
        }
    };   
    for (var i=0; i<chars.length; i++){
        chars[i].fillColor=ca[Math.floor((Math.random() * ca.length))];
    }
}

app.doScript(randomFill, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Random Character Colors');
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 ,
Apr 22, 2024 Apr 22, 2024

Hi @Paperback Pat, did you configure my script to suit your requirements? If you are having trouble, let me know what colors or color group you want to use and I'll tell you how to configure for that. Including a demo .indd would be good, too.

- Mark

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
New Here ,
Apr 22, 2024 Apr 22, 2024

@m1b I wasn't able to get your script working for me, but it's probably my lack of knowledge with the code. Either nothing would happen (your original code), or I'd get code errors when running the script (because I was trying to insert your code into the original code or something). 

Is the code you supplied me complete, or truncated? Do I just copy paste the exact thing into my .jsx file? That's what I tried, and nothing happened, so then I tried just sections of it, or merging it with other code, and then I started running into error messages. 

I'll provide a demo file when I can!

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 ,
Apr 22, 2024 Apr 22, 2024

Hi @Paperback Pat my code is complete, but not configured. You need to do that part. I can do it for you, if you post a demo.indd and tell me which color group to use or which colors to pick.

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
New Here ,
Apr 23, 2024 Apr 23, 2024

thanks so much! I only know enough about this to get into a little trouble, so thank you for your patience!

I sent you a link to a demo file. 

One more note, and something to add to the wishlist would be a way to control the color order so it's pink, orange, green, navy, turquoise.

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 ,
Apr 24, 2024 Apr 24, 2024

Hi @Paperback Pat, okay so on private message you've added a couple of new parts: (1) target a paragraph style, and (2) specify and a color order with no repetitions. By supplying a demo document (I've attached it here for anyone to follow along) you've also confirmed that you only want colors from a specific color group. That's enough information for me to configure the script. I'll list it again, rather than update the original one, because this also has the extra function `getTexts` which is the function that collects the headings to color.

 

Also, to make it easier for you to see what you can adjust, I've moved the configuration details into a `settings` object at the start of the script. You will see what I mean when you read the script below.

 

Oh, I've also added a `shuffler` function for randomizing the colors such that they are shuffled around in batches—so each batch of colours is shuffled each time they cycle, with a quick check to make sure that the first and last colors in the batches don't match. The result should be that no two colors are adjacent. You can change "colorPicker: shuffler" to "colorPicker: cycler" if you want to see what happens if each color is applied in turn.

 

There's bound to be bugs, because I only tested on your simple document, but it's a starting point. Let me know how it goes.

- Mark

 

/**
 * @file Color Characters.js
 *
 * There are three working parts to this script, each of which
 * can be configured:
 * 
 *   1. `getTexts` function which collects texts from the document.
 * 
 *   2. `getColors` function, which will collect colors
 *      from the document based on the parameters specified; and
 *
 *   3. `colorCharacters` function, which assigns colors to characters.
 *
 * See each function's documentation below.
 *
 * @author m1b
 * @discussion https://community.adobe.com/t5/indesign-discussions/indesign-script-to-randomly-apply-color-swatches-to-text-characters/m-p/14567096
 */
function main() {

    var settings = {
        paragraphStyleName: 'Chap_Title',
        colorGroupName: 'Chap_Title_Colors',
        colorPicker: shuffler,
    };

    if (0 === app.documents.length)
        return alert('Please select some text and try again.');

    var doc = app.activeDocument;

    var texts = getTexts({
        items: doc,
        findGrepPreferences: {
            appliedParagraphStyle: settings.paragraphStyleName,
        },
    });

    if (0 === texts.length)
        return alert('No texts were found with the current options.');

    var colors = getColors({
        doc: doc,
        includeColorGroups: [settings.colorGroupName],
    });

    if (0 === colors.length)
        return alert('No colors were found with the current options.');

    // do the coloring
    colorCharacters(texts, colors, settings.colorPicker);

    // finished!

    /**
     * Returns a random number between 0 and `max`,
     * cycling when `index` exceeds `max`.
     * @author m1b
     * @version 2024-04-24
     * @param {Character} [ch] - a character (not used)
     * @param {Number} index - the character index.
     * @param {Number} max - the maximum index.
     * @returns {Number} - a random index
     */
    function shuffler(ch, index, max) {

        index = index % max;

        var self = callee;

        if (0 === index) {

            // randomize once every cycle

            self.arr = [];
            for (var i = 0; i < max; i++)
                self.arr[i] = i;

            var i = max,
                r,
                temp;

            while (i--) {

                r = Math.floor(Math.random() * (i + 1));
                // swap randomly chosen element with current element
                temp = self.arr[i];
                self.arr[i] = self.arr[r];
                self.arr[r] = temp;

                if (0 === i && self.previousIndex === self.arr[0]) {
                    // swap first two to avoid adjacent values
                    temp = self.arr[0];
                    self.arr[0] = self.arr[1];
                    self.arr[1] = temp;
                }

            }

            self.previousIndex = self.arr[max - 1];

        }

        return self.arr[index];

    };

};

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Color Characters');


/**
 * Returns an array of colors from a document.
 * ----------------------------------------------
 * General usage notes:
 *   - leave `includeSwatches` undefined to use every swatch
 *   - using `filter` will override all other parameters.
 * ----------------------------------------------
 * Example 1 - Get all swatches, except some:
 *
 *   var colors = getColors({
 *       doc: doc,
 *       excludeSwatches: ['None', 'Registration', 'Paper'],
 *   });
 * ----------------------------------------------
 * Example 3 - Get all swatches in a color group:
 *
 *   var colors = getColors({
 *       doc: doc,
 *       includeColorGroup: 'My Favourite Colours',
 *   });
 * ----------------------------------------------
 * Example 2 - Get all swatches with name starting "PANTONE":
 *
 *   var colors = getColors({
 *       doc: doc,
 *       filter: function (swatchName) {
 *         return /^PANTONE/.test(swatchName);
 *       },
 *   });
 * ----------------------------------------------
 * @author m1b
 * @version 2024-04-20
 * @param {Object} options
 * @param {Array<String>} [options.includeSwatches] - swatch names to specifically include (default: include all swatches).
 * @param {Array<String>} [options.excludeSwatches] - swatch names to specifically exclude (default: no exclusions).
 * @param {Array<String>} [options.includeColorGroups] - color group names to specifically include (default: include all color groups).
 * @param {Array<String>} [options.excludeColorGroups] - color group names to specifically exclude (default: no exclusions).
 * @param {Function} [options.filter] - function that returns true to include swatch (default: no filter).
 * @returns {Array<Color>}
 */
function getColors(options) {

    options = options || {};

    var doc = options.doc || app.activeDocument,
        includeSwatches = options.includeSwatches || [],
        excludeSwatches = options.excludeSwatches || [],
        includeColorGroups = options.includeColorGroups || [],
        excludeColorGroups = options.excludeColorGroups || [],
        filter = options.filter;

    const INCLUDE_ALL_SWATCHES = (
        0 === includeColorGroups.length
        && 0 === includeSwatches.length
        && undefined == filter
    );

    var allSwatches = doc.colorGroups.everyItem().colorGroupSwatches.everyItem().swatchItemRef,
        swatches = [];

    for (var i = 0, sw; i < allSwatches.length; i++) {

        sw = allSwatches[i];

        if (undefined != filter) {
            // include according to filter function
            if (filter(sw.name))
                swatches.push(sw);
            else
                continue;
        }

        if (
            getThing(excludeSwatches, undefined, sw.name)
            || getThing(excludeColorGroups, undefined, sw.parentColorGroup.name)
        )
            // ignore specifically-excluded swatch
            continue;

        if (

            // include all swatches by default
            INCLUDE_ALL_SWATCHES

            // include swatch in specific color group
            || getThing(includeColorGroups, undefined, sw.parentColorGroup.name)

            // include specific swatch
            || getThing(includeSwatches, undefined, sw.name)

        )
            swatches.push(sw);

    }

    return swatches;

};

/**
 * Assigns fill color to selected text randomly.
 * ----------------------------------------------
 * Example `colorIndexPicker` functions:
 *
 *    function cycler(ch, index, max) {
 *        // return the next value, in order, cycling
 *        return index % max;
 *    };
 *
 * ----------------------------------------------
 * Example `characterPicker` functions:
 *
 *    function pickHalfCharacters() {
 *        return Math.random() < 0.5;
 *    }
 *
 *    function pickEveryNthCharacter(ch, index) {
 *        var n = 2;
 *        return (index + 1) % n === 0;
 *    }
 * ----------------------------------------------
 * @author m1b
 * @version 2024-04-20
 * @param {Array|Collection<TextFrame|Text>} things - array or collection of DOM object's with characters.
 * @param {Array<Color|null>} colors - array of colors to use.
 * @param {Function} [colorIndexPicker] - function that determines which color to use (default: pick random color).
 * @param {Function} [characterPicker] - function that determines if a character is colored (default: pick every character).
 */
function colorCharacters(things, colors, colorIndexPicker, characterPicker) {

    colorIndexPicker = colorIndexPicker || defaultColorPicker;
    characterPicker = characterPicker || defaultCharacterpPicker;

    if (undefined == things[0])
        things = [things];

    for (var i = 0, characters; i < things.length; i++) {

        if (!things[i].hasOwnProperty('characters'))
            continue;

        if (things[i].hasOwnProperty('pageItems'))
            colorCharacters(things[i].pageItems, colors, colorIndexPicker, characterPicker);

        if (things[i].hasOwnProperty('tables'))
            colorCharacters(things[i].tables.everyItem().cells, colors, colorIndexPicker, characterPicker);

        if (things[i].hasOwnProperty('footnotes'))
            colorCharacters(things[i].footnotes, colors, colorIndexPicker, characterPicker);

        characters = things[i].characters;

        characterLoop:
        for (var j = 0, r, len = characters.length; j < len; j++) {

            if (!characterPicker(characters[j], j, len - 1))
                continue characterLoop;

            // get the next color index
            r = colorIndexPicker(characters[j], j, colors.length);

            // color the character
            characters[j].fillColor = colors[r];

        }

    }

    function defaultColorPicker(ch, index, max) {
        return Math.floor(Math.random() * max);
    };

    function defaultCharacterpPicker() {
        return true;
    };

};

/**
 * Returns a thing with a `key` matching `value`.
 * If `key` is undefined, evaluate the object itself.
 * @author m1b
 * @version 2024-04-20
 * @param {Array|Collection} things - the things to look through.
 * @param {String} [key] - the property name (default: undefined).
 * @param {*} value - the value to match.
 * @returns {*}
 */
function getThing(things, key, value) {

    for (var i = 0, obj; i < things.length; i++)
        if ((undefined == key ? things[i] : thing[i][key]) == value)
            return things[i];

};


/**
 * Returns texts found in `items`.
 * 
 * Note: this is intended to use with
 * findGrep - it won't work without
 * a `findGrepPreferences` object.
 * ----------------------------------------------
 * Example - styled paragraphs of document:
 *
 *   var texts = getTexts({
 *     items: doc,
 *     findGrepPreferences: {
 *         appliedParagraphStyle: 'My Style',
 *     },
 *   });
 * ----------------------------------------------
 * @author m1b
 * @version 2024-04-24
 * @param {Object} options
 * @param {*} options.items - the DOM objects to extract text from, eg. Document or Document.selection.
 * @param {Object} options.findGrepPreferences - properties to configure findGrep.
 * @param {Function} [options.filter] - function that, given the object, returns true to collect its text (default: no filter).
 * @returns {Array<Text>}
 */
function getTexts(options) {

    options = options || {};

    if (undefined == options.items)
        throw Error('getTexts: expected `options.items` parameter.');

    if (undefined == options.findGrepPreferences)
        throw Error('getTexts: expected `options.findGrepPreferences` parameter.');

    var items = options.items,
        texts = [];

    if ('Document' === items.constructor.name)
        items = items.stories;

    if (!items.hasOwnProperty(0))
        items = [items];

    // set up find grep
    app.findGrepPreferences = NothingEnum.NOTHING;
    app.changeGrepPreferences = NothingEnum.NOTHING;

    for (var key in options.findGrepPreferences)
        if (options.findGrepPreferences.hasOwnProperty(key))
            app.findGrepPreferences[key] = options.findGrepPreferences[key];

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

        if (
            undefined != options.filter
            && true !== options.filter(items[i])
        )
            continue;

        if (
            undefined != items[i].contents
            && 0 === items[i].contents.length
        )
            continue;

        if ('function' !== typeof items[i].findGrep)
            continue;

        texts = texts.concat(items[i].findGrep());

    }

    return texts;

};

 

 

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
New Here ,
Apr 24, 2024 Apr 24, 2024
LATEST

Thank you so much, to everyone here who helped. This script is great!

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