Skip to main content
NDL_DH
Known Participant
July 31, 2022
Answered

Script to remove extra spaces in text blocks?

  • July 31, 2022
  • 7 replies
  • 3152 views

Is there a script to be able to remove extra spaces (and soft returns) within a text block in photoshop?

And if so, how would I load the script again? I remember there's a folders somewhere I need to put the script file into? Then it shows up under the fle menu, under automations, right. 


This topic has been closed for replies.
Correct answer Stephen Marsh

@NDL_DH – Yes, as I previously wrote I don't know why the formatting is lost or how to avoid that. More accomplished scripters may be able to answer.

 

You can use the Edit > Find and Replace Text command. ScriptingListener can also capture the use of this as well and it doesn't remove the formatting in my simple tests.

 

The issue is that it uses strings as input/output, I can't work out how to "inject" variables or regular expressions. Therefore it would need repetition with hard-coded values: find/replace two spaces with one space. Repeat again for three spaces and replace with one space etc. Not the end of the world, but it could be better...

 

Edit:

 

findReplaceText("  ", " ", true, false, false, false, false); // 2 spaces
findReplaceText("   ", " ", true, false, false, false, false); // 3 spaces
findReplaceText("    ", " ", true, false, false, false, false); // 4 spaces
findReplaceText("     ", " ", true, false, false, false, false); // 5 spaces

function findReplaceText(find, replace, checkAll, forward, caseSensitive, wholeWord, ignoreAccents) {
	function s2t(s) {
        return app.stringIDToTypeID(s);
    }
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var reference = new ActionReference();
	reference.putProperty( s2t( "property" ), s2t( "replace" ));
	reference.putEnumerated( s2t( "textLayer" ), s2t( "ordinal" ), s2t( "allEnum" ));
	descriptor.putReference( s2t( "null" ), reference );
	descriptor2.putString( s2t( "find" ), find );
	descriptor2.putString( s2t( "replace" ), replace );
	descriptor2.putBoolean( s2t( "checkAll" ), checkAll );
	descriptor2.putBoolean( s2t( "forward" ), forward );
	descriptor2.putBoolean( s2t( "caseSensitive" ), caseSensitive );
	descriptor2.putBoolean( s2t( "wholeWord" ), wholeWord );
	descriptor2.putBoolean( s2t( "ignoreAccents" ), ignoreAccents );
	descriptor.putObject( s2t( "using" ), s2t( "findReplace" ), descriptor2 );
	executeAction( s2t( "replace" ), descriptor, DialogModes.NO );
}

 

7 replies

NDL_DH
NDL_DHAuthor
Known Participant
August 5, 2022

@Stephen Marsh 
@c.pfaffenbichler 
I get the same results using this, below.
Removes extra spaces but the styling still defaults.


/*
var doc = app.activeDocument;
try {
    if (doc.activeLayer.kind == LayerKind.TEXT) {
        doc.activeLayer.textItem.contents = doc.activeLayer.textItem.contents.replace(/ +/g, ' ');
    }
} catch (e) {}
*/


var aLay = app.activeDocument.activeLayer;
try{
if(aLay.textItem && aLay.textItem.contents != "") {


var changedText= aLay.textItem.contents.replace (/ +/g, ' ');

aLay.textItem.contents = changedText;

} 
} catch (e) {}
Stephen Marsh
Stephen MarshCorrect answer
Adobe Expert
August 6, 2022

@NDL_DH – Yes, as I previously wrote I don't know why the formatting is lost or how to avoid that. More accomplished scripters may be able to answer.

 

You can use the Edit > Find and Replace Text command. ScriptingListener can also capture the use of this as well and it doesn't remove the formatting in my simple tests.

 

The issue is that it uses strings as input/output, I can't work out how to "inject" variables or regular expressions. Therefore it would need repetition with hard-coded values: find/replace two spaces with one space. Repeat again for three spaces and replace with one space etc. Not the end of the world, but it could be better...

 

