AppleScript makes line endings a complicated issue. Script Debugger does a lot to make them simple, or at least transparent. But sooner or later you may run into problems with line endings, so here’s an explanation.
Imagine that two mighty forces are at work, tussling with line endings:
The AppleScript compiler. AppleScript is a compiled language, and this compilation involves a transformation performed directly on your code. Your code starts life as ordinary text, but when it is compiled, your file becomes a compiled script file, and you are shown the decompiled bytecode. The AppleScript compiler goes back to the early 1990s, a time when Macintosh line endings were all CR (ASCII 13). So, after compilation, every complete line of code in your compiled script file ends with a CR.
Unix. Mac OS X is Unix, and the standard Unix line-end character is LF (ASCII 10). For example, a script written in a Unix scripting language such as Perl or Ruby needs to have LF line endings or it may not run properly. Many Mac OS X text applications conform to this standard as well. For example, when you create a new multi-line file in TextEdit and save it as plain text, the line endings are LF. This issue is particularly acute in AppleScript when you use do shell script
, because a multi-line string intended for the Unix shell will usually expect LF as a line-end character.
So, the AppleScript compiler wants your line endings to be CR, but Mac OS X wants your line endings to be LF. The conflict between these forces is always going on. Sometimes this conflict works behind the scenes — for example, the AppleScript compiler will change your line endings to CR, no matter what they were before, and that’s that. But the conflict also arises up front, every time you press the Return key while you’re typing in a script file. At that moment, some character needs to be entered, so what should it be?
Script Debugger helps you deal with this conflict, in two main ways:
Visibility. Script Debugger makes it possible for you to see your line endings — you can show invisibles.
Freedom of Choice. Script Debugger lets you choose what character the Return key enters; it’s an Editor preference (New Line Character). The factory default for this preference is LF, and if you create a new multi-line script with the preference set this way, and invisibles showing, you can actually watch AppleScript change the line endings from LF to CR when you compile.
Script Debugger also lets you choose what line endings should be used when you save a script as text. This, however, introduces a further complicating factor.
The problem stems from the fact that in AppleScript, a literal string can span multiple lines:
set s to "
"
The integrity of the line-end character within this string (which might be LF or CR) is preserved through decompilation, because behind the scenes the compiled script is just bytecode (and the byte in question is part of a literal string). But now suppose you elect to save this script as text. What should Script Debugger do? The character after the first "
is a line ending. If you tell Script Debugger to save with CR line endings or LF line endings, this character will become CR or LF, respectively, regardless of what it is “really” supposed to be (thus possibly altering the functionality of your script).
This is why Script Debugger provides the As Is option (the default), which leaves all line endings in the resulting text file the same as in your compiled script. The totally safe solution, though, is not to use any literal line endings within quoted strings. Don’t use the “escaped” literals "\r"
or "\n"
, because the AppleScript decompiler turns these into actual line endings. Instead, construct your strings in code, generating line endings at runtime (using, for example, the return
or linefeed
global variable). Of course, if you never save as text, then the issue doesn’t arise in the first place.
Finally, be aware that pasting (or dragging) from a text file into a script can raise line-end character issues. What is pasted is text, which can have any kind of line ending. Script Debugger does not magically convert these as the paste is performed. If there are multi-line string literals in what is pasted, or if the target script is text, incorrect line endings may now be present in the script. Again, show invisibles will be a great help here.