2008年02月26日(火) 23:28 [Debian

Inspiron1525にDebianを入れて数日経つがいまだに設定途上。
ひとまず経過報告をしてみる。

サウンド
×。音が出ない。これから設定する予定。
有線LAN(Marvell Yukon 88E8040 PCI-E Fast Ehternet)
OK。インストール時に認識されなかったが、問題無く動作した。
無線LAN(Intel Wireless WiFi Link 4965AGN)
△。苦労した末、無事認識された。設定はしていないので実運用は行っていない。そういう意味で△。
Firefoxのプロファイル移行
OK。Windowsで使っているプロファイルを移行した。一部、設定を書き換えたが、基本的にそのままで動いた。
Thunderbirdのプロファイル移行
まだ行っていない。
メッセンジャー
OK。pidginをインストールして、MSNメッセが使用できるようになった。

その他の点では特に問題無く使用できている。
いろいろ手間取ってはいるが、それはそれで楽しいので引き続き快適なデスクトップ環境が整えられるようにいろいろ試していきたい。現在無線LANの設定途中なので、それが落ち着いたら少しずつ設定中の話も投稿していく予定。

ちなみに、インストール時にLogicoolのマウス「VX nano」を繋いでいたのだが、GUIのインストーラが起動しなかった。

それにしても、こうやってLinuxでデスクトップ環境を整えていると、一般に普及しないのは当然だなぁ、と思う。

2008年02月22日(金) 23:27 [Debian

Inspiron1525にDebianを入れてみた。

Debianデスクトップ

久しぶりにLinuxのデスクトップ画面を見たけれど、かなり綺麗になっている。
少なくとも、見栄えだけなら十分メイン環境として使っていけそうだ。

今回、ネットワークインストールCDでは内蔵NICを認識してくれなかったため、DVDイメージからインストールを行った。その後、NICドライバのインストールなどに結構手間取ってしまった。その過程やインストール時の話はまた改めて投稿しようと思う。

ちなみに、まだ無線LANは使用できるようになっていない。せっかくのノートなので、早く有線環境から脱したいところだ。

2008年02月16日(土) 23:35 [日記・その他

DELL Inspiron1525が無事到着した。
オーダーステータスで進行状況が見られるため長く感じたが、振込から9日で到着したことになる。
Inspiron1525
外観は青。マットな質感で満足出来るレベルだ。正直、カッコイイ。

が、フタを開けると驚愕の光景。
Inspiron1525キーボード
凄まじく安っぽい作りになっていた。
パームレスト部分が安っぽいのは覚悟していたが、タッチパッドまでが同じ素材で作られているとは思わなかった。タッチパッドが筐体のへこみにしか見えない。
キートップは若干違う作りになっていたが、同じと言っていいだろう。

とは言え、不満どころか「これぞDELL!」と思えてむしろ満足。新品にも関わらず液晶に指紋がついている辺り、押さえるポイントを分かっているとしか思えない。早速、付属の液晶クリーナーが活躍する運びとなった。

今回、付属OSとしてWindows Vista Home Premiumを購入したので、Aeroを楽しみながらVistaに慣れ親しんでみようと思う。

先日、数独のソースコードをダウンロードできるようにしたが、せっかくなのでダウンロード数をカウントできるプラグインを導入してみた。実現可能なプラグインはいくつかあるようだったが、その中で便利そうに思えた下記のプラグインを採用させてもらった。

bovendeur.org:『Download Counter for Wordpress』

導入・設定

上記URLを辿ったページに「Downloading」という項があり、文中の「here」からダウンロードできる。最初、「here」にリンクが張られていることに気づかなくて、しばらく探してしまった。

ダウンロードしたファイルを解凍すると、「wp-downloadcounter」というフォルダが作られるので、フォルダごと「wp-content/plugins」ディレクトリにアップロードし、管理画面から有効にすればひとまず導入は完了となる。

導入完了後、管理画面から「管理」→「Downloads」と辿ると、下記のような画面が表示されるので、初期設定を行う。
DownloadCounter
「Use pretty links」のチェックを外し、「Save changes」ボタンで保存する。
「Use pretty links」の詳細については後述する「きれいなURLを使う」の項を参照してもらいたい。チェックするとURLの生成方法が変わるのだが、若干手間が必要になる。まずは、プラグインの動作を簡単に確認しておきたいのでチェックを外しておく。

最後に、ファイルをアップロードするディレクトリを用意する。既にそういった用途のディレクトリがある場合はそのまま使用していいし、新たにお好みのディレクトリを作成してもいい。私は「files」というディレクトリにいろいろなファイルをアップロードしているので、そこを使用することにした。

ダウンロード数をカウントさせてみる

ダウンロードさせるファイルを上記で作成した(作成されていた)ディレクトリにアップロードする。
アップロード完了後、管理画面から「管理」→「Downloads」を辿り、「Add Download」ボタンを押してファイルの登録画面に移動する。
DownloadCounterのファイル登録
「Name」には任意の名前を、「URL」にはアップロードしたファイルのURLを入力し、「Save」ボタンで保存する。

画面下に登録したファイルの情報が表示され、ダウンロード数などが参照できるようになっている。
「With counter」に張られたリンクからダウンロードするとダウンロード数がカウントされ、「Without counter」に張られたリンクではプラグインを通さないためカウントされない。よって、前者のURLを使用すれば良い。

きれいなURLを使う(Use pretty links)

通常、「http://(サイトのURL)/?download=sudoku」といったURLが生成されるが、見るからにCGI経由なので見栄えが良くない(と考える人がいるかもしれない)。そこで、「Use pretty links」と「Download slug」を使用する。

管理画面の英文を訳すと大体下記のようになる。

Use pretty links

ここをチェックすると、ダウンロードスラッグ(以下のDownload slugのこと)を使用したURLが生成されます。チェックしなかった場合、「/?download=<名称>」のようなURLが生成されます。

Download slug

この値を変更した場合、新しいダウンロードスラッグを反映させるために管理画面の「パーマリンク設定」からパーマリンク構造を更新する必要があります。あなたがパーマリンク構造を更新するまで、訪問者は「404 NOT FOUND」ページを受け取ることになります。

「Use pretty links」をチェックし、「Download slug」に任意のスラッグを入力する。ダウンロードスラッグは既存カテゴリーのスラッグと被らない方が無難だろう。ここでは「download」とする。

設定を保存すると、登録したファイルの「With counter」のURLが変更される。

http://spring.sakurasaita.net/?download=sudoku

http://spring.sakurasaita.net/download/sudoku

プラグインで生成されるURLがダウンロードスラッグを使用したものに置き換わるだけということに注意しなければいけない。そのままでは、このURLにアクセスしても404 NOT FOUNDとなり、使用できない。解説に従えばパーマリンク構造を変更するらしいのだが、単にパーマリンク構造を変更しただけでダウンロードできるとも思えない。そこで、「.htaccess」ファイルを編集することにした。(もし、本来はその他の手順で行うべきなのだとしたら、ぜひお教えいただきたい)

「.htaccess」ファイルを作成し、下記のように編集する。

<IfModule mod_rewrite.c>
    # 置換を有効にする
    RewriteEngine On
    # URL先頭から置換を開始する
    RewriteBase /
    # 先頭が「/download/」で始まる場合のみ置換する
    RewriteCond %{REQUEST_URI} ^/download/
    # 「download/文字列」を「?download=文字列」に置換する
    RewriteRule ^download/(.+) ?download=$1 [L]
</IfModule>

これでdownload以下へのアクセスは「?download=<名称>」にリダイレクトされるため、正常にアクセス出来るようになる。
もし、パーマリンク構造を変更していて、既に「.htaccess」ファイルが存在する場合は下記のように赤字を追記すれば良い。

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_URI} ^/download/
    RewriteRule ^download/(.+) ?download=$1 [L]
    # DownloadCounterで使用するURLは置換対象から除く
    RewriteCond %{REQUEST_URI} !^/download/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>

これで、エントリーへのリクエストとダウンロードへのリクエストの両方を扱えるようになる。

動作確認時の注意点

「Use pretty links」の確認を行う場合、一度ブラウザのキャッシュをクリアした方がいい。
いろいろなパターンの設定を試していた時、正常にダウンロードできるはずなのにダウンロードできない、ダウンロードできないはずなのに正常にダウンロードできるといったことがあったからだ。念のため、ブラウザのリクエストヘッダを確認してみたところ、期待しない動作の場合はそもそもリクエストヘッダが送信されていなかった。そこでキャッシュをクリアしたところ、期待通りの動作を行うようになった。

まとめ

以上でDownloadCounterの設定は完了となる。
個人的には、「Use pretty links」は使用しないで「?download=<名称>」とする方がダウンロードされるんだなということがはっきりするので好みかもしれない。

ファイルがダウンロードされたということは、少なくともエントリーに興味をもってくれた人がいたということになるので、単にアクセス数が伸びるよりもうれしい。今後もDonwloadCounterを活用させてもらおうと思う。

.htaccessの説明

上記で作成した「.htaccess」ファイルだが、Apacheにあまり馴染みの無い方は内容を把握しきれないかもしれない。把握していない設定を使用するのも気持ち悪いと思うので、簡単に説明しようと思う。本項はDownloadCounterの設定には直接関係ないので読み飛ばしても何ら問題無い。

<IfModule mod_rewrite.c>
    ~
</IfModule>

これは「mod_rewrite」モジュールがロードされている場合のみ、タグに囲われたディレクティブを読み込ませるために記述する。実際の置換には関わらない部分であり、保険のために記述する。

RewriteEngine On

置換エンジンを有効にする。もし、置換をやめたい場合、「On」→「Off」とすれば、せっかく書いた置換ルールを削除しないで置換をやめることができる。

RewriteBase /

URLのどの部分から置換を開始するのかを指定する。
RewriteBaseディレクティブを省略すると、ローカルのファイルパスが使用されてしまう。「/index.php」がローカルのパスでは「/var/www/html/index.php」となっている場合、後者が使用されることになる。これは大抵期待外れなので、常にきっちりと指定した方が良い。

RewriteCond %{REQUEST_URI} ^/download/

RewriteCondディレクティブは置換対象の条件を指定する。
%{REQUEST_URI}は、リクエストヘッダのリソース部分を扱える。リクエストヘッダが「GET /perl/28.html HTTP/1.1」だとすると、「/perl/28.html」となる。
上記例ではリソースの先頭が「/download/」で始まるURLを置換対象としてくれ、という意味になる。

RewriteRule ^download/(.+) ?download=$1 [L]

RewriteRuleディレクティブは、RewriteCondディレクティブの条件に合致したURLを実際に置換する。
URLの先頭「download/(何かの文字列)」を「?donwload=(何かの文字列)」に置換している。「$1」とは、置換元文字列の括弧で囲まれた部分を使用するよという意味になる。括弧が複数個ある場合は、「$1」「$2」「$3」と数字を増やしていけばいい。
末尾に記載されている「[L]」はLastのことで、このRewriteRuleディレクティブで置換されたURLは置換を終了するという意味だ。これ以降にもRewriteRuleディレクティブが指定されている場合に期待しない置換が行われることを防いでくれる。

RewriteCond %{REQUEST_URI} !^/download/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

1行目は、リソースの先頭が「/download/」で始まらないURLを置換対象としてくれ、という意味になる。記述しなくても、問題ないので単なる保険だ。

2~3行目で使用されている%{REQUEST_FILENAME}はファイルのローカルパスを扱える。「/index.php」がローカルのパスでは「var/www/html/index.php」となっている場合、後者が使用される。「-f」「-d」という記述は、「ファイルだったら置換対象」「ディレクトリだったら置換対象」の意味だ。しかし、先頭に「!」が付いているため真偽が逆になり、「ファイルでなかったら」「ディレクトリでなかったら」となる。
つまり、2~3行目はローカルのパスでチェックして、ファイルでもディレクトリでもない(要は存在しない)ファイルへのリクエストだったら置換対象としてくれ、という意味になる。

4行目は、リソースをindex.phpに置換している。パーマリンク構造の細かな解析はindex.php内で行われているのだろう。末尾の「[L]」は、先の説明と同様となる。

もっと細かく知りたい場合は下記のリンクを参照して欲しい。
Apache module mod_rewrite

2008年02月12日(火) 0:30 [Perl

バレーボール関係で埋まりかけた連休の合間を見て、数独を解くPerlスクリプトを書いたので、ネタにしようと思う。(自宅サーバネタはまた間に合わなかった)

Wikipedia:数独

上記URLに画像が紹介されている一番ポピュラーな縦9マス横9マスの問題の場合、各列には1~9の数字が1つだけ入り、各行にも1~9の数字が1つだけ入る。更に3×3の正方形内にも1~9の数字が独立して入る。この3つのルールに違反しない数字を書くマスに埋めていくのが数独だ。間違った数字を入れてしまうとどこかで矛盾が生じてしまい、全マスに数字を収められなくなってしまう。逆を取れば、全マスに数字を収められればそれが正解となる。

今回作成したスクリプトは、まず最初のマスに適当に数字を入れ、次のマスへ移動する。そこでも適当に数字を入れる。入れられる数字が無かった場合、1つ前のマスに戻り別の数字を入れ、また次のマスへ移動し、入れられる数字があれば入れていく。これを全マスに数字を収められるまで繰り返していく。いわゆるバックトラックという手法になる。(芸が無いと言えばそれまでだが)

スクリプトは以下のように使用する。

perl sudoku.pl question.txt

「question.txt」(ファイル名は任意)には、空きマスは「0」として空白区切りで下記のように問題を記述する。

0 0 3 5 1 2 0 0 0
0 1 0 0 4 0 3 2 0
6 0 0 0 8 0 0 4 0
3 0 0 0 0 4 0 0 6
1 4 9 0 0 0 7 8 5
5 0 0 9 0 0 0 0 4
0 3 0 0 9 0 0 0 2
0 5 8 0 3 0 0 1 0
0 0 0 1 2 5 8 0 0

これを実行し問題を解くことが出来た場合、空きマスの「0」が数字に書き換えられた「question-answer.txt」が生成される。

4 7 3 5 1 2 9 6 8
8 1 5 6 4 9 3 2 7
6 9 2 3 8 7 5 4 1
3 2 7 8 5 4 1 9 6
1 4 9 2 6 3 7 8 5
5 8 6 9 7 1 2 3 4
7 3 1 4 9 8 6 5 2
2 5 8 7 3 6 4 1 9
9 6 4 1 2 5 8 7 3

例では9×9の問題を使用しているが、もっと大きな問題でも解くことができる(はず)。問題に無理がある場合はもちろん失敗してしまう。問題があっているのに失敗することは無いが、あったらごめんなさい。

ここをクリックでコードの表示・非表示を切り替える。

需要は無いだろうけど、ダウンロードは下記からどうぞ。

ダウンロード

バグがあった場合は、ぜひご連絡を。

今度はイラストロジックを解くスクリプトにでも挑戦してみようかなと思う。

2008年02月07日(木) 21:17 [日記・その他

先月16日に発売された「Inspiron1525」をDELL通販で購入してみた。安価なうえに、標準搭載の入出力端子がおいしい。

  1. IEEE1394a
  2. 8-in-1 メモリカードリーダ
  3. VGAビデオ出力/S-Video
  4. HDMIポート

今使用しているノートも(値段を除けば)この辺りが決め手となったので、ポイントが高い。
正直、「hp dv6700 雫」も良かったかなぁと思うのだが、hpは英語キーボードを別途入手するのが面倒なので今回は見送りとなった。

そんなわけで、商品自体は満足出来そうである。不満なのはDELLの通販そのものだ。

支払い方法で「ジャパンネット銀行から振り込み」を選択したのだが、発注後のメールでは「現金前振込」となっており、三菱東京UFJ銀行の口座が記載されていた。選び間違えたかと思い、DELLのサイトから注文内容を確認しようとしたのだが、それらしきページがどこにも見当たらない(見落としか?)。オーダーステータスという注文状況を確認する機能を使おうとしたら、入金後か発注数日後にならないと使えないとのこと。

送られてくるメールも日本語変だし、正直不親切すぎやしないか。

結局、待ちきれずに振り込んでしまったのだが、無事受注確認のメールが届いた。
さすがにここまで来れば後は待つだけなので一安心ではある。

2008年02月05日(火) 23:00 [Perl

PerlのNet::DNSモジュールを使用して、DNSに問い合わせを行ってみる。

Net::DNSモジュールのインストール

標準ではNet::DNSがインストールされていないため、cpanにてインストールを行う。

$ su -
Password: **********
# perl -MCPAN -e shell
cpan>install Net::DNS

これでインストールは完了。
cpanを最初に利用する場合は設定などを聞かれるが、私の場合、ほぼ全てを初期値のままで設定した。「Asia」、「Japan」とダウンロード先のサーバを指定した程度だ。

Windowsの場合はPPMなどを利用すると良いだろう。その辺りのことについては別の機会に投稿しようと思う。

正引き(ホスト名→IPアドレス)

ホスト名からIPアドレスを取得する。

use strict;
use Net::DNS;

my $host = 'spring.sakurasaita.net';
my $res = Net::DNS::Resolver->new;

#ホスト名のIPアドレスを取得(正引き)
if(my $query = $res->search($host, 'A')){
    # Aレコードのみを取得し、IPアドレスの一覧を印字
    print map {$_->address."\n"} grep($_->type eq 'A', $query->answer);
}else{
    print $res->errorstring, "\n";
}

answerの結果でtypeがAレコードの場合のみaddressを取得している。これには訳があり、取得しようとするホスト名がCNAMEレコードだった場合、addressが使用できず、「$_->address」でエラーが発生してしまうためだ。

レコードの種類については、「@IT:主なDNSレコードの種類」が参考になる。

上記のスクリプトを実行すると以下のような結果になる。

# $hostが「spring.sakurasaita.net」の場合
$ perl dns.pl
210.250.97.3
# $hostが「www.google.com」の場合
$ perl dns.pl
66.249.89.104
66.249.89.147
66.249.89.99

逆引き(IPアドレス→ホスト名)

IPアドレスからホスト名を取得する。IPアドレスは任意のものに変更した方が確実に動作するかもしれない。

use strict;
use Net::DNS;

my $ip = '66.249.89.99';
my $res = Net::DNS::Resolver->new;

# IPアドレスのホスト名を取得(逆引き)
if(my $query = $res->search($ip, 'PTR')){
    # PTRレコードのみを取得し、ホスト名の一覧を印字
    print map {$_->ptrdname."\n"} grep($_->type eq 'PTR', $query->answer);
}else{
    print $res->errorstring;
}

answerの結果でtypeがPTRレコードの場合のみホスト名を取得している。これを実行すると以下のような結果になる。

$ perl dns.pl
jp-in-f99.google.com

任意のDNSサーバに問い合わせる  正引き(ホスト名→IPアドレス)

DNSサーバのIPアドレスを更新した場合、周囲のDNSサーバに変更が反映されるまでには多少の時間が必要になる。例えば、ダイナミックDNSサービスを使用していて、IPアドレスの更新を行い、更新が正常に行われているか確認するとする(VALUE-DOMAINなどたまに更新されていないことがある)。その際、プロバイダのDNSサーバに問い合わせたのではタイムラグの問題で変更が反映されていない可能性がある。よって、ドメインを管理している大元のDNSサーバに問い合わせるのが最も確実な方法となる。

下記のスクリプトは、ドメインを管理しているDNSサーバを取得し、取得したDNSサーバに問い合わせを行っている。

use strict;
use Net::DNS;

my $domain = 'sakurasaita.net';
my $host = 'spring.sakurasaita.net';
my $res = Net::DNS::Resolver->new;
my @ns;

# ドメインを管理しているDNSサーバの一覧を取得
if(my $query = $res->query($domain, 'NS')){
    # NSレコードのみを取得し、DNSサーバの一覧を取得
    @ns = map {$_->nsdname} grep($_->type eq 'NS', $query->answer);
    # 取得したDNSサーバの一覧を印字
    print "DNSサーバ:\n";
    print map {"$_\n"} @ns;
}else{
    print $res->errorstring, "\n";
    exit;
}

# 問い合わせるDNSサーバを設定する
$res->nameservers(@ns) if(@ns > 0);

# ホスト名のIPアドレスを取得(正引き)
if(my $query = $res->search($host, 'A')){
    # Aレコードのみを取得し、IPアドレスの一覧を印字
    print "IPアドレス:\n";
    print map {$_->address."\n"} grep($_->type eq 'A', $query->answer);
}else{
    print $res->errorstring, "\n";
}

上記のスクリプトを実行すると以下のような結果になる。

$ perl dns.pl
DNSサーバ:
ns3.value-domain.com
ns1.value-domain.com
ns2.value-domain.com
IPアドレス:
210.250.97.3

「spring.sakurasaita.net」のIPアドレスを問い合わせているのに、DNSサーバの一覧を取得する部分では「sakurasaita.net」を指定している。これは、「spring.sakurasaita.net」にNSレコード(ドメインを管理するDNSサーバを定義するレコード)を指定していないからであって、必ずしも上位レベルのドメインを指定しなければいけないというわけではない。

私の場合、一部のサブドメインにNSレコードを設定しているが、そのサブドメインはDNSサーバの一覧取得にも使用できる。

# 上記スクリプトの下記変数の値のみ変更
my $domain = 'flower.sakurasaita.net';
my $host = 'flower.sakurasaita.net';

上記の変更を行った後に実行すると以下のような結果になる。

$ perl dns.pl
DNSサーバ:
ns1.dns.ne.jp
ns2.dns.ne.jp
IPアドレス:
219.94.128.32

ダイナミックDNSのIPアドレスを更新した後、問い合わせるDNSサーバを指定した場合としなかった場合とで結果を比べてみれば違いが分かると思う。

まとめ

CGIを作成するのであればあまり必要の無い知識だが、スクリプトで手軽にDNS問い合わせを行えるのはおもしろい。このモジュールを利用してダイナミックDNSサービスのIPアドレスを更新するスクリプトを作成してみようと思う(というより、既に作成してあるのでまとめて投稿しようと思う)。

『外国人が「日本に長く居すぎた…」と実感するとき』という記事が秀逸。

4. 外国人が電車に乗っているのを見て、「わおっ、ガイジンがいるっ」と思うとき

爆笑w

他は以下から。

痛いニュース:『外国人が「日本に長く居すぎた…」と実感するとき』

2008年02月02日(土) 2:51 [WordPress

WordPress標準のエディタが非常に使いづらい。デフォルトではビジュアルエディタが有効になっており、投稿の編集時はまずビジュアルエディタに投稿が読み込まれるのだが、私はもっぱらコードエディタで編集を行っている。そのためすぐにコードエディタへ切り替えるのだが、一度ビジュアルエディタで読み込んでしまうとソースが意図しない形に変換されてしまう。これでは編集を行うたびに細かい修正が必要になってしまい、非常に不便だ。

また、投稿を表示する際に改行コードをbrタグに変換するなどの処理が行われているのだが、意図しない部分にpタグが挿入されてしまうことが多い。基本的には重宝する機能なわけだが、codeタグ内にpタグを埋め込まれてしまうとcodeタグのCSSが効かなくなってしまい困ってしまう(何かうまいCSSの書き方があるのかもしれないが、見つけることが出来なかった)。
それだけではなく、「<p></code></p>」のように不可思議なネストが生成されてしまう場合もある。

機械的に文章を解析しタグを挿入しているわけだから、不都合が生じるのは仕方のないことだが、如何せん不便と思うパターンが多すぎる。そこで、WordPressの癖を覚えつつ、やむを得ない部分はソースの改造を行い、エディタと上手な関係を築けるように工夫していこうと思う。

ビジュアルエディタを無効にする

冒頭に書いた通り、ビジュアルエディタはソースを変換してしまうので無効に設定する。

管理画面の「ユーザー」タブからビジュアルエディタを無効にしたいユーザーを選び、編集画面の「ビジュアルエディタを使用する」のチェックを外し、「ユーザーを更新」を押してやれば無効になる。これで、編集画面からはビジュアルエディタのタブが無くなり、最初からコードエディタでソースが読み込まれるようになる。

codeタグ内のpタグを除去する

投稿表示の際に挿入されるpタグをどこまで制御するか迷ったが、回避策を見つけることが出来なかった「codeタグに挿入されるpタグ」に対してのみ対策を取ることにした。これには、WordPressのソースを一部変更する必要がある。

wp-includesのformatting.phpを編集する。「function wpautop」で検索するとpタグやbrタグの挿入処理を行っている関数が見つかるので、関数末尾の「return $pee」の前に下記の2行を挿入する。

$pee = preg_replace('| {4}|', str_repeat('&nbsp;',4), $pee);
$pee = str_replace('\\', '\\\\', $pee);
$pee = preg_replace(
        '|<code.*?>.*?</code>|se'
        , "str_replace(array('<p>', '</p>'), array('', '<br /><br />'), '$0')"
        , $pee);
$pee = StripSlashes($pee);

1行目では、半角スペースが4つ続いた場合に「&nbsp;」に変換し、ブラウザ上でも半角スペースを複数個表示できるようにしている。CSSで「white-space: pre;」とすれば、スペースのままでも期待通りに表示されるのだが、枠から溢れて表示されてしまうのに抵抗があったため、使用していない。

2行目では、投稿内の「\」を「\\」にエスケープしている。理由は4行目に関わってくる。

3行目では、pタグを削除し、段落を設けるためにクロージング側のタグをbrタグ2つに変換している。今回のコードではここが主の部分となる。

4行目では、StripSlashesにより投稿内のエスケープを除去している。理由はpreg_replaceをeオプションで実行した場合に、文字列内のクォートがエスケープされてしまうからだ。例えば、<span class="comment">などとしている場合に、「"」が「\"」となってしまい、HTMLタグが正常に認識されなくなってしまう。その対策としてStripSlashesを使用するのだが、この関数は全てのエスケープ文字を除去してしまうため、「\n」などの「\」までが削除されてしまう。そこで2行目の処理が必要になってくるわけだ。

PHP未経験者とはいえ、後手に回る対応が多く、とてもスマートとは言えない手順となってしまったが、実利は得られるので良しとする。

ちなみに、pタグ・brタグの挿入を完全に停止してしまうには、wp-includesのdefault-filters.phpを下記のように変更すればいい。

add_filter('the_content', 'wpautop');
add_filter('the_excerpt', 'wpautop');
    ↓
// pタグ・brタグの挿入を停止するためコメントアウト
// add_filter('the_content', 'wpautop');
// add_filter('the_excerpt', 'wpautop');

これでそもそも変換処理が行われなくなる。

codeタグ前後のpタグを調整する

上述の手順でcodeタグ内のpタグは除去されるようになったが、codeタグ外のpタグが期待しない形で挿入されてしまう。具体的には、下記のようになる。

<p>下記がコードです。<br />
<code>ここがコードです</code><br />
上記がコードです。</p>

本来は下記のように挿入して欲しい。

<p>下記がコードです。</p>
<code>ここがコードです</code>
<p>上記がコードです。</p>

前者の例になるのは、codeタグがインライン要素だからだ。「display:block」として無理やりブロック要素としているために、期待と相容れなくなってしまっている。そこで、codeタグがブロック要素として扱われるように変更する。

wp-includesのformatting.phpを編集する。pタグの除去と同様に「function wpautop」で検索した関数を変更する。

$allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody~省略~)';
    ↓
// 先頭にcodeを追記する
$allblocks = '(?:code|table|thead|tfoot|caption|colgroup|tbody~省略~)';

これで、codeタグがブロック要素として扱われるようになるので、期待した通りにpタグが挿入されるようになる。当然ながら、pタグ除去の手順でpタグ・brタグの挿入を完全に停止してしまっていた場合はこの対応を行う意味が無い。

クォートの変換を無効にする

WordPressでは「'」や「"」のようなクォートなどが「&#****;」といったコードに変換されてしまうようだ。これではコードを記述する際に意図しない形になってしまい困ってしまう。コピー&ペーストも出来ない。

また、私の場合は下記のような問題が発生していた。二度登場する「'A'」に注目して欲しい。

if(my $query = $res->search($host, 'A')){
    # <span class="comment">を利用したあとのクォートが変換される。
    print map {$_->address."\n"} grep($_->type eq ‘A’, $query->answer);
}

この中途半端な状態について原因の特定は行っていないのだが、実はcodeタグ内のクォートは変換されないように作られているのではないかと予想している。しかし、<span>といった別のタグが呼び出されることで、それ以降がcodeタグ内ではないと判断され変換されてしまっているのではないか。もちろん想像に過ぎないのだが。

原因は何にせよ、クォートも入力した通りに表示して欲しいので変換機能を停止させてしまう。これにはプラグインを使用する。

Multimeter:『Kill WPTexturize』

このプラグインをwp-content\pluginsにアップロードし、管理画面から有効にするだけで全投稿のクォートが元のままで表示されるようになる。

また、この問題の解決には以下のサイトを参考にさせてもらった。

BirDesign:『クォーテーションを変換しないようにする』

まとめ

以上の作業を行うことで、WordPressでの編集作業がずいぶんと気楽に行えるようになった。

後は挿入されるpタグ・brタグのため、改行の位置にほんの少し気を遣っていくだけだ。

Copyright 2008 As You Like It All rights reserved.
Powered by Wordpress, Base template by WEB MAGIC, Photo by Encyclorecorder