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.
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
...
Copy link to clipboard
Copied
Forgot to mention one more thing: The text boxes must touch each other.
Copy link to clipboard
Copied
You could try googling something like "one dimensional bin packing problem javascript" as a starting point. Interesting problem!
Copy link to clipboard
Copied
Thanks for the suggestion. Will do.
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)
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.
Copy link to clipboard
Copied
Thanks Michael, that's really cool! Is there a place to edit the default gutter between boxes?
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.
Copy link to clipboard
Copied
Thank you. Do I need an extended keyboard to use the tip?
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.
Copy link to clipboard
Copied
Hi Michael, thanks for the answers. Unfortunately, my keyboard doesn't work. Is it cmd+arrow or just arrow?
Thanks again.