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

How to batch color hundreds of text boxes with matching swatches?

Community Beginner ,
Oct 28, 2022 Oct 28, 2022

Copy link to clipboard

Copied

I have an indesign file where I need to color the background of a text box. The text contained within that text box is also the name of a corresponding swatch. I have imported hundreds of swatches, with matching texts.

I want to use Data Merge or XML import to batch color each entry in my database.

How could I achieve this ?

I have tried several old scripts that used HEX, RGB or CMYK but none of them worked with recent Indesign versions.

TOPICS
Scripting

Views

216

Translate

Translate

Report

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 ,
Oct 28, 2022 Oct 28, 2022

Copy link to clipboard

Copied

Hi @Federico267836568h03, please try this script and let me know if I have understood your request. - Mark

/**
 * Set the fillColor of any text frame
 * whose contents matches a swatch name.
 * @author m1b
 * @version 2022-10-29
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-batch-color-hundreds-of-text-boxes-with-matching-swatches/m-p/13305809
 */
function main() {

    var doc = app.activeDocument,
        textFrames = doc.textFrames,
        swatches = doc.swatches;

    for (var i = 0; i < textFrames.length; i++)
        for (var j = 0; j < swatches.length; j++)
            if (swatches[j].name == textFrames[i].contents.replace(/(^\s*|\s*$)/g,'')) // trim whitespace
                textFrames[i].fillColor = swatches[j];

} // end main

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Fill Text Frames');

 

Votes

Translate

Translate

Report

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 ,
Oct 29, 2022 Oct 29, 2022

Copy link to clipboard

Copied

I'm pretty sure you don't have to iterate through all the swatches and compare each one?? 

 

So this should work as well:

 

textFrames[i].fillColor = doc.swatches(textFrames[i].contents.replace(/(^\s*|\s*$)/g,''))) // trim whitespace

 

At least in VB you could do something like that - is it not possible in JS?

But then you would need to use try catch 

Votes

Translate

Translate

Report

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 ,
Oct 29, 2022 Oct 29, 2022

Copy link to clipboard

Copied

Sure you could do it like this:

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

    var sw = swatches.itemByName(textFrames[i].contents.replace(/(^\s*|\s*$)/g, ''));
    
    if (sw.isValid)
        textFrames[i].fillColor = sw;

}

 I think this might be faster. Good idea. Feel free to do a test to see if it is actually faster.

- Mark

Votes

Translate

Translate

Report

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 ,
Oct 29, 2022 Oct 29, 2022

Copy link to clipboard

Copied

You are right, in JS it's .itemByName(string) not just .item(string) 😉 I prefer VB 😉

I hope it would be faster - otherwise it would mean that scripting engine inside InDesign isn't optimised. 

Votes

Translate

Translate

Report

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 Beginner ,
Nov 03, 2022 Nov 03, 2022

Copy link to clipboard

Copied

The original script while a bit slow, worked perfectly.

This one (the second script), didn't work. I got this error message:

Federico267836568h03_0-1667504901159.png

 

Votes

Translate

Translate

Report

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 ,
Nov 03, 2022 Nov 03, 2022

Copy link to clipboard

Copied

Because this part is missing at the beginning:

 

function main() {

    var doc = app.activeDocument,
        textFrames = doc.textFrames,
        swatches = doc.swatches;

Votes

Translate

Translate

Report

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 ,
Nov 03, 2022 Nov 03, 2022

Copy link to clipboard

Copied

LATEST

Sorry @Federico267836568h03, I only posted the variant of the for loop, not the whole script. The whole script is like this, using @Robert at ID-Tasker's suggestion. Let me know if it is faster. 🙂

/**
 * Set the fillColor of any text frame
 * whose contents matches a swatch name.
 * @author m1b
 * @version 2022-10-29
 * @discussion https://community.adobe.com/t5/indesign-discussions/how-to-batch-color-hundreds-of-text-boxes-with-matching-swatches/m-p/13305809
 */
function main() {

    var doc = app.activeDocument,
        textFrames = doc.textFrames,
        swatches = doc.swatches;

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

        var sw = swatches.itemByName(textFrames[i].contents.replace(/(^\s*|\s*$)/g, ''));

        if (sw.isValid)
            textFrames[i].fillColor = sw;

    }

} // end main

app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Fill Text Frames');

Votes

Translate

Translate

Report

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