Skip to main content
Known Participant
September 16, 2019
Question

Writing an applescript to import text to text layer

  • September 16, 2019
  • 8 replies
  • 5864 views

Hi all

Is there an easy way to write an AppleScript that would do this:

From an open PS document.
1) Go to a specified txt document.
2)  Copy the first line
3) Paste into new text layer

4) Change name of text layer to a specified value
5)  Duplicate document and name with the text from layer
6) Save as 
7) Go back to original document and repeat until reaching the end of the lines in the document.

There's a tutorial on youtube using Java and JSON, but I'd like to avoid Java if I can.

This topic has been closed for replies.

8 replies

Chuck Uebele
Community Expert
Community Expert
September 16, 2019

The "~" in the path points to your personal folders. If you're using an external drive, you don't use that. You need set the exact path. I'm unfamilar with Mac's path naming. There are two ways to describe a path. One uses forward slashes '/' and the other uses back slashes '\'. If you use back slashes, you have to use double one. It's best to use the forward slash.

 

The error in line 28 might be due to how you named the text layer. The name is case sensitive, so they have to match your layer name and the name used in the code.

dcsimagesAuthor
Known Participant
September 16, 2019

That did it. Removing the tilde in the path and making the name of the text layer all lower case fixed it.

Thanks so much again. I have been putting off implementing this idea for 2 years because the idea of manualy changing the text in thousands of files was too daunting. I will still have to go in and adjust the font size for words or phrases with more than 10 characters, but that's only about 5% and I can deal with that.

At some point I can try to figure out how to set the font size in the script and break the source files down and separate them by character totals, but that's for another day.

In the mean time I can get started.

Chuck Uebele
Community Expert
Community Expert
September 16, 2019
Great. That's how I got into scripting: too lazy to do all that manual formatting.
Chuck Uebele
Community Expert
Community Expert
September 16, 2019

I forgot to check if the text layer name changes when the new text is added. If it does, you need to add a line of code to rest the layer name:

 

TxtLayer.name = 'text';

dcsimagesAuthor
Known Participant
September 16, 2019

So, I edited the script to put in the save as location as so

var txtFile = new File('~/Desktop/Text.txt');//enter path and file name for text file
var saveFolder = new Folder('~/Volumes/9TB-2/Mug Designs saved PSD/')
if(!saveFolder.exists){saveFolder.create()};//creates the save folder if it doesn't exists


The script finds the first line of text and creates a duplicate file named with the first name in the txt, but doesn't change the content of the text layer or save and close. The new document just stays open in PS.

I also get this error meassage
 Error 1302: No Such element

Line:28

-> var txtLayer =
newFile.Layers.getByName('text');

Chuck Uebele
Community Expert
Community Expert
September 16, 2019

Here's the script if you already have a text layer. Just make sure the text layer name matches what the name is in the code in the getByName line. I'm assuming you want "text" as the name, so that's what it's set up for.

And, yes, you save it as a .jsx file.

 

#target photoshop

app.preferences.rulerUnits = Units.PIXELS;

var txtFile = new File('~/desktop/textFile.txt');//enter path and file name for text file
var saveFolder = new Folder('~/desktop/Saved Files/')
if(!saveFolder.exists){saveFolder.create()};//creates the save folder if it doesn't exists

var psdOptions = new PhotoshopSaveOptions()
psdOptions.layers = true

var doc = activeDocument;//original file

var run = true;

if (txtFile.exists){
    var txtInfo = readTextFile (txtFile).split('\n');
    }
else{
    run = false;
    alert('There is no text file.')
    }

if(run){
    for(var i=0;i<txtInfo.length;i++){
        dupeFile (txtInfo[i])
        var newFile = app.activeDocument;
        var txtLayer = newFile.layers.getByName('text');
        txtLayer.textItem.contents = txtInfo[i];
        newFile.saveAs (new File(saveFolder +'/' + txtInfo[i] + '.psd'), psdOptions);
        newFile.close(SaveOptions.DONOTSAVECHANGES);
        }//end for loop
    }//end if to run

function readTextFile(file){		
		file.encoding = "UTF8";
		file.lineFeed = "unix";
		file.open("r", "TEXT", "????");
		var str = file.read();
		file.close();
         return str
        }
    
function dupeFile(name){
       var idDplc = charIDToTypeID( "Dplc" );
        var desc5 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idDcmn = charIDToTypeID( "Dcmn" );
            var idOrdn = charIDToTypeID( "Ordn" );
            var idFrst = charIDToTypeID( "Frst" );
            ref1.putEnumerated( idDcmn, idOrdn, idFrst );
        desc5.putReference( idnull, ref1 );
        var idNm = charIDToTypeID( "Nm  " );
        desc5.putString( idNm, name );//new name of file .
    executeAction( idDplc, desc5, DialogModes.NO ); 
    }
Chuck Uebele
Community Expert
Community Expert
September 16, 2019

Yes, it would be better to use an existing text layer, where you can set the formatting and position. Then you can get rid if all that code to create and format the layer. You just need to get the layer.

 

Yes, just change the paths to there the text file is and where you want to save it. You can create a loop for multiple text files. 

dcsimagesAuthor
Known Participant
September 16, 2019

So I would remove

function createTextLayer(textContent){
    var artLayerRef = newFile.artLayers.add()
    artLayerRef.kind = LayerKind.TEXT;
    artLayerRef.name = 'text';
    var textItemRef = artLayerRef.textItem;
    textItemRef.justification = Justification.LEFT;
    textItemRef.size = 200;
    textItemRef.position =[20, 200];
    textItemRef.contents = textContent;
    }

