そして道は続く...

Rinaldiコレクションには、大技は発揮しないが小粋な働きをするもの、スタック開発者の想像力を刺激するものなど、貴重なXCMDがまだまだたくさんある。最終回はそういった小道具たちを一挙掲載する。

再び、ファイルについて

ファイルを扱う主要なXCMDは第2回で取り上げたが、痒いところに手が届くファイルツールはほかにもある。ファイルの特殊な属性を調べたり設定したりできるので、管理者にとっては大変便利なツールだ。

SetFileFlagは、ファインダがファイル管理に使っているフラグ(目印)を調べたり設定したりする。ユーザーには直接関係ないものが多いが、invisibleフラグを使ってファイルをファインダ上で見えなくするのは、利用価値があるだろう。

SetFileFlag <file path/name>,<flag name>[,<flag state>] [,"DontResolveAlias"]

<flag name>

次のうちいずれか。()内はSystem7でのみ使える。

busy (hasCustomIcon), noCopy (isStationery), hasBundle, System (nameLocked), invisible (isInvisible)

<flag state>

TRUE/FALSEで指定する。省略値はTRUE

ShowHideFolderを使えば、フォルダごと隠すことも可能だ。

ShowHideFolder "HD:Secret:",TRUE

とすると、ハードディスク上の「Secret」というフォルダ全体を見えなくすることができる。2番目の引数をFALSEにしてやれば、もう一度見えるようになる。もっとも、これらの手段で隠したファイルやフォルダも、ハイパーカードのファイルダイアログでは見えてしまうから、完全なものではない。子供が余計なフォルダをいじらないようにする程度なら、これでも十分だろう。

見えていても構わないけれど捨てられては困るというようなファイルはロックしておくという手があった。

SetFinderLock "ImportantFile",TRUE

これが便利なのは、スクリプト中でロックを設定したり解除したりできるところだ。普段はファイルをロックしておき、必要なときだけリスト1のようなスクリプトでロックを外して書き込み、再度ロックする。こうすれば、重要なファイルが誤って消去されたり変更されたりする心配もない。

SetFInfoはファイルのタイプやクリエータを変更する。使い方は

SetFInfo <file name>[,<t=type>] [,<c=creator>] [,"DontResolveAlias"]

特に説明の必要はないだろう。リスト2は、指定されたフォルダ内のテキストファイルのクリエータを全部YooEditのものに変更するスクリプトだ。

CreateAliasはその名の通りエイリアスを作成してくれる。

CreateAlias <target path>[,<dest path>]

これも使い方は見ての通り。<dest path>を指定しておけば、いちいちエイリアスを移動したり名称変更したりする必要がない。省略すると、同じフォルダにAliasファイルが作成される。ユーティリティソフトを使ってもSetFInfoやCreateAliasと同様のことは可能だが、何度も繰り返すようにスクリプトの中からこういう属性を設定できることがありがたいのだ。

ファイルを選択する

ハイパーカードのanswer fileはシンプルな命令なので、複数のファイルを選択したり、画像のプレビューを表示したりすることはできない。こうしたときに便利なのがFullSFPackだ。

FullSFPack(<dialog style> [,<type 1[...,type 4]>] [,<default dir>] [,<new name>] [,<prompt>] [,"DontResolveAlias"])

<dialog style>
表示するダイアログを以下のうちから指定する。
G[et]
通常のファイル選択ダイアログ
P[ut]
ファイル名指定のダイアログ(ask fileと同じ)
V[olume]
ボリューム選択ダイアログ
F[older]
フォルダ選択
M[ultiple]
複数ファイルを選択。結果は複数行になる。
Q[uickTime]
PICTやQTのプレビューを表示
<type 1[...,type 4]>
ファイルタイプを指定する。省略すると全タイプ。
<default dir>
ダイアログを表示するときに最初に開くフォルダを指定できる。
<new name>
"P[ut]"オプションの時にデフォルトの名前を用意する。
<prompt>
ダイアログに表示するプロンプト文字列
"dontResolveAlias"
この文字列を渡すと、エイリアスを展開せずエイリアス自身のパスを返す。G[et] と M[ultiple]の時のみ有効。

