Adjust script to add artboard guides instead of document guides
Copy link to clipboard
Copied
I have this script that someone shared with me a while ago to add guides to a selection, but when working with artboards, it creates document guides, not artboard guides. Is it possible to change that?
// Add guides to selection.jsx
//@target Photoshop
if (app.documents.length) {
// Get doc.
var doc = app.activeDocument;
if (doc.selection) {
// Get bounds of selection.
var bounds = doc.selection.bounds;
doc.selection.deselect();
// Add guides to match bounds of selection.
doc.guides.add(Direction.VERTICAL, bounds[0]);
doc.guides.add(Direction.HORIZONTAL, bounds[1]);
doc.guides.add(Direction.VERTICAL, bounds[2]);
doc.guides.add(Direction.HORIZONTAL, bounds[3]);
} else {
alert("Make a selection");
}
} else {
alert("Open a document");
}
Explore related tutorials & articles
Copy link to clipboard
Copied
@TiagoRocha I would assume so...so couldn't you replace the document with artboards?
// Add guides to selection within the active artboard.jsx
//@target Photoshop
if (app.documents.length)
{ var doc = app.activeDocument;
if (doc.selection.length > 0) { // Check if something is selected
var selectedArtboard = doc.artboards.activeArtboard; // Get the active artboard
if (selectedArtboard) { // Ensure an artboard is active
var bounds = doc.selection.bounds;
// Convert selection bounds to artboard coordinates
var artboardBounds = selectedArtboard.artboardRect;
var left = bounds[0] - artboardBounds[0];
var top = bounds[1] - artboardBounds[1];
var right = bounds[2] - artboardBounds[0];
var bottom = bounds[3] - artboardBounds[1];
doc.selection.deselect();
// Add guides RELATIVE to the artboard
selectedArtboard.guides.add(Direction.VERTICAL, left);
selectedArtboard.guides.add(Direction.HORIZONTAL, top);
selectedArtboard.guides.add(Direction.VERTICAL, right);
selectedArtboard.guides.add(Direction.HORIZONTAL, bottom);
} else {
alert("No active artboard found. Please select an artboard.");
}
} else {
alert("Make a selection within an artboard.");
}
} else {
alert("Open a document");
}
Or something like that?
Copy link to clipboard
Copied
@creative explorer – Unfortunately, the app.activeDocument.artboards property is only valid for Adobe Illustrator's ExtendScript DOM and doesn't exist in Adobe Photoshop's ExtendScript DOM. If the source of this code was a generative AI "hallucination", it would be good to vote it down to help train the AI platform in question.
Copy link to clipboard
Copied
I don't believe that the DOM has been updated for artboard guides, which leaves AM code.
The cleaned SL plugin output shows the following for canvas guides:
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
descriptor2.putUnitDouble(s2t("position"), s2t("pixelsUnit"), 175); // Position
descriptor2.putEnumerated(s2t("orientation"), s2t("orientation"), s2t("vertical")); // "Horizontal" or "Vertical"
descriptor2.putEnumerated(s2t("kind"), s2t("kind"), s2t("document"));
reference.putIndex(s2t("good"), 1);
descriptor2.putReference(s2t("null"), reference);
descriptor.putObject(s2t("new"), s2t("good"), descriptor2);
reference2.putClass(s2t("good"));
descriptor.putReference(s2t("null"), reference2);
descriptor.putEnumerated(s2t("guideTarget"), s2t("guideTarget"), s2t("guideTargetCanvas")); // Canvas guides
executeAction(s2t("make"), descriptor, DialogModes.NO);
While artboard guides shows this:
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
descriptor2.putUnitDouble(s2t("position"), s2t("pixelsUnit"), 175); // Position
descriptor2.putEnumerated(s2t("orientation"), s2t("orientation"), s2t("vertical")); // Horizontal or Vertical
descriptor2.putEnumerated(s2t("kind"), s2t("kind"), s2t("document"));
reference.putIndex(s2t("good"), 5);
descriptor2.putReference(s2t("null"), reference);
descriptor2.putInteger(c2t("GdCA"), 0); // ?
descriptor2.putInteger(c2t("GdCR"), 255); // ?
descriptor2.putInteger(c2t("GdCG"), 74); // ?
descriptor2.putInteger(c2t("GdCB"), 74); // ?
descriptor.putObject(s2t("new"), s2t("good"), descriptor2);
reference2.putClass(s2t("good"));
descriptor.putReference(s2t("null"), reference2);
descriptor.putEnumerated(s2t("guideTarget"), s2t("guideTarget"), s2t("guideTargetSelectedArtboard")); // Artboard guides
executeAction(s2t("make"), descriptor, DialogModes.NO);
The "guideTarget" of "guideTargetCanvas" vs. "guideTargetSelectedArtboard" is obvious to me, however, I have no idea what significance the following four lines have, except that they appear to be critical:
descriptor2.putInteger(c2t("GdCA"), 0); // ?
descriptor2.putInteger(c2t("GdCR"), 255); // ?
descriptor2.putInteger(c2t("GdCG"), 74); // ?
descriptor2.putInteger(c2t("GdCB"), 74); // ?
The values don't appear to be consistent with either the artboard or canvas size or coordinates. The values appear to be close but not exact to the current preferences/settings for artboard guide colour.
Copy link to clipboard
Copied
I have made some refinements to the original script while I was adjusting it for artboard guides:
/*
Add guides to selection.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/adjust-script-to-add-artboard-guides-instead-of-document-guides/m-p/15141437
*/
#target Photoshop
if (app.documents.length) {
app.activeDocument.suspendHistory("Add Guides to Selection", "main()");
function main() {
// Get active document
var doc = app.activeDocument;
// Store the current ruler units
var originalUnits = app.preferences.rulerUnits;
// Set units to pixels
app.preferences.rulerUnits = Units.PIXELS;
var selectionBounds = null;
try { selectionBounds = activeDocument.selection.bounds; } catch (e) { }
if (selectionBounds) {
try {
// Get bounds of selection
var bounds = doc.selection.bounds;
// Deselect after getting bounds
doc.selection.deselect();
// Add guides to match bounds of selection
doc.guides.add(Direction.VERTICAL, bounds[0]);
doc.guides.add(Direction.HORIZONTAL, bounds[1]);
doc.guides.add(Direction.VERTICAL, bounds[2]);
doc.guides.add(Direction.HORIZONTAL, bounds[3]);
} catch (e) {
alert("Error creating guides: " + e);
} finally {
// Restore original ruler units
app.preferences.rulerUnits = originalUnits;
}
}
else {
alert("Make a selection");
}
}
} else {
alert("Please open a document");
}
While this is the script that you asked for adding artboard guides, as opposed to canvas guides.
Note: The guide colour has to be hard coded into the script, I have used 128rgb as a placeholder. I'll need to see if it's possible to pick up on the preferences/settings for the artboard guide colour rather than hard-coding in the colour.
/*
Add Artboard Guides to Selection.jsx
Stephen Marsh
v1.0 - 9th February 2025
https://community.adobe.com/t5/photoshop-ecosystem-discussions/adjust-script-to-add-artboard-guides-instead-of-document-guides/m-p/15141437
*/
#target Photoshop
if (app.documents.length) {
app.activeDocument.suspendHistory("Add Artboard Guides to Selection", "main()");
function main() {
// Check if the active layer is an artboard, alternatively one could also use a basic layerSet check
if (isArtboard() === true) {
// Get active document
var doc = app.activeDocument;
// Store the current ruler units
var originalUnits = app.preferences.rulerUnits;
// Set units to pixels
app.preferences.rulerUnits = Units.PIXELS;
var activeSelection = null;
try { activeSelection = doc.selection.bounds } catch (e) { }
if (activeSelection) {
try {
// Trim to transparent pixels to ensure that the bounds are correct
doc.trim(TrimType.TRANSPARENT, true, true, true, true);
// Get bounds of selection
var bounds = doc.selection.bounds;
// Deselect after getting bounds
doc.selection.deselect();
// Add guides to match bounds of selection
artboardGuides(bounds[0].value, "vertical");
artboardGuides(bounds[1].value, "horizontal");
artboardGuides(bounds[2].value, "vertical");
artboardGuides(bounds[3].value, "horizontal");
} catch (e) {
alert("Error creating guides: " + e);
} finally {
// Restore original ruler units
app.preferences.rulerUnits = originalUnits;
}
}
else {
alert("Make a selection");
}
} else {
alert("Please select an artboard");
}
}
} else {
alert("Please open a document");
}
// Helper Functions
function artboardGuides(thePosition, theOrientation) {
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
descriptor2.putUnitDouble(s2t("position"), s2t("pixelsUnit"), thePosition); // Position
descriptor2.putEnumerated(s2t("orientation"), s2t("orientation"), s2t(theOrientation)); // Horizontal or Vertical
descriptor2.putEnumerated(s2t("kind"), s2t("kind"), s2t("document"));
reference.putIndex(s2t("good"), 5);
descriptor2.putReference(s2t("null"), reference);
descriptor2.putInteger(c2t("GdCA"), 0); // Alpha?
descriptor2.putInteger(c2t("GdCR"), 128); // Red
descriptor2.putInteger(c2t("GdCG"), 128); // Green
descriptor2.putInteger(c2t("GdCB"), 128); // Blue
descriptor.putObject(s2t("new"), s2t("good"), descriptor2);
reference2.putClass(s2t("good"));
descriptor.putReference(s2t("null"), reference2);
descriptor.putEnumerated(s2t("guideTarget"), s2t("guideTarget"), s2t("guideTargetSelectedArtboard")); // Artboard guides
executeAction(s2t("make"), descriptor, DialogModes.NO);
}
function isArtboard() {
// modified from a script by greless with hints from jazz-y!
// returns true or false
try {
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
var options = executeActionGet(r);
return options.hasKey(stringIDToTypeID('artboard')); // test for the required key
} catch (e) {
//alert(e);
}
}
Copy link to clipboard
Copied
@Stephen Marsh You have an issue with your script. You might not have tried a file with multiple artboards and a layer not included in the artboards. With AM code, a marquee will be created with bounds of the overall document, but a guide will use the artboard boundries. So your guides will be off.
Copy link to clipboard
Copied
Thanks, no I didn't think to test for such an edge-case. I hate scripting artboards.
EDIT: Ah, it's not just an empty artboard, a second artboard has issues.
I put in an explicit check to ensure that an artboard was selected and also a trim to transparency to account for canvases that haven't been "shrink-wrapped".
What would be the workaround? Saving with shrink wrap on before adding the guides? Looping over all top level layerSets and checking if their length was zero, then adding a temporary layer and or content?
Copy link to clipboard
Copied
I don't know what a workaround would be yet. Your method works for one dartboard, but I haven't tested 2 artboards. The trouble is that a marquee will be based off the document boundaries whereas a guide will be bases off an artboard's, no matter which is selected in the layer panel. To make matters worse, when you get the bounds of the dartboard. It's always 0, 0 for the top and left. It's not based on the document edges, so you can't compensate for the artboard's offset. Only thing that i can think of is to create a filled layer at the boundaries inside the artboard, then move it outside the artboard. Then you could get the AB's boundaries.
Copy link to clipboard
Copied
I have this AM code from @Rune L-H
// Artboard bounds - by Rune L-H
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var artBoardRect = executeActionGet(ref).getObjectValue(stringIDToTypeID("artboard")).getObjectValue(stringIDToTypeID("artboardRect"));
var artBoardRectWidth = new UnitValue(artBoardRect.getDouble(stringIDToTypeID("right")) - artBoardRect.getDouble(stringIDToTypeID("left")), "px");
var artBoardRectHeight = new UnitValue(artBoardRect.getDouble(stringIDToTypeID("bottom")) - artBoardRect.getDouble(stringIDToTypeID("top")), "px");
artBoardRectWidth = parseInt(artBoardRectWidth);
artBoardRectHeight = parseInt(artBoardRectHeight);
And this one is from you:
function artboard_rectangle(layer) {
/*
https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-scripting-artboard-size-values/td-p/13255332
by Chuck Uebele
*/
try {
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("artboard"));
if (layer) r.putIdentifier(stringIDToTypeID("layer"), layer.id);
else r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var d = executeActionGet(r).getObjectValue(stringIDToTypeID("artboard")).getObjectValue(stringIDToTypeID("artboardRect"));
var bounds = new Array();
bounds[0] = d.getUnitDoubleValue(stringIDToTypeID("left"));
bounds[1] = d.getUnitDoubleValue(stringIDToTypeID("top"));
bounds[2] = d.getUnitDoubleValue(stringIDToTypeID("right"));
bounds[3] = d.getUnitDoubleValue(stringIDToTypeID("bottom"));
return bounds;
} catch (e) {
alert("An artboard must be selected!");
}
}
However, I haven't tested them in this context.
Copy link to clipboard
Copied
It looks like my script gets the correct bounds. I've writen so many scripts that I don't remember doing this. I'll have to see if it can be used to correct the issue.
Copy link to clipboard
Copied
Well, with the help of @Stephen Marsh Here's a script that works. It doesn't have full error checking, so you have to make sure you have a selection made and an artboard selected.
#target photoshop
var doc = activeDocument
var abL = doc.activeLayer
// Store the current ruler units
var originalUnits = app.preferences.rulerUnits;
// Set units to pixels
app.preferences.rulerUnits = Units.PIXELS;
var activeSelection = null;
try { activeSelection = doc.selection.bounds } catch (e) { alert('A selection must be made')}
var abBounds = artboard_rectangle (abL)
var correctedOffset = [];
correctedOffset[0] = activeSelection[0].value-abBounds[0];
correctedOffset[1] = activeSelection[1].value-abBounds[1];
correctedOffset[2] = activeSelection[2].value-abBounds[0];
correctedOffset[3] = activeSelection[3].value-abBounds[1];
// Add guides to match bounds of selection
artboardGuides(correctedOffset[0], "vertical");
artboardGuides(correctedOffset[1], "horizontal");
artboardGuides(correctedOffset[2], "vertical");
artboardGuides(correctedOffset[3], "horizontal");
/*
artboardGuides(bounds[0].value, "vertical");
artboardGuides(bounds[1].value, "horizontal");
artboardGuides(bounds[2].value, "vertical");
artboardGuides(bounds[3].value, "horizontal");
*/
app.preferences.rulerUnits = originalUnits;
function artboardGuides(thePosition, theOrientation) {
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
descriptor2.putUnitDouble(s2t("position"), s2t("pixelsUnit"), thePosition); // Position
descriptor2.putEnumerated(s2t("orientation"), s2t("orientation"), s2t(theOrientation)); // Horizontal or Vertical
descriptor2.putEnumerated(s2t("kind"), s2t("kind"), s2t("document"));
reference.putIndex(s2t("good"), 5);
descriptor2.putReference(s2t("null"), reference);
descriptor2.putInteger(c2t("GdCA"), 0); // Alpha?
descriptor2.putInteger(c2t("GdCR"), 128); // Red
descriptor2.putInteger(c2t("GdCG"), 128); // Green
descriptor2.putInteger(c2t("GdCB"), 128); // Blue
descriptor.putObject(s2t("new"), s2t("good"), descriptor2);
reference2.putClass(s2t("good"));
descriptor.putReference(s2t("null"), reference2);
descriptor.putEnumerated(s2t("guideTarget"), s2t("guideTarget"), s2t("guideTargetSelectedArtboard")); // Artboard guides
executeAction(s2t("make"), descriptor, DialogModes.NO);
}
function artboard_rectangle(layer) {
try {
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("artboard"));
if (layer) r.putIdentifier(stringIDToTypeID("layer"), layer.id);
else r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var d = executeActionGet(r).getObjectValue(stringIDToTypeID("artboard")).getObjectValue(stringIDToTypeID("artboardRect"));
var bounds = new Array();
bounds[0] = d.getUnitDoubleValue(stringIDToTypeID("left"));
bounds[1] = d.getUnitDoubleValue(stringIDToTypeID("top"));
bounds[2] = d.getUnitDoubleValue(stringIDToTypeID("right"));
bounds[3] = d.getUnitDoubleValue(stringIDToTypeID("bottom"));
return bounds;
} catch (e) {
alert("An artboard must be selected!");
}
}
function isArtboard() {
// modified from a script by greless with hints from jazz-y!
// returns true or false
try {
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
var options = executeActionGet(r);
return options.hasKey(stringIDToTypeID('artboard')); // test for the required key
} catch (e) {
//alert(e);
}
}
function artboardGuides(thePosition, theOrientation) {
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
var reference2 = new ActionReference();
descriptor2.putUnitDouble(s2t("position"), s2t("pixelsUnit"), thePosition); // Position
descriptor2.putEnumerated(s2t("orientation"), s2t("orientation"), s2t(theOrientation)); // Horizontal or Vertical
descriptor2.putEnumerated(s2t("kind"), s2t("kind"), s2t("document"));
reference.putIndex(s2t("good"), 5);
descriptor2.putReference(s2t("null"), reference);
descriptor2.putInteger(c2t("GdCA"), 0); // Alpha?
descriptor2.putInteger(c2t("GdCR"), 128); // Red
descriptor2.putInteger(c2t("GdCG"), 128); // Green
descriptor2.putInteger(c2t("GdCB"), 128); // Blue
descriptor.putObject(s2t("new"), s2t("good"), descriptor2);
reference2.putClass(s2t("good"));
descriptor.putReference(s2t("null"), reference2);
descriptor.putEnumerated(s2t("guideTarget"), s2t("guideTarget"), s2t("guideTargetSelectedArtboard")); // Artboard guides
executeAction(s2t("make"), descriptor, DialogModes.NO);
}
Copy link to clipboard
Copied
That's great @Chuck Uebele – thanks for correcting my code!
@TiagoRocha – Please mark Chuck's reply as a correct answer if works for you (it did for me).
P.S. There appears to be a duplicate artboardGuides function code block which can be removed.

