Namazu 2.0.10 の改良

目次

  1. 概要
  2. 前提条件
  3. ライセンス
  4. Namazu 2.0.10 の改良
    1. HTTP ヘッダで charset パラメタを出力する
    2. URI の query の区切り文字として ; を使用する
    3. UTF-8 で URI エンコードされた URI を解釈するようにする
    4. パッチの適用およびインストール
  5. ソースコード

概要

tomeibus.com のサイト内検索エンジンとしては、 Namazu を使っています。Namazu は全文検索システムとして日本では定評のあるシステムです。 また、 HTML 4.01 [J] として正しい HTML 文書を出力する という当サイトの方針にも合致しています。

しかし、元の Namazu 2.0.10 のままでは、当サイトの方針のうち、以下の3点と合致しません。

  1. HTTP ヘッダで charset パラメタを出力する
  2. URI の query の区切り文字として(&ではなく);を使用する (HTML 4.01 B.2.2 [J] で推奨されている)
  3. URI の非ASCII文字は、 UTF-8 で URIエンコードする (RFC 2718 2.2.5項で推奨されている)

この文書では、この3点を改良する方法を示します。

前提条件

本文書では、 Namazu 2.0.10 安定版を使用することを前提に書かれています。 Red Hat Linux用 RPMパッケージ、Debian GNU/Linux用 debパッケージ、 Windows(95/98/me/NT/2000/XP)版やその他については対象外です。

Namazu 2.0.10 より前のバージョン、あるいは後のバージョンでは、 この文書で書かれている事情と異なる可能性があります。

また、本文書は、 Namazu を CGI としてのみ利用する場合にのみ有効です。 本文書で書かれた改良を実施すると、コマンドラインからの入力を UTF-8 で 行わなければならなくなります。 コマンドラインからの入力については従来通り自動判別を行うようにソースコードを修正しました。

ライセンス

本ページで公開されているソースコードはフリーソフトウェアです。 あなたは、Free Software Foundation が公表した GNU General Public License (GNU 一般公有使用許諾) バージョン 2 (日本語訳) あるいはそれ以降の各バージョンの中からいずれかを選択し、 そのバージョンが定める条項に従って本プログラムを 再頒布または変更することができます。

本ソースコードは有用とは思いますが、頒布にあたっては、 市場性及び特定目的適合性についての暗黙の保証を含めて、 いかなる保証も行ないません。 詳細については GNU General Public License をお読みください。

Namazu 2.0.10 の改良

HTTP ヘッダで charset パラメタを出力する

これを実現するのは簡単です。 namazurc ファイルに以下の行を追加することにより実現できます。


ContentType "text/html; charset=euc-jp"

URI の query の区切り文字として ; を使用する

残りの2点 (URI の query の区切り文字として(&ではなく);を使用するURI の非ASCII文字は、 UTF-8 で URIエンコードする) については、ソースコードの変更を行う必要があります。

この節で、 tomeibus.com の方針と合致するように Namazu のソースコードを改良し、 そのソースコードの変更点を記述します。

変更対象ファイル

Namazu 2.0.10 アーカイブを展開してできるディレクトリの src ディレクトリにある cgi.c, output.c ファイルが対象です。

変更方法(2002-12-21変更方法変更)

namazu-2_0_10-uri-query-separator.patch.gz を伸長し、出力されたパッチを適用します。

namazu.tar.gz を展開したディレクトリに移動し、シェルから gzcat namazu-2_0_10-uri-query-separator.patch.gz | patch -p1 と入力して下さい。

ソースコードの変更点

namazu.cgi で ; による query 区切りを受け付けるようにする

URI によって与えられた query を解釈するのは src/cgi.c ファイルの get_cgi_vars 関数で行っています。get_cgi_vars 関数中で


tmp = strchr(querystring, '&');

というコードがあり、このコードにより query 中の & の位置を調べていることが 分かります。

セミコロンによる query 区切りを解釈できるようにするには、上記ソースコードを 以下のように書き換えます。


char *tmp1, *tmp2;

tmp1 = strchr(querystring, '&');
tmp2 = strchr(querystring, ';');
if (tmp2 == NULL || (tmp1 != NULL && tmp1 < tmp2)) {
    tmp = tmp1;
} else {
    tmp = tmp2;
}

この改良により、従来の & による query 区切りと互換を保ちつつ ; による query 区切りを受け付けるようにすることができました。

namazu.cgi で ; による query 区切りを出力するようにする

前項の改良により、 ; による query 区切りを受け付けるようには なりました。しかし、 namazu.cgi が検索結果の出力を行うとき、検索結果の下部に 表示されるページリストのリンクの query が & を含んでいます。

namazu.cgi で HTML 出力を行う output.c の改良により問題を修正します。

