Need guidance with modifying word scramble InDesign applescript

I am fairly new to applescripting and InDesign applescripting and I am looking for some guidance.

I found a simple letter substitution cipher applescript for InDesign that replaces a letter with the letter 13 letters after it in the alphabet. I can’t remember where I found it and couldn’t relocate it when I went searching for it recently.


–set theAlphabet to {“a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”, “l”, “m”, “n”, “o”, “p”, “q”, “r”, “s”, “t”, “u”, “v”, “w”, “x”, “y”, “z”, “A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, “I”, “J”, “K”, “L”, “M”, “N”, “O”, “P”, “Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”}
tell application “Adobe InDesign CS5.5”
if (count of every document) > 0 then
set theAlphabet to “abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”
set theROT to “nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM”
– set ReplacementText to “”
–set ReplacementText to the selection
set ReplaceThis to the selection
set ReplacementText to ReplaceThis as string
set WithThis to “”
if ReplacementText is not “” then
–repeat with i from 1 to the count of characters in ReplaceThis
considering case
repeat with eachChar in ReplacementText
– (*
set x to the offset of eachChar in theAlphabet
if x is not 0 then
set WithThis to ¬
WithThis & (character x of theROT) as string
else
set WithThis to (WithThis & eachChar) as string
end if
–*)

			end repeat
		end considering
		set ReplaceThis to item 1 of ReplaceThis
		set the contents of ReplaceThis to WithThis --as string
	else
		display dialog "select some text first"
	end if
else
	display dialog "you need to select text in an open document"
end if

end tell


The script works well: You select the text you to change, click the script and it does the letter substitution.

I am looking to modify the script so it will use the Fisher-Yates shuffle algorithm instead of the ROT-13 system of letter replacement. This way the substitutions will be unique each time the script is run.

Here is the applescript for the Fisher-Yates algorithm I found:


set myList to {“A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, “I”, “J”, “K”, “L”, “M”, “N”, “O”, “P”, “Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”}

–set myList to {ABCDEFGHIJKLMNOPQRSTUVWXYZ}

set answer to listShuffle(myList)

on listShuffle(theList)

set listLength to count of theList

repeat while listLength > 1
	
	
	
	set r to random number from 1 to listLength
	
	set item1 to item listLength of theList
	set item2 to item r of theList
	
	set item listLength of theList to item2
	set item r of theList to item1
	
	set listLength to listLength - 1
	
end repeat

return theList

end listShuffle

return myList


I have been tooling around with it for a week and realized I am way over my head.

I am not looking for someone to give me a completed solution, but I am hoping someone could point me in the right direction.

Thanks.

Hi. This accomplishes what you are requesting, although it’s unclear how you plan to descramble the random substitutions.

set staticAlpha to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set alphaList to staticAlpha
set scrambled to {}

