Skip to main content
Known Participant
March 25, 2020
Answered

Convert InDesign Applescript to javascript

  • March 25, 2020
  • 2 replies
  • 2392 views

Hi Everyone,

At a previous job of mine, a colleague had developed and shared an awesome script that cleans all the whitespace out of InDesign layouts (Multiple Space to Single Space, Remove Leading Whitespace, Remove Trailing Whitespace, Multiple Return to Single Return). This thing works like magic.

 

Every job I've had since getting this script were in Mac environments. The only thing I had to do to make it work on later versions of InDesign was to edit "tell application" to the updated app. However, right now I'm working remotely and I've been forced to use my PC to get work done and it would be really helpful if I had a javascript version of it.

 

Of course you guys can use this and/or pass it around so long as you credit my colleague. His info is in the prologue of the script.

 

Warning: this script does not play well with designers who do not lay their text out properly. If you use double returns and multiple spaces or tabs in your layout instead of proper paragraph styles with "space after", this script will wreck the layout.

 

-----------------------------------------------------------------------------------
--
-- Script Name: Clean Text White Space.scpt
-- Version: 1.0
-- Author: Brendan McBryan
-- Contact: brendan.mcbryan@gmail.com
-- Date: March 3, 2011
-- Application: Adobe InDesign CS4
--
-- Description: This AppleScript is designed to be run from the scripts panel in InDesign CS4. It will run the most common Find & Change actions relating to cleaning up white space in Text. 
--
--The Actions included are: Multiple Space to Single Space, Remove Leading Whitespace, Remove Trailing Whitespace, Multiple Return to Single Return.
--
-----------------------------------------------------------------------------------
tell application "Adobe InDesign CC 2018"
	
	
	--MULTIPLE SPACE TO SINGLE SPACE
	--Clear the find/change preferences.
	set find grep preferences to nothing
	set change grep preferences to nothing
	
	--Load Find/Change variables for Multiple Space to Single Space
	set varFind to "[~m~>" & "~f~|~S~s~<~/~.~3~4~% ]{2,}" as string
	set varChange to "\\s" as string
	set include hidden layers of find change grep options to true
	set the find what of find grep preferences to varFind
	set the change to of change grep preferences to varChange
	
	-- Execute Multiple Space to Single Space
	tell active document
		set varFoundMultipleSpace to change grep
	end tell
	
	--REMOVE LEADEING WHITESPACE	
	--Clear the find/change preferences.
	set find grep preferences to nothing
	set change grep preferences to nothing
	
	--Load Find/Change variables for Remove Leading Whitespace
	set varFind to "^ " as string
	set varChange to "" as string
	set include hidden layers of find change grep options to true
	set the find what of find grep preferences to varFind
	set the change to of change grep preferences to varChange
	
	-- Execute Multiple Space to Remove Leading Whitespace
	tell active document
		set varFoundLeadingSpace to change grep
	end tell
	--MULTIPLE RETURN TO SINGLE RETURN
	--Clear the find/change preferences.
	set find grep preferences to nothing
	set change grep preferences to nothing
	
	--Load Find/Change variables for Multiple Return to Single Return
	set varFind to "~b~b+" as string
	set varChange to "\\r" as string
	set include hidden layers of find change grep options to true
	set the find what of find grep preferences to varFind
	set the change to of change grep preferences to varChange
	
	-- Execute Multiple Return to Single Return
	tell active document
		set varFoundMultipleReturn to change grep
	end tell
	
	--REMOVE TRAILING WHITESPACE
	--Clear the find/change preferences.
	set find grep preferences to nothing
	set change grep preferences to nothing
	
	--Load Find/Change variables for Remove Trailing Whitespace
	set varFind to "\\s+$" as string
	set varChange to "" as string
	set include hidden layers of find change grep options to true
	set the find what of find grep preferences to varFind
	set the change to of change grep preferences to varChange
	
	-- Execute Remove Trailing Whitespace
	tell active document
		set varFoundTrailingSpace to change grep
	end tell
	--Display Change Count	
	set varAnswer to the button returned of (display dialog ¬
		("Changed " & (count varFoundMultipleSpace) & " Multiple Spaces to Single Spaces" & return & ¬
			"Removed " & (count varFoundLeadingSpace) & " instances of Leading Space" & return & ¬
			"Changed " & (count varFoundMultipleReturn) & " Multiple Returns to Single Returns" & return & ¬
			"Removed " & (count varFoundTrailingSpace) & " instances of Trailing Space") ¬
			as string ¬
		buttons {"Undo", "Thanks!"} ¬
		with title "Success!")
	
	--Undo if requested
	if varAnswer = "Undo" then
		tell application "System Events"
			repeat 4 times
				keystroke "z" using command down
			end repeat
		end tell
	end if
	
