2006 年 8 月 16 日 22 時 20 分

参照の適用


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


MixiExporter はテンプレートに埋め込む方式なので、
出力する対象がテキストか HTML かによって、
埋め込み方を変えないといけない。

テキスト形式のテンプレートに埋め込むなら、
そのままの置き換えで構わないが、
HTML/XML 形式のテンプレートに埋め込むなら、
以前とは逆に、一部の文字を実体参照に置き換える必要がある。

また、昨日論じた改行に関しては、
テキストの場合はそのままで良いが、
HTML の場合は、<BR> 等、XHTML の場合は <br />、
XML の場合は CDATA 空間や適当な要素にする必要がある。

さて、どうしようか。

とりあえず、実体参照に置き換える役割を持つ関数を作る。

========== part of HttpUtil.js ==========

// HTML の実体参照で符号化する
String.prototype.encodeHTML = function () {
    var value = this;
    value = value.replace(/&/g, "&amp;");
    value = value.replace(/>/g, "&gt;");
    value = value.replace(/</g, "&lt;");
    value = value.replace(/"/g, "&quot;");
    return value;
}

========== end of part of HttpUtil.js ==========

そして、出力形式については、
テンプレートのフォーマットを引数として受け取る手や、
埋め込む際のエスケープの仕方を指定させる手がある。

ここでは単純にするため、テンプレートファイルの
拡張子を見て、html/htm/xml であれば、
実体参照への置き換えと、改行の <br /> への置き換えを、
テキストであればそのままという方法にしよう。

書式ごとに出力クラスを作って対処してもいいが、
本格的にツール化を考える時にやればよいので、
今日はべた書きで行くことにする。

まず、テキスト形式のバカテンプレートを作成する。

========== default.txt ==========
----------------------------------------
$date の日記: $title
----------------------------------------
$body
========== end of default.txt ==========

以前作った HTML のアホテンプレと使い分けるわけだ。

さて、_export 関数を書き換えてみよう。

========== part of Main.js ==========

function _export(user, password, template, outDir) {

    // テンプレートの拡張子を得る
    var match = template.match(/\.([^.]+)$/);
    var extension = match == null ? "html" : match[1];

    // 拡張子によってテキストをエスケープする
    var escaper;
   
    switch (extension.toLowerCase()) {
    case "htm":
    case "html":
    case "xml":
        escaper = function (text) {
            return text.encodeHTML().replace(/(?:\r\n|[\r\n])/g, "<br />\r\n");
        };
        break;
   
    default:
        escaper = function (text) {
            return text;
        };
        break;
    }

    // フォルダ名の最後に \ をつける
    if (outDir.charAt(outDir.length - 1) != "\\") {
        outDir += "\\";
    }

    // テンプレートのマクロを表す正規表現
    // $title とか $$ とか
    var macro = /\$(\w+|\$)/ig;
   
    // 日記格納用変数
    var item;

    // item と escaper を参照するマクロ置換クロージャ
    var func = function (match, name) {
        switch (name) {
        case "$":
            return "$";
        case "title":
            return escaper(item.getTitle());
        case "body":
            return escaper(item.getContent());
        case "date":
            return escaper(item.getDate().format());
        default:
            return "";
        }
    };

    // 準備完了

    // テンプレートを読み込む
    var template = _readFileText(template, "UTF-8");

    // ログイン(接続前に 3000 ミリ秒待機)
    var session = new MixiSession(
            user, password, 3000);

    // 日記オブジェクトを作成
    var diary = new MixiDiary(session);

    // 日記列挙オブジェクトを作成
    var iterator = diary.iterator();

    // 項目を列挙
    while (iterator.hasNext()) {

        // 項目を取得
        var item = iterator.next();

        // テンプレートに埋め込む
        var content = template.replace(macro, func);

        // ファイル名を決める
        var date = item.getDate();
        var filename = date.getFullYear().formatLeadingZeroes(4)
                + "-" + (date.getMonth() + 1).formatLeadingZeroes(2)
                + "-" + date.getDate().formatLeadingZeroes(2)
                + "-" + date.getHours().formatLeadingZeroes(2)
                + "-" + date.getMinutes().formatLeadingZeroes(2)
                + "." + extension;

        _writeFileText(outDir + filename, "UTF-8", content);

        // テストなので 1 件だけ
        break;
    }

}

========== end of part of Main.js ==========

さて、以下のように実行してみる。

$ MixiExporter.wsf out /user:メールアドレス /password:パスワード /template:default.txt

out フォルダに 2006-08-15-23-48.txt ができた。
本文は通常の改行であり、普通のテキストファイルとなった。

$ MixiExporter.wsf out /user:メールアドレス /password:パスワード

out フォルダに 2006-08-15-23-48.html ができた。
本文は <br /> + 改行となっており、
" や < は &quot; や &lt; に変換されている。

これである程度自由に出力ができるようになった。



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