repeat count alphaList times
	set randomLetter to alphaList's some item
	set {text item delimiters, scrambled's end} to {randomLetter, randomLetter}
	set alphaList to alphaList's text item 1 & alphaList's text item 2
end repeat

set text item delimiters to ""
set scrambled to scrambled as text

tell application "Adobe InDesign CS3"'s document 1
	if selection is not {} then
		tell selection to repeat with numb3r from 1 to count characters
			if character numb3r is in staticAlpha then set character numb3r to scrambled's text (offset of (character numb3r as text) in staticAlpha)
		end repeat
	else
		display dialog "Select some text."
	end if
end tell

Marc - Thanks for the script.

However, I receive a syntax error “Expected “,” but found application constant or consideration” on line 17 - (character numb3r as text) - the “as text” is highlighted.

Hmm. Try removing the coercion to text and adding an explicit “get.”

(offset of (get character numb3r) in staticAlpha)

No errors when I compile the script in Script Editor.

However, I receive the following error when I select the text in a text frame in InDesign and run the script:

Error Number: -1728
Error String: Can’t get text 0 of “JSLWECKTXYVFPZHGIDOBUNRQMA.”

Here is line 17 with the changes

if character numb3r is in staticAlpha then set character numb3r to scrambled’s text (offset of (get character numb3r) in staticAlpha)

Hi. I can’t reproduce your error. Did you change anything? I see a period inside your error string, but there are none in my variable. If the compared lists lack parity, an offset of 0 will be returned, and there can be no item 0 of anything. Read through the event log to see if you can spot the problem.

I did change “Abode InDesign CS3” to “Abode InDesign 5.5”

Here is the full script with the changes

set staticAlpha to “ABCDEFGHIJKLMNOPQRSTUVWXYZ”
set alphaList to staticAlpha
set scrambled to {}

repeat count alphaList times
set randomLetter to alphaList’s some item
set {text item delimiters, scrambled’s end} to {randomLetter, randomLetter}
set alphaList to alphaList’s text item 1 & alphaList’s text item 2
end repeat

set text item delimiters to “”
set scrambled to scrambled as text

tell application “Adobe InDesign CS5.5”'s document 1
if selection is not {} then
tell selection to repeat with numb3r from 1 to count characters
if character numb3r is in staticAlpha then set character numb3r to scrambled’s text (offset of (get character numb3r) in staticAlpha)
end repeat
else
display dialog “Select some text.”
end if
end tell

The offset command is bouncing back which will slow down the command. You can solve this many different ways but here is one:

The correct way to use offset, it’s more lines but faster because it got rid of silent -10004 errors

set staticAlpha to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set alphaList to staticAlpha
set scrambled to {}

repeat count alphaList times
	set randomLetter to alphaList's some item
	set {text item delimiters, scrambled's end} to {randomLetter, randomLetter}
	set alphaList to alphaList's text item 1 & alphaList's text item 2
end repeat

set text item delimiters to ""
set scrambled to scrambled as text

tell application "Adobe InDesign CS5.5"'s document 1
	if selection is not {} then
		tell selection to repeat with numb3r from 1 to count characters
			if character numb3r is in staticAlpha then
				set theChar to get character numb3r
				tell current application to set theOffset to offset of theChar in staticAlpha
				set character numb3r to scrambled's text theOffset
			end if
		end repeat
	else
		display dialog "Select some text."
	end if
end tell

It may sound nitpicking but since you mentioned you’re new to AppleScript I think it’s better to learn the right way from the start. The offset command is part of an AppleScript extension (osaxen). Meaning the command is ran in an special context outside AppleScript just like normal scripting language extensions. What happens is that the offset command is called while targeting Adobe InDesign, the command is tried to be executed there. The “command call manager” (event manager) sees that the command is not allowed to run outside the current application context and will stop the command from being executed by InDesign. Then an error will be returned and the command will be tried to run again in the current application context. The solutions above will eliminate this problem.

BTW, this strict way of calling commands from osaxen is since 10.6.

In general I agree with your approach, but in the case of offset there’s a simpler way to achieve the same thing if you are running 10.9 or later: insert use scripting additions at the beginning of the code.

More simply still”and not specific to Yosemite”the contextual problem that DJ observed can be corrected here with the simple addition of the word my.

if character numb3r is in staticAlpha then set character numb3r to scrambled's text (my (offset of (character numb3r as text) in staticAlpha))

That said, surely the silent errors are not the root cause of an offset of 0? That fix seems more like it is aimed at adjusting the efficiency of the script. What I wrote in post #2 works perfectly (under CS3 on Mavericks) in spite of suffering from the same flaw.

Thanks everyone. All of them are working. I am not sure what was throwing the error when I ran it before.

Now it’s time to figure out how it works.

I have noticed that 4 out of the 10 times I run the scripts above one or two of the letters are not replaced.

Example:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Y S L K C F R Q E U V P N T X W H B A G O D M I J Z

Both F and Z were not replaced.

What would be the best way to modify the scripts to make sure all letters are change?

Is there a way to check the scrambled alphabet against the static alphabet?

Something like this:

repeat with i from 1 to count alphaList
	repeat
		set randomLetter to alphaList's some item
		if randomLetter is not character i of staticAlpha then exit repeat
	end repeat
	set {text item delimiters, scrambled's end} to {randomLetter, randomLetter}
	set alphaList to alphaList's text item 1 & alphaList's text item 2
end repeat

Shane Stanley, that works great. Thank you for your assistance.