複数ファイルを選択できるM[ultiple](画面1)は様々な場面で応用できるだろう。また、<default dir>を指定するオプションも、待ち望んでいた機能だ(*注1)。フォルダの選択は、最新のハイパーカードならanswer folderで可能だが、バージョン2.2以前ではXCMDを使うしかない。(*注2

ファイルについての情報

ファイルの情報を得る手段としては既にGetDirGetFInfoを紹介したが、ここでもう少しいろいろなツールをあげておく。

FileIsOpenはファイルが別のアプリケーションで開かれてないかどうかをチェックできる。

FileIsOpen <file path>

とすると、結果がTRUE/FALSEで返される。このXFCNで確認すれば、ネットワーク上で複数のユーザーが同じファイルを同時に編集するというような事故を防げるだろう。

FolderSizeを使うとフォルダ内のファイルの合計サイズを調べることができる。ファイルサーバー上に個人ファイルも集中管理している場合、ディスクの消費状況をチェックし、不要ファイルの削除を促すなどの応用が考えられる。

FolderSize(<folder path>[,<logical>] [,"ResolveAlias"])

<logical>
TRUEにすると、ファイルの論理サイズ(*注3)の合計、FALSEなら物理サイズの合計を調べる。省略した場合はTRUE。
"ResolveAlias"
この文字列を引数として与えると、ファイルやフォルダのエイリアスも展開して、オリジナルのファイルのサイズを合計に加える。省略したときはエイリアスは展開しない(エイリアスファイルのサイズを計算)。

システムフォルダの名前は「システム」「System」のように利用者が自由に変更できるから、機能拡張書類などのフォルダへのパスは人によって違うかも知れない。そういうときFindFolderを用いると、機能拡張、コントロールパネルなどの特別なフォルダの所在地を確認できる。これまでに取り上げたCopyFile、CopyResと組み合わせると、かなり強力なインストーラ・スタックが作成できるだろう。

FindFolder([<folder descriptor>[,<create it>]])

<folder descriptor>

フォルダのタイプを指定する文字。以下のものが設定できる(最初の1文字だけでよい)。

    A[pple menu]
    C[ontrol Panel]
    D[esktop]
    E[xtensions]
    F[onts]
    P[references]
    M[onitor printing]
    N[etwork trash]
    T[rash]
    I[tems startup]
    S[ystem]
    Y : TemporarY items

省略値はS(システムフォルダ)

<create it>

TUREを指定すると、該当するフォルダが見つからないときはそれを作成する。省略するとFALSE。

文字列を、もう少し

ハイパーカードにとっての基本データである文字列を処理するXCMDは第1回で検討したが、さらにいくつか役に立つツールを紹介する。

HowManyはある文字パターンがコンテナ中に何回出現するかを高速に数え上げるXFCNだ。これも使用法はシンプルである。

HowMany("sh","She sells sea shells by the sea shore")

とすると、この早口言葉には"sh"が3回登場するということが分かる。簡単なことのようだが、ハイパートークでスクリプトを書くとなるとリスト3のようになって意外に複雑な操作が必要だ。しかもスピードは50〜100倍と、その差は歴然としている。

FullOffsetは、ハイパーカードのoffset関数をより厳密に動作させるようにしたものだ。

FullOffset(<pattern>,<text>[,<offset>] [,<international>])

最初の2つは普通のoffsetと同じ。

<offset>
<text>内の検索を始める位置を指定できる。省略値は1、つまり最初から。
<international>
еとё(半角)のような、ヨーロッパ言語で用いるアクセント記号を無視して同じ文字とみなすかどうか。省略値はTRUE、つまり同じとみなす。FALSEにすると厳密に比較する。

なお、得られる結果は日本語の「文字数」ではなく、バイト数になっていることに注意。

offsetはハイパーカード(日本語版)の中でも問題の多い関数で、バージョンによって働きが少しづつ異なっている。例えばバージョン2.3では、

offset("純粋","アイテム")

を実行すると、結果がなんと3になってしまう。これは、最新のoffsetの場合、еとё(半角)を同じ文字とみなすというように、欧州言語で用いるアクセント記号を無視して検索を行うことが原因だと思われる。欧米ではこのほうが便利なのかもしれないが、これでは日本語の検索が台無しだ(*注4)。せめてアクセント記号を考慮するかしないかというオプションを用意して欲しかった。FullOffsetではこれをはっきり指定できるほか、検索開始位置を指示する機能も意外に便利。

StripDupは、リストの中から重複を省いて、各要素を1回だけ抽出したリストを作成してくれる。UNIXのuniq命令や、Excelの「フィルタオプションの設定」で「重複するレコードを無視」とした場合と同じだ。同様のことをハイパートークで処理すると、リスト4のように煩わしく時間もかかる。使い方は単純明快:

StripDup(<list>[,<case sens>] [,<separator>])

<separator>はコンマ、スペース、改行以外の文字をアイテム区切り文字とするオプション。StripDupを利用すれば、テキスト・データベースで誤ってレコード(行)を複製してしまい、同じ情報が何件もできてしまったというようなとき、重複を取り除いてきれいなデータを再生することができる。

もっと、Rinaldiを

誌面も残り少ない。最後はノンジャンルだ。

CreateCustomIconは、PICTやJPEGのファイル(*注5)に、その画像を縮小したアイコンを加えてくれる。

Notificationは、バックグラウンドで動いているハイパーカードから、メニューバー右上に小さなハイパーカードアイコンを点滅させて、フォアグラウンドに合図を送るXCMDだ。idleを利用して自動操作をさせているときなど、これを使って作業の終了を知らせることができる。

最後にCalendoid。これは名前の通り、コンパクトな1カ月カレンダーをフローティング・ウィンドウとして表示してくれる。残念ながらそのままでは画面4(左)のように曜日が文字化けしてしまう。これを修正するには、ResEditなどでリソースを開き、genevaに設定されているフォントをosakaなどに変更してやる必要がある(画面5)。興味がある方は、バックアップをとった上で自己責任で試してみてください。

*     *     *

6回でリナルディ氏のXCMDを解説するというのはかなり無謀な試みだったが、応用範囲の広い主要なものは紹介できたと思う。同氏のツールはまだたくさんあるが、他のものは用途がある程度特定されていて、使い方もシンプルなものが多い。折に触れてホームページなどでもフォローして行くつもりなので、積極的にコレクションを活用し、「使える」スタックを創作されることを期待する。

*注1

MS-DOSならdir命令一つで簡単にできることがマッキントッシュでは標準になっておらず、イライラした人も多いに違いない。これで今日からスマートに目的のフォルダを開くことが可能になる。

*注2

FullSFPackにはシステム7が、さらにQ[uickTime]オプションを使うためにはQuickTimeが必要。また、ダイアログ用のリソースは自動生成されるが、ロックされたボリューム上のスタックではこれができないため、あらかじめ用意されたDLOG、DITLなどのリソースも合わせてコピーしておく。詳しくはスタックの解説を参照。

*注3

ディスクは管理のためあらかじめ一定サイズのブロックに区切られており、ファイルはその単位ごとにディスクを消費する。だから、1文字しか記入していないファイルでも、最小のブロックの大きさ(ディスクによって異なるが、例えば250MBのディスクなら9KB)を占有する。この占有スペースを論理サイズ、ファイルに保存される本当の情報量を物理サイズという。

*注4

フォントにOsakaなどの日本語を指定したダミーのフィールドを作り、ファイルから読み込んだ文字列にこのフィールドの内容(空でかまわない)をつけ加えて、文字列が日本語であるということを明示してやると、offsetは正しく働くようになる。

*注5

JPEGのファイルフォーマットであるJFIFが使えると記述されているが、バージョン1.2で試したところではエラーになってしまった。

リスト

リスト1

-- ファイルFileNameのロックを外して更新する

on updateLockFile FileName, str
  SetFinderLock FileName, FALSE
  open file FileName
  write str to file FileName
  close file FileName
  SetFinderLock FileName, TRUE
end updateLockFile

リスト2

-- テキストファイルのクリエータをYooEditに一括変換

on mouseUp
  put SelectDir("フォルダを選んでください") into pName
  put GetDir(pName,"t=TEXT","o=p") into fileList
  repeat with i=1 to numebr of lines of fileList
    SetFileInfo line i of fileList, "c=YoED"
  end repeat
end mouseUp

リスト3

-- 変数tgの中にpatが何回出現するかを数え上げる

function countUp pat, tg
  put 0 into count
  put 1 into s
  put number of chars of pat into len
  put number of chars of tg into n
  repeat
    get offset(pat, char s to n of tg)
    if it is 0 then return count
    add 1 to count
    add it+len-2 to s
  end repeat
end countUp

リスト4

--リストstrから重複行を省いたリストを作成する

function uniq str
  sort str
  get ""
  repeat with i=1 to number of lines of str
    if it is line i of str then next repeat
    get line i of str
    put it & RETURN after res
  end repeat
  return res
end uniq

(MacUser Japan, December 1996)