Copy link to clipboard
Copied
I was using a group's all page items property to locate page items after ungrouping them, which didn't work because their object references contain the group that no longer exists, making those object references invalid. The ungroup command doesn't return any data to capture (even though on page 64 of the InDesign AppleScript manual a variable is set to the results of an ungroup command).
I opted to add script labels to each group's children before ungrouping, but I'm not in love with that method because I often use script labels for other purposes and eventually I'll end up disrupting another process. Are there any other ways to capture page items after they've been ungrouped? Thank you.
Copy link to clipboard
Copied
With JS you can use extractLabel and insertLabel which won't be disruptive. I don't have a clue about AS
if you want to apply properties to all of the unGrouped items you can use this approach (again in JS)
myGroup = app.documents[0].groups[0];
myGroupItems = myGroup.pageItems.everyItem();
alert (myGroupItems.fillColor = "C=0 M=100 Y=0 K=0");
myGroup.ungroup();
myGroupItems.fillColor = "Black";
Don't know if that will help but you can see this way the object remain valid after the ungroup.
Trevor
Copy link to clipboard
Copied
Thanks for the help Trever. AppleScript has Extract Label and Insert Label, which I never knew anything about. If I go that route, would I be able to collect all the page items with a specific label for a specific key in one line, or would I need to iterate through all page items, using extract label for each item? If you write an example in JS, I should be able to translate it to AS.
Your suggestion of applying a color was helpful, too. Thanks again.
Copy link to clipboard
Copied
Hi,
as AS doesn't provide 'everyItem()' you've got to set the new object refrence.
A bit complicated 😉
In my case the class is rectangle, you've got to cycle thru classes to make a universal approach.
this works with a group of rectangles:
tell application "Adobe InDesign CS5.5"
tell active document
set myGroup to group 1
set myTest to item 1 of (all page items of myGroup)
set {myClass, myId} to {class, id} of object reference of myTest
ungroup myGroup
if myClass is rectangle then set myObjectRefernce to item 1 of (every rectangle whose id is myId)
end tell
end tell
Hope it'll be of some help
Hans-Gerd Claßen
EDIT!!!
Guess it is easier as you can refer to 'page item', so just extract the id...
tell application "Adobe InDesign CS5.5"
tell active document
set myGroup to group 1
set myTest to item 1 of (all page items of myGroup)
set myId to id of object reference of myTest
ungroup myGroup
set myObjectRefernce to item 1 of (every page item whose id is myId)
end tell
end tell
Copy link to clipboard
Copied
Thanks for the info Hans. This was the approach I was going for, but I couldn't figure out how to implement it. Thank you.
Copy link to clipboard
Copied
hi,
what to know about¿
example usage:
tell application "Adobe InDesign CS5.5"
tell active document
set myGroup to group 1
set myGroupItems to (all page items of myGroup)
set myIDList to {}
repeat with i from 1 to count of myGroupItems
copy id of object reference of item i of myGroupItems to end of myIDList
end repeat
ungroup myGroup
repeat with j from 1 to count of myIDList
delete item 1 of (every page item whose id is (item j of myIDList))
end repeat
end tell
end tell
Copy link to clipboard
Copied
Hi John
You can set the labels using insertLabel and everyItem() but you have to iterate through the items to check if they have the label or use a prototype on an array or objects see http://forums.adobe.com/message/3079012#3079012 for details look also at the link at the bottom of that thread. See also http://forums.adobe.com/message/4657726#4657726
I won't go into more details as I don't know if any of this is applicable to AS. If you tell me it is I shall try help some more.
An alternative approach is to write a function in JS and use app.doScript to call it from the AS (I presume you can do that).
AS I said I don't know AS
Regards Trevor
Copy link to clipboard
Copied
Good morning,
just the method:
tell application "Adobe InDesign CS5.5"
tell active document
set myGroup to group 1
set myGroupItems to (all page items of myGroup)
set counter to 0
repeat with i from 1 to count of myGroupItems
set counter to counter + 1
set theItem to item i of myGroupItems
set theLabel to "customLabel" & counter
theItem insert label key "theCustomLabel" value theLabel
end repeat
ungroup myGroup
repeat with j from 1 to count of page items
try
set myLabel to page item j extract label key "theCustomLabel"
select page item j
display dialog myLabel
end try
end repeat
end tell
end tell
Have a good day
P.S. to keep talking about id change to thisline :
set theLabel to "" & id of theItem |
Copy link to clipboard
Copied
I know this is a really old post, but I was looking for the same thing and eventually worked out a better (for me) solution.
If you select the item, then ungroup using the menu command, all items in the group are selected.
app.scriptMenuActions.itemByID(118845).invoke(); TheUnGroupedObjects = app.selection; |
Using menu commands always seems odd, but this is easier to implement in my code.
Happy Ungrouping!
(CC2015, OSX)
Copy link to clipboard
Copied
Hi Naomi,
thank you for this.
Yes, that's one way!
With ExtendScript we could also do this:
var doc = app.documents[0];
var myGroup = doc.groups[0];
// Building an array:
var myGroupItems = myGroup.pageItems.everyItem().getElements();
myGroup.ungroup();
// If you like a selection of the ungrouped items:
app.select(myGroupItems);
Or loop through the myGroupItems array to do something else.
Regards,
Uwe
Copy link to clipboard
Copied
This works for me, even though it should not work - the problem of the original poster: the final statement "get myPageItems" leaves the list in the result display of the AppleScript Editor, there you'll see the specifiers of the list items still refer to the removed group.
tell application id "com.adobe.indesign"
tell active document
-- if not (exists group 1) then undo
set myGroup to group 1
set myPageItems to every page item of myGroup
ungroup myGroup
select myPageItems
get myPageItems
end tell
end tell
The JavaScript method getElements() as used by Uwe iterates all elements of a collection and asks them for their preferred specifier (aka ScriptObject). I'm not aware of a similar operation for AppleScript that would achieve the same thing in one step, but we can get close without script labels or colors. All page items have a unique ID within the document, and we can retrieve them via that ID. The following loop just adds them to the selection, but could do anything else for further processing.
tell application id "com.adobe.indesign"
tell active document
-- if not (exists group 1) then undo
set myGroup to group 1
set myIDs to id of every page item of myGroup
ungroup myGroup
repeat with i in myIDs
select page item id i existing selection add to
end repeat
end tell
end tell
Copy link to clipboard
Copied
Hi Uwe,
Something funny (although of little interest here) is that we don't even need to create an explicit Array from getElements(). The plural specifier, once resolved, can be passed to app.select:
// Plural specifier.
var every = myGroup.pageItems.everyItem();
// Resolve spec (before ungrouping!)
every.isValid;
myGroup.ungroup();
app.select(every);
I didn't know that. Sounds cool.
@+
Marc
Copy link to clipboard
Copied
https://forums.adobe.com/people/Marc+Autret wrote
… I didn't know that. Sounds cool.
Hi Marc,
yes, cool. I did't know that as well 🙂
Even after resolving with isValid—and I think, using every other mutual property of pageItem will do as well
A potential problem while developing scripts:
Sometimes we are not aware that we already resolved a collection by doing an "innocent" $.writeln() or alert() while developing scripts.
Take a homogenous group of rectangles that are grouped.
It's not necessary that all group elements are of the same kind of elements for the snippet to work, but it is showing the case.
Spot the difference what is returned in line 10 and 16. And leave out line 13 and test again.
// Group homogenously consisting of rectangles only:
var myGroup = app.documents[0].groups[0];
// Plural specifier.
var every = myGroup.pageItems.everyItem();
// Look out WHEN, WHAT and HOW you ask:
// Collection yet is not resolved:
$.writeln(every); // [object PageItem]
// But asking for constructor or constructor.name will resolve the collection:
$.writeln(every.constructor.name); // PageItem
// Spot the difference:
$.writeln(every); // [object Rectangle]
// I did not activate the following:
// Resolve spec (before ungrouping!)
// every.isValid;
// Is working as long as the $.writeln() lines are there:
myGroup.ungroup();
app.select(every);
If we remove line 13 with the $.writeln() the snippet will return an error.
Now we know why.
Thanks,
Uwe
Copy link to clipboard
Copied
The problem with resolving the plural specifier even extends to the ESTK (ExtendScript Toolkit app).
If we are working with breakpoints in debug mode and asking the JavaScript console after every.isValid and then step on in debugging every is already resolved because we asked and the script will work without a flaw. A false positive so to say 😉
Running the script on its own would throw an error.
Hm.
So if we want to know e.g. what every is we should consult the Data Browser of the ESTK and not ask the JavaScript Console or do a $.writeln() or an alert(). But maybe the Data Browser cannot tell all we want to know before resolving…
Regards,
Uwe
Copy link to clipboard
Copied
One more specific thing about what can happen if we do not look much into
WHEN, HOW and WHAT we ask by:
1. using the JavaScript Console of the ESTK or
2. using $.writeln() or alert():
Example from above:
Have one group of rectangles only.
every holds group.pageItems.everyItem()
We set a breakpoint to the code here:
myGroup.ungroup()
before app.select(every) in the next line can be executed.
Run 1 of script until breakpoint.
JavaScript Console input and returned values:
every
Result: [object PageItem]
every.isValid
Result: true
every
Result: [object PageItem]
Run 2 of script until breakpoint.
JavaScript Console input and returned values:
every
Result: [object PageItem]
every.constructor.name
Result: PageItem
every
Result: [object Rectangle]
In both cases every is resolved and the script will run without errors even if the explicit script code is not resolving every.
Running the script without any ado will result in an error.
Regards,
Uwe
// EDIT
Copy link to clipboard
Copied
Hi Uwe,
What's happening is that if "every" is not resolved then groups[0] becomes the next group which is the real group[0] if it exits.
i.e. Draw 2 groups, first a magenta one and then a black one.
The black one is groups[0] and the magenta is groups[1].
After the group[0] (black) is undone then magenta will become group[0] and be selected
If we run the script again the magenta group will be ungrouped and and error will be thrown because there's no valid group[0].
Resolving "every" will preserve it as it's own entity so it refers to itself and not to group[0] (which it is know longer)
every === app.documents[0].groups[0] will show false.
every can be resolved by calling a property
every.name or whatever.
Other DOM items merely need touching but with the collections they need referencing.
HTH, regards,
Trevor
Copy link to clipboard
Copied
Hi Trevor,
sorry, that I made it not more clear:
Run 2 of the script starts again on a fresh document with only one group of rectangles.
There is no second group in the document.
What I am seeing here is that calling every.constructor.name by using the JavaScript Console or doing it with a $.writeln() or an alert() is tickling [object Rectangle] out of calling every afterwards in the console or by $.writeln().
It's obviously a difference if you resolve with every.isValid (or any other property but constructor) vs. every.constructor.name .
All of course if the plural specifier is holding the same type of page items. Like rectangles in my case. If it is a mix—say one rectangle and one text frame—the result for $.writeln(every) will still be [object PageItem] after doing every.constructor.name .
Regards,
Uwe
Copy link to clipboard
Copied
In reply 13 I said:
Hm.
So if we want to know e.g. what every is we should consult the Data Browser of the ESTK and not ask the JavaScript Console or do a $.writeln() or an alert(). But maybe the Data Browser cannot tell all we want to know before resolving…
That's wrong.
Using the Data Browser of the ESTK and clicking one of the triangles to see what's in an object will also resolve the asked element.
In my case every. Not only that, it will act like every.constructor.name and if I ask every in the JavaScript Console [object Rectangle] instead of [object PageItem] will be shown:
Screen 1: Breakpoint is reached. DataBrowser is open. Variable every is still not inspected in the DataBrowser.
every in the JavaScript Console returns [object PageItem]
Screen 2: Variable every is opened in the Data Browser:
Screen 3: In this moment every is resolved. Because if I run this script to the end after opening every in the Data Browser, the script is running without error. Without inspecting the variable in the Data Browser the script will throw an error.
Back to the moment I opened the variable in the Data Browser:
If I ask every again in the JavaScript Console it is as if I asked every.constructor.name in the JavaScript Console.
Because every will return [object Rectangle] now for my group of rectangles. And the Data Browser is also showing this after asking:
Regards,
Uwe