*1.はじめに [#b128e2c5]
#author("2017-10-31T16:31:19+09:00","saisyu","saisyu")
記述が古く、かつ誤りや問題も多いので、削除しました。
掲示板やメールフォームなど、動的なWebサイトの構築には、Perlを使ったCGIが一番手軽だ。しかし、こと多言語処理となると、問題が多いとされてきた。
Perlで日本語を処理する場合、jcode.pl などの日本語コード対応のモジュールを用意するのが一般的だ。これでJISコードに定義される文字は使えるようになるが、しかし、例えば中国語との多言語混在処理になると、お手上げだ。
日本語のCGIでも、ブラウザがJIS外の文字を「&#xnnnn;」に自動変換する機能を使って、多言語を混在させることはできるのだが、InternetExplorerとNetscapeでは機種依存文字の扱いが異なる、IE5.0では、日本語フォントにUnicode対応フォントを指定しないと一部の文字が「・」化けするという問題がどうしても発生する。
しかし、文字コードにUTF-8を使うと、jcode.pl に頼ることなく、Perl5.xで、多言語処理をすることができる。UTF-8とは、Unicodeの文字を処理するための文字コード番号の付け方の一つだ。といわれてもよくわからない人が多いと思うが、要するに、インターネットでUnicodeの文字を使うときに使われる文字コードだということだ。衆知のように、Unicodeは世界のあらゆる文字コードを一つの文字コード体系にまとめたもので、これを使えば、欧州諸語はもとより、日本語と中国語、ハングルなども混在処理することができる。
以下、日本語・中国語混在掲示板を例に、多言語処理可能なCGIの作成方法について解説する。
*2.UTF-8でCGIを多言語化 [#u3268045]
**2.1 準備 [#a0d2087f]
多言語CGIを作るのは、実はとても簡単だ。作業に必要なのは、
-カスタマイズしてもよいフリーCGIや自作CGI
-Unicodeに対応したエディタ
近頃は、EmEditorをはじめとする多くのエディタがUTF-8に対応しているので、それら最新版のオンラインエディタをダウンロードして使おう。ただし、エディタで中国語・日本語を混在表示するためには、Unicodeに対応したフォントが必要になる。SimSun、MS Song、PMingLiUなどのフォントを使えば良い。ただし、一部の環境やエディタでは、それらのフォントが上手く使えない場合もある。その場合は、Office2000/XP付属の「Arial Unicode MS」などのフォントを使おう。
**2.2 CGIの改造 [#b7886d07]
日本語CGIをUTF-8対応に改造するポイントは、以下の三点だ。
-CGIスクリプト、データファイルなどを全てUTF-8で保存する。
-HTMLファイル生成部分で、生成されるページのヘッダにUTF-8指定メタタグ<meta http-equiv="Content-Type" content="text/html; charset=utf-8">を設定する。
-jcode.plによる日本語処理部分を無効にする。
CGIを設置するサーバがPerl5.8に対応していたら、スクリプトの冒頭の行頭に「#」のついている行の後に「use encode;」と書き加える。そうすれば、完全にUnicodeに対応するが、BBS程度であれば、これを記述しなくてもおおむね問題なく動作する。Perlのバージョンがそれ以前であったら、この行は書き加えない。
現在、Perl5.5以前のバージョンがあいかわらず使われているサーバも多い。そのため、以下では、Perl5.5以前を念頭に解説する。
それでは実際に、CGIをUTF-8によって多言語化してみよう。ここでは、[[CGI-StaTion>http://www7.big.or.jp/~jawa/]]が配布している掲示板CGI、JawaNote(v1.41)を、EmEditorを使って改造する。
ダウンロードしたファイルを解凍すると、次の5つのファイルが得られる。
-jawaback.gif
-jawanote.cgi
-jawanote.log
-jcode.pl
-readme.htm
これらのうち、改造しなくてはならないのは、「jawanote.cgi」だけ、その他のファイルに手を加える必要はないし、jcode.plは必要ない。
***CGIをUTF-8で保存する [#b02b8421]
#ref(em.png,nolink);
まず、「jawanote.cgi」をEmEditorで開く。右クリックして「EmEditor」を選べばよい。文字化けしたら、「ファイル」→「読み直し」で文字コードを変更する。次に、「ファイル」→「名前をつけて保存」を選択し、文字コードを「UTF-8」、「Unicodeサイン(BOM)を付ける」をOFFに設定して、上書き保存する。
これで、CGIファイルがUTF-8で保存された。
***UTF-8設定タグを追加する [#s04b2a79]
次に、HTML生成部分に、UTF-8指定のメタタグを追加する。EmEditorで「<html>」を検索すると、123行目以下に、次のように記述されている。
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=$charset_code">
<TITLE>$note_title</TITLE>
124行目を書き換えて
<HTML><HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<TITLE>$note_title</TITLE>
のように改造する。
また、
if ($err) { print "Content-type: text/html\n\n<HTML><BODY>"; }
の<HTML>と<BODY>の間にメタタグを入れる。""の中なので、タグの中の「"」を「\"」にするのを忘れずに。
if ($err) {
print "Content-type: text/html\n\n<HTML><meta http-equiv=\"Content-Type\"
content=\"text/html; charset=utf-8\"><BODY>";
}
***jcodeの設定を無効にする [#m8a3b589]
次に、「jcode」を検索する。まず72行目
$jcode = './jcode.pl'; # jcode.pl のある場所
行頭に「#」を記入し、無効にする。つづけて、218行目
&jcode'convert(*comment,'euc');
と222行目、703行目の
&jcode'convert(*comment,$mojicode);
も無効にする。たいていのCGIは、以上の設定だけで大丈夫だが、サンプルのCGIはちょっと凝っていて、文字コード判別処理を600行目以下でしている。
# [ 文字コード関連 ]
#
sub check_code {
if (!(-r $jcode)) { &error(1,"jcode.pl がみつかりません。"); }
require $jcode;
local($text) = ord(substr("中澤重人=じゃわ(^-^;;",0,1));
if ($text == 0xc3) { $mojicode = "euc"; $charset_code = "x-euc-jp"; }
elsif ($text == 0x92) { $mojicode = "sjis";$charset_code = "x-sjis"; }
else { &error(1,"サポートしてない文字コードです"); }
}
sub change_code {
local($text)=$_[0];
&jcode'convert(*text,$mojicode);
if ($mojicode eq 'sjis') { &jcode'h2z_sjis(*text); }
if ($mojicode eq 'euc') { &jcode'h2z_euc(*text); }
$text =~ s/</</g;
$text =~ s/>/>/g;
return $text;
}
ここも、jcodeと文字コード関係の部分を全て無効にする。
# [ 文字コード関連 ]
#
sub check_code {
# if (!(-r $jcode)) { &error(1,"jcode.pl がみつかりません。"); }
# require $jcode;
local($text) = ord(substr("中澤重人=じゃわ(^-^;;",0,1));
# if ($text == 0xc3) { $mojicode = "euc"; $charset_code = "x-euc-jp"; }
# elsif ($text == 0x92) { $mojicode = "sjis";$charset_code = "x-sjis"; }
# else { &error(1,"サポートしてない文字コードです"); }
}
sub change_code {
local($text)=$_[0];
# &jcode'convert(*text,$mojicode);
# if ($mojicode eq 'sjis') { &jcode'h2z_sjis(*text); }
# if ($mojicode eq 'euc') { &jcode'h2z_euc(*text); }
$text =~ s/</</g;
$text =~ s/>/>/g;
return $text;
}
このような文字コードチェック部分を備えているCGIは、むしろ少数派だ。もしも、Perlの知識が無くてよくわからなければ、以上のような複雑な文字コード処理部分の無いフリーCGIを選ぼう。
掲示板のフォームが日本語と中国語で表示されるようにするには、CGIファイルのフォームの説明部分を書き換える。フォームの表示部分は、270行目以下なので、そこを例えば下のように加筆修正すればよい。
<B>タイトル(标题)</B>
</TT></TD><TD>
<INPUT TYPE=text NAME=title SIZE=42 MAXLENGTH=80 VALUE="$title_area">
</TD></TR><TR><TD><TT>
<B>ハンドル(笔名)</B>
</TT></TD><TD>
<INPUT TYPE=text NAME=name SIZE=42 MAXLENGTH=42 VALUE="$COOKIE{'name'}">
</TD></TR><TR><TD><TT>
<B>URL(家页)</B>
</TT></TD><TD>
***フォント指定の変更 [#m3c71a8c]
改造に使っているcgiでは、表示フォントを設定している部分がある。132行目
<BASEFONT SIZE=3 FACE="MS ゴシック"><TT>
一般のHTML解説書では言及されていないが、日本語のフォント名を直接指定した場合、海外版OSからアクセスした際に
問題が生ずる。考えてみれば、英語版のOSで日本語のフォント名を解釈できないのは当然であろう。
この問題は、フォント名指定に日本語フォント名ではなく、日本語フォントの対応する英語名称(Post Script Name)
を使うことで解決できる。例えば「MS ゴシック」は「MS Gothic」、「MS 明朝」は「MS Mincho」と記述する。
<BASEFONT SIZE=3 FACE="MS Gothic"><TT>
よりアクセシビリティーを高めるためには、スタイルシートでフォント名とともにフォントファミリーも設定する、さらにはフォントを一切指定せず、
<BASEFONT SIZE=3><TT>
とするのが望ましい。
***完了 [#hb3922c3]
これで、CGIの改造は完了した。あとは、日本語CGIを設置するのと同じように各種設定をおこない、アップロード、パーミッションを変更すればよい。
改造したCGI:
#ref(jawanote.lzh);
>CGIファイルのみです。[[CGI-StaTion>http://www7.big.or.jp/~jawa/]]さんからログファイルなどのセットをダウンロードして、CGIファイルを上書きして設置してください。設置方法も[[CGI-StaTion>http://www7.big.or.jp/~jawa/]]さん参照。なお、このCGIを利用することによって生じたあらゆる損害に対して、千田大介は責任をとりません。自己責任において、ご利用ください。転載等については、[[CGI-StaTion>http://www7.big.or.jp/~jawa/]]さんの規定に準じます。
>>改造版CGIに、言語タグ置換機能を追加しました。書式は以下の通り。
&lang(言語コード){文字列}
ex.
&lang(zh-cn){简体字}
&lang(zh-tw){繁體字}
>>文字列の中に改行が入っても大丈夫です。言語コードの一覧は、http://alis.isoc.org/langues/iso639.ja.htmあたりを参照して下さい。中国語は、大陸(簡体字):zh-cn、台湾(繁体字):zh-twです。BBS自体のページ言語が日本語に指定してあるため、日本語文字列については言語設定の必要はありません。
[[設置サンプル>http://www.wagang.jp/bbss/utf8-bbs/jawanote.cgi]]:ご自由におためしください。
他のCGIでも改造のポイントは同様だが、メール送信機能を持ったCGIの場合は、メールヘッダ部分の文字コード指定を「Content-Type: text/plain; charset="UTF-8"」に変更しなくてはならない。
おまけ:
[[YY-BOARD>http://www.kent-web.com/bbs/yybbs.html]]v.5.33をUTF-8したCGI。以下のCGIを、[[KTNT-WEB>http://www.kent-web.com/]]さんから落としたオリジナルファイルと入れ替ればOKのハズ。動作保証・質問などは一切受け付けません。自己責任でお使い下さい。
>こちらも、言語タグ置換機能を追加しました。指定方法は上のJawa Noteと同じです。
#ref(yy.lzh);
[[設置サンプル>http://wagang.econ.hc.keio.ac.jp/yybbs/yybbs.cgi]]:ご自由におためしください。
>アイコンは、使用登録するのが面倒なので、置いていません(笑)。
*3.問題点 [#v8ce7042]
Perlは5.6で正式にUTF-8に対応し、5.8でマルチコード対応がほぼ完成した。
これは、文字列を文字単位で扱えるようにした、ということであり、
バイト単位で扱う場合にはPerl5.xでも問題が生じないようだ。
もちろん、文字の字数をカウントするようなUTF-8 CGIは、Perl5.6、
できれば5.8以上でなくては作れないが、掲示板程度であれば問題なく動作する。
しかし、UTF-8のCGIであるということで、幾つかの制限事項がある。
**3.1ブラウザの対応 [#he52daed]
Internet Explorerの場合は、バージョン4以降であれば、問題なくUTF-8のCGI
を使ったページを閲覧・投稿ができるが、Netscapeの場合はバージョ
ン6以降を使わなくてはならない。バージョン4.xもUTF-8には対応しているが、
しかし、Unicode内部処理化されていないため、書き込みができない。
**3.2表示フォントの問題 [#m5b959e5]
もう一つの問題が、表示フォントの問題だ。よく言われるように、「骨」の字は日本
と中国で字形が違う。しかし、前述の設定では、フォントの指定を全くしていないため、
日本語と中国語の「骨」を区別することができない。この問題は、ここ電脳瓦崗寨PukiWikiや[[UniWiki]]
などで実装している、spanタグで言語を指定
する機能を組み込めば解決できるが、最新版ブラウザでしか期待する効果が得
られない。((言語指定機能は、最新の改造配布版CGIに組み込み済み。))
もしも旧版ブラウザでも見られるようにしたければ、カスケード
スタイルシートを設定し、かつ書き込み部分に言語指定タグ・符号などを書き込むようにして、
言語によってフォント指定を切り替えるようにするしかないが、かなり面倒である。
多少の問題点はあるものの、上述の方法を使えば英語・日本語の豊富なCGIスクリプトを簡単に多言語化できるのであるから、その利点は大きいと言えよう。
なお、Perl5.6以前の環境でCGIをUTF-8化が出来るか否かは、実はかなり簡単に見分けられる。正規表現の置換先文字列にダブルバイトが入っていると、Perl5.6以前では動作不良が発生する、ということである。
※UTF-8ページであるため、半角「¥」は「\」で表示されています。日本語環境で作業する場合は、読み替えてください。