Previous: Format Conversion Round-Trip, Up: Format Conversion [Contents][Index]
前のサブセクション(Format Conversion Round-Tripを参照)で説明したラウンドトリップ指定とは対照的に、変数after-insert-file-functions
とwrite-region-annotate-functions
を使用して、読み取りと書き込みの変換を個別に制御できます。
変換は、ある表現を起点として、他の表現を生成します。これを行う変換が1つだけのときは、何を起点とするかに関して競合は存在しません。しかし、複数の変換呼び出しが存在する場合、同じデータを起点にする必要がある2つの変換の間に、競合が発生するかもしれません。
この状況を理解するには、write-region
中のテキストプロパティの変換コンテキストが最善です。たとえば、あるバッファーの位置42の文字が‘X’で、それのテキストプロパティがfoo
だとします。foo
にたいする変換が、たとえばそのバッファーに‘FOO:’を挿入することにより行われる場合、それは位置42の文字‘X’を‘F’に変更します。そして次の変換は、間違ったデータを起点に開始されるでしょう。
競合を避けるためには、協調的な変換がバッファーを変更せずに、position昇順でソートされた、(position
. string)
という形式の要素をもつリストを、注釈(annotations)に指定します。
2つ以上の変換が存在する場合、write-region
はそれらの注釈を、1つのソート済みリストに破壊的にマージします。後でそのバッファーのテキストを実際にファイルに書き込む際に、対応する位置にある指定された注釈を混合します。これはすべて、バッファーを変更せずに行われます。
これとは対照的に、読み取り時にはそのテキストの混合された注釈は、即座に処理されます。insert-file-contents
は、変更される何らかのテキストの先頭にポイントをセットしてから、そのテキストの長さで変換関数を呼び出します。これらの関数は常に、挿入されるテキストの先頭のポイントをリターンするべきです。最初の変換により注釈が削除されても、その後の変換が誤って処理することはないので、このアプローチは読み取りに際しては正しく機能します。すべての変換関数は、それが認識する注釈のスキャン、その注釈の削除、バッファーテキストの変更(たとえばテキストプロパティのセット等)、およびそれらの変更に由来する更新されたテキスト長のリターンを行うべきです。1つの関数によりリターンされた値は、次の関数への引数になります。
write-region
にたいして呼び出す、関数のリスト。リスト内の各関数は、書き込まれるリージョンの開始と終了の、2つの引数で呼び出される。これらの関数は、そのバッファーのコンテンツを変更するべきではない。かわりに注釈をリターンすること。
特別なケースとして、関数がカレントと異なるバッファーをリターンするかもしれない。Emacsはこれを、カレントバッファーが出力される変更されたテキストを含むものとして理解する。つまり、Emacsはwrite-region
呼び出しの引数startとendを、新たなバッファーのpoint-min
とpoint-max
に変更して与える。さらに、以前のすべての注釈はこの関数により処理されるので、Emacsはそれらの破棄も行う。
この変数の値が非nil
の場合、それは関数であること。この関数は、write-region
完了後に引数なしで呼び出される。
write-region-annotate-functions
内のある関数がカレントと異なるバッファーをリターンした場合、Emacsはwrite-region-post-annotation-function
を複数回呼び出す。Emacsは最後にカレントだったバッファーでそれを呼び出し、その前にカレントだったバッファーで再度これを呼び出す、...のようにして元のバッファーに戻る。
したがって、write-region-annotate-functions
内の関数は、バッファーを作成して、kill-buffer
のそのバッファーでのローカル値にこの変数を与え、変更されたテキストでそのバッファーをセットアップして、そのバッファーをカレントにすることができる。そのバッファーは、write-region
完了後にkillされるだろう。
このリスト内の各関数は、挿入されるテキストの先頭にポイントがある状態で、挿入される文字数を1つの引数として、insert-file-contents
により呼び出される。すべての関数はポイントを未変更のまま、その関数によって変更された、挿入後テキストの新たな文字数をリターンするべきである。
わたしたちは、ユーザーがファイル内にテキストプロパティを格納したりそれらを取得するために、そしてさまざまなデータフォーマットを体験することにより、適切なフォーマットを見つけるために、これらのフックを使用してLispプログラムを記述することを推奨します。最終的には、わたしたちがEmacs内にインストールできる、良質で汎用性のある拡張をユーザーが開発することを望みます。
わたしたちは、テキストプロパティの名前や値として、任意のLispオブジェクトの処理を試みることは推奨しません — なぜなら汎用的なプログラムはおそらく記述が困難で、かつ低速だからです。かわりに、十分な柔軟性をもち、エンコードが難しすぎない、想定されるデータ型のセットを選択してください。