Copy link to clipboard
Copied
Hi,
I've used data merge to create multiple groups (images + text) of variable sizes.
Now I would like to place them as anchored objects into a text frame so I can flow them easily (inline).
I can Cut/Paste each group, one at a time, into a text frame and it works perfectly… but it's long and inneffective.
I would like to create a script that create a text frame and place the selected groups into it.
Is it possible ? Maybe there is already something for that kind of manoeuvre, but after a lot of reasearch I'm stuck.
Thanks for anyone help !
Hi @Zaphod, those demo docs were perfect, thanks. I've written a script for this and it works pretty well in my simple testing. It might need some tweaks for your particular use though, but see how you go.
The script tries to apply an Object Style to each item to be anchored. I think this is wise (see attached demo.indd which has an example Object Style that only applies anchored object settings and nothing else). You can turn this off by changing `settings.applyObjectStyleToEachItem` to false
...Copy link to clipboard
Copied
Can you post two sample .indd files: (a) after the data merge with the groups, and (b) with the final anchored groups? The sample documents just need to have a page or two. This would speed things up I think.
- Mark
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Unfortunately, not enough.
You need to show us a raw example after importing data - with multuiple records - so we can asses structure of the document.
Copy link to clipboard
Copied
Sorry that's all I have for now, can't show you the real images (nda).
It still represent exactly what I want to do… I have hundred of these boxes to create with a few items in each. I just want to select the groups on top and click a script to inline them instead of copy/paste each one individually.
I don't understand what I could send more… The 5 goups are the RAW example of the merge. I've just add the inline exemple under.
Copy link to clipboard
Copied
Of course, I understand.
But you've copy&pasted part of the data - that is otherwise somehow / somewhere located on the page(s) - in order to automate it - we need to know "surroundings".
In my tool, I can easily locate objects - but I need to see their real location - in order to "group" them together logically.
Then, you can do pretty much anything. Pure scripting would require a lot of extra work to locate and organise objects.
So you would be interested only in those:
But it would still be helpful to see an example with more sample data.
No need for graphics - those Magenta Rectangles are perfectly fine - just few more rows + other objects on the page - preferably part of the original file, without any other modifications.
Copy link to clipboard
Copied
Thanks for you patience. I'm still researching this method so I dont have exemple with more data. Anyway the action I want to accomplish will allways be to inline 2-5 groups max at a time.
Here is the direct document I get from the merge, without any retouching (except for the missing images).
Copy link to clipboard
Copied
Piece of cake.
I've duplicated your "rows" and added an extra page.
In RED - sorting order - Page Index, Pos Y (so same row), Pos X
Then, grouped by "rows":
Now it's just a case of selecting all objects in the "group" and do extra steps so they'll land as InLine group in the destination story.
But as you don't have all your "ducks in a row" - it would have to wait.
A bit different process - extracting tables - but the same principle:
Copy link to clipboard
Copied
OK… sorry… I don't understand this last message ! Why the new row, the new page ?
What do you mean I dont have "all my ducks in a row it would have to wait" ?
The script I imagine should work directly on this example… create a new text frame and Inline the selected groups in it.
Maybe it's to complicated and I'm way over my head !
Copy link to clipboard
Copied
OK… sorry… I don't understand this last message ! Why the new row, the new page ?
I've been just simulating a bigger document - you'll either have one "row" / group of objects per page - or multiple - doesn't matter for my tool - but could be a game changer for a custom script.
What do you mean I dont have "all my ducks in a row it would have to wait" ?
I like "Everybody Loves Raymond" show - and they use this phrase there.
You simply don't have a finalised database, template, etc. - so there is no point doing "finall version" if a lot can change, right?
The script I imagine should work directly on this example… create a new text frame and Inline the selected groups in it.
But your file isn't a real example - have you tried to import more records at a time?
Maybe it's to complicated and I'm way over my head !
No, not at all for my tool - it's just like I've already said - you don't have all the info at hand - you are just starting - which is VERY good as you can alter your workflow if needed.
Copy link to clipboard
Copied
Thank you for all the explanations, and patience. I understand.
Maybe I've put you on the wrong path talking about the data merge part.
What I want, is a tool for my team to rapidly inline multiple selected groups (manually selected as we work in documents). These groups would not always be created by data merge processes. I dont want to automatize an entire document. Just the selected groups on the page I'm working on. This script could work for different situations.
The best version would work like making a mask in Illustrator : you select an existing text frame (on top) + the groups to inline. Click the script and all the groups are individually cut/paste (anchored/inline) in the text frame.
Thanks again
Copy link to clipboard
Copied
That changes everything...
I'm not JS guy so you need to wait for someone else to pitch in with working JS code.
But... I think there will be a bit of a problem - after you select objects to be grouped - how script should know where to place them? I don't think you can stop / pause regular JS script so user can change selection - it probably would have to be done as UXP Script?
Yeah, if you select "destination" TextFrame together with groups - script can do it the way you want.
But I don't see how much faster / more convenient it would be than clicking Ctrl+G, Ctrl+X, dblclick in the destination TF and Ctrl+V.
Unless the destination placement would always be at the end of the TextFrame - but then, what if you have text there or it's threaded with other TextFrames?
The end result in the Illustrator is a bit different to what you want to achieve in the InDesign...
Copy link to clipboard
Copied
Just clicking one script would be less time consuming then executing a 4 steps manoeuvre 3-5 times. Over hundred of pages, that would be a lot of hours saved !
The Illustrator example, was just to demonstrate the way Illustrator use the Top object to received the bottom object. Nothing to do with actual masking.
Copy link to clipboard
Copied
Unless your real endgoal is to just add frame around those groups? And keep everything neatly together?
Copy link to clipboard
Copied
There could be an existing text frame selected with the groups, ready to received the anchored objects. Or the script could create a predetermine text frame (ex.5"x1.5" at 0.5,0.5) that we will adjust anyway.
The goal is to automatically align and space correctly all these little groups trough a document. Inlining them allow me to apply different styles to sync all these parameters through the document.
Copy link to clipboard
Copied
Hi @Zaphod, those demo docs were perfect, thanks. I've written a script for this and it works pretty well in my simple testing. It might need some tweaks for your particular use though, but see how you go.
The script tries to apply an Object Style to each item to be anchored. I think this is wise (see attached demo.indd which has an example Object Style that only applies anchored object settings and nothing else). You can turn this off by changing `settings.applyObjectStyleToEachItem` to false.
The script also sorts the items (prefering left-right and then top-bottom order). If you don't want this, just comment out the `items.sort` line.
Here's how it looks in the demo file:
/**
* Anchor selected items.
* @author m1b
* @discussion https://community.adobe.com/t5/indesign-discussions/automatically-placing-multiple-groups-into-a-text-frame-inline/m-p/14335102
*/
function main() {
var settings = {
applyObjectStyleToEachItem: true,
anchoredObjectStyleName: 'Anchored Column'
};
app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
var doc = app.activeDocument,
items = doc.selection;
if (0 === items.length)
return alert('Please select some page items and try again.');
// sort so that objects are anchored in correct order
items.sort(sortByLeftThenTop);
var anchoredObjectStyle = doc.objectStyles.itemByName(settings.anchoredObjectStyleName);
if (
!anchoredObjectStyle.isValid
&& settings.applyObjectStyleToEachItem
)
return alert('Could not find "' + settings.anchoredObjectStyleName + '" object style.');
// create a text frame to put the items in
var exampleTextFrame = items[0].parent.textFrames.add({
geometricBounds: boundingRectangle(items),
});
// add the items to the new text frame
anchorSelectedPageItems(items, exampleTextFrame.insertionPoints[0], settings.applyObjectStyleToEachItem && anchoredObjectStyle);
// for convenience(?) leave the selection as the anchored text
exampleTextFrame.parentStory.texts[0].select();
};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Anchor Selection');
/**
* Anchors supplied `items`, one at a time,
* to the supplied `insertionPoint`. Can apply
* an optional Object Style to each item.
* Note the insertionPoint will move along
* so that each anchored item will be added
* after the previous one.
* @author m1b
* @version 2024-01-05
* @param {Array<PageItem>} items - indesign page items.
* @param {InsertionPoint} insertionPoint - the place to add the items.
* @param {ObjectStyle} [anchoredObjectStyle] - the object style to apply to each item (default: none).
*/
function anchorSelectedPageItems(items, insertionPoint, anchoredObjectStyle) {
if (undefined == items)
throw error('anchorSelectedPageItems failed: no `items` supplied.');
if (undefined == insertionPoint)
throw error('anchorSelectedPageItems failed: no `insertionPoint` supplied.');
for (var i = 0; i < items.length; i++) {
// do the insertion
items[i].anchoredObjectSettings.insertAnchoredObject(insertionPoint);
if (
undefined != anchoredObjectStyle
&& anchoredObjectStyle.isValid
)
items[i].appliedObjectStyle = anchoredObjectStyle;
}
};
/**
* Sort Indesign page items by horizontal
* position, then vertical position.
* @author m1b
* @version 2024-01-05
* @param {PageItem} a
* @param {PageItem} b
* @returns {Number} - the sort direction.
*/
function sortByLeftThenTop(a, b) {
if (a.geometricBounds[1] < b.geometricBounds[1]) return -1;
if (a.geometricBounds[1] > b.geometricBounds[1]) return 1;
if (a.geometricBounds[0] < b.geometricBounds[0]) return -1;
if (a.geometricBounds[0] > b.geometricBounds[0]) return 1;
return 0;
}
/**
* Returns a bounding rectangle that
* encompasses the geometric bounds
* of all items supplied, with optional
* padding added all around.
* @author m1b
* @version 2024-01-05
* @param {Array<PageItem>} items - the items to bound.
* @param {Number} [padding] - the padding all around, in points (default: 0)
* @returns {Array<Number>} - the bounding rectangle.
*/
function boundingRectangle(items, padding) {
padding = padding || 0;
var b = [Infinity, Infinity, -Infinity, -Infinity];
for (var i = 0; i < items.length; i++) {
if (b[0] > items[i].geometricBounds[0])
b[0] = items[i].geometricBounds[0];
if (b[1] > items[i].geometricBounds[1])
b[1] = items[i].geometricBounds[1];
if (b[2] < items[i].geometricBounds[2])
b[2] = items[i].geometricBounds[2];
if (b[3] < items[i].geometricBounds[3])
b[3] = items[i].geometricBounds[3];
}
return [b[0] - padding, b[1] - padding, b[2] + padding, b[3] + padding];
};
Edit 2024-01-05: added some missing documentation.
Let me know how it works for you.
- Mark
Copy link to clipboard
Copied
Wow, beautiful ! It works like a charm, can't thank you enough.
I'm a beginner at scripting, and that script taught me so much. I will refer to it many time. Thanks !
Copy link to clipboard
Copied
Great to hear! Yeah you can do cool things with scripting. Good luck with your learning!
Find more inspiration, events, and resources on the new Adobe Community
Explore Now