トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

BugTrack-wiki/331

ページの作成や編集にはユーザ登録が必要です。

ブロックプラグインの複数行引数内のインラインプラグインをブロックプラグインと誤認する。

  • 投稿者: ぐうます
  • カテゴリ: 本体
  • 優先度: 重要
  • 状態: 完了
  • 日時: 2009年06月21日 01時00分11秒

 内容

次のような Wiki ソースを記述した場合、

{{pre
{{inline プラグインのつもり}}なのです。
}}
さてここは pre プラグインの中? 外?

次のような結果になります。

{{inline プラグインのつもり}}なのです。
}}
さてここは pre プラグインの中? 外?

注:ブロックプラグインが終了してくれないので、ここにブロックプラグインの終了書式を追加してあります。

この現象の直接原因は、Wiki::Parser::parse() 内の処理で、一度ブロックプラグインの中に入ると、インラインプラグイン書式をブロックプラグインと誤認することです。しかし、その根本原因としては、ブロックプラグインの複数行引数内についても、ネストしたブロックプラグインを解釈しようとしていることにあるように思います。

ブロックプラグインの複数行引数は必ずしも Wiki ソースとは限らないので、Wiki ソースとして解釈する必要は本来ないはずです。しかし、複数行引数が Wiki ソースである場合にはブロックプラグインがネストすると最も外側のブロックプラグインの終了書式('}}' のみの行)がどれか分からなくなるため、現バージョンでは複数行引数内についても Wiki ソースとして解釈しようとするのだと思います。

私見としましては、

  • ブロックプラグインの複数行引数は Wiki ソースとして解釈しない。
  • '}}' のみの行が出現した時点でブロックプラグイン終了。
  • '}}' のみの行を複数行引数に渡したいときには、'\}}'とする。

とするといいのではないかと思うのですが、現状との互換性的には問題あるかもしれません。

さて、仕様的にはどうなるべきなのでしょうか?

 コメント

  • 以下のような修正で上記現象は回避できるんじゃないかな? - KG (2009年06月25日 18時26分44秒)
