Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


Arrange an array of different text boxes to fit in pages

Community Beginner ,
Jul 16, 2021 Jul 16, 2021

Copy link to clipboard

Copied

Hi,

I have 40 text boxes which vary in height. 

I was looking for a script that automatically arranges the text boxes to fit in a page (A4 size). 

(1) The order of text boxes doesn't matter.

(2) The number of text boxes fitted in a page doesn't matter: Some pages can have, say, two text boxes, and some seven to ten boxes. 

(3) The text boxes arranged in a page do not have to fill the page exactly. 

 

I'd appreciate any clues. Thanks. 

TOPICS
Scripting

Views

142

Likes

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

correct answers 1 Correct answer

Enthusiast , Jul 17, 2021 Jul 17, 2021
Hi again, I've had a play with some code and got this. It will accept an array of values and output an array of arrays of values whose sum do not exceed the specified capacity. By entering values denoting lengths in mm and capacity of 297 (length of A4 page in mm), you should have a basis to do your text frame layout script. Haven't tested much myself, so please let us know how it works out, or if you need more help. /* by m1b at https://community.adobe.com/t5/indesign/arrange-an-array-of-d...

Likes

Translate

Translate
Community Beginner ,
Jul 16, 2021 Jul 16, 2021

Copy link to clipboard

Copied

Forgot to mention one more thing: The text boxes must touch each other. 

Likes

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
Enthusiast ,
Jul 17, 2021 Jul 17, 2021

Copy link to clipboard

Copied

You could try googling something like "one dimensional bin packing problem javascript" as a starting point. Interesting problem!

Likes

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 ,
Jul 17, 2021 Jul 17, 2021

Copy link to clipboard

Copied

Thanks for the suggestion. Will do.

Likes

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
Enthusiast ,
Jul 17, 2021 Jul 17, 2021

Copy link to clipboard

Copied

Hi again, I've had a play with some code and got this. It will accept an array of values and output an array of arrays of values whose sum do not exceed the specified capacity. By entering values denoting lengths in mm and capacity of 297 (length of A4 page in mm), you should have a basis to do your text frame layout script. Haven't tested much myself, so please let us know how it works out, or if you need more help.

 

 

/*
    by m1b at https://community.adobe.com/t5/indesign/arrange-an-array-of-different-text-boxes-to-fit-in-pages/m-p/12182653#M437483
    adapted from code found at https://www.geeksforgeeks.org/bin-packing-problem-minimize-number-of-used-bins/
*/

// example values (here representing lengths in mm)
var values = [125, 200, 205, 280, 30, 40, 170, 45, 77];

// capacity of each bin (here representing length of A4 page in mm)
var capacity = 297;

// get the result
var fittedLengths = getPackedBins(values, capacity);

// show the result as A4 pages
$.writeln("Number of pages required: " + fittedLengths.length);

for (var i = 0; i < fittedLengths.length; i++) {
    $.writeln('Page ' + (i + 1) + ' lengths: ' + fittedLengths[i].join(' mm + ') + ' mm  (' + (capacity - sumArray(fittedLengths[i])) + 'mm remaining)');
}


function getPackedBins(values, binCapacity) {

    // sort values, descending order
    values = values.sort(function (a, b) { return b - a });

    // start with no bins
    var bins = [];
    // array to keep track of remaining capacity
    var binRemainder = new Array(values.length); for (var i = 0; i < values.length; ++i) binRemainder[i] = 0;

    // place each item in a bin
    for (i = 0; i < values.length; i++) {

        var j,
            value = values[i],
            freeSpace = binCapacity,
            bestBinIndex = 0;

        // find the best bin that can accommodate value
        if (value > binCapacity) $.writeln('Value "' + value + '" cannot fit into an empty bin.');

        // initialize minimum space left and index of best bin

        for (j = 0; j < bins.length; j++) {
            if (binRemainder[j] >= value && binRemainder[j] - value < freeSpace) {
                bestBinIndex = j;
                freeSpace = binRemainder[j] - value;
            }
        }

        // can't fit value in any bin, so create a new bin
        if (freeSpace == binCapacity) {
            binRemainder[bins.length] = binCapacity - value;
            bins.push([value]);
        } else {
            // put value in best bin
            binRemainder[bestBinIndex] -= value;
            bins[bestBinIndex].push(value);
        }

        // uncomment this line to see the bins array populate over time
        // $.writeln('bins = [' + bins.join('], [') + ']');
    }
    return bins;
}

// only used for displaying the remainders
function sumArray(a) {
    var sum = 0;
    for (var i = 0; i < a.length; ++i) sum += a[i];
    return sum;
}

 

 

By the way, this is the result for me, written to the console:

Number of pages required: 5
Page 1 lengths: 280 mm  (17 mm remaining)
Page 2 lengths: 205 mm + 77 mm  (15 mm remaining)
Page 3 lengths: 200 mm + 45 mm + 40 mm  (12 mm remaining)
Page 4 lengths: 170 mm + 125 mm  (2 mm remaining)
Page 5 lengths: 30 mm  (267 mm remaining)

Likes

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
Adobe Community Professional ,
Jul 17, 2021 Jul 17, 2021

Copy link to clipboard

Copied

The following is not a script and it doesn't quite do what you want but it could prove useful if you didn't already know...

 

Click and drag out a text box. Before releasing the mouse, tap the up/down arrow keys to add/remove text boxes in the vertical direction and tap the right/left arrow keys to add/remove text boxes in the horizontal direction.

Likes

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
Enthusiast ,
Jul 17, 2021 Jul 17, 2021

Copy link to clipboard

Copied

Thanks Michael, that's really cool! Is there a place to edit the default gutter between boxes?

Likes

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
Adobe Community Professional ,
Jul 17, 2021 Jul 17, 2021

Copy link to clipboard

Copied

Thanks mate. I don't know how to edit the default gutter. I'd be keen to know that one myself.

 

The Gap Tool could help you out here. By default, the Gap Tool will move gaps. However, if you hold down Command/Control you can resize gaps, even down to 0 extremely quickly.

Likes

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 ,
Jul 18, 2021 Jul 18, 2021

Copy link to clipboard

Copied

Thank you. Do I need an extended keyboard to use the tip? 

Likes

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
Adobe Community Professional ,
Jul 18, 2021 Jul 18, 2021

Copy link to clipboard

Copied

No extended keyboard necessary. All you need are the arrow keys and the Command key on a Mac or the Control key on Windows.

Likes

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 ,
Jul 18, 2021 Jul 18, 2021

Copy link to clipboard

Copied

LATEST

Hi Michael, thanks for the answers. Unfortunately, my keyboard doesn't work. Is it cmd+arrow or just arrow?

 

Thanks again.

Likes

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