output.c の print_query 関数は、 query 部分の出力を行っています。 そこで、 query を出力するときに、 & の代わりに ; を 出力するようにします。

UTF-8 で URI エンコードされた URI を解釈するようにする

当サイトでは、 RFC 2718 2.2.5項 により推奨されている UTF-8 を使った URI エンコードを使用しています。

しかし、 Namazu は、 EUC-JP・Shift_JIS・ISO-2022-JP による URI エンコードにしか 対応していません。そのため、ソースコードを改良して、 UTF-8 による URI エンコードを 解釈できるようにします。

なお、 EUC-JP・Shift_JIS による URI エンコードと区別ができないため、 この変更を行うと、 EUC-JP・Shift_JIS・ISO-2022-JP による URI エンコードは解釈できなく なります。

変更対象ファイル

Namazu 2.0.10 アーカイブを展開してできるディレクトリの nmz ディレクトリにある codeconv.c ファイルが対象です。 また、追加されるファイルがあるため、 nmz ディレクトリの Makefile.am, Makefile.in も変更されます。

コマンドライン版 namazu が UTF-8 で入力しなければならなくなるなどの問題があるため、 src ディレクトリにある namazu.c, namazu-cgi.c, namazu-cmd.c を変更し、 問題点を解消しました。(2002/04/21 追加)

追加ファイル

Namazu 2.0.10 アーカイブに含まれるファイル以外に、 既存の日本語文字コードと Unicode の間のマッピングルール にある 「Cで書いた JISX0201, JISX0208, JISX0212 <-> Unicode-1.1 のコンバータ」 に含まれるソースファイルのうち、 Unicode→JISX0201,JISX0208,JISX0212 の変換関数 (unicode_to_jisx0201.c, unicode_to_jisx0208.c, unicode_to_jisx0212.c) を使用します。

これらのプロトタイプ宣言は、 codeconv-unicode.h に定義します。

変更方法(2002-12-21変更方法変更)

namazu-2_0_10-uri-utf8.patch.gz を伸長し、出力されたパッチを適用します。

namazu.tar.gz を展開したディレクトリに移動し、シェルから gzcat namazu-2_0_10-uri-utf8.patch.gz | patch -p1 と入力して下さい。

ソースコードの変更点

「Cで書いた JISX0201, JISX0208, JISX0212 <-> Unicode-1.1 のコンバータ」のダウンロード

Namazu の内部文字コードは EUC-JP です。したがって、 query が UTF-8 で与えられる場合は UTF-8 から EUC-JP に変換する必要があります。 (註: 将来的には、内部コードは UTF-8 になるようです。)

UTF-8 と EUC-JP の相互変換には巨大なテーブルを使用して変換しなければなりません。 車輪の再発明を防ぐため(手抜き、とも言う)、既存のコードを利用します。今回利用したのは、 既存の日本語文字コードと Unicode の間のマッピングルール というサイトにある 「Cで書いた JISX0201, JISX0208, JISX0212 <-> Unicode-1.1 のコンバータ」 です。

このソースコードは、 JIS X 0201, JIS X 0208, JIS X 0212 と UCS-2 との相互変換しか できません。 UTF-8 → UCS-2、および JIS X 0201, JIS X 0208, JIS X 0212 → EUC-JP の 変換コードは自分で書きました。

コンバータの関数定義ファイル作成

このコンバータには.hファイルがついていませんので、自分で作成しました。 ファイル名は codeconv-unicode.h としました。

UTF-8 → UCS-2 の変換

UTF-8 は、 RFC 2279 [J] によって定義されているので、この定義を元に UTF-8 → UCS-2, UCS-4 の変換を行います。

UCS-2 → JIS X 0201, JIS X 0208, JIS X 0212 の変換

変換は「Cで書いた JISX0201, JISX0208, JISX0212 <-> Unicode-1.1 のコンバータ」 を使用します。

UCS-2 → JIS X 0201

JIS X 0201 Roman set は EUC-JP では使わないので、無視します。

UCS-2 で、 JIS X 0201 Kana にあたる部分は U+FF61〜U+FF9F の部分です。 この部分が来た場合は、 Unicode11ToJisx0201 関数に文字コードを渡します。

UCS-2 → JIS X 0208, JIS X 0212

UCS-2 では、 JIS X 0208 と JIS X 0212 の文字はバラバラに配置されているため、 簡単に判別することはできません。 そこで、 まず Unicode11ToJisx0208 関数に文字コードを渡し、 JIS X 0208 の中に 該当する文字があれば JIS X 0208 とみなし、文字がなければ JIS X 0212 であると みなすことにします。

Unicode11ToJisx0208 関数は引数のUCS-2文字コードに対応する JIS X 0208 文字がない場合、 0 を返すので、これを利用します。