Edit:

 

findReplaceText("  ", " ", true, false, false, false, false); // 2 spaces
findReplaceText("   ", " ", true, false, false, false, false); // 3 spaces
findReplaceText("    ", " ", true, false, false, false, false); // 4 spaces
findReplaceText("     ", " ", true, false, false, false, false); // 5 spaces

function findReplaceText(find, replace, checkAll, forward, caseSensitive, wholeWord, ignoreAccents) {
	function s2t(s) {
        return app.stringIDToTypeID(s);
    }
	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var reference = new ActionReference();
	reference.putProperty( s2t( "property" ), s2t( "replace" ));
	reference.putEnumerated( s2t( "textLayer" ), s2t( "ordinal" ), s2t( "allEnum" ));
	descriptor.putReference( s2t( "null" ), reference );
	descriptor2.putString( s2t( "find" ), find );
	descriptor2.putString( s2t( "replace" ), replace );
	descriptor2.putBoolean( s2t( "checkAll" ), checkAll );
	descriptor2.putBoolean( s2t( "forward" ), forward );
	descriptor2.putBoolean( s2t( "caseSensitive" ), caseSensitive );
	descriptor2.putBoolean( s2t( "wholeWord" ), wholeWord );
	descriptor2.putBoolean( s2t( "ignoreAccents" ), ignoreAccents );
	descriptor.putObject( s2t( "using" ), s2t( "findReplace" ), descriptor2 );
	executeAction( s2t( "replace" ), descriptor, DialogModes.NO );
}

 

c.pfaffenbichler
Adobe Expert
August 6, 2022

I guess repeating the replacement of double-spaces until there are none would suffice. 

 

DOM-support for Type Layers is not great unfortunately and, as you are probably aware, editing them via AM-code is a bit »peculiar«. Not impossible but, for me at least, not exactly comfortable. 

 

NDL_DH
NDL_DHAuthor
Known Participant
August 5, 2022
NDL_DH
NDL_DHAuthor
Known Participant
August 1, 2022

@Stephen Marsh Also, sorry for all these messages, but is there a way to remove a space and an adjoining return or soft return..?
Along with the multiple space, or a separate jsx to deal with occurances of space followed by a return or soft return..?

Stephen Marsh
Adobe Expert
August 2, 2022

@NDL_DH wrote:

@Stephen Marsh Also, sorry for all these messages, but is there a way to remove a space and an adjoining return or soft return..?
Along with the multiple space, or a separate jsx to deal with occurances of space followed by a return or soft return..?


 

As I wrote earlier, I can't see a way to change a soft-return.

 

Multiple spaces and or multiple spaces and a line ending to be replaced with a space would be:

 

var doc = app.activeDocument;
try {
    if (doc.activeLayer.kind == LayerKind.TEXT) {
        doc.activeLayer.textItem.contents = doc.activeLayer.textItem.contents.replace(/ +\r/g, ' ');
    }
} catch (e) {}

 

I'm not sure why this would affect the formatting, however, I don't have a great deal of experience with scripting text layer changes so it may be something basic.

NDL_DH
NDL_DHAuthor
Known Participant
August 5, 2022

I'll test this out tomorrow and post results. 

Thanks again. 

NDL_DH
NDL_DHAuthor
Known Participant
August 1, 2022

@Stephen Marsh This script below, removes the spaces from the selected text layer, but it also removes all the formating, and defaults to the headline styling (font weight, size, color, etc).

Is there a way to retain the existing styling? 


 

var doc = app.activeDocument;

        app.activeDocument.activeLayer.kind == LayerKind.TEXT ;

            doc.activeLayer.textItem.contents = doc.activeLayer.textItem.contents.replace(/ +/g, ' ');
        
Stephen Marsh
Adobe Expert
August 2, 2022

That is unexpected, I didn't intend for the formatting to be removed, however, you are indeed correct.

 

