We will use the AppleScript "pdflatexc" by Claus Gerhardt to illustrate the principles involved in calling a Unix shell script from an Applescript. This particular shell script isn't very interesting; it adds the location of the teTeX binary files to the $PATH variable and calls pdflatex to typeset.
The shell script itself is independent of TeXShop and can be run from the Terminal by typing "pdflatexc myfile.tex" provided the directory holding pdflatexc is in the search path for binaries. Here is that shell script:
set path= ($path /Library/TeX/texbin /usr/texbin /usr/local/bin)
pdflatex --shell-escape "$1"
The AppleScript used to call this shell script is more interesting. Here it is:
set fileName to #TEXPATH#
set n to (number of characters of contents of fileName)
set fileNamequoted to quoted form of fileName
set baseName to do shell script "basename " & fileNamequoted
set m to (number of characters of contents of baseName)
set dirName to quoted form of (characters 1 thru (n - m - 1) of fileName as string)
set shellScript to "cd " & dirName & ";"
set shellScript to shellScript & "~/Library/TeXShop/bin/pdflatexc " & baseName
do shell script shellScript
tell document frontName
refreshpdf
end tell
Ignoring the introductory comments, the first seven lines of this script are a magic recipe by Claus Gerhardt to save the source file and find the name of the document in question, setting "frontName" to this name. This recipe uses a compiled script named "setpath.scpt" in ~/Library/TeXShop/Scripts to do all the hard work. Careful reading shows that these lines find the path ~/Library/TeXShop/Scripts/setname.scpt and call this script with parameters #NAMEPATH# and #TEXPATH#.
In many AppleScripts all of this could be accomplished in an easier way using the commands:
However, Gerhardt's script has two advantages. First, his script can be called when the front document is a log file, say /Users/koch/Examples/myfile.log, that is, in a case when the front document is not the document which should receive later commands. Second, if the file has never been saved, Gerhardt's script returns an error when trying to save, while the "save" command would cause TeXShop to hang after it put up a save dialog (see the help document Writing Scripts with TeXShop Typesetting Commands for details.)
The next six lines of the script define the variables dirName and baseName. If the source file is "/Users/koch/This directory/Stuff/myfile.tex", dirName is " '/Users/koch/This directory/Stuff' ", including the single and double quotation marks, and baseName is "myfile.tex." A lot of this work is required so spaces can occur in the names of folders. As always, tex does not allow spaces in the final file name.
The next three line call the shell script. The result is the same as typing "cd dirName; ~/Library/TeXShop/bin/pdflatexc baseName" in a Terminal, although, to be absolutely precise, dirName would have to be replaced by its unquoted form, i.e., if we use the example above, by '/Users/koch/This directory/Stuff' including the single quotes because of the space in the name of one directory.
Shell commands in AppleScript are issued in the form
If one wants to combine several shell scripts, it is better to write the command in an equivalent formy
Notice the space behind cmd and the quotes. The ampersand is a binary concatenation operator, i.e.,
When the shell is called via an applescript, the default working directory is the root directory. The command
changes the directory to the directory specified in dirName; dirName is already quoted so that additional quotes are not needed.
If one would like to keep the working directory and issue further commands, then these commands may not be stated in the form "do shell script", since then a new shell would be invoked. In the terminal one would separate consecutive commands by semicolons, in AppleScript one does it by concatenating ";", i.e.,
This is done in the above example: cmd(1) = cd, "input(1)" = dirName, cmd(2) = ~/Library/TeX/bin/pdflatexc - calling the shell script -, and "input(2)" = baseName.
The lines
are simply a convenient way to concatenate this sequence of commands and input into one variable.
The final three lines update the Preview window.
To be sure, several of these lines are complicated, but these lines can be copied without change into new scripts.