「さくらスクリプト」の多機能パーサ機能を持つ非ビジュアルコンポーネントです。単一行のさくらスクリプトを処理します。つまり典型的には\tから始まり\eで終わる、1行のスクリプトです。Entryなどが絡んだ複数行スクリプトには対応していませんが、補助としては使えます。
といった用途の両方に使えるよう設計されています。また、タグのパターンについては完全にカスタマイズが可能です。
TagPattern, MetaPatternプロパティに、さくらスクリプトの解析の基準となるパターンを指定します。添付されているテキストファイルをコピーすれば一応OKです。
InputStringプロパティに、スクリプトを指定すれば、スクリプトが解析され、Count,
MarkUpType, Strの各プロパティを通してアクセスできます。
例えば、「\t\s[0]いらっしゃい%ませ、%usernameさん、\s[5]\\300のお\買い上げになりますね\e」という文字列をInputStringに入れた場合には、Count=10となり、MarkUpType,
Strプロパティには以下のような値が入ります。
TSsParserでは、Indexで区別されるスクリプト素片、つまり下の表における各行を「マークアップ」と呼ぶことにします。(本来、タグやメタ文字以外の文字列までマークアップと呼ぶのは変ですが…)
| Index | Str[Index] | MarkUpType[Index] |
|---|---|---|
| 0 | \t | mtTag |
| 1 | \s[0] | mtTag |
| 2 | いらっしゃい%ませ、※ | mtStr |
| 3 | %username | mtMeta |
| 4 | さん、 | mtStr |
| 5 | \s[5] | mtTag |
| 6 | \\300のお※ | mtStr |
| 7 | \買 | mtTagErr |
| 8 | い上げになりますね | mtStr |
| 9 | \e | mtTag |
Str[2]については、EscapeInvalidMeta =
falseの場合の結果です。trueの場合は、「いらっしゃい\%ませ」となります。Str[6]については、LeaveEscape =
trueの場合の結果です。falseの場合は、「\300のお」となります。\\ や \%
の文字列を変換せずに残すかどうか設定します。falseにすることで、\\ や \% は1文字に変換されてmtStrマークアップに代入されます。MetaPatternによって、%文字以降がメタ文字列と判断できない場合、%文字を「\%」にエスケープするかどうか設定します。TSsParserをスクリプトの色分けなどに使用する場合は、文字列長が変わらないようにfalseにします。堅牢なスクリプト作成のための文法チェックのためにはtrueにします。Str[0]、最後のマークアップはStr[Count-1]です。LeaveExcape,
EscapeInavlidMetaの両プロパティの影響を受けます。type TSsMarkUpType = (mtTag, mtMeta, mtTagErr, mtStr);
マークアップの種類を返します。最初のマークアップはMarkUpType[0]、最後のマークアップはMarkUpType[Count-1]です。TSsParseEvent = procedure (Sender: TObject; const Script:
String;タグまたはメタ文字列のパターンマッチ試行の前に呼び出されます。このイベントを使用すると、
var Len: integer; var MarkType: TSsMarkUpType; var Extra: String) of object;
TagPattern,
MetaPatternの仕様では切り出せないマークアップが将来できた場合に、スクリプトからのタグやメタ文字列の切り出しを自由にコーディングできます。
Scriptは解析途中のスクリプトです。1文字目は必ず「\」または「%」となっています。Lenは呼び出し時には0が代入されています。
このイベントハンドラ内で、Scriptの先頭から始まる部分を解析します。マークアップを解釈できた場合はそのマークアップの長さ(バイト数)をLen(>2)に、タイプをMarkTypeに、必要ならExtraに文字列を入れて、イベントハンドラを終了してください。解釈できない場合はLen=0のまま終了すれば、そのまま通常のパターンマッチ試行に入ります。
要は、文字列先頭からここまでがタグ(メタ文字列)だよ、というのを見つけて返してくれ、ということです。
Len>1であっても、Scriptの1文字目が\なのにMarkUpTypeがmtTagでもmtTagErrでもない場合、あるいはScriptの1文字目が%なのにMarkUpTypeがmtMetaでない場合は例外が発生します。
Strの先頭部分、Patternで示されるパターンが存在すれば、マッチした部分のバイト数(文字数ではない)を返します。マッチングが失敗した場合は0を返します。
Match('ABC', 'AB') = 2
Match('ABC', 'A%.%.') = 3
Match('A20BC', 'A%D') = 3
Match('\s[20]', '\s%b') = 6
Match('\s2', '\s%b') = 0\s[3] や \_c[こんにちは] , \q1[#cancel][キャンセル]
といったマークアップから、スクウェアブラケットに囲まれたパラメータを取り出します。Tagは取り出したいタグ全体、Indexは何番目のパラメータを取り出すか、で、1から始まります。\\
や \] によるエスケープに対応し、これらのエスケープは自動的に元の形に戻されます。
GetParam('\s[3]', 1) = '3';
GetParam('\s[3]', 2) = '';
GetParam('\j[http://www.yahoo.co.jp/index[1\].html]', 1) = 'http://www.yahoo.co.jp/index[1].html'\ を \\ に、] を
\] に変換した文字列を返します。堅牢なスクリプト作成のためには是非利用するようにしてください。TagPattern, MetaPatternプロパティに、さくらスクリプトを解析するときのパターンを指定します。
アーカイブ同梱のテキストファイルからコピーすることもできますが、将来のタグ拡張等のためにこの仕様が存在します。このパターンリスト自身をテキストファイルなどから読み込むようにすることで、実行ファイルを更新せずにタグ解析部のみを更新することも可能です。
「タグが\で始まる」「メタ文字列が%で始まる」「\\や\%はエスケープ」などといった基本的な仕様が変更にならない限り、タグの通常の増減に関しては、Patternプロパティを変更することで、大抵対応できると思います。特殊な書き方の場合、イベントを利用する方法もあります。
TagPatternの各行が、1つのタグに応答するパターンです。例えば、「\e」という行をTagPatternプロパティに追加することで、「\e」というタグに反応できるようになり、「!_c」という行を追加すれば、「\_c」というタグはエラーである、と解析するようになります。
(このようにエラーになったタグを無視するのか、あるいはどう処理するのかどうかなどについては、解析者の実装にかかっています。TSsParserでは、そのタグをエラーとして属性づけるだけです。)
パターンは上から順番に試行され、マッチした時点で試行を中止します。
TagPatternの各行は、\記号または!記号で始めてください。\記号で始まるパターンは、マッチした場合それを正当なタグをして処理します。!記号で始まるパターンは、マッチした場合それをタグのエラーとして処理します。
例えば、「\w」タグの処理のためには、
\w%d
!w%.
という2行をTagPatternに加えるとよいでしょう。これで、\w9 等は正当なタグで、数字以外がwの後にきた場合は
\wあ といった全体をタグエラーとして処理する、という意味になります。
MetaPatternの各行が、1つのメタ文字列に応答するパターンです。例えば「selfname」という行をMetaPatternプロパティに追加することで、「%selfname」というメタ文字列に反応します。MetaPatternの場合は、%以降に続く文字列をそのまま記述するような格好で大丈夫です。(パターンも使えます)
マッチ試行はパターンリストの上から順番に行われるため、MetaPatternプロパティで、例えば selfname2
という行は selfname より上に配置される必要があります。
正規表現みたいなものですが、そこまで高機能ではありません。逆に正規表現では表現しづらい表記に対応してたりもしますが。
%d は任意の整数1文字にマッチします。\s%d というパターンは、\s0
や \s3 にマッチします。%D は任意の整数列に最長マッチします。\s[%D] というパターンは、\s[0]
や \s[10] にマッチします。%b は[]で囲まれた文字列にマッチします。\] や \\
によるエスケープに対応します。\j%b というパターンは、 \j[http://www.a.com/index[1\].html]
にマッチします。%. は任意の1文字(シングルバイト・マルチバイト問わず)にマッチします。%m は任意のシングルバイト文字にマッチします。%M は任意のマルチバイト文字にマッチします。%% は「%」記号そのものにマッチします。使用しないといけない機会はおそらく将来もありません。%% として解釈しますが、このような使い方はしないでください。マッチングは以下のように行われます。
「%」を見つけた場合はメタ文字列の可能性があるので、マッチングを開始します。%以下が有効なメタ文字列として解釈できない場合は、「%」は意味をなさない通常の%文字列として、\%にエスケープされて(EscapeInvalidMetaで制御可能)前のmtStrマークアップにくっつきます。
mtTagタイプとして、エラータグとなった場合はmtTagErrとして切り出します。TagPatternのどの行にもマッチしなかった場合は、\の次の1文字を含めて、エラータグとして切り出します。独自SSTPサーバ構築補助に利用する場合は、LeaveEscape := false; EscapeInvalidMeta := false;
とすると簡単です。
SsParser1.InputString := Edit1.Text;
for i := 0 to SsParser1.Count-1 do begin
case SsParser.MarkUpType[i] of
mtStr: Memo1.Lines.Add(SsParser.Str[i]);
mtTag: {タグ関連の処理}
mtTagErr: Memo1.Lines.Add(SsParser.Str[i]); //処理せずにそのまま表示
mtMeta: {メタ文字列変換語表示}
end;
end;
色分けが目的の場合、スクリプトが変わる心配のないよう、LeaveEscape := true; EscapeInvalidMeta :=
false; とします。
以下は、タグ部分に色を設定するHTMLマークアップです。
var Html: String;
//
SsParser1.InputString := Edit1.Text;
for i := 0 to SsParser1.Count-1 do begin
case SsParser.MarkUpType[i] of
mtStr: Html := Html + SsParser.Str[i];
mtTag: Html := Html + '<font
color="green">' + SsParser.Str[i] + '</font>';
mtTagErr: Html := Html + '<font color="red">' +
SsParser.Str[i] + '</font>';
mtMeta: Html := Html + '<font color="blue">' +
SsParser.Str[i] + '</font>';
end;
end;
Edit2.Text := Html;
以下は、OnSsParseイベントの使用例です。もっとも単純に、\uタグを判定します。TagPatternの1行目に \u
と書いた場合と同じ動作となります。
procedure TForm1.SsParser1SsParse(Sender: TObject; const Script:
String;
var Len: integer; var MarkType: TSsMarkUpType; var Extra: String)
begin
if Pos('\u', Script) = 1 then begin
Len := Length('\u');
MarkType := mtTag;
end;
end;
一番最後のサーフィスが何になるかを判定します。ただし本来は、\0, \1によるスコープ切り替え処理や、\_sによるシンクロナイズドセッションの処理が必要でしょう。
var Last: integer;
//
SsParser1.InputString := Edit1.Text;
for i := 0 to SsParser1.Count-1 do begin
if SsParser.Match(SsParser.Str[i], '\s%b') > 0 then begin
try
Last := StrToInt(SsParser.GetParam(SsParser.Str[i]));
except
on EConvertError do
;
end;
end;
end;
with SsParser1 do InputString := InputString;
とすることで、EscapeInvalidMeta等の解析オプションや、MetaPattern等の解析パターンが変化したときに再解析を行えます。変な書き方ですが。
InputStringに改行文字やその他の空白文字が含まれていた場合、通常の文字と同じように扱います。つまり、改行文字だからといって特に何らかの処理が行われたり、逆に処理の邪魔になったりすることはありません。改行を
\n に変更したい、などの場合はあらかじめ StringReplace などを利用して自分で変換してください。
TagPatternで行頭が ! で始まるパターンを指定することや、OnSsParseイベントでmtTagErrマークアップを返す事で、\で始まる任意の文字列をタグエラーと見なすことができます。また、TagPatternでマッチしなかった場合は、\記号の次の1文字までを含めてタグエラーとして2文字分切り出します。この利用方法ですが、
TagPatternを変更する事で、SSTP権限で動かないタグのチェックを行うことができます。Position、MarkUpAtを追加。