AppleScript Endec (Encoder/Decoder) 1.0.2
AppleScript Endec (Encoder/Decoder) 1.0.2
- Subject: AppleScript Endec (Encoder/Decoder) 1.0.2
- From: Bill Cheeseman <email@hidden>
- Date: Sun, 18 Feb 2001 05:44:26 -0500
At the end of this message you will find the text of Wolf Rentzsch's script
"AppleScript Endec 1.0.2". Copy it (including the opening "(*" comment
delimiter), paste it into your script editor, compile and save.
It works best as a compiled script for OSA Menu -- put it in the OSA Menu
Scripts folders for your script editor(s) and your e-mail client(s), or in
those applications' Scripts folders, if they have one. It can also work as
an AppleScript applet. The one script takes care of both encoding and
decoding.
This script does not approach the problem of mangled AppleScript characters
in e-mail messages the same way as Richard23's Convert Script does. Details
appear in the opening comment to the script.
Wolf will put this script on his web site Monday, where you can check for
any future upgrades: <
http://redshed.net/applescriptEndec>.
Here's the script:
--BEGIN SCRIPT
(*
NAME
AppleScript Endec (Encoder/Decoder) 1.0.2
WEB PAGE
<
http://redshed.net/applescriptEndec>
PURPOSE
This script quickly encodes and decodes AppleScript scripts
for transport through Internet email systems.
USE
Copy an existing script onto the clipboard and run this script
and click the "Encode" button. The newly encoded script will replace
the original script on the clipboard. Now you can paste the encoded
script into an email message.
To decode an encoded script from an email, copy the encoded script
from the email, onto the clipboard. Run this script, and click the
"Decode" button. The newly decoded script will replace the encoded
script on the clipboard.
Before munging your data, this script makes sure the clipboard holds
textual information.
The script also tries to figure out whether you're likely to encode
or decode the script by looking for the encoder ID. If it's there,
chances are you want to decode the script, and the "Decode" button
is set as the default button. Otherwise the default button is set to
"Encode". This heuristic has multiple failure possibilities, but the
worst case scenario is that this script circles the wrong button for
you -- no biggie.
REQUIREMENTS
This script was written and tested on Mac OS 9. This
script uses Finder 9 to access and modify the clipboard. Older
Finders didn't offer this feature, but I'm not sure in what version
Apple added it. If you're stuck on an old system, you can modify
this script to use a Scripting Addition to muck with the clipboard.
This script doesn't use any nonstandard Scripting Additions.
HISTORY
Sat, Feb 17, 2001 -> Version 1.0
o Created by Jonathan 'Wolf' Rentzsch, jon at redshed dot net.
Sat, Feb 17, 2001 -> Version 1.0.1WJC
o Enhanced by Bill Cheeseman, cheeseb at banet dot net.
o Added property kEncoderID, routines to mark an encoded script with
name and version, to warn if mark is not present when decoding,
and to remove mark when decoding.
o Added test for kEncoderID instead of kEscapeChar for defaultButton.
o Added ASCII characters 173, 178, 179, 199 and 200.
Sat, Feb 17, 2001 -> Version 1.0.2
o Enhanced by Jonathan 'Wolf' Rentzsch.
o Integrated Bill's modifications.
o Took a comment from Bill and ran with it: I now translate the
single greater-than-or-equal-to 8-bit character to the email-happy
AppleScript equivalent ">=". Same deal with "<=".
o Enhanced Bill's checkEncoder function to look for and remove the
encoder mark, no matter where it appears in the clipboard.
o Wrapped decoding logic in try/error block with a reasonable error
message if decoding fails (probably the user was trying to decode
something that wasn't an encoded script).
ENCODING
The encoding system is simple, any character in the
"kEscapeList" string will be encoded. I could only think of the line
continuation character (ASCII 194) that needs encoding, however Bill
Cheeseman added a few more.
Each encoded character is converted into two email-safe hexadecimal
characters. Those two characters are placed after an "escape
character", currently defined as "`". I chose this character after I
couldn't think of any use for it in AppleScript other than being
used in string literals. Time will probably show me wrong, so it's
easy to set to another character -- just set the "kEscapeChar"
property to your character of choice.
For lines beginning with tabs, this script also replaces each tab
with two spaces (up to eight tabs deep). Hopefully this will make
scripts easier to read and transport. Script Editor doesn't seem to
mind: when confronted with such an indentation style, it simply
rewrites the script with its preferred tab-based indentation style.
SPEED
Most of the text munging is using the AppleScript's highly
efficient text item delimiter split/merge idiom. On my Pismo
PowerBook G3/400 I couldn't find any script that took longer than
one second to encode or decode.
DISTRIBUTION (BREAKING THE CHICKEN-AND-THE-EGG SYNDROME)
Obviously all this work would be for naught if folks didn't use it to
share scripts. I put this script in a public domain for all to use
and share.
Interesting note: I took pains to keep maximum length of each line
to 70 characters, and every character in this script is ASCII. That
means this script can be distributed in normal email without special
encoding.
Without this special formatting, I'd have to encode this script for
transport. Of course, then you'd need this script to decode it.
Frustrating, huh?
The formatting meant I had to introduce variables where there were
none before, so don't mock the "inefficiencies" of the code.
*)
property kEscapeChar : "`"
-- Characters to escape.
property A : ASCII character 173 -- unequal
property B : ASCII character 194 -- continuation character
property C : ASCII character 199 -- left chevron
property D : ASCII character 200 -- right chevron
property kEscapeList : kEscapeChar & A & B & C & D
property kHexList : "0123456789ABCDEF"
-- PLEASE CHANGE kEncoderID IF REVISED:
property kEncoderID : "-- Encoded with AppleScript Endec 1.0.2"
-- The UI for encoding/decoding the script on the clipboard.
tell application "Finder"
activate
set clipboardContents to the clipboard
if class of clipboardContents is string then
set prompt to "There's a script on the clipboard. Do you want to:
Encode the script for transport
or
Decode the script to use it?"
set bList to {"Cancel", "Decode", "Encode"}
if clipboardContents contains kEncoderID then
set defaultButton to "Decode"
else
set defaultButton to "Encode"
end if
display dialog prompt buttons bList default button defaultButton
tell me
if the button returned of the result is "Encode" then
set output to encodeScript from clipboardContents
else
set clipboardContents to checkEncoder(clipboardContents)
set output to decodeScript from clipboardContents
end if
end tell
set the clipboard to the output
end if
end tell
-- Escapes common AppleScript-isms for email transport.
to encodeScript from unencodedScript
set output to kEncoderID & return & unencodedScript
set ltoet to ASCII character 178
set output to replaceText from ltoet to "<=" for output
set gtoet to ASCII character 179
set output to replaceText from gtoet to ">=" for output
repeat with escapeChar in kEscapeList
set escapeChar to escapeChar as anything
set escapeCode to kEscapeChar & hex2(ASCII number escapeChar)
set output to replaceText from escapeChar to escapeCode for output
end repeat
-- Convert beginning-of-line tab runs into double spaces
repeat with tabDepth from 8 to 1 by -1
set textToFind to return
set rText to return
repeat tabDepth times
set textToFind to textToFind & tab
set rText to rText & " "
end repeat
set output to replaceText from textToFind to rText for output
end repeat
return output
end encodeScript
-- Decodes the hexadecimal encoded script.
to decodeScript from encodedScript
try
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to {kEscapeChar}
set encodedScriptList to every text item of encodedScript
repeat with i from (count of encodedScriptList) to 2 by -1
set encodedScriptPart to item i of encodedScriptList
set decodedNumber to unhex2(text 1 thru 2 of encodedScriptPart)
set decodedCharacter to ASCII character decodedNumber
set restOfPart to text 3 thru -1 of encodedScriptPart
set item i of encodedScriptList to decodedCharacter & restOfPart
end repeat
set AppleScript's text item delimiters to {""}
set unencodedScript to encodedScriptList as text
set AppleScript's text item delimiters to oldDelimiters
return unencodedScript
on error
error "Decoding failed.
Are you sure the clipboard contains an encoded script?"
end try
end decodeScript
-- Given an 8 bit number, returns its two-character hexadecimal
-- string equivalent.
on hex2(theNumber)
set output to ""
repeat 2 times
set characterIndex to (theNumber mod 16) + 1
set output to (character characterIndex of kHexList) & output
set theNumber to theNumber div 16
end repeat
return output
end hex2
-- Given a two-character hexadecimal string, returns its equivalent
-- number.
on unhex2(theString)
set firstCharacter to character 1 of theString
set firstNumber to (offset of firstCharacter in kHexList) - 1
set secondCharacter to character 2 of theString
set secondNumber to (offset of secondCharacter in kHexList) - 1
return (firstNumber * 16) + secondNumber
end unhex2
-- replaceText from "Y" to "A" for "xxYYzz"
-- --> "xxAAzz"
to replaceText from textToFind to replacementText for sourceText
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to {textToFind}
set sourceTextList to every text item of sourceText
set AppleScript's text item delimiters to {replacementText}
set theResult to sourceTextList as text
set AppleScript's text item delimiters to oldDelimiters
return theResult
end replaceText
-- Looks for (and removes) encoder ID (mark).
-- If one can't be found, warns the user.
to checkEncoder(clipboardContents)
set encoderLine to kEncoderID & return
if clipboardContents contains encoderLine then
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to {encoderLine}
set output to last text item of clipboardContents
set AppleScript's text item delimiters to oldDelimiters
return output
else
set prompt1 to "This script may have been encoded using another"
set prompt2 to " utility or another version of this utility."
set prompt3 to "Check the decoded output for correct syntax."
set prompt to prompt1 & prompt2 & return & return & prompt3
set bList to {"Cancel", "OK"}
set defaultButton to "OK"
beep
tell application "Finder"
display dialog prompt buttons bList default button defaultButton
end tell
return clipboardContents
end if
end checkEncoder
-- END SCRIPT
-
Bill Cheeseman, Quechee, Vermont <
mailto:email@hidden>
The AppleScript Sourcebook
<
http://www.AppleScriptSourcebook.com/>
Vermont Recipes-A Cocoa Cookbook
<
http://www.stepwise.com/Articles/VermontRecipes/>