Skip to main content
Known Participant
September 11, 2024
Answered

Script says group with image plus another item contains 3 items? Please help

  • September 11, 2024
  • 1 reply
  • 1019 views

Hello, 

 

I have a script which counts how many things are in a group. 

 

 

Is it becuase indesign is reading a parent bound plus the image inside the rectangle, PLUS the blue box, so there is three things? 

I have the following code and am struggling to know how to intergrate a group which has an image and another thing 

My thought was to adjust this part
if (item instanceof Group && item.allPageItems.length === 2) to have OR group selection of image, bounding rectangle, and other thing then ... but I'm just not getting anywhere 

Any advice would be great 

Thanks 


Smyth

app.doScript(function() {
    // Get the active document
    var doc = app.activeDocument;

    // Get document grid preferences
    var gridPreferences = doc.gridPreferences;
    var baselineIncrement = gridPreferences.baselineDivision;

    // Add a precision threshold to handle floating-point precision issues
    var precisionThreshold = 0.1; // This helps to avoid errors when height is close to baselineIncrement

    // Function to adjust height
    function adjustHeight(item) {
        var currentHeight = item.geometricBounds[2] - item.geometricBounds[0];

        if (currentHeight > baselineIncrement + precisionThreshold) {
            // Reduce the bottom edge to shrink the height
            if (item instanceof Image && item.parent instanceof Rectangle) {
                adjustHeight(item.parent); // Adjust the height of the parent frame, not the image itself
            } else {
                item.geometricBounds = [
                    item.geometricBounds[0],
                    item.geometricBounds[1], 
                    item.geometricBounds[2] - baselineIncrement,
                    item.geometricBounds[3]
                ];
            }
        } else {
            // Move the item upwards if its height is equal to or less than one baseline (within threshold)
            var moveAmount = Math.abs(baselineIncrement); // Ensure positive value

            item.geometricBounds = [
                item.geometricBounds[0] - moveAmount,
                item.geometricBounds[1],
                item.geometricBounds[2] - moveAmount,
                item.geometricBounds[3]
            ];
        }
    }

    // Function to find and assign smaller and larger items in a group of two
    function findSmallerGroupItem(group) {
        var groupItem1 = group.allPageItems[0];
        var groupItem2 = group.allPageItems[1];

        var heightItem1 = groupItem1.geometricBounds[2] - groupItem1.geometricBounds[0];
        var heightItem2 = groupItem2.geometricBounds[2] - groupItem2.geometricBounds[0];

        var smallGroupItem, largeGroupItem;

        // Compare heights and assign smaller and larger
        if (heightItem1 < heightItem2) {
            smallGroupItem = groupItem1;
            largeGroupItem = groupItem2;
        } else {
            smallGroupItem = groupItem2;
            largeGroupItem = groupItem1;
        }

        return {
            smallGroupItem: smallGroupItem,
            largeGroupItem: largeGroupItem
        };
    }

    // Function to resize and center the smaller group item
    function resizeAndCenterSmallerGroupItem(smallGroupItem, largeGroupItem) {
        var largeTop = largeGroupItem.geometricBounds[0];
        var largeBottom = largeGroupItem.geometricBounds[2];
        var largeCenter = (largeTop + largeBottom) / 2;

        // Calculate the new height and top position for the smaller item
        var smallWidth = smallGroupItem.geometricBounds[3] - smallGroupItem.geometricBounds[1];
        var smallNewTop = largeCenter - (baselineIncrement / 2);

        // Resize the smaller item to match baseline increment
        smallGroupItem.geometricBounds = [
            smallNewTop,
            smallGroupItem.geometricBounds[1],
            smallNewTop + baselineIncrement,
            smallGroupItem.geometricBounds[3]
        ];

        // Adjust the smaller item’s horizontal position if necessary
        var currentBounds = smallGroupItem.geometricBounds;
        smallGroupItem.geometricBounds = [
            currentBounds[0],
            currentBounds[1],
            currentBounds[2],
            currentBounds[3] // No horizontal adjustment needed in this case
        ];
    }

    // Function to process each item or group recursively
    function processItem(item) {
        if (item instanceof Group && item.allPageItems.length === 2) {
            // If the item is a group with exactly two items, find smaller and larger items
            var groupItems = findSmallerGroupItem(item);

            // Resize and center the smaller item within the larger item
            resizeAndCenterSmallerGroupItem(groupItems.smallGroupItem, groupItems.largeGroupItem);

            // Now adjust the height of the larger item as well
            adjustHeight(groupItems.largeGroupItem);

        } else if (item instanceof GraphicLine || item instanceof TextFrame || item instanceof Rectangle) {
            adjustHeight(item);
        } else if (item instanceof Group) {
            for (var j = 0; j < item.allPageItems.length; j++) {
                processItem(item.allPageItems[j]);
            }
        } else if (item instanceof Image) {
            // Check if the image is inside a rectangle (frame)
            var parent = item.parent;
            if (parent instanceof Rectangle) {
                adjustHeight(parent);
            } else {
                adjustHeight(item);
            }
        } else {
            alert("Selection contains unsupported items. Please select only vertical rules, text frames, picture boxes, or groups.");
        }
    }

    // Check if there are any selected objects
    if (app.selection.length === 0) {
        alert("Please select one or more vertical rules, text frames, picture boxes, or groups.");
    } else {
        // Iterate over all selected objects
        for (var i = 0; i < app.selection.length; i++) {
            processItem(app.selection[i]);
        }
    }
}, ScriptLanguage.JAVASCRIPT, null, UndoModes.ENTIRE_SCRIPT, "Adjust Item Height Based on Baseline Increment");



 

