ls2 プラグインで、常にget_source() を呼んでいる / include処理の改善

修正

PukiWiki 1.5.0 のタイミングで、以上の修正を含まないソースコードにロールバックしています。 1.5.1 にも入っていなかったので改めて修正を行いました。

メッセージ

ls2 プラグインには、ページの内容をスキャンする必要のある、title とinclude のオプションがあります。

しかし、これらのオプションを使わない時にもget_source() を呼んでいるため、無駄が多くなっています。
この無駄を省くことで、上のオプションを使わない時の速度をls プラグインと同等に なるようにしましょう。

cvs:plugin/ls2.inc.php (1.25) をベースに

 function plugin_ls2_get_headings($page, & $params, $level, $include = FALSE)
 {
 (中略)  
 	$ret .= '<a id="list_' . $params["page_$page"] . '" href="' . $href .
 		'" title="' . $title . '">' . $s_page . '</a>';
 	array_push($params['result'], $ret);
 
-	$anchor = PLUGIN_LS2_ANCHOR_ORIGIN;
-	$matches = array();
-	foreach (get_source($page) as $line) {
-		if ($params['title'] && preg_match('/^(\*{1,3})/', $line, $matches)) {
-			$id    = make_heading($line);
-			$level = strlen($matches[1]);
-			$id    = PLUGIN_LS2_ANCHOR_PREFIX . $anchor++;
-			plugin_ls2_list_push($params, $level + strlen($level));
-			array_push($params['result'],
-				'<li><a href="' . $href . $id . '">' . $line . '</a>');
-		} else if ($params['include'] &&
-			preg_match('/^#include\((.+)\)/', $line, $matches) &&
-			is_page($matches[1]))
-		{
-			plugin_ls2_get_headings($matches[1], $params, $level + 1, TRUE);
-		}
-	}
+	if ($params['title'] || $params['include']) {
+		$anchor = PLUGIN_LS2_ANCHOR_ORIGIN;
+		$matches = array();
+		foreach (get_source($page) as $line) {
+			if ($params['title'] && preg_match('/^(\*{1,3})/', $line, $matches)) {
+				make_heading($line);
+				$level = strlen($matches[1]);
+				$id    = PLUGIN_LS2_ANCHOR_PREFIX . $anchor++;
+				plugin_ls2_list_push($params, $level + 1);
+				array_push($params['result'],
+					'<li><a href="' . $href . $id . '">' . $line . '</a>');
+			} else if ($params['include'] &&
+				preg_match('/^#include\((.+)\)/', $line, $matches) &&
+				is_page($matches[1]))
+			{
+				plugin_ls2_get_headings($matches[1], $params, $level + 1, TRUE);
+			}
+		}
+	}
 }



特定の条件で無限ループする

同じページを複数回参照したときに抜け出す条件が、if ($params['title'] && $is_done) となっていて、titleを指定せずにincludeを指定した場合に、ソースを読みに行って無限ループする可能性があります。

そこで、すでにページを読み取ったかだけで判定するようにしてみました。あと、あらかじめ$params["page_$page"] を初期化しないようにして、isset だけで表示したかどうかを判定できるように手順を変えてみました。



get_source() がFALSE を返してきた時の対策

BugTrack/2449 に移動しました


ソース読み取り時のマルチライン対応(仮)

BugTrack/2450 に移動しました

include の相対パスページ指定及びオプション指定への対応

... また、include を見つけた場合に、notitleなどのパラメータが含まれている場合や、相対パスを考慮していないので、存在しないページと判定されスキップされる場合があります。



総合コメント



作業中のバグなど


*1 参照渡ししているから
*2 make_heading() の返り値を$id に入れて無いだけですけど
*3 複数回ls2 が呼ばれてもid が重ならないように、static $_ls2_anchor = 0; は外せませんが

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-10-30 (月) 00:38:00
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 8.2.12. HTML convert time: 0.516 sec.

SourceForge