end tell

 This script does a grep find and change for several things, prompts you with how many things it changed, and gives you the option to undo what it did.

 

Please let me know if anyone can help with this. Thanks!!

This topic has been closed for replies.
Correct answer brian_p_dts

Here's my go-to findchange. You'd put the existing strings from your applescript into the multidimensional "fcs" array. 

 

 

 

 

var myChangeGrep = function( findPrefs, changePrefs, story ) {

		for ( var i in findPrefs ) {
			app.findGrepPreferences[i] = findPrefs[i];
		}
		for ( var j in changePrefs ) {
			app.changeGrepPreferences[j] = changePrefs[j];
		}
		story.changeGrep( true );

		app.findGrepPreferences = NothingEnum.NOTHING;
		app.changeGrepPreferences = NothingEnum.NOTHING;
	};

var main = function() {
    var doc = app.activeDocument;
    var fcs = [
        ["findstring", "changestring"],
        ["findstring", "changestring"],
        //more arrays here
    ];

    app.findGrepPreferences = NothingEnum.NOTHING;
    app.changeGrepPreferences = NothingEnum.NOTHING;

    for (var i = 0; i < fcs.length; i++) {
         myChangeGrep({findWhat:fcs[i][0]}, {changeTo:fcs[i][1]}, doc); 
    }
}



main();

 

 

 

2 replies

rob day
Community Expert
Community Expert
March 26, 2020

I use an Applescript with a handler so the code is easier to read and edit, and the searches can be set as single lines:

 

tell application "Adobe InDesign 2020"
	activate
	--replaces multiple tabs with single tab
	my GrepSearch("\\t+", "\\t")
	--removes any white space at the start of a paragraph including multiple returns
	my GrepSearch("^\\s*", "")
	--replaces multiple spaces with one space
	my GrepSearch("\\p{zs}{2,}", "\\s")
	--replaces soft return with a hard return
	my GrepSearch("\\s?\\n", "\\r")
	--replaces non breaking spaces with spaces
	my GrepSearch("~s|~S", "\\s")
end tell

on GrepSearch(f, c)
	tell application "Adobe InDesign 2020"
		set find grep preferences to nothing
		set change grep preferences to nothing
		set find what of find grep preferences to f
		set change to of change grep preferences to c
		change grep
	end tell
end GrepSearch

 

Here’s the equivalent in JS—both search the entire document:

 

//replaces multiple tabs with single tab
grepSearch("\t+", "\t");
//removes any white space at the start of a paragraph including multiple returns
grepSearch("^\s*", "")
//replaces multiple spaces with one space
grepSearch("\p{zs}{2,}", "\s")
//replaces soft return with a hard return
grepSearch("\s?\n", "\r")
//replaces non breaking spaces with spaces
grepSearch("~s|~S", "\s")


function grepSearch(f,c){
    app.findGrepPreferences.findWhat=NothingEnum.NOTHING
    app.changeGrepPreferences.changeTo=NothingEnum.NOTHING
    app.findGrepPreferences.findWhat = f;
    app.changeGrepPreferences.changeTo = c;
    app.activeDocument.changeGrep( true )
}
Known Participant
March 26, 2020

Thanks for posting! I'm not sure those search terms would be helpful in my workflow. The script I use is primarily to clean up text that I'm bringing in from Word docs from other people. This script cleans up all the garbage that comes from bad practices that people who are accustomed to using Word pick up and also people just not being careful. (Pasting in from word has it own annoyances too, like when you paste in a bulleted or numbered list, and now I can build a script to fix that).

 