if (Unicode11ToJisx0208(uc)) {
    /* JIS X 0208 に対する処理 */
} else if (Unicode11ToJisx0212(uc)) {
    /* JIS X 0212 に対する処理 */
}

JIS X 0208, JIS X 0212 のどちらにも対応しない文字の場合は、本ソースコードでは ASCII の . を返すことにします。

JIS X 0201, JIS X 0208, JIS X 0212 → EUC-JP の変換

JIS X 0201 (Kana) は、 0x7E + 0xA1〜0xDF と変換します。

JIS X 0208 は 0xA1〜0xFE + 0xA1〜0xFE と変換します。

JIS X 0212 は 0x7F + 0xA1〜0xFE + 0xA1〜0xFE と変換します。

UTF-8 → EUC-JP の変換関数 utf8toeuc

これまでに述べた変換をまとめて作成した関数が utf8toeuc 関数です。

この関数では、 「Cで書いた JISX0201, JISX0208, JISX0212 <-> Unicode-1.1 のコンバータ」 を使用しているので、 codeconv-unicode.h をインクルードする必要があります。

関数 nmz_codeconv_internal の変更

前のバージョンでは関数 nmz_codeconv_internal の変更を行っていましたが、 設定ファイルを UTF-8 として読んでしまう、などの問題点があったため、 nmz_codeconv_internal は元に戻し、代わりに nmz_codeconv_query を変更しました。

関数 nmz_codeconv_query の変更

Namazu で namazu.cgi やコマンドラインから入力されたコードを 内部コード(EUC-JP)に変換しているのは、 nmz/codeconv.c の nmz_codeconv_query 関数です。

ところが、この関数は、 namazu.cgi とコマンドラインから入力されたコードを区別していません。 コマンドラインからの入力は従来通り文字コードの自動判別を使ってもよいのですが、 namazu.cgi からの入力は UTF-8 に対応させなければなりません。

この目的のため、 nmz_codeconv_query_cmd, nmz_codeconv_query_cgi という2つの関数を 作成します。そして、コマンドラインから呼び出すときは nmz_codeconv_query_cmd、 namazu.cgi から呼び出されるときは nmz_codeconv_query_cgi を呼び出すようにします。

UTF-8 に対応させた場合、従来の EUC-JP・Shift_JIS・ISO-2022-JP 自動判別を併用すると、 誤ったコード判別が多くなるため、この EUC-JP・Shift_JIS・ISO-2022-JP 自動判別機能は 使用せず、 nmz_codeconv_query_cgi では UTF-8 に決め打ちして内部コードへの変換を行う ことにします。

namazu-cmd.c, namazu-cgi.c, namazu.c の変更

nmz/codeconv.c の nmz_codeconv_query 関数は、 src/namazu.c の namazu_core 関数から呼び出されています。この関数は、 namazu.cgi からの呼び出しでも、 コマンドラインからの呼び出しでも、同じように呼び出されます。

namazu_core 関数は、 src/namazu-cmd.c および src/namazu-cgi.c の両方の main 関数から 呼び出されています。

namazu_core 関数からは nmz_codeconv_query 関数を削除し、 代わりに namazu-cmd.c および namazu-cgi.c の両方の main 関数で namazu_core 関数が呼び出される直前に nmz_codeconv_query_cmd 関数または nmz_codeconv_query_cgi 関数を呼び出すように変更しました。

JIS X 0201 Kana → JIS X 0208

改良ついでに、入力中の JIS X 0201 Kana (いわゆる半角カナ)を JIS X 0208 (いわゆる全角文字) に変換するようにソースコードを変えました。 nmz/codeconv.c の hankana2zenkana 関数が JIS X 0201 Kana → JIS X 0208 を行っています。

Makefile の変更

Unicode 関連の関数を持つファイルを追加したため、 Makefile を変更する 必要があります。

nmz ディレクトリの Makefile.in, Makefile.am ファイルに、 unicode_to_jisx0212.c, unicode_to_jisx0208.c unicode_to_jisx0201.c, codeconv-unicode.h の追加に関する変更を反映させました。

パッチの適用およびインストール

Namazu 2.0.10 を http://www.namazu.org/ から 取得し、展開したあと、2つのパッチを当てます。パッチはシェルから gzcat patch-archive-file | patch -p1 と入力して適用します。 どちらのパッチを先にあてても問題ありません。 どちらか一方のパッチのみの適用でも問題ありません。

パッチの適用が正常に終わったら、通常の Namazu と同様にコンパイルを行います。 マニュアルに書いてある通りに configure, make, make install を行えば問題ないはずです。

ソースコード

以下に本文書による変更を加えたソースコードを圧縮して置いておきます。

また、パッチファイルも置いておきます。 パッチの適用方法については、パッチの適用およびインストール の節を参照して下さい。

本ソースコードは GPL に基づき配布しています。詳しくは ライセンス を参照して下さい。