テキストプロパティの通常の使用では、ほとんどの場合は複数または多くの連続する文字が同じ値のプロパティをもちます。文字を1つずつ調べるプログラムを記述するよりも、同じプロパティ値をもつテキスト塊(chunks of text)を処理するほうがより高速です。
以下はこれを行うことに使用できる関数です。これらはプロパティ値の比較にeq
を使用します。すべての関数においてobjectのデフォルトはカレントバッファーです。
より良いパフォーマンスのためには、特に単一のプロパティを検索する関数におけるlimit引数の使用が重要です。さもないと興味のあるプロパティが変化しない場合に、バッファー終端までのスキャンで長い時間を要するでしょう。
これらの関数はポイントを移動しません。そのかわりに位置(またはnil
)をリターンします。ポイントは常に文字と文字の間にあることを思い出してください。これらの関数によりリターンされる位置は、異なるプロパティをもつ2つの文字の間にあります。
この関数は文字列かバッファーobject内の位置posから、何らかのテキストプロパティの変化が見つかるまでテキストを前方にスキャンして、変化のあった位置をリターンする。言い換えるとposの直後の文字とプロパティが等しくない、posの先にある最初の文字の位置をリターンする。
limitが非nil
ならスキャンは位置limitで停止する。そのポイントより前にプロパティが変化しなければ、この関数はlimitをリターンする。
プロパティがobject終端まで変化せず、かつlimitがnil
なら値はnil
。値が非nil
なら、それはpos以上の位置。limitがposと等しいときのみ値はposになる。
以下はすべてのプロパティが定数であるようなテキスト塊によりバッファーをスキャンする方法の例:
(while (not (eobp))
(let ((plist (text-properties-at (point)))
(next-change
(or (next-property-change (point) (current-buffer))
(point-max))))
ポイントからnext-changeへテキストを処理...
(goto-char next-change)))
これはnext-property-change
と似ているが、posから前方ではなく後方にスキャンする点が異なる。値が非nil
なら、それはpos以下の位置。limitとposが等しい場合のみposをリターンする。
この関数はプロパティprop内の変化にたいしてテキストをスキャンして、変化があった位置をリターンする。このスキャンは文字列かバッファーobject内の位置posから前方に行われる。言い換えるとposの直後の文字とプロパティpropが等しくない、posの先にある最初の文字の位置をリターンする。
limitが非nil
ならスキャンは位置limitで終了する。そのポイントより前にプロパティの変化がなければ、next-single-property-change
はlimitをリターンする。
プロパティがobject終端まで変化せず、かつlimitがnil
なら値はnil
。値が非nil
なら、それはpos以上の位置。limitがposと等しいときのみ値はposになる。
これはnext-single-property-change
と似ているが、posから前方ではなく後方にスキャンする点が異なる。値が非nil
なら、それはpos以下の位置。limitとposが等しい場合のみposをリターンする。
next-property-change
と似ているが、これはテキストプロパティと同様にオーバーレイも考慮して、バッファー終端より前に変化が見つからなければ、nil
ではなくバッファー位置の最大をリターンする点が異なる(この点ではnext-property-change
よりも対応するオーバーレイ関数next-overlay-change
と似ている)。この関数はカレントバッファーだけを処理するのでobjectオペランドは存在しない。これはいずれかの種類のプロパティが変化した、次のアドレスをリターンする。
これはnext-char-property-change
と似ているが、posから前方ではなく後方へスキャンすること、および変化が見つからなければバッファー位置の最小をリターンする点が異なる。
next-single-property-change
と似ているが、これはテキストプロパティと同様にオーバーレイも考慮して、object終端より前に変化が見つからなければ、nil
ではなくobject内の有効な位置の最大をリターンする点が異なる。next-char-property-change
と異なり、この関数はobjectオペランドをもつ。objectが非バッファーならテキストプロパティだけが考慮される。
これはnext-single-char-property-change
と似ているが、posから前方ではなく後方へスキャンすること、および変化が見つからなければobject内の有効な位置の最小をリターンする点が異なる。
この関数はstartとendの間に少なくともプロパティpropに値valueをもつ文字が1つあれば非nil
をリターンする。より正確には、これはそのような最初の文字の位置、それ以外はnil
をリターンする。
5つ目のオプション引数objectはスキャンする文字列かバッファーを指定する。位置はobjectにたいして相対的。objectのデフォルトはカレントバッファー。
この関数はstartとendの間に少なくともプロパティpropに値valueをもたない文字が1つあれば非nil
をリターンする。より正確には、これはそのような最初の文字の位置、それ以外はnil
をリターンする。
5つ目のオプション引数objectはスキャンする文字列かバッファーを指定する。位置はobjectにたいして相対的。objectのデフォルトはカレントバッファー。
predicateにしたがい、値がvalue
(デフォルトはnil
)にマッチするようなプロパティpropをもつ次のテキストリージョンを検索する。
この関数はポイントを移動するという点においてsearch-forward
(文字列の検索を参照)や類似関数をモデルとするが、match-beginning
や類似関数とは異なりマッチを記述する構造もリターンする。
値がマッチするようなテキストプロパティが見つからなければ、この関数はnil
をリターンする。見つかった場合にはマッチしたテキストプロパティをもつリージョン終端にポイントを置いて、そのマッチに関する情報とともにprop-match
構造体をリターンする。
predicateはt
( equal
のシノニム)、nil
( “not
equal”を意味する)、または2つの引数(value、およびマッチ候補のバッファー位置のテキストプロパティpropの値)で呼び出される述語関数のいずれかを指定できる。その述語関数はマッチがあれば非nil
、なければnil
をリターンすること。
not-currentが非nil
の場合には、もしプロパティがマッチしたリージョン内に既にポイントがあればそのリージョンをスキップして、次のリージョンを探す。
prop-match
構造はprop-match-beginning
(マッチ先頭)、prop-match-end
(マッチ終端)、prop-match-value
(マッチ先頭のpropertyの値)というアクセサ関数をもつ。
以下の例では下記のような内容をもつバッファーを使用する:
This is a bold and here’s bolditalic and this is the end.
すなわち単語“bold”はbold
フェイス、単語“italic”はitalic
フェイスをもつものとする。
まず最初は:
(while (setq match (text-property-search-forward 'face 'bold t)) (push (buffer-substring (prop-match-beginning match) (prop-match-end match)) words))
これはbold
フェイスを使用するすべての単語を選択する。
(while (setq match (text-property-search-forward 'face nil t)) (push (buffer-substring (prop-match-beginning match) (prop-match-end match)) words))
これはフェイスプロパティをもたないすべての断片を選択する。結果としてリスト‘("This is a " "and here's " "and this is the end")’が得られるだろう(push
を使用しているので逆順になる; リスト変数の変更を参照)。
(while (setq match (text-property-search-forward 'face nil nil)) (push (buffer-substring (prop-match-beginning match) (prop-match-end match)) words))
これはface
に何らかがセットされているすべてのリージョンを選択するがプロパティが変化する箇所で分割するので結果は‘("bold"
"bold" "italic")’になるだろう。
これを使用するかもしれないより現実的な例してURLを表す特定のセクションがあり、それらがshr-url
でタグ付けされているバッファーがあると仮定してみる。
(while (setq match (text-property-search-forward 'shr-url nil nil)) (push (prop-match-value match) urls))
これはそれらすべてのURLのリストを与えるだろう。
これはtext-property-search-forward
と同様だが、後方に検索する。マッチが見つかったらポイントはマッチしたリージョンの終端ではなく先頭に配置される。