「さくらスクリプト」の多機能パーサ機能を持つ非ビジュアルコンポーネントです。単一行のさくらスクリプトを処理します。つまり典型的には\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 |
デフォルトはtrueです。mtStrで切り出された通常文字列に含まれる、\\
や \%
の文字列を変換せずに残すかどうか設定します。falseにすることで、\\
や \%
は1文字に変換されてmtStrエレメントに代入されます。
TSsParserをスクリプトの色分けや、危険タグチェックなどに使用する場合は、文字列長やスクリプトそのものが変わらないようにtrueにします。独自SSTPサーバ開発の場合などは、falseにすることで変換の手間を省けます。
変更した場合、その結果は次回の解析から反映されます。
デフォルトはfalseです。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でない場合は例外が発生します。
SSTP解析用のパターンマッチングを行います。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から始まります。\\
や \]
によるエスケープに対応し、これらのエスケープは自動的に元の形に戻されます。
Indexがゼロ以下の場合、パラメータが取り出せなかった場合などには、空文字列が返ります。
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'
\j[] の中に安全に代入できるように、\
を \\
に、]
を \]
に変換した文字列を返します。堅牢なスクリプト作成のためには是非利用するようにしてください。
TagPattern, MetaPatternプロパティに、さくらスクリプトを解析するときのパターンを指定します。
通常はアーカイブ同梱のテキストファイルからコピーすれば問題はありませんが、将来のタグ拡張等のためにこの仕様が存在します。このパターンリスト自身をテキストファイルなどから読み込むようにすることで、実行ファイルを更新せずにタグ解析部を更新することも可能です。
「タグが\で始まる」「メタ文字列が%で始まる」「\\や\%はエスケープ」などといった基本的な仕様が変更にならない限り、タグの通常の増減に関しては、Patternプロパティを変更することで、大抵対応できると思います。特殊な書き方の場合、イベントを利用する方法もあります。
TagPatternの各行が、1つのタグに応答するパターンです。例えば、「\e」という行をTagPatternプロパティに追加することで、「\e」というタグに反応できるようになり、「!_c」という行を追加すれば、「\_c」というタグはエラーである、と解析するようになります。
パターンは上から順番に試行され、マッチした時点で試行を中止します。
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
は任意のマルチバイト文字にマッチします。%%
は「%」記号そのものにマッチします。使用しないといけない機会はおそらく将来もありません。%%
として解釈しますが、このような使い方はしないでください。マッチングは以下のように行われます。
独自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 + '<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;
一番最後のサーフィスが何になるかを判定します。ただし本来は、\h, \uによる切り替えなどが必要でしょう。
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 begin end;
end;
end;
end;
with SsParser1 do InputString := InputString;
とすることで、EscapeInvalidMeta等の解析オプションや、MetaPattern等の解析パターンが変化したときに再解析を行えます。変な書き方ですが。
InputStringに改行文字やその他の空白文字が含まれていた場合、通常の文字と同じように扱います。つまり、改行文字だからといって特に何らかの処理が行われたり、逆に処理の邪魔になったりすることはありません。改行を
\n
に変更したい、などの場合はあらかじめ
StringReplace などを利用して自分で変換してください。
TagPatternで行頭が !
で始まるパターンを指定することや、OnSsParseイベントでmtTagErrエレメントを返す事で、\で始まる任意の文字列をタグエラーと見なすことができます。また、TagPatternでマッチしなかった場合は、\記号の次の1文字までを含めてタグエラーとして2文字分切り出します。この利用方法ですが、
「あれ以外の何か with 任意 phase 40」には、スクリプト解析に関して、以下に挙げる問題があります。原因は面倒なので挙げませんが。
\\30
といった文字列は本来
\\
をエスケープと解釈するべきですが、\3
が危険タグのため、\\30
が \0
に変換されて実行されてしまいます。を\-
など、円記号の前に特定の文字が来る場合、危険タグチェックをすり抜けます。\漢
や \w漢
といった記述で文字化けが生じます。\能-
や \w能-
といった記述で危険タグが実行される場合があります。能%selfname
といった記述で、%selfname
が正しく変換されません。\\%selfname
といった記述で、%selfname
が正しく変換されません。\j[http://www.珪.com/]
といった記述で、「珪」の2バイト目が
]
記号とコードが同じであるため解析エラーを起こす場合があります。\q
も同様です。\w\\-
といった記述で、危険タグがブロックされずに実行されてしまいます。(これは初期developer's
testにも残っていた問題)TSsParserとは関連しませんが、%songname %enamyname
等が危険タグを含む文字列に変換された場合にそのまま実行される、といった問題点もあります。最新版では以上の問題はすべて解決されています。
TSsParserは以上の問題点を含まないはずです(パターンの書き方によっては別ですが)ので、TSsParserの解析は、「何か phase inverse 22.00」以降互換、ということになります。Phase40.01以前対応を視野に入れたプログラム作成でセキュリティに考慮したい場合、上に挙げた問題点に対して自力で対応してください。
TSsParserは独自SSTPサーバ作成補助も視野にいれたコンポーネントですので、上記の問題に対して対応する予定はありません。