from your script and replace it with? Sorry for being a pain, but my last hands on coding was in BASIC on a TRS80 in high school in 1979.

Chuck Uebele
Community Expert
Community Expert
September 16, 2019

Here is a script that will do what you want, I think. You need to insert the path and name of your text file, adjust whare you want the text layer, it's size, and font.

 

#target photoshop

app.preferences.rulerUnits = Units.PIXELS;

var txtFile = new File('~/desktop/textFile.txt');//enter path and file name for text file
var saveFolder = new Folder('~/desktop/Saved Files/')
if(!saveFolder.exists){saveFolder.create()};//creates the save folder if it doesn't exists

var psdOptions = new PhotoshopSaveOptions()
psdOptions.layers = true

var doc = activeDocument;//original file

var run = true;

if (txtFile.exists){
    var txtInfo = readTextFile (txtFile).split('\n');
    }
else{
    run = false;
    alert('There is no text file.')
    }

if(run){
    for(var i=0;i<txtInfo.length;i++){
        dupeFile (txtInfo[i])
        var newFile = app.activeDocument;
        createTextLayer (txtInfo[i]);
        newFile.saveAs (new File(saveFolder +'/' + txtInfo[i] + '.psd'), psdOptions);
        newFile.close(SaveOptions.DONOTSAVECHANGES);
        }//end for loop
    }//end if to run

function createTextLayer(textContent){
    var artLayerRef = newFile.artLayers.add()
    artLayerRef.kind = LayerKind.TEXT;
    artLayerRef.name = 'text';
    var textItemRef = artLayerRef.textItem;
    textItemRef.justification = Justification.LEFT;
    textItemRef.size = 200;
    textItemRef.position =[20, 200];
    textItemRef.contents = textContent;
    }

function readTextFile(file){		
		file.encoding = "UTF8";
		file.lineFeed = "unix";
		file.open("r", "TEXT", "????");
		var str = file.read();
		file.close();
         return str
        }
    
function dupeFile(name){
       var idDplc = charIDToTypeID( "Dplc" );
        var desc5 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idDcmn = charIDToTypeID( "Dcmn" );
            var idOrdn = charIDToTypeID( "Ordn" );
            var idFrst = charIDToTypeID( "Frst" );
            ref1.putEnumerated( idDcmn, idOrdn, idFrst );
        desc5.putReference( idnull, ref1 );
        var idNm = charIDToTypeID( "Nm  " );
        desc5.putString( idNm, name );//new name of file .
    executeAction( idDplc, desc5, DialogModes.NO ); 
    }

 

 

 

dcsimagesAuthor
Known Participant
September 16, 2019

First off, thanks very much for doing this.

 

A couple of questions.


Is this based on my first set of parameters or the later one when I realized that just changing the content of an existing text layer might be easier?

My second idea would actually be better, because I wouldn't have to run a batch action to set the text layer attributes, just manually tweek some of the font sizes if some of the text lines end up being too large for the space alotted.

Do I copy and save this as a .jsx?

I presume I can change the file paths to read from and save to an external drive. Saving to the desktop would fill the drive before all the files could be finished. I have about 3000 or so lines per txt file and there are 4 txt files to process. I'll be saving to a 12 TB RAID 5.

Thanks again

Dave


Chuck Uebele
Community Expert
Community Expert
September 16, 2019

Carriage returns are fine.

 

So I take it that the file needs to be saved as a psd?

 

Does your original file already have the text layer, and you just need to change the contents, or does a new text layer need to be created?

 

 

dcsimagesAuthor
Known Participant
September 16, 2019

Yes they need to be saved as psd's

Yes, changing the text in an existing text layer would be the easiest. That way it would automatically have the font, color and effects already applied. Wouldn't have to rename the type layer either. I was thinking that I would be running a batch action to set  all those on the resultant files.

So the procedure would be

1) Get line from txt

 

2) Change content of text layer 

3) Duplicate document

4) Save as psd, renaming it with the content of the text file. It can be saved in the location of the original psd.

Actually, I think that on a Mac you can still set a file as a template in file info so that the original can't be overwritten. Would that be helpful?

So, let's say I have a file with 4 lines on it.

John
Mary
Joe
George

I open my existing PSD which is a background layer and a text layer called "name". I run the script from within PS. It looks for the txt file in a specified location, copies the first line, ( to the clipboard?) selects the text layer named "name", pastes the text John, duplicates the doc, save as psd, pasting "John" from the clipboard into the file name field and close. It then goes to Mary in the txt file and repeats, then Joe, then George and then stops.

So I end up with a folder with my origianl template and 4 psd files named John, Mary, Joe and George each having the appropriate text inserted in the text layer

Chuck Uebele
Community Expert
Community Expert
September 16, 2019

What does the text document consist of? How are the lines separeted: periods, commas, line breaks, etc. What is the naming convention for the layers?

dcsimagesAuthor
Known Participant
September 16, 2019

The line consist of 1 - 3 words.

The lines are currently separated by carriage returns but I could add commas or semi colons easily.

The text layer can be just named "text" for simplicity. They all need to be named the same for running an action on the file later.


Chuck Uebele
Community Expert
Community Expert
September 16, 2019

Is there a reason you want to use apple script? More people know extendscript and can offer more help. Your requirements look fairly straightforward though and should be able to be done.

dcsimagesAuthor
Known Participant
September 16, 2019

Hi Chuck

I'm willing to learn ExtendScript.

Just want to avoid Java