Last active
March 5, 2026 15:24
-
-
Save elmimmo/760714a9c26b3c72f5c5d9ae00821283 to your computer and use it in GitHub Desktop.
InDesign script to apply an object style to images by the name of their frame.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //DESCRIPTION:Apply an object style to placed images inside frames by the name of their frame. | |
| //by Jorge Hernández Valiñani (@Estudio Fénix) + Codex (GPT-5) | |
| #target indesign | |
| (function() { | |
| var UNDO_LABEL = "Aplicar estilo de objeto a imágenes"; | |
| var DIALOG_TITLE = "Aplicar estilo de objeto a contenido"; | |
| var ALERT_SELECT_GRAPHIC_FRAME = "Escoge un marco gráfico con una imagen colocada."; | |
| var ALERT_FRAME_NAME_REQUIRED = "El marco seleccionado no tiene nombre. Asigna un nombre al marco para continuar."; | |
| var ALERT_OPEN_DOCUMENT = "Abre un documento antes de ejecutar el script."; | |
| var ALERT_NO_OBJECT_STYLES = "No hay estilos de objeto disponibles en el documento."; | |
| var UI_LABEL_OBJECTS_WITH_NAME = "Marcos con nombre:"; | |
| var UI_LABEL_OBJECT_STYLE = "Estilo de objeto:"; | |
| var UI_BUTTON_CANCEL = "Cancelar"; | |
| var UI_BUTTON_OK = "OK"; | |
| var ALERT_DONE_PREFIX = "Listo.\nMarcos revisados con nombre \""; | |
| var ALERT_DONE_MIDDLE = "\": "; | |
| var ALERT_DONE_SUFFIX = "\nContenidos con estilo aplicado: "; | |
| app.doScript( | |
| main, | |
| ScriptLanguage.JAVASCRIPT, | |
| undefined, | |
| UndoModes.ENTIRE_SCRIPT, | |
| UNDO_LABEL | |
| ); | |
| function main() { | |
| if (app.documents.length === 0) { | |
| alert(ALERT_OPEN_DOCUMENT); | |
| return; | |
| } | |
| var doc = app.activeDocument; | |
| if (app.selection.length !== 1) { | |
| alert(ALERT_SELECT_GRAPHIC_FRAME); | |
| return; | |
| } | |
| var selectedFrame = resolveSelectedFrame(app.selection[0]); | |
| if (!selectedFrame || !selectedFrame.isValid) { | |
| alert(ALERT_SELECT_GRAPHIC_FRAME); | |
| return; | |
| } | |
| if (!selectedFrame.name || selectedFrame.name === "") { | |
| alert(ALERT_FRAME_NAME_REQUIRED); | |
| return; | |
| } | |
| var selectedImages = collectImagesFromFrame(selectedFrame); | |
| if (selectedImages.length === 0) { | |
| alert(ALERT_SELECT_GRAPHIC_FRAME); | |
| return; | |
| } | |
| var objectStyles = collectAllObjectStyles(doc); | |
| if (objectStyles.length === 0) { | |
| alert(ALERT_NO_OBJECT_STYLES); | |
| return; | |
| } | |
| var styleNames = []; | |
| var i; | |
| for (i = 0; i < objectStyles.length; i++) { | |
| styleNames.push(objectStyles[i].name); | |
| } | |
| var targetName = selectedFrame.name; | |
| /* | |
| Code for Import https://scriptui.joonas.me — (Triple click to select): | |
| {"activeId":0,"items":{"item-0":{"id":0,"type":"Dialog","parentId":false,"style":{"enabled":true,"varName":null,"windowType":"Dialog","creationProps":{"su1PanelCoordinates":false,"maximizeButton":false,"minimizeButton":false,"independent":false,"closeButton":true,"borderless":false,"resizeable":false},"text":"Aplicar estilo de objeto a contenido","preferredSize":[0,0],"margins":16,"orientation":"column","spacing":10,"alignChildren":["left","top"]}},"item-1":{"id":1,"type":"Group","parentId":0,"style":{"enabled":true,"varName":null,"preferredSize":[0,0],"margins":0,"orientation":"row","spacing":10,"alignChildren":["left","center"],"alignment":null}},"item-2":{"id":2,"type":"StaticText","parentId":1,"style":{"enabled":true,"varName":null,"creationProps":{"truncate":"none","multiline":false,"scrolling":false},"softWrap":false,"text":"Objetos con nombre:","justify":"left","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-3":{"id":3,"type":"StaticText","parentId":1,"style":{"enabled":true,"varName":null,"creationProps":{"truncate":"none","multiline":false,"scrolling":false},"softWrap":false,"text":"StaticText","justify":"left","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-4":{"id":4,"type":"Group","parentId":0,"style":{"enabled":true,"varName":null,"preferredSize":[0,0],"margins":0,"orientation":"row","spacing":10,"alignChildren":["left","center"],"alignment":null}},"item-5":{"id":5,"type":"StaticText","parentId":4,"style":{"enabled":true,"varName":null,"creationProps":{"truncate":"none","multiline":false,"scrolling":false},"softWrap":false,"text":"Estilo de objeto:","justify":"left","preferredSize":[0,0],"alignment":null,"helpTip":null}},"item-6":{"id":6,"type":"DropDownList","parentId":4,"style":{"enabled":true,"varName":null,"text":"DropDownList","listItems":"Item 1, -, Item 2","preferredSize":[0,0],"alignment":null,"selection":0,"helpTip":null}},"item-7":{"id":7,"type":"Group","parentId":0,"style":{"enabled":true,"varName":null,"preferredSize":[0,0],"margins":[10,0,0,0],"orientation":"row","spacing":10,"alignChildren":["right","top"],"alignment":"fill"}},"item-8":{"id":8,"type":"Button","parentId":7,"style":{"enabled":true,"varName":null,"text":"Cancelar","justify":"center","preferredSize":[80,0],"alignment":null,"helpTip":null}},"item-9":{"id":9,"type":"Button","parentId":7,"style":{"enabled":true,"varName":"ok","text":"OK","justify":"center","preferredSize":[80,0],"alignment":null,"helpTip":null}}},"order":[0,1,2,3,4,5,6,7,8,9],"settings":{"importJSON":true,"indentSize":false,"cepExport":false,"includeCSSJS":true,"showDialog":true,"functionWrapper":false,"afterEffectsDockable":false,"itemReferenceList":"None"}} | |
| */ | |
| var dialogWindow = new Window("dialog"); | |
| dialogWindow.text = DIALOG_TITLE; | |
| dialogWindow.orientation = "column"; | |
| dialogWindow.alignChildren = ["left", "top"]; | |
| dialogWindow.spacing = 10; | |
| dialogWindow.margins = 16; | |
| var nameGroup = dialogWindow.add("group", undefined, { name: "nameGroup" }); | |
| nameGroup.orientation = "row"; | |
| nameGroup.alignChildren = ["left", "center"]; | |
| nameGroup.spacing = 10; | |
| nameGroup.margins = 0; | |
| var objectsLabel = nameGroup.add("statictext", undefined, UI_LABEL_OBJECTS_WITH_NAME, { name: "objectsLabel" }); | |
| objectsLabel.text = UI_LABEL_OBJECTS_WITH_NAME; | |
| var nameValueLabel = nameGroup.add("statictext", undefined, targetName, { name: "nameValueLabel" }); | |
| nameValueLabel.text = targetName; | |
| var styleGroup = dialogWindow.add("group", undefined, { name: "styleGroup" }); | |
| styleGroup.orientation = "row"; | |
| styleGroup.alignChildren = ["left", "center"]; | |
| styleGroup.spacing = 10; | |
| styleGroup.margins = 0; | |
| var styleLabel = styleGroup.add("statictext", undefined, UI_LABEL_OBJECT_STYLE, { name: "styleLabel" }); | |
| styleLabel.text = UI_LABEL_OBJECT_STYLE; | |
| var styleDropdown = styleGroup.add("dropdownlist", undefined, styleNames, { name: "styleDropdown" }); | |
| styleDropdown.selection = 0; | |
| var buttonGroup = dialogWindow.add("group", undefined, { name: "buttonGroup" }); | |
| buttonGroup.orientation = "row"; | |
| buttonGroup.alignChildren = ["right", "top"]; | |
| buttonGroup.spacing = 10; | |
| buttonGroup.margins = [0, 10, 0, 0]; | |
| buttonGroup.alignment = ["fill", "top"]; | |
| var cancelButton = buttonGroup.add("button", undefined, UI_BUTTON_CANCEL, { name: "cancel" }); | |
| cancelButton.preferredSize.width = 80; | |
| var okButton = buttonGroup.add("button", undefined, UI_BUTTON_OK, { name: "ok" }); | |
| okButton.preferredSize.width = 80; | |
| var selectedStyleIndex = 0; | |
| if (dialogWindow.show() !== 1) { | |
| dialogWindow.close(); | |
| return; | |
| } | |
| selectedStyleIndex = styleDropdown.selection ? styleDropdown.selection.index : 0; | |
| dialogWindow.close(); | |
| if (selectedStyleIndex < 0 || selectedStyleIndex >= objectStyles.length) { | |
| selectedStyleIndex = 0; | |
| } | |
| var selectedStyle = objectStyles[selectedStyleIndex]; | |
| var appliedCount = 0; | |
| var visitedFrames = 0; | |
| var items = doc.allPageItems; | |
| for (i = 0; i < items.length; i++) { | |
| var it = items[i]; | |
| if (!it || !it.isValid) continue; | |
| if (!it.name || it.name !== targetName) continue; | |
| var imgs = collectImagesFromFrame(it); | |
| if (imgs.length === 0) continue; | |
| visitedFrames++; | |
| for (var j = 0; j < imgs.length; j++) { | |
| var img = imgs[j]; | |
| try { | |
| img.appliedObjectStyle = selectedStyle; | |
| appliedCount++; | |
| } catch (_e) { | |
| // Ignore items that do not accept object style assignment. | |
| } | |
| } | |
| } | |
| // alert(ALERT_DONE_PREFIX + targetName + ALERT_DONE_MIDDLE + visitedFrames + ALERT_DONE_SUFFIX + appliedCount); | |
| function resolveSelectedFrame(sel) { | |
| if (!sel || !sel.isValid) return null; | |
| var n = safeCtorName(sel); | |
| if (n === "Rectangle" || n === "Oval" || n === "Polygon") { | |
| return sel; | |
| } | |
| if (n === "Image" || n === "PDF" || n === "ImportedPage") { | |
| try { | |
| if (sel.parent && sel.parent.isValid) return sel.parent; | |
| } catch (_e) {} | |
| } | |
| return null; | |
| } | |
| function safeCtorName(obj) { | |
| try { | |
| return obj.constructor && obj.constructor.name ? obj.constructor.name : ""; | |
| } catch (_e) { | |
| return ""; | |
| } | |
| } | |
| function collectImagesFromFrame(frame) { | |
| var out = []; | |
| if (!frame || !frame.isValid) return out; | |
| try { | |
| for (var k = 0; k < frame.images.length; k++) { | |
| var im = frame.images[k]; | |
| if (im && im.isValid) out.push(im); | |
| } | |
| } catch (_e) {} | |
| return out; | |
| } | |
| function collectAllObjectStyles(documentRef) { | |
| var out = []; | |
| var seen = {}; | |
| if (!documentRef || !documentRef.isValid) return out; | |
| try { | |
| for (var idx = 0; idx < documentRef.objectStyles.length; idx++) { | |
| var st = documentRef.objectStyles[idx]; | |
| pushStyleIfNew(st, out, seen); | |
| } | |
| } catch (_e) {} | |
| try { | |
| for (var g = 0; g < documentRef.objectStyleGroups.length; g++) { | |
| collectStylesFromGroup(documentRef.objectStyleGroups[g], out, seen); | |
| } | |
| } catch (_e) {} | |
| return out; | |
| } | |
| function collectStylesFromGroup(group, out, seen) { | |
| if (!group || !group.isValid) return; | |
| try { | |
| for (var i = 0; i < group.objectStyles.length; i++) { | |
| pushStyleIfNew(group.objectStyles[i], out, seen); | |
| } | |
| } catch (_e) {} | |
| try { | |
| for (var j = 0; j < group.objectStyleGroups.length; j++) { | |
| collectStylesFromGroup(group.objectStyleGroups[j], out, seen); | |
| } | |
| } catch (_e) {} | |
| } | |
| function pushStyleIfNew(styleRef, out, seen) { | |
| if (!styleRef || !styleRef.isValid) return; | |
| var key; | |
| try { key = styleRef.toSpecifier(); } catch (_e) { key = styleRef.name; } | |
| if (seen[key]) return; | |
| seen[key] = true; | |
| out.push(styleRef); | |
| } | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment