Copy link to clipboard
Copied
Copy link to clipboard
Copied
This was done on the hoof. It requires the number of rows to be entered.
var items = app.activeDocument.pageItems;
var array = [];
for (var i = 0; i < items.length; i++) {
if (items[i].parent.parent == app.activeDocument &&
items[i].typename != "TextFrame") {
array.push(items[i]);
}
}
array.sort(function(a, b) {
return a.left == b.left ? a.top - b.top : a.left - b.left;
});
var n = prompt("Number of rows:");
for (var i = 0; i < n; i++) {
var group = app.activeDocument.groupItems.add();
array[i].moveToEnd(group);
for (var j = array.length - 1; j > -1; j--) {
if (array[j] != array[i]) {
var b1 = array[i].geometricBounds;
var b2 = array[j].geometricBounds;
if (b2[1] >= b1[1] && b2[3] < b1[1] ||
b2[1] <= b1[1] && b2[1] > b1[3]) {
array[j].moveToEnd(group);
}
}
}
}
Copy link to clipboard
Copied
I'm not sure if I am doing something wrong with your script but I cannot get it to work. I enter the number of lines but nothing gets grouped.
Copy link to clipboard
Copied
Bryan, I tried Femkes approach with a bunch of plain path objects, similar to what you showed in your initial post. The script worked fine.
You may want to provide another sample Illustrator file, so she can take a look and perhaps see what is the reason why it didn't work for you.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
I can't explain why the script would fail silently. Unfortunately, I can't open your file because I use an old version of AI.
(1) Do you get an error message?
(2) Is at least one new group item added to your layers panel?
(3) You could try adding alert(array.length) before the prompt(); if the alert reads 0, then the problem is in the first half of the script.
Copy link to clipboard
Copied
Here's another approach... To get the grouping right, I instead sorted the shapes from tallest to shortest, then checked each shape again all others in each group to see if they overlapped at all. If they do, I put them in that group. This may break on some edge cases but works for this particular file. I sent this to @BryanPagenkopf to check some other files so we'll see if it really works. Cheers ✌️
var doc = app.activeDocument;
groups = groupObjectsByLine(doc.selection);
if (groups) {
alert("Groups Created:\n" + groups.length);
}
function groupObjectsByLine(sel) {
var groups = [];
// sort the selected page items by their height (tallest to shortest)
sel.sort(function (a, b) {
var aHeight = a.geometricBounds[3] - a.geometricBounds[1];
var bHeight = b.geometricBounds[3] - b.geometricBounds[1];
return bHeight - aHeight;
});
// check if each page item shares bounds with others
var item, placed;
while (sel.length > 0) {
item = sel.pop();
placed = false;
for (var i = 0; i < groups.length; i++) {
group = groups[i];
if (overlappingBounds(item, group)) {
item.move(group, ElementPlacement.PLACEATEND);
placed = true;
}
}
// if an item didn't fit into any current groups make a new group
if (!placed) {
g = doc.groupItems.add();
groups.push(g);
item.move(g, ElementPlacement.PLACEATEND);
}
}
return groups;
}
function overlappingBounds(item, group) {
var top = item.geometricBounds[1];
var bottom = item.geometricBounds[3];
var gTop = group.geometricBounds[1];
var gBottom = group.geometricBounds[3];
if (bottom > gTop || top < gBottom) {
return false;
}
return true;
}
Copy link to clipboard
Copied
Femke, I saved Bryan's second sample as an Illustrator CS5 file, so you can download and open it in your Illustrator version.
Download Bryan's Line Grouping Example (CS5 format)
Meanwhile I tried jduncan's approach and as far as I can see it works fine.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
@femkeblanco, your script does work. Bryan sent me a version of the script in a direct message and linked to this post so I just assumed they were the same but that was not the case. The script you pasted above does work as advertised. I just wanted to set the record straight. Cheers!
Copy link to clipboard
Copied
Thanks @jduncan.