Skip to main content
Participant
August 21, 2025
Question

InDesign Script - Dynamically Resize Text Frame Width Based on Template Variable

  • August 21, 2025
  • 2 replies
  • 212 views

Hi All,

Turning to you after spending a good deal of time with Claude and ChatGPT. 

I have an InDesign script that processes txt data to create labels using different templates. For my "stone_acres" case, I need to dynamically resize the ingredients text frame width based on which background template is used:

  • When currData["template"] == "STNAC_OG": ingredients text frame should be 2.6268 inches wide (189 points)
  • When currData["template"] == "STNAC_CV": ingredients text frame should be 3.5403 inches wide (254 points)

The text frame contains ingredient information and needs to wrap around logos placed from a "Logos" layer. The script processes the template AFTER text replacement has occurred, so the original placeholder <ingredient_concat> has been replaced with actual ingredient text starting with "Ingredients:".

Issues: They are not sizing correctly- text widths appear too large and run off the page.

Current Code:

Text replacement happens early in the script:

javascript

for (var prop in currData) {

    if (currData[prop] == undefined) currData[prop] = "";

    app.findTextPreferences.findWhat = "<" + prop + ">";

    app.changeTextPreferences.changeTo = currData[prop];

    docRef.changeText();

}

Current stone_acres case (problematic):

javascript

case "stone_acres":

    var backLayer = docRef.layers.itemByName("Background");

    makeVisible("@" + currData["template"], backLayer.pageItems);


    var logoLayer = docRef.layers.itemByName("Logos");

    var logoData = getLogoData(currData).split(logoSeparator);

    var allPics = [];


    for (var logoIndex = 0; logoIndex < logoData.length; logoIndex++) {

        var currLogoName = logoData[logoIndex];

        

        var currLogo = logoLayer.pageItems.itemByName("@" + currLogoName);

        if (currLogo.isValid) {

            currLogo.visible = true;

            allPics.push(currLogo);

            

            // Enable text wrap around this logo

            currLogo.textWrapPreferences.textWrapMode = TextWrapModes.BOUNDING_BOX_TEXT_WRAP;

            currLogo.textWrapPreferences.textWrapOffset = [3, 3, 3, 3]; // 3pt offset on all sides

        }

    }


    // Find and resize the ingredient field

    var ingredientField = null;

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

        var frame = docRef.textFrames[i];

        try {

            if (frame.contents.indexOf("Ingredients:") == 0) {

                ingredientField = frame;

                break;

            }

        } catch (e) {}

    }


    if (ingredientField) {

        var currentBounds = ingredientField.geometricBounds;

        

        if (currData["template"] == "STNAC_OG") {

            ingredientField.geometricBounds = [

                currentBounds[0], // top

                currentBounds[1], // left

                currentBounds[2], // bottom

                currentBounds[1] + 189 // right = left + 189 points (2.6268 inches)

            ];

        }

        

        if (currData["template"] == "STNAC_CV") {

            ingredientField.geometricBounds = [

                currentBounds[0], // top

                currentBounds[1], // left

                currentBounds[2], // bottom

                currentBounds[1] + 254 // right = left + 254 points (3.5403 inches)

            ];

        }

    }


    if (allPics.length) {

        allPics.sort(function(a, b) {

            var aHeight = a.geometricBounds[2] - a.geometricBounds[0];

            var bHeight = b.geometricBounds[2] - b.geometricBounds[0];

            if (aHeight > bHeight) return -1;

            return 1;

        });


        var rightX = allPics[0].geometricBounds[3];

        for (var logoIndex = 1; logoIndex < allPics.length; logoIndex++) {

            rightX = Math.max(rightX, allPics[logoIndex].geometricBounds[3])

        }


        for (var p = 0; p < allPics.length; p++) {

            allPics[p].move(undefined, [rightX - allPics[p].geometricBounds[3], 0]);

            rightX = allPics[p].geometricBounds[1] - 3;

        }

    }


    // Remove invisible logos AFTER setting text wrap and resizing text box

    for (var logoIndex = logoLayer.pageItems.length - 1; logoIndex >= 0; logoIndex--) {

        if (!logoLayer.pageItems[logoIndex].visible)

            logoLayer.pageItems[logoIndex].remove();

    }


    break;

Questions:

  1. Is there a better way to resize text frames dynamically based on data variables?
  2. Are there issues with my geometric bounds calculations?

InDesign Version: 19.5.5 

Template Setup: Text frames have no assigned names (this is a concatenated field), content is replaced via find/change, logos positioned on a separate layer with text wrap enabled.

 

2 replies

Community Expert
August 23, 2025

You can set the measurement unit used by the script, with something like the following

app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS
-Manan
-Manan
John D Herzog
Inspiring
August 22, 2025

Do you have your Indesign set to points? I have my Indesign set to inches and use inches in my scripts. What size do they come out to? You can check the size of what came out to what you were expecting and figure out what unit type it is using.

Participant
August 22, 2025

Hi John- it's set to inches in the property box.

Is this what you mean?

Ty!

 

 

 

John D Herzog
Inspiring
August 22, 2025

In the Preferences/Units & Increments. I would try switching over to points real quick and see if that fixes the problem. Faster than trying to adjust the script.