Ah @kalle27850504iimx that's exactly what I needed!
Here's a script that will (I hope!) do what you want. It works on your sample files at least. Actually I made one of your masks into a compound path item because they are more difficult to work with. Let me know how it goes.
- Mark

/**
* @file Create Clipping Groups From Layers.js
*
* Using masks from one layer, and artwork from another,
* create clipping groups on another layer.
* See `settings` object for configuration.
*
* @author m1b
* @discussion https://community.adobe.com/t5/illustrator-discussions/need-help-automating-clipping-masks-for-multiple-paths-in-illustrator/m-p/15089842
*/
(function () {
var settings = {
// the layer names used in document
CLIPPED_LAYER_NAME: 'print ready',
MASK_LAYER_NAME: 'print media',
DESIGN_LAYER_NAME: 'design',
// whether to hide layers after making groups
hideDesignLayer: true,
hideMaskLayer: true,
};
var doc = app.activeDocument;
var clippedLayer = getThing(doc.layers, 'name', settings.CLIPPED_LAYER_NAME),
maskLayer = getThing(doc.layers, 'name', settings.MASK_LAYER_NAME),
designLayer = getThing(doc.layers, 'name', settings.DESIGN_LAYER_NAME);
if (!clippedLayer || !maskLayer || !designLayer)
return alert('Document does not have the required layers:\n' + [settings.CLIPPED_LAYER_NAME, settings.MASK_LAYER_NAME, settings.DESIGN_LAYER_NAME].join('\n'));
var readyItems = [],
maskItems = maskLayer.pageItems,
designItems = designLayer.pageItems;
// for each mask item, collect the designItems that intersect
// with it and create the clipping group using those items
for (var i = 0; i < maskItems.length; i++) {
var maskItem = maskItems[i],
maskBounds = maskItem.visibleBounds,
intersectingItems = getIntersectingItems(designItems, maskBounds);
if (0 === intersectingItems.length)
continue;
var group = clippedLayer.groupItems.add(),
groupMask = maskItem.duplicate(group, ElementPlacement.PLACEATBEGINNING),
compoundPathWorkaroundPathItem = undefined;
if ('CompoundPathItem' === groupMask.constructor.name) {
// workaround for bug with scripting API that won't allow
// making a clipping group with compound path item
compoundPathWorkaroundPathItem = group.pathItems.add();
compoundPathWorkaroundPathItem.move(group, ElementPlacement.PLACEATBEGINNING)
}
for (var j = 0; j < intersectingItems.length; j++)
intersectingItems[j].duplicate(group, ElementPlacement.PLACEATEND);
// convert group to a clipping group
group.clipped = true;
if (compoundPathWorkaroundPathItem) {
// workaround for bug with scripting API that won't allow
// making a clipping group with compound path item
// (I use a surrogate path item, which I then remove
// and switch with the compound path item we want)
compoundPathWorkaroundPathItem.remove();
groupMask.pathItems[0].clipping = true;
}
readyItems.push(group);
}
if (settings.hideDesignLayer)
designLayer.visible = false;
if (settings.hideMaskLayer)
maskLayer.visible = false;
})();
/**
* Returns a thing with matching property.
* If `key` is undefined, evaluate the object itself.
* @author m1b
* @version 2024-04-21
* @param {Array|Collection} things - the things to look through.
* @param {String} [key] - the property name (default: undefined).
* @param {*} value - the value to match.
*/
function getThing(things, key, value) {
for (var i = 0, obj; i < things.length; i++)
if ((undefined == key ? things[i] : things[i][key]) == value)
return things[i];
};
/**
* Returns array of an `items` that have
* bounds intersecting with `bounds`, if any.
* @author m1b
* @version 2025-01-15
* @param {Array<PageItem>} items - the items to check.
* @param {Array<Number>} bounds - the target bounds (LTRB for Illustrator, TLBR for Indesign).
* @param {Boolean} [useGeometricBounds] - whether to use geometricBounds (default: false, visibleBounds).
* @returns {Array<PageItem>}
*/
function getIntersectingItems(items, bounds, useGeometricBounds) {
var found = [],
boundsType = true === useGeometricBounds ? 'geometricBounds' : 'visibleBounds';
for (var i = 0; i < items.length; i++)
if (boundsDoIntersect(items[i][boundsType], bounds))
found.push(items[i]);
return found;
};
/**
* Returns true if the two bounds intersect.
* @author m1b
* @version 2024-03-10
* @param {Array} bounds1 - bounds array.
* @param {Array} bounds2 - bounds array.
* @param {Boolean} [TLBR] - whether bounds arrays are interpreted as [t, l, b, r] or [l, t, r, b] (default: based on app).
* @returns {Boolean}
*/
function boundsDoIntersect(bounds1, bounds2, TLBR) {
if (undefined == TLBR)
TLBR = (/indesign/i.test(app.name));
return !(
TLBR
// TLBR
? (
bounds2[0] > bounds1[2]
|| bounds2[1] > bounds1[3]
|| bounds2[2] < bounds1[0]
|| bounds2[3] < bounds1[1]
)
// LTRB
: (
bounds2[0] > bounds1[2]
|| bounds2[1] < bounds1[3]
|| bounds2[2] < bounds1[0]
|| bounds2[3] > bounds1[1]
)
);
};