I'm just curious why you would want to replace soft returns with hard returns and non breaking spaces with spaces. I need to use those all the time.

Known Participant
March 26, 2020

Now it's my turn to give back a bit.

 

Here are scripts I just made that would help clean up your text brought in from word. Of course the correct way to have bulleted and numbered lists is with a proper InDesign paragraph style. But pasting lists in from Word comes with extra junk. So these scripts will clean that up.

 

Bulleted List script:

 

var myChangeGrep = function( findPrefs, changePrefs, story ) {

		for ( var i in findPrefs ) {
			app.findGrepPreferences[i] = findPrefs[i];
		}
		for ( var j in changePrefs ) {
			app.changeGrepPreferences[j] = changePrefs[j];
		}
		story.changeGrep( true );

		app.findGrepPreferences = NothingEnum.NOTHING;
		app.changeGrepPreferences = NothingEnum.NOTHING;
	};

var main = function() {
    var doc = app.activeDocument;
    var fcs = [
        ["~8\t", ""],
    ];

    app.findGrepPreferences = NothingEnum.NOTHING;
    app.changeGrepPreferences = NothingEnum.NOTHING;

    for (var i = 0; i < fcs.length; i++) {
         myChangeGrep({findWhat:fcs[i][0]}, {changeTo:fcs[i][1]}, doc); 
    }
}



main();

 

 

Numbered list script:

 

var myChangeGrep = function( findPrefs, changePrefs, story ) {

		for ( var i in findPrefs ) {
			app.findGrepPreferences[i] = findPrefs[i];
		}
		for ( var j in changePrefs ) {
			app.changeGrepPreferences[j] = changePrefs[j];
		}
		story.changeGrep( true );

		app.findGrepPreferences = NothingEnum.NOTHING;
		app.changeGrepPreferences = NothingEnum.NOTHING;
	};

var main = function() {
    var doc = app.activeDocument;
    var fcs = [
        ["\\d+\.\t", ""],
    ];

    app.findGrepPreferences = NothingEnum.NOTHING;
    app.changeGrepPreferences = NothingEnum.NOTHING;

    for (var i = 0; i < fcs.length; i++) {
         myChangeGrep({findWhat:fcs[i][0]}, {changeTo:fcs[i][1]}, doc); 
    }
}



main();

 

 

I hope this helps someone!

brian_p_dts
Community Expert
brian_p_dtsCommunity ExpertCorrect answer
Community Expert
March 25, 2020

Here's my go-to findchange. You'd put the existing strings from your applescript into the multidimensional "fcs" array. 

 

 

 

 

var myChangeGrep = function( findPrefs, changePrefs, story ) {

		for ( var i in findPrefs ) {
			app.findGrepPreferences[i] = findPrefs[i];
		}
		for ( var j in changePrefs ) {
			app.changeGrepPreferences[j] = changePrefs[j];
		}
		story.changeGrep( true );

		app.findGrepPreferences = NothingEnum.NOTHING;
		app.changeGrepPreferences = NothingEnum.NOTHING;
	};

var main = function() {
    var doc = app.activeDocument;
    var fcs = [
        ["findstring", "changestring"],
        ["findstring", "changestring"],
        //more arrays here
    ];

    app.findGrepPreferences = NothingEnum.NOTHING;
    app.changeGrepPreferences = NothingEnum.NOTHING;

    for (var i = 0; i < fcs.length; i++) {
         myChangeGrep({findWhat:fcs[i][0]}, {changeTo:fcs[i][1]}, doc); 
    }
}



main();

 

 

 

Known Participant
March 25, 2020

That sounds promising. Unfortunately, I'm not much of a coder at all. Could you expand on your explanation a bit?

 

Thanks!

brian_p_dts
Community Expert
Community Expert
March 25, 2020

Everywhere where you have this expression:

 

 

set varFind to "\\s+$" as string
set varChange to "" as string

 

 

Fill in the "findstring" and "changestring" in the fcs array in my example: 

 

fcs = [

    ["\\s+$", ""],

    ["[~m~>" & "~f~|~S~s~<~/~.~3~4~% ]{2,}",  "\\s"],

    and so on

];