Claus Gerhardt さんによる AppleScript 「pdflatexc」を使って、AppleScript から UNIX のシェルコマンドを呼び出す原理を例示してみましょう。このシェルスクリプト自体は大しておもしろくありません ; teTeX のバイナリの場所を $PATH 変数に加え、pdflatex を呼び出してタイプセットを行なっています。

シェルスクリプトそのものは、TeXShop には依存していませんし、pdflatexc を含むディレクトリがバイナリの検索パスにあれば「pdflatexc myfile.tex」と打ち込むことで Terminal からも実行できます。これがそのシェルスクリプトです:

#!/bin/tcsh
# pdflatexc
# Claus Gerhardt
#
# Usage
# pdflatexc filename.tex

set path= ($path /usr/local/teTeX/bin/powerpc-apple-darwin-current /usr/local/bin)

pdflatex --shell-escape "$1"

もちろん、いくつもの作業を次々とこなしてゆくような、より複雑なスクリプトを書くこともあるでしょう。そういうときにこそ、こうした技法が役に立つようになります。

このシェルスクリプトを呼び出すのに使う AppleScript はもうちょっとおもしろいものです。まずはご覧ください:

--Applescript
-- Apply only to an already saved file.
-- すでに保存済みのファイルにのみ適用すること。
-- Claus Gerhardt, Nov. 2003

set scriptPath to (do shell script "dirname " & "~/Library/TeXShop/Scripts/ex")
set scriptPath to scriptPath & "/setname.scpt"
set scriptName to POSIX file scriptPath as alias
set scriptLiB to (load script scriptName)
tell scriptLib
set frontName to setname(#NAMEPATH#,#TEXPATH#)
end tell

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

前置きのコメントはさておき、このスクリプトの冒頭7行は、Claus Gerhardt さんの魔法のレシピです──ソースファイルを保存し、処理しようとしている文書の名前を見つけて「frontName」にセットしています。このレシピでは、~/Library/TeXShop/Scripts にある「setpath.scpt」というコンパイル済みのスクリプトを使ってハードな作業すべてをこなしています。注意深く読み解いてみれば、この数行は ~/Library/TeXShop/Scripts/setname.scpt というパスを見つけ、パラメータ #NAMEPATH# と #TEXPATH# でスクリプトを呼び出していることがわかります。

多くの AppleScript では、これはすべて、次のようなコマンドを使う簡単な方法で済ませられます:

set frontName to #DOCUMENTNAME#
tell document frontName of application "TeXShop"
save
end tell

しかしながら Gerhardt さんのスクリプトには長所が2つあります。ひとつは、前面にある文書がログファイル(たとえば /Users/koch/Examples/myfile.log のようなもの)であっても──換言すれば、これ以降のコマンドを受け入れないような種類の文書だったとしても──スクリプトを呼び出せる、ということです。もうひとつは、ファイルが一度も保存されていなかった場合、Gerhardt のスクリプトは保存を行なおうとしてエラーを返します──その一方で「保存」コマンドにより、保存ダイアログを出して TeXShop は保留状態になります(詳しくはヘルプの「TeXShop のタイプセットコマンドでスクリプトを書く」を参照してください)。

つづく6行では、変数 dirName と baseName を定義しています。ソースファイルが「/Users/koch/This directory/Stuff/myfile.tex」の場合、dirName は、シングルクオートとダブルクオートを含めて「" '/Users/koch/This directory/Stuff' "」となり、baseName は「myfile.tex」となります。この作業部分が必要なのは、フォルダ名にスペースがあってもいいようにです。依然として TeX は、最終的なファイル名にあるスペースを容認しません。

そのまた次の3行がシェルスクリプトを呼び出しています。結果的には Terminal で「cd dirName; ~/Library/TeXShop/bin/pdflatexc baseName」と打ち込むのと同じとはいえ、はるかに正確です──というのも、dirName は引用ではない形(つまり、上の例で言えば、途中のディレクトリにスペースがあるのでシングルクオートを含めて「'/Users/koch/This directory/Stuff'」)に置き換えねばならないのです。

AppleScript におけるシェルスクリプトは次のような形で発令されます──

do shell script "cmd input"

複数のシェルスクリプトを結合させたいのであれば、対等につなぐ形式で書くのがいいでしょう──

do shell script "cmd " & "input"

cmd と引用符の間の半角スペースに注意してください。アンパサンド(&記号)はバイナリの連結演算子です。つまりこういうことです──

"cmd " & "input" = "cmd input"

シェルが AppleScript で呼び出される場合、デフォルトの作業ディレクトリはルートディレクトリです。

do shell script "cd " dirName

上のコマンドでは、ディレクトリを dirName で定められているディレクトリに変更しています ; dirName はすでに引用済みなので引用符を加える必要はありません。

作業ディレクトリを動かさずにさらにコマンドを入れたいのであれば、「do shell script」の形では記述できません──それだと新規シェルが呼び出されてしまいます。Terminal では連続するコマンドをセミコロンで区切りますが、AppleScript では「";"」を使います。つまりこういうふうに──

do shell script "cmd(1) " & "input(1)" & ";" & "cmd(2) " & "input(2)"

上記の例で言うならこれは、こういうことです: cmd(1) = cd ・ "input(1)" = dirName ・ cmd(2) = ~/Library/TeX/bin/pdflatexc(シェルスクリプトを呼び出しています) ・ "input(2)" = baseName。

set shellScript to "cd " & dirName & ";"
set shellScript to shellScript & "~/Library/TeX/bin/pdflatexc " & baseName

──という2行は単に、ひとつながりのコマンドを変数ごとに分かち書きしているだけのことです。

最後の3行でプレビューウインドウを更新しています。

たしかに複雑な行もいくつかありますが、そうしたものでも、そのままコピーして新しいスクリプトに使えます。

マクロ・ヘルプ
シェルコマンドでスクリプトを書く