Copy link to clipboard
Copied
The basic idea is to prompt the user for a layer name.
If the layer name exists, run an action.
If the layer name does not exists, prompt the user for a layer name.
The next time the script runs in the same open document,
the script does not prompt for a layer name,
it remembers the previously entered layer name and runs an action if the layer exists.
If the layer name does not exists, the script prompts the user for a layer name.
I can manage most of the script behavior with an if else statement and prompt box.
However, I am not sure how to bypass the initial prompt dialog when running the script a second time on the same open document.
That is ,if layer name already exists in the layer pallet.
Try this. for some reason, the active layer is not highlighted if a layer isn't selected when the script if first run, but it still works. It's better to select some layer first before running the script.
...#target photoshop
var infoFile = new File('~/Desktop/layer-info.txt');
// redundant var file = infoFile;
var info =''
var doc = activeDocument;
var layerName = ''
//not needed readFile(file);
getInfo();
writeFile (infoFile, info);
////////////////////////////////////////////////////
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Most likely you should use either an xml or csv file to store the layer name. That way the script can check to see if that layer exists. I use xml files all the time to store UI values, and have one script that does something similar. It checks to see if a value was added to the xml so that editing can be done on a file then the script can be restarted and bypass the ui.
Copy link to clipboard
Copied
I have never used external xml files with photoshop scripts.
Can you please point me to an example, how to use an external xml file for temporary variable storage.
Copy link to clipboard
Copied
For you purpose, a csv or just a plain text file would work and is easy. here's a sample of what to do.
var infoFile = new File('/c/Images/info.txt')//whatever path and filename you want to use here.
var layerInfo ='layername***docname'//Here put you document name and layer name. Use whatever you want to split up the info.
writeFile (infoFile, layerInfo)
function getInfo(){
var infoArray = readFile (infoFile).split('***')//use whatever you want to split the array up
alert(infoArray)
}
function readFile(file) {
if (!file.exists) {
alert( "Cannot find file: " + deodeURI(file.absoluteURI));
}
else{
file.encoding = "UTF8";
file.lineFeed = "unix";
file.open("r", "TEXT", "????");
var str = file.read();
file.close();
return str;
};
};
function writeFile(file, info) {
file.encoding = "UTF8";
file.open("w", "TEXT", "????");
//unicode signature, this is UTF16 but will convert to UTF8 "EF BB BF"
file.write("\uFEFF");
file.lineFeed = "unix";
file.write(info);
file.close();
};
Copy link to clipboard
Copied
Thanks for providing the example. Questions about the second line of the sample script
Does docname reference the script name?
Copy link to clipboard
Copied
No, that would be the file name of your image, just to make sure you're using not only the same image but the same layer. It may not be needed. Just thought I'd throw that in.
Copy link to clipboard
Copied
The part, I don't understand is the docname. Will the script work with different files or only with filename specified in the docname.
Copy link to clipboard
Copied
The sample script writes the variable to the external txt file.
The next step is to check if the variable name in the external txt file.
How can the script check if the variable name is in the external txt file?
Copy link to clipboard
Copied
It will work with any file. You don't have to put in the docname. You do that if you want to make sure you are using the same file. You can put whatever you want.
This script isn't meant to be run by itself, meaning that there are parts to write the information to the text file and other parts to read that information back into a variable for you to use with your script. The flow would be:
Check to see if the text file exist, and if it does read the info into a variable/array. Then then the array to see if either the same file is open (the use of docname). Then see if there is the same layer name. If there isn't the proper info or text file. your UI comes up and ask the user to select that info. If the user selects new info, then the scripts rewrites the information to the text file. In line 11, I have an alert showing the contents of the array infoArray. That is the array that was created by reading the information in the text file. So you read the info from the text file, then use that array to get the info for your script to check to see if the file has the same layer name.
The script above just has the building blocks to create your script.
Copy link to clipboard
Copied
Thanks for the explanation. Does this sequence make sense for the script?
1-Declare variables aLayName and infoFile
2-Check if external file exist
3-Read external file variable
4-if external variable exists run action
5-if external variable does not exists prompt user for layer name
6-Write layer name to external file
7- Return to step 2
Copy link to clipboard
Copied
Yes, that makes sense. If at any time you want to reset the text file you can simply remove it or send blank information to it.
Copy link to clipboard
Copied
The script is able to check if the dependency file exists.
Then it checks if the dependency file has a string.
If the string length is grater than 0, it returns the existing string.
If the string is less than 0 it prompts the user for input.
It writes the string input to the dependency file.
Next it reads the and outputs returned string.
For the most part the script works returning the input string.
The second time the script runs it returns undefined as the string.
What can be causing this shift?
var infoFile = new File('~/Desktop/layer-info.txt');
var file = infoFile;
var info;
readFile(file);
getInfo();
writeFile (infoFile, info);
///////////////////////////////////////////////////////////////
// FUNCTIONS
////////////////////////////////////////////////////////////////
//Check if file exist
function readFile(file) {
if (!file.exists) {
alert( "Cannot find file: " + decodeURI(file.absoluteURI));
}
else{
file.encoding = "UTF8";
file.lineFeed = "unix";
file.open("r", "TEXT", "????");
var str = file.read();
file.close();
return str;
};
};
//Get file info
function getInfo(){
var infoArray = readFile (infoFile).split('***');
if(infoFile.length == 0){
info = prompt ('Enter a Layer Name');
return;
}
alert(infoArray)
}
//Write string to external file
function writeFile(file, info) {
file.encoding = "UTF8";
file.open("w", "TEXT", "????");
//unicode signature, this is UTF16 but will convert to UTF8 "EF BB BF"
file.write("\uFEFF");
file.lineFeed = "unix";
file.write(info);
file.close();
};
Copy link to clipboard
Copied
Try this. for some reason, the active layer is not highlighted if a layer isn't selected when the script if first run, but it still works. It's better to select some layer first before running the script.
#target photoshop
var infoFile = new File('~/Desktop/layer-info.txt');
// redundant var file = infoFile;
var info =''
var doc = activeDocument;
var layerName = ''
//not needed readFile(file);
getInfo();
writeFile (infoFile, info);
///////////////////////////////////////////////////////////////
// FUNCTIONS
////////////////////////////////////////////////////////////////
//Check if file exist
function readFile(file) {
if (!file.exists) {
alert( "Cannot find file: " + decodeURI(file.absoluteURI));
}
else{
file.encoding = "UTF8";
file.lineFeed = "unix";
file.open("r", "TEXT", "????");
var str = file.read();
file.close();
return str;
};
};
//Get file info
function getInfo(){
info=''//clear variable
var matchLayer = false;
if(infoFile.exists){
info = readFile (infoFile);
}//end if for file check
while(!matchLayer){
try{
doc.layers.getByName(info);
matchLayer = true;
}
catch(e){
info = prompt ('Layer name does not match any layer.\nEnter a Layer Name');
}
}//end while
}//end function
//Write string to external file
function writeFile(file, info) {
file.encoding = "UTF8";
file.open("w", "TEXT", "????");
//unicode signature, this is UTF16 but will convert to UTF8 "EF BB BF"
file.write("\uFEFF");
file.lineFeed = "unix";
file.write(info);
file.close();
};
Copy link to clipboard
Copied
Thanks for reviewing the script. When exiting the prompt via cancel button the script goes into an endless loop.
I try adding the return after line 44 and 46 to exit the loop gracefully. However this disable the loop.
Is there a better way to exit the prompt?
Copy link to clipboard
Copied
Yes, it will keep looping until you type in a correct name for a layer - it has to be exact. I didn't address canceling out out the loop.
Copy link to clipboard
Copied
Change the catch statement to this. This will get it out the of the loop if you press cancel:
catch(e){
info = prompt ('Layer name does not match any layer.\nEnter a Layer Name');
if(info == null){return}
}
Copy link to clipboard
Copied
Yes, that works great. Thank you.
Finally, Is there a method to that can clear the external txt file when the active photoshop document closes?
I am unable to clear the external txt file once it has been written.
Copy link to clipboard
Copied
You most likely need another script to either delete the file or overwrite it. To delete it, it would be something like:
var infoFile = new File(path)
infoFile.remove()
Copy link to clipboard
Copied
Without using the scripts events manager. Can a photoshop script run in the background so that when the active document closes the external txt file is automatically removed?
Copy link to clipboard
Copied
No, if a script runs, it pretty much locks up PS. How often do you need to purge the text file? Is it for each new document? If that is the case, then some code can be added to detect if it's a new document.
Copy link to clipboard
Copied
Actually, there is no need to purge the txt file. I tested the script on documents with different layer structures. If the script does not find the layer name stored in the txt file it prompts for a new layer name overwriting the old one. If it finds the layer name it runs an action on the layer.
Thanks sharing your knowledge and expertise. I truly, appreciate your help.
Copy link to clipboard
Copied
No problem, glad it's working out for you now.
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more