2006 年 8 月 15 日 23 時 48 分

参照の展開


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


さて、8/9 に考察した、HTML の参照について考えてみよう。
基本的には以前に作成した decodeHTML メソッドを使い、
HTML の参照を展開してやればよいのだ。

HTML を解析して返却しているのは、
MixiDiaryIterator と MixiDiaryEntry の 2 クラスなので、
まずはそれらを修正しよう。

最初に MixiDiaryIterator#next だ。
ここで扱っている文字列は日記のタイトルである。
これを MixiDiaryEntry に渡しているが、
渡す時点でテキストにしておこう。

また、ついでに写真の URL も少しまともにしておく。
連想配列風のオブジェクトを作成し、
photoURL と thumbnailURL のプロパティとして登録する。

========== part of MixiDiary.js ==========

// 次の日記項目を返す
MixiDiaryIterator.prototype.next = function () {

    // _entries が空なら次を読み込む
    if (this._entries != null && this._entries.length == 0) {
        this._getNextPage();
    }

    // _entries が null ならそれ以上ない
    if (this._entries == null) {
        throw MixiError("これ以上日記がありません");
    }

    // 日記を取り出す
    var entry = this._entries.shift();
   
    // 写真の URL を取得し、配列に格納
    // 要素は photoURL と thumbnailURL プロパティを持つ
    var images = [];

    if (entry[2].length > 0) {
        this._rexImages.lastIndex = 0;
        for (;;) {
            var match = this._rexImages.exec(entry[2]);
            if (match == null) break;
            images.push({
                photoURL : match[1],
                thumbnailURL : match[2]
            });
        }
    }

    // 日記オブジェクトを作成して返す
    return new MixiDiaryEntry(
            this._session, parseInt(entry[3], 10),
            parseInt(entry[4], 10),
            entry[1].decodeHTML(), images);

}

========== end of part of MixiDiary.js ==========

こちらは大した作業ではない。

そして、次に MixiDiary#_retrieve だ。
ここで扱っている文字列は、日記本文である。
日記本文は複数行にわたる文字列なので、
参照だけでなく、改行についても考えないといけない。

HTML においては、一部の例外を除き、
改行文字は空白文字と同じように扱われる。
強制的に改行するためには、<br> 要素が使用される。

mixi も例外ではない。日記をレイアウトする際には、
日記上の改行を、「改行+<br>」に置き換えているようだ。
なので、これを改行に置き換える処理も入れることにする。

========== part of MixiDiaryEntry.js ==========

// 日記ページを取得して解析
MixiDiaryEntry.prototype._retrieve = function () {

    // ページを読み込む
    var html = this._session.fetch("http://mixi.jp/view_diary.pl",
            { id : this._id, owner_id : this._ownerID } );

    // 解析
    var match = html.match(MixiDiaryEntry._REX_DIARY);
    if (match == null) {
        throw new MixiError("日記ページを解析できませんでした。");
    }

    // 日時は Date オブジェクトに
    this._date = new Date(match[1], match[2] - 1,
            match[3], match[4], match[5]);

    // 本文は改行の処理と参照の展開をして返す
    this._content = match[6].replace(/(?:\r\n|[\r\n])<br>/g, "\r\n").decodeHTML();
}

========== end of part of MixiDiaryEntry.js ==========

改行の処理は、String#replace を使うのだが、
改行には OS によって異なる 3 種類の実装がある。
それらは、CRLF、LF、CR である。

JavaScript の \r と \n のエスケープ文字は、
C 言語と違い、単純に CR と LF にマッピングされるので、
改行を表す正規表現は (?:\r\n|[\r\n]) となる。

WSH は、Windows 環境で利用しているので、
変換後の改行は CRLF(\r\n)としておこう。

改行処理は、参照の展開の前に行う必要がある。
例えば、HTML の説明をしているような日記本文の場合、
「&lt;br&gt;」なんてテキストが出現するが、
先に参照を展開すると、「<br>」になってしまう。

幸い mixi は「改行+<br>」を改行としているので、
逆にしても問題は起こらないが、
これは、Web プログラミングでは注意しておくべき点だ。

さて、こういう風に修正をすると、
MixiDiaryEntry から取得できる文字列項目は、
テキストとして取り扱うことができるようになる。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.