This is what I was referring to with regards to removing the for loop:

 

var doc = app.activeDocument;
try {
    if (doc.activeLayer.kind == LayerKind.TEXT) {
        doc.activeLayer.textItem.contents = doc.activeLayer.textItem.contents.replace(/ +/g, ' ');
    }
} catch (e) {}

 

I'm not sure why this would affect the formatting, however, I don't have a great deal of experience with scripting text layer changes so it may be something basic.

NDL_DH
NDL_DHAuthor
Known Participant
August 5, 2022

This removes the spaces, but defaults the styling to whatever the top most style is, like previously mentioned.

It's so close I can taste it.

Monday I'll try to look for something that retains styling, that maybe I can place at the end of this script, IDK...?

c.pfaffenbichler
Adobe Expert
August 1, 2022
And if so, how would I load the script again? I remember there's a folders somewhere I need to put the script file into? 

Presets > Scripts 

 

In the program they are listed under File > Scripts 

NDL_DH
NDL_DHAuthor
Known Participant
August 1, 2022

Yes, thanks for showing me the location, found it.

Cheers.

Stephen Marsh
Adobe Expert
August 1, 2022

@NDL_DH 

 

The following script will replace 1 or more word spaces with a single word space in the active document:

 

var doc = app.activeDocument;
for (var j = 0; j < doc.layers.length; j++) {
    try {
        doc.activeLayer = doc.layers[j];
        if (app.activeDocument.activeLayer.kind == LayerKind.TEXT) {
            doc.activeLayer.textItem.contents = doc.activeLayer.textItem.contents.replace(/ +/g, ' ');
        }
    } catch (e) {}
}

 

I am not sure if Photoshop has the same level of support as one would find in InDesign, I can't get a soft return (shift + return)  to work:

 

.replace(/\u2029/g, '')

 

Edit: Instructions for saving and installing script code here –

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

NDL_DH
NDL_DHAuthor
Known Participant
August 1, 2022

Wow, thanks so much for this.

Just waiting for my admin at work to place it in the scripts folder.

Will report back results and mark correct hopefully by tomorrow.

Just to be clear though, this script I can run while having a text box selected (or the actual text selected, i.e., with the type tool) and it will only effect what I have selected, right?

Just want to make sure it's not going to effect everything within the PSD, regardless if it's selected or not. That would be bad.  

Stephen Marsh
Adobe Expert
August 1, 2022

It edits alll text layers in the open doc.

 

Remove the for loop to only edit the active layer.

 

The script can also be browsed without installation.

NDL_DH
NDL_DHAuthor
Known Participant
July 31, 2022

..I have a InDesign script that use to remove extra spacces, posted below.
Making a photoshop version of the below would be a good start..?

 

//reset GREP preferences
app.findGrepPreferences=app.changeGrepPreferences=null;


app.findGrepPreferences.findWhat="[~m~>~f~|~S~s~<~/~.~3~4~% ]{2,}";



app.changeGrepPreferences.changeTo="\\s";


 
var sel = app.selection;  
    for(var n=0;n<sel.length;n++)  
    {  
        sel[n].changeGrep();  
    };  


//reset GREP preferences
//app.findGrepPreferences=app.changeGrepPreferences=null;

 

NDL_DH
NDL_DHAuthor
Known Participant
July 31, 2022

EDIT:
..I have an InDesign script that I use to remove extra spacces, posted below.

Making a photoshop version of the below script would be a good start..?

//reset GREP preferences
app.findGrepPreferences=app.changeGrepPreferences=null;


app.findGrepPreferences.findWhat="[~m~>~f~|~S~s~<~/~.~3~4~% ]{2,}";



app.changeGrepPreferences.changeTo="\\s";


 
var sel = app.selection;  
    for(var n=0;n<sel.length;n++)  
    {  
        sel[n].changeGrep();  
    };  


//reset GREP preferences
//app.findGrepPreferences=app.changeGrepPreferences=null;