Skip to main content
Inspiring
February 8, 2025
Pregunta

Adjust script to add artboard guides instead of document guides

  • February 8, 2025
  • 4 respuestas
  • 889 visualizaciones

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");
}

4 respuestas

Chuck Uebele
Community Expert
Community Expert
February 10, 2025

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);
}
Stephen Marsh
Community Expert
Community Expert
February 11, 2025

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.

Stephen Marsh
Community Expert
Community Expert
February 9, 2025

@TiagoRocha 

 

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);
    }
}

 

Chuck Uebele
Community Expert
Community Expert
February 9, 2025

@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.

 

 

Stephen Marsh
Community Expert
Community Expert
February 9, 2025

@Chuck Uebele 

 

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?

Stephen Marsh
Community Expert
Community Expert
February 9, 2025

@TiagoRocha 

 

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.

creative explorer
Community Expert
Community Expert
February 9, 2025

@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?

m
Stephen Marsh
Community Expert
Community Expert
February 10, 2025

@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.