* InterWikiName の地味な拡張案とおまけ [#p483337c]

- ページ: [[BugTrack2]]
- 投稿者: 名無しさん
- 優先順位: 低
- 状態: 提案
- カテゴリー: 本体新機能
- 投稿日: 2007-10-18 (木) 22:15:58
- バージョン: 

** メッセージ [#rf035a2e]
処理方法は同じだが出力時に利用するエンコードだけを変えたい、&br;という場合の新しい設定文法と、その改造案の提案。

#contents

***これまでの経緯 [#y5534c65]
[[雑談]] より

- 置き換えている間に、いろんなページを見たので、ついでに提案。&br;CVSリポジトリのwiki ディレクトリへアクセスしやすくなる、新しいInterWikiName の文字コード変換タイプを追加できませんか?&br;[[cvs-wiki:PukiWiki/1.4/Manual/Plugin]] と書いて、[[ここ>cvs:wiki/50756B6957696B692F312E342F4D616E75616C2F506C7567696E.txt]] に飛ぶようなタイプを。 --  &new{2007-10-17 (水) 01:37:53};
-- 挿入位置指定は今でもあるから良いとして、%% str_replace('%', '', rawurlencode($param)) %%(([[rawurlencode()>PHP関数:rawurlencode]] はアルファベットの変換はしないんだった…、移転時にミスに気がついた)) encode($param) してくれるタイプがあれば、&br;表記が短くなる & 見やすくなるので、良いとは思うのですが、dev サイトでしか役に立たない気も…。 --  &new{2007-10-17 (水) 01:37:53};
-- もし、CVS 内のファイルをすべてUTF-8 にするという時がきた場合に、これ関連の書き換えが楽になるはず。&br;というのも提案理由ですが、そんな時が来ることはあるのかな…。 --  &new{2007-10-17 (水) 01:37:53};
- 我々にとっては便利ですね :) こうした加工の技は一種類である必要はなく、文字コードの概念と直交しているので、既存の文字コード指定と独立した設定文法を考えて下さい。これはデザインの問題なので、既存のユーザーが問題を起こさないものが望ましいです。 -- [[henoheno]] &new{2007-10-17 (水) 22:25:15};
-- ・・・そういえばYukiWikiのInterWikiでは、euc() といった記法で文字コードを指定していたなあ -- [[henoheno]] &new{2007-10-17 (水) 22:25:15};
 [[PukiWiki http://pukiwiki.sourceforge.jp/?euc($1)]]

***改造後のイメージ [#m061a0ec]
下の改造案を適用して、InterWikiName のページに次のように登録する。
 [http://test.com/$1.htm test-euc] encode:euc
 [http://test.com/$1.htm test-utf8] encode:utf8
-[[test-euc:雑談]] と書くと
--&color(#FB7E21){http://test.com/BBA8C3CC.htm}; になる

-[[test-utf8:雑談]] と書くと
--&color(#FB7E21){http://test.com/E99B91E8AB87.htm}; になる

PukiWiki で書いたものをHTML に変換して使っているサイトなら都合がいいかもしれない。(ページ名を別名に変えてなければ、ですけど)

***改造案 [#da09fdc7]
[[cvs:lib/make_link.php]] (1.37) をベースに
  // Render an InterWiki into a URL
  function get_interwiki_url($name, $param)
  {
   (中略)
  	default:
 -		// Alias conversion of $opt
 -		if (isset($encode_aliases[$opt])) $opt = & $encode_aliases[$opt];
 -
 -		// Encoding conversion into specified encode, and URLencode
 -		$param = rawurlencode(mb_convert_encoding($param, $opt, SOURCE_ENCODING));
 +		if (strpos($opt, ':') === FALSE) {
 +			// Alias conversion of $opt
 +			if (isset($encode_aliases[$opt])) $opt = & $encode_aliases[$opt];
 +
 +			// Encoding conversion into specified encode, and URLencode
 +			$param = rawurlencode(mb_convert_encoding($param, $opt, SOURCE_ENCODING));
 +		} else {
 +			$type = explode(':', $opt, 2);
 +
 +			switch($type[0]) {
 +
 +			case 'encode':
 +				// Alias conversion of $opt
 +				if (isset($encode_aliases[$type[1]])) $type[1] = & $encode_aliases[$type[1]];
 +
 +				$param = encode(mb_convert_encoding($param, $type[1], SOURCE_ENCODING));
 +				break;
 +
 +			default:
 +				$param = '';
 +			}
 +		}
  	}

***改造後について、補足など [#y1908d4a]
コードを見れば、わかる事が大半ですが…。

-その他(default:) の中に追加したので、これまでに書き足したタイプ(yw など)が優先される(書き直す必要は無い)
-その他で、コロン(:) が無い場合はこれまでの処理

-新しいタイプ名が「encode:エンコードタイプ」になっているのは、encode() を使っているからという安易な理由(もっといい名前をください…)

-これまでなら、処理は同じだが出力に使うエンコードは…という場合に、その数分タイプを用意する必要があったが、これなら共通化できる(と思う)。
--追加したswitch の中に新しいタイプを追加すれば、「タイプ名:エンコードタイプ」の形式を利用できる
--そこまで必要ない場合は、これまでどおりの場所に追加すればよい

--------
**コメント [#k1902e8c]

#comment


*おまけ (InterWikiName 関連の疑問など) [#d6c0457f]

**get_interwiki_url 関数の正規表現について(ついでで、Link_url_interwiki クラス) [#g3dfee41]
get_interwiki_url() の中では
 foreach (get_source($interwiki) as $line)
	if (preg_match('/\[(' . '(?:(?:https?|ftp|news):\/\/|\.\.?\/)' .
	    '[!~*\'();\/?:\@&=+\$,%#\w.-]*)\s([^\]]+)\]\s?([^\s]*)/',
	    $line, $matches))
		$interwikinames[$matches[2]] = array($matches[1], $matches[3]);
となっていて、キャプチャ2番目のエイリアスの部分は、] 以外なら何でも良いことになっている

しかし、bracket の中にInterWikiName を書いた場合の処理(Link_interwikiname クラスが担当)には、
-InterWikiName の中には、空白文字やコロンも含まれてはいけない
-エイリアスとの区切りを示す> や>[[はInterWikiName の最後には書いてはいけない

と書いているように見える

  	function get_pattern()
  	{
  		$s2 = $this->start + 2;
  		$s5 = $this->start + 5;
  		return <<<EOD
  \[\[                  # open bracket
  (?:
   ((?:(?!\]\]).)+)>    # (1) alias
  )?
  (\[\[)?               # (2) open bracket
  ((?:(?!\s|:|\]\]).)+) # (3) InterWiki
  (?<! > | >\[\[ )      # not '>' or '>[['
  :                     # separator
  (                     # (4) param
   (\[\[)?              # (5) open bracket
   (?:(?!>|\]\]).)+
   (?($s5)\]\])         # close bracket if (5)
  )
  (?($s2)\]\])          # close bracket if (2)
  \]\]                  # close bracket
  EOD;
  	}

Link_url_interwiki クラスはInterWikiName のページに書き込んだときに、正しい書式なら表示を変えるためにあると思うので、&br;もしget_interwiki_url() の正規表現を変えるのなら、追従した方が良いと思い、見出しに挙げました。(修正案は何も書いて無いですけど)

あと、コメントアウトした行を除外せずに、リストを収得しているのはどうなんでしょう?&br;非表示だけど実は有効のまま、というのを認めるかどうかなんですけど。

つまり、[[official:InterWikiName]] に書いてあるコメントアウトは、現状では意味が無いということに…。

***関連 [#r8203c2b]
- [[official:続・質問箱/326]]

--------
***コメント [#xdf7659c]

#comment


**mb_convert_encoding 関数に無効なエンコードタイプが使われた場合について(エラーネタ) [#o742773f]
現状でも、エンコードタイプの入力をミスするとPHPがエラーを返してきます。

エラーを表示させなくするだけなら
 -	$param = rawurlencode(mb_convert_encoding($param, $opt, SOURCE_ENCODING));
 +	$param = rawurlencode(@mb_convert_encoding($param, $opt, SOURCE_ENCODING));
で十分だが、なぜか空文字が返されている。

自分のところではなぜかうまく動作したフォロー方法
	$str = @mb_convert_encoding($param, $opt, SOURCE_ENCODING);
	if ($str !== FALSE) {
		$param = rawurlencode($str);
	} else {
		$param = rawurlencode($param);
	}
しかし、[[rawurlencode() の説明>PHP関数:rawurlencode]]にはエラー時に関する記述が無いので、確実性に欠ける。((全てのバージョンで、同じエラーを返すのかなど。型一致で比較しているので、FALSE を返しているのは確かでしょうけど…))

エラーを表示しない、で十分だと思いますので、後半部分は気にしないでください。

--------
***コメント [#ab9e5534]

#comment

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Site admin: PukiWiki Development Team

PukiWiki 1.5.3+ © 2001-2020 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u12. HTML convert time: 0.107 sec.

OSDN