--- Parser.pm.org       Sat Sep 22 16:51:01 2007
+++ Parser.pm   Thu Jun 25 18:24:50 2009
@@ -95,13 +95,15 @@
                                next;
                        }
                } elsif($line =~ /^{{(.+)$/){
+                       my $plugin = $self->{wiki}->parse_inline_plugin($1);
+                       my $info   = $self->{wiki}->get_plugin_info($plugin->{command});
                        if ($self->{block}) {
-                               $self->{block}->{level}++;
+                               if($info->{TYPE} eq "block"){
+                                       $self->{block}->{level}++;
+                               }
                                $self->{block}->{args}->[0] .= $line."\n";
                                next;
                        }
-                       my $plugin = $self->{wiki}->parse_inline_plugin($1);
-                       my $info   = $self->{wiki}->get_plugin_info($plugin->{command});
                        if($info->{TYPE} eq "block"){
                                unshift(@{$plugin->{args}}, "");
                                $self->{block} = $plugin;
  • 変更を示して下さり、ありがとうございます。しかし、「ネストした内側のブロックプラグインが、その FSWiki にインストールされていること」が前提になっていますよね? なので、例えばプラグイン投稿する際、投稿したブロックプラグインの使用例を {{pre}}で記述するときには、逆にブロックプラグインのつもりで書いたものがインラインプラグインとして認識されてブロックプラグイン終了記号が 1 つ余る形に認識されてしまいます。 - ぐうます (2009年06月25日 19時30分29秒)
  • 気づかれてしまいました。(^^) 仰るとおりです。只今、修正案を考えています。 - KG (2009年06月25日 19時34分11秒)
  • さて、今度はどうでしょうか? - KG (2009年06月25日 20時09分07秒)
--- Wiki.pm.org Sat Sep 22 16:51:01 2007
+++ Wiki.pm     Thu Jun 25 20:06:34 2009
@@ -788,7 +788,7 @@

        if($quote!=3){
                my $info = $self->get_plugin_info($cmd);
-               return undef if (defined($info->{TYPE}) && $info->{TYPE} ne 'block');
+               return undef if (!defined($info) || defined($info->{TYPE}) && $info->{TYPE} ne 'block');
        }

        if($tmp ne ""){

--- Parser.pm.org       Sat Sep 22 16:51:01 2007
+++ Parser.pm   Thu Jun 25 20:06:24 2009
@@ -95,13 +95,15 @@
                                next;
                        }
                } elsif($line =~ /^{{(.+)$/){
+                       my $plugin = $self->{wiki}->parse_inline_plugin($1);
+                       my $info   = defined($plugin) ? $self->{wiki}->get_plugin_info($plugin->{command}) : undef;
                        if ($self->{block}) {
-                               $self->{block}->{level}++;
+                               if($info->{TYPE} eq "block" || !defined($plugin)){
+                                       $self->{block}->{level}++;
+                               }
                                $self->{block}->{args}->[0] .= $line."\n";
                                next;
                        }
-                       my $plugin = $self->{wiki}->parse_inline_plugin($1);
-                       my $info   = $self->{wiki}->get_plugin_info($plugin->{command});
                        if($info->{TYPE} eq "block"){
                                unshift(@{$plugin->{args}}, "");
                                $self->{block} = $plugin;
  • あ〜、ちょっとだめかもですね。存在しないブロックプラグインに対して「〜プラグインは存在しません。」のメッセージが出ないですねぇ・・・(ーー;) - KG (2009年06月25日 20時15分13秒)
  • 存在しないブロックプラグインを指定された場合に、「〜プラグインは存在しません。」と出力するようにするのですが・・・、その際に、複数行パラメータ部は画面上には出さなくてもよい?それとも、整形済みテキストとして画面上に出力した方がよい? - KG (2009年06月29日 14時31分47秒)
  • 「〜プラグインは存在しません。」のエラーが出る現状を考えてみると、エラーとともに引数部が表示されたりしないので、そこから類推すると複数行パラメータ部がエラー時に画面上に表示されなくてもよいのではないかと私は思います。 - ぐうます (2009年06月29日 20時09分33秒)
  • とりあえず、上記仕様でのバグFIXをアップします。fswiki363_bugfix_20090630.patch(312) - KG (2009年06月30日 11時01分49秒)
  • 上記バグとは別に、ブロックプラグイン以外のプラグイン(パラグラフ、インライン)をブロックプラグイン記述で使用した場合に「〜プラグインは存在しません。」と出力されなかったバグも修正しました。 - KG (2009年06月30日 11時04分03秒)
  • パッチの作成、ありがとうございます。複数行パラメータ部を評価してしまうと、'{{' と '}}' の数がアンマッチになるような内容を{{pre}}に書けないと考えたのが最初に書いた私見の元にあったのですが、
    • '{{' や '}}' を記述する状況が Wiki 書式以外に考えにくいこと、
    • Wiki 書式なら、'{{' と '}}' の数はほとんどの場合マッチさせるであろうこと、
    • 数少ないであろうマッチさせたくないときには、行頭空白の整形済みテキストで対応できるであろうこと、
    • '\}}' 記法の導入で損なわれる互換性

等々を考慮すると、KG さんのパッチが正解であろうと考えが変わりました。後日、KG さんのパッチを元にして、BugTrack-wiki/330 の対策案を更新致します。 - ぐうます (2009年07月02日 07時04分51秒)

Parser.pm
sub parse {
・・・
 		} elsif($line =~ /^{{(.+)$/){
			if ($self->{block}) {
				my $plugin = $self->{wiki}->parse_inline_plugin($1);
				my $info   = $self->{wiki}->get_plugin_info($plugin->{command});
-				$self->{block}->{level}++ if($info->{TYPE} ne "inline");
+				$self->{block}->{level}++ if($info->{TYPE} eq "block");
				$self->{block}->{args}->[0] .= $line."\n";
				next;
			}
			my $plugin = $self->{wiki}->parse_inline_plugin($1);
			my $info   = $self->{wiki}->get_plugin_info($plugin->{command});
			if($info->{TYPE} eq "block"){
  • 上記修正をコミットしました。r177 - KG (2017年12月07日 23時53分48秒)
お名前: コメント:
fswiki363_bugfix_20090630.patch

最終更新時間:2017年12月07日 23時54分05秒