*AutoLink -ページ: BugTrack -投稿者: [[ぱんだ]] -優先順位: 低 -状態: 着手 -カテゴリー: 本体新機能 -投稿日: 2003-01-22 (水) 16:28:15 -バージョン: 1.3.3 **メッセージ [[極悪版 wiki>極悪:AutoLink]]などで実装されている、「既存ページ名の自動リンク」をPukiWikiに実装してみます。 最初の版は<pre>~</pre>の中も置換してしまうというダサい動作だったので、まじめに作ってみました。 -$nowikinameを1にすると、WikiNameの自動リンクを抑制します。 -$autolinkを1以上の数値にすると、$autolink文字以上の長さのBracketNameページ名と合致する文字列が自動的にリンクになります。 -$nowikiname=1かつ$autolink>0のときは、WikiNameのページもAutoLinkで処理します。 --つまり、ページが存在するWikiNameはリンクになり、そうでない場合はリンクになりません。 ***ダウンロード PukiWiki/1.3.3用です。 #ref(193_1.3.3.diff) ---- **コメント -[[極悪版 wiki>極悪:AutoLink]] のようなすでに存在するWikiNameへは自動でリンクしてくれると嬉しいですが・・・。Wikiらしくていいなぁと -- [[baniko]] SIZE(10){2003-01-22 (水) 09:46:36} --これってWikiNameじゃなくってBracketNameのことでしょうか。BracketNameへの自動リンクは副作用がかなりありそう… -- [[reimy]] SIZE(10){2003-01-22 (水) 09:50:09} -表現がまずかったですね。存在するページ名へのリンクです。 -- [[baniko]] SIZE(10){2003-01-22 (水) 09:53:57} --BracketNameによるページへの自動リンクは副作用があるので…。採用するとすればオプション扱いかな。 -- [[reimy]] SIZE(10){2003-01-22 (水) 10:06:22} --仕掛け自体は簡単なんですが。ページが増えると結構重い処理になります。 -- [[ぱんだ]] SIZE(10){2003-01-22 (水) 13:25:44} --ページを作成したときに、ページ名のindex-listをファイルに落とすようにして、そいつで処理するのでは軽減できないでしょうか? -- [[baniko]] SIZE(10){2003-01-22 (水) 13:28:36} ---- -よさげな感じですね。テストして負荷なども調べてみようと思います。あとは、4バイトが決めうちでいいのか・・・。 -- [[baniko]] SIZE(10){2003-01-23 (木) 12:23:27} -CafeWikiを遅ればせながらテストしております。にほんごWikiName自動リンク機能はすばらしかったです。やはり必須機能ですね。 -- [[tejicube]] SIZE(10){2003-01-23 (木) 12:24:59} --その機能まってました!どのへんに差し込めばいいでしょうか?html.phpの -- [[tejicube]] SIZE(10){2003-01-23 (木) 12:30:41} -レポートお待ちしてます :) -- [[ぱんだ]] SIZE(10){2003-01-23 (木) 12:59:34} --$pageからブラケットを取ったらうまく動きました! -- [[tejicube]] SIZE(10){2003-01-23 (木) 14:21:12} -193_1.3.3.diffを添付しました。 -- [[ぱんだ]] SIZE(10){2003-01-23 (木) 16:12:09} -if ($arr[19] != '') { は if ($arr[19] != '') がデフォルトですかね。Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}''が出ました。まだリンク具合は確認してませんが実験してみます。 -- [[たらこせる]] SIZE(10){2003-01-23 (木) 16:15:36} -ってもうdiffで修正済みですね。すんません。 -- [[たらこせる]] SIZE(10){2003-01-23 (木) 16:17:54} -''InterWikiテクニカル''がInterWikiとテクニカルに分かれてしまいますね。func.php/get_autolink_pattern()の array_unshift($arr,"(?:$WikiName)"); は array_push($arr,"(?:$WikiName)"); のほうがいいかもしれません。 -- [[ぱんだ]] SIZE(10){2003-01-23 (木) 16:24:30} -稼動してます。負荷かかってるかなあ。 -- [[たらこせる]] SIZE(10){2003-01-23 (木) 16:26:45} -やっぱり [[WikiName]] と WikiName のどっちを取るかという問題になる…。 -- [[ぱんだ]] SIZE(10){2003-01-23 (木) 16:35:37} --ちなみにAutoLinkでは[[WikiName]]が存在したとしても WikiNameを見に行きます。(仕様) -- [[ぱんだ]] SIZE(10){2003-01-23 (木) 16:37:23} -これ、やっぱり面白いですね...。次期検索結果画面をBracketName化した時点でinclude作成(ほげ?表示をしない)してくれたりしたらその後のファイル構築もかなり面白くなりそう。 -- [[たらこせる]] SIZE(10){2003-01-23 (木) 17:12:20} --よくわかりません。 検索結果画面をBracketName化とはいったい… -- [[ぱんだ]] SIZE(10){2003-01-26 (日) 21:43:44} --よく、ではなくぜんぜんわかんないですね...。興奮して書き込んでるようで何を思ったんだったか...。1.通常の編集時にBracketNameを作成、2.現在は[[ほげ]]と表示されるが勝手にページを作ってしまう3.勝手につくったページの内容はその単語のサイト内使用頻度の検索結果、といったことを考えていたように記憶していますが何が面白いのか''自分でわからなくなっています''。 -- [[たらこせる]] SIZE(10){2003-01-26 (日) 22:23:08} -193_1.3.3.diffを差し替えました。 array_unshiftを(array_shiftではなく)array_pushにしただけです。 -- [[ぱんだ]] SIZE(10){2003-01-23 (木) 17:42:59} -試してみました。大体導入前の 2~5 倍の負荷が掛かっている模様。現在はページ数が少ないから良いけれど、これからのことを考えると……もうちょっと高速化できるといいなぁ。 -- [[未亜]] SIZE(10){2003-02-16 (日) 19:49:58} -初めまして。(おそらく)多少効率のいいAutoLinkPatternを生成する関数(autolink2.php)を書いてみました。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 01:40:27} --PukiWiki1.3.3に最初からついてるページ+ランダムに生成した約2000ページでテストしてみたところぱんださんのより約0.5sec高速でした。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 01:43:23} --また、PukiWiki1.3.3に最初からついてるページのみでのテストでは有意な差は確認できませんでした。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 01:44:14} --ぱんださんのも私のもget_existpages関数にかなり時間を食われているようでしたのでページ一覧、あるいは生成したパターンをキャッシュすることで高速化を図ることができると思います。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 01:47:34} --テスト環境はPenIII450MHz,Mem640MB,OSwin2kです。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 01:49:57} --数字上は100ページくらいでも差(上記テスト環境において0.02sec程度でもちろん体感できません)がでるのですが、いかんせんテストデータのページ名が実際にはありえないようなもの(4~15文字のランダムな英数字の羅列)なので…。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 02:10:31} ---こりゃあ、うちのを1.4にして、実験するのがよさそうだな。1.3.xよりも重くなるのはちょっと…ですが(^^;; -- [[reimy]] SIZE(10){2003-02-22 (土) 08:06:13} --…すごいですね。この最適化は多分、似たような名前((BugTrack/...とか :) ))のページが多いほど効くと思います。 -- [[ぱんだ]] SIZE(10){2003-02-22 (土) 14:07:34} --1.4では、ページの更新時にキャッシュ(cache/autolink.dat)を作るようにしているので、多少パターン解析に時間を費やしても効果が期待できます。 -- [[ぱんだ]] SIZE(10){2003-02-22 (土) 14:09:32} ---1.4試してみました。最初からついてる20ページ+ランダム生成の1000ページでテストしてみましたが1.3.3に比べてかなり高速ですね。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 16:39:51} --見れば見るほど興味深いアルゴリズムです。1.4に取り込んでみました。変更点は以下 -- [[ぱんだ]] SIZE(10){2003-02-22 (土) 16:36:05} +++$resultの初期化 +++変数名をちょっと変更($tを$count, $nを$pos) +++substr(...)をmb_substr(...)に、strlen(...)をmb_strlen(...)に、$hoge{$n}をmb_substr($hoge,$n,1)にした。 ---$resultの初期化は添付用に整形したときにコピーし忘れてしまったようです。変数名は適当だったので(思いつかなったので…)変更助かります。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 16:44:02} ---マルチバイト処理は私もどうしようか迷ったのですが…やはり入れないとまずいでしょうか? -- [[hirofummy]] SIZE(10){2003-02-22 (土) 16:52:24} ---autolink.datが目視で確認できる、ということだけですかね。あまり深い意味はないです。 -- [[ぱんだ]] SIZE(10){2003-02-22 (土) 19:31:38} ---mb_substrを使う場合、strlenもmb_strlenに変えないと日本語を含むページ名の処理がおかしくなるかもしれません。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 17:27:29} ---修正漏れですね。直しました。 -- [[ぱんだ]] SIZE(10){2003-02-22 (土) 19:31:38} --今気がついたのですが、[[WikiName]]とWikiNameのようなページが存在した場合意図通りにパターンが生成されない可能性があります。sort($auto_pages,SORT_STRING);となっている部分を$auto_pages=array_values(array_unique($auto_pages));と書き換えれば正しい動作になるはずです。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 19:06:38} ---autolink2.phpを修正する場合は$auto_pagesを$listに読み替えて下さい。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 19:09:01} ---1.3.x系の宿命ですね。PukiWiki/1.4では問題ないです。([[PukiWiki/1.4/NoBracketName]]参照) -- [[ぱんだ]] SIZE(10){2003-02-22 (土) 19:31:38} ---1.3.xと1.4では大分違いがあるのですね。まだ詳しく見ていないのですがconvert_htmlなんかは1.4の方がおもしろそうな印象を受けました。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 20:57:28} ---あら、PukiWiki/1.4がうまくリンクできていないですね。PukiWikiがWikiNameだからでしょうか。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 20:59:28} ---と思いきや今度は「WikiName」がリンクされてないですね…なぜだ…。 -- [[hirofummy]] SIZE(10){2003-02-22 (土) 21:20:11} ---おや、WikiName直ってますね。なんだったんだろう…。 -- [[hirofummy]] SIZE(10){2003-02-23 (日) 00:48:51} ---devサイトは直接潜り込んで修正しています。CVSより新しいこともしばしば :) -- [[ぱんだ]] SIZE(10){2003-02-23 (日) 01:00:41} ---WikiNameがリンクされていないのはpreg_replaceがマルチバイト文字の処理に失敗している可能性が濃厚です。([[開発日記/2003-02-22]]) -- [[ぱんだ]] SIZE(10){2003-02-23 (日) 00:53:34} ---PukiWiki/1.4がリンクされない件ですが、get_autolink_pattern_sub()内で - if ($count > 1) + if ($x or $count > 1) { $result = '(?:'.$result.')'; } としておくといいんじゃないかと。 -- [[ぱんだ]] SIZE(10){2003-02-23 (日) 00:53:34} ---自分の書いたコードなのにだんだん分からなくなってきました X( 一晩寝てちゃんと考えてみます。 -- [[hirofummy]] SIZE(10){2003-02-23 (日) 01:45:19} ---マルチバイト処理問題ですが、[[■:http://www.din.or.jp/~ohzaki/perl.htm#JP_Match]]にあるように、結構根が深そうです。例えばここの検索機能を使って「好」を検索すると見事にはまります。 -- [[hirofummy]] SIZE(10){2003-02-23 (日) 16:25:53} -このサイトのautolinkキャッシュはhttp://pukiwiki.sourceforge.jp/dev/cache/autolink.dat にあります。面白いですよ。 -- [[ぱんだ]] SIZE(10){2003-02-22 (土) 16:39:49} --括弧がいっぱいあって、まるでLisp系のプログラムを見ているような(笑い) -- [[reimy]] SIZE(10){2003-02-22 (土) 23:12:42} -う~ん、やっぱり副作用が大きすぎるような…。AutoLink=6でやってみたところ、&color(crimson){script};というページがあるとDe&color(crimson){script};ionというようになるし、&color(crimson){京都};、&color(crimson){大阪};というページがあると東&color(crimson){京都};千代田区、東&color(crimson){大阪};市になってしまう。--[[reimy]] SIZE(10){2003-02-26 (水) 22:18:18} --Descriptionは(?![[:alpha:]])の利用でなんとかなりそう((マルチバイト処理で引っかかるかもしれませんが…))ですが、「東&color(crimson){京都};」は難しそうですね。 -- [[hirofummy]] SIZE(10){2003-02-26 (水) 23:13:22} --対策案:ダミーのリストを用意し、それと実在ページのリストからオートリンクパターンを生成する。オートリンクの対象になった文字列のうち、ダミーはリンク処理をせずにスルーする。ダミーリストは適当なPukiWikiのページとする(保守が楽なように)。 -- [[hirofummy]] SIZE(10){2003-02-26 (水) 23:18:27} --reimyさんの例ならば、Description、東京都、東大阪という単語をダミーリストに追加することで余計なオートリンクを一応避けることができます。 -- [[hirofummy]] SIZE(10){2003-02-26 (水) 23:22:07} --というわけで試してみました。以下手順。 ---func.phpにあるget_autolink_pattern関数先頭のglobal~(402行目付近)を以下のように書き換える。 - global $WikiName,$autolink,$nowikiname; + global $WikiName,$autolink,$nowikiname,$ignorelistpage,$forceignorelistpage; ---$auto_pagesをソートしている部分(418行目付近)を以下のように書き換える。 - sort($auto_pages,SORT_STRING); + $auto_pages = array_merge( + $auto_pages, + get_ignorelist($ignorelistpage), + get_ignorelist($forceignorelistpage) + ); + $auto_pages = array_values(array_unique($auto_pages)); ---以下の関数を追加する。 function get_ignorelist($page) { $list = array(); $src = get_source($page); $n = sizeof($src); for($i=0;$i<$n;$i++) { if($src[$i]{0}!='-') continue; $pagename = trim(substr($src[$i],1)); if(!is_pagename($pagename)) continue; $list[] = $pagename; } return $list; } ---make_link.phpにあるLink_autoクラス(148行目付近)を以下のように書き換える。 class Link_auto extends Link { + var $ignorelist; + function Link_auto($start) { + global $forceignorelistpage; parent::Link($start); + $this->ignorelist = get_ignorelist($forceignorelistpage); } ---toStringメソッド(181行目付近)を以下のように書き換える。 function toString($page = '') { + if(!is_page($this->name)) return $this->name; + if(in_array($this->name,$this->ignorelist)) return $this->name; return make_pagelink( $this->name, $this->alias, '', ($page == '') ? $this->page : $page ); } ---pukiwiki.ini.phpの適当な位置に以下の行を追加する。 $ignorelistpage = "IgnoreList"; $forceignorelistpage = "ForceIgnoreList"; ---以上で完了。 ---無視リストのページでは「-」で始まる行が無視ページの指定として扱われます。InterWikiNameを記述するときのような感じです。ただしBracketでくくる必要はありません。 ---IgnoreList中で指定したページは、実在すれば無視されずオートリンクの対象になります。 ---ForceIgnoreList中で指定したページは、実在してもオートリンクの対象から外れます。 -上記コードを取り込みました。[[cvs:func.php]](v1.4:r1.26),[[cvs:make_link.php]](v1.4:r1.22),[[cvs:pukiwiki.ini.php]](v1.4:r1.28) -- [[ぱんだ]] SIZE(10){2003-03-06 (木) 15:03:55} -不用意にAutoLinkされたくない文字列のページは、階層化したページに入れることでうまく対処できそう。 -- [[reimy]] SIZE(10){2003-03-08 (土) 07:50:34} #comment