This topic has been closed for replies.
Correct answer rob day

Hello, 

 

Thank you for the advice, this was distroying my soul. 

I will give it a shot tonight when I am back home. 

I know the script and this function is very daft on appearance but it's a workarround for a content management system running through InDesign.

 

Ill update later, 

 

Best, 

 

Smyth 


Hi @SmythWharf , Also, as @Robert at ID-Tasker , suggests .allPageItems returns an array (not a collection) of all objects inside of the group, while .pageItems returns a collection of the top level objects that are page items inside the group.

 

So here on a selected group, .allPageItems gets the image, its container frame, and the text frame. If I get the .pageItem collection as an array via .getElements(), just the 2 page item objects—the image rectangle container and the text frame are returned:

 

 

 

var g = app.activeDocument.selection[0]
alert("\rAll Page Items: \r" + g.allPageItems +"\r\rPage Items: \r" + g.pageItems.everyItem().getElements())

 

 

 

1 reply

Robert at ID-Tasker
Brainiac
September 12, 2024

Switch from "allPageItems" to "pageItems".

 

pageItems is a collection of "direct" childrens only - allPageItems is a collection of all childrens and their childrens and so on. 

 

If your group in on a page - and is the only object on that page - myPage.pageItems will return ONLY this group - but myPage.allPageItems will return this group PLUS everything in this group.

 

Robert at ID-Tasker
Brainiac
September 12, 2024

And yes, linked image is a child of the Rectangle. 

 

rob day
Community Expert
September 12, 2024

Thank you both for your insight. 

@Robert at ID-Tasker Yes I had a quick look at the ID Tasker... curious thing.

 

@rob day I will look into this

Regarding the above I have adjusted the processItem and the findSmallerGroupItem functions and up pageItems has done it  - a good thing to learn! 

Thank you very much! 

Best, 

 

Smyth 


and up pageItems has done it

 

Here’s another example of the diiference between the allPageItems Array and the pageItem Collection, where you might not get the result you expect.

 

Visually it looks like this group has 6 items, but allPageItems returns 8 objects, and pageItems returns 2 pageItems:

 

var g = app.activeDocument.selection[0]
alert("\rAll Page Items: (" + g.allPageItems.length + ") \r" + g.allPageItems +"\r\rPage Items: (" + g.pageItems.count() + ") \r" + g.pageItems.everyItem().getElements())