◆F99a.q8oVE::Blog
perl で seq を実装してみた
◆F99a.q8oVE: 2008/08/13 03:29:21

この前は mktemp を書いてましたが、今度は seq を書いてみました。 seq は、shell script でループを書く時によく使ってます。

勉強ということで、Test::Base を使ってみたり、コードは gist に貼ってみたり...。 しかし、これだと feed reader 上で直接コードが読めないところが難点かな。

(ref: Happy Testing Perl:第 2 回 Test::Base の紹介|gihyo.jp ... 技術評論社)

gist: 5103 — GitHub
perl で mktemp を実装してみた
◆F99a.q8oVE: 2008/08/03 20:44:40

最近、シェルスクリプトをいじってることが多いんだけど、シェルスクリプト中で使って便利なのが mktemp.

それで、乱用ぎみに使っていたのですが、とある環境で作業をしていて、mktemp を使おうと思ったら無かったんで perl で実装してみたり。

utils: perl/mktemp@09177d8ec349にあげておいた。 ライセンスはBoost Software License 1.0 (BSL1.0).

もっときれいに書けないかな〜。

#!/usr/bin/env perl
use strict;
use warnings;
use Fcntl;

# use Data::Dumper;

my $try_count = 10;

my %options = (
  t => 'using_tempdir',
  u => 'unsafe',
  d => 'dir',
);
my %mode = (
  using_tempdir => 0,
  unsafe => 0,
  dir => 0,
);
my $template;

foreach my $arg (@ARGV) {
  if ($arg =~ /^-(.*)$/) {
    foreach (split //, $1) {
      die "unknown option: $_" unless exists $options{$_};
      $mode{$options{$_}} = 1;
    }
  } else {
    $template ||= $arg;
  }
}

unless (defined $template) {
  $mode{using_tempdir} ||= 1;
  $template = 'tmp.XXXXXXXXXX';
}

# warn Dumper \%mode;
# warn $template;

my $temp_name;

while ($try_count) {
  $temp_name = $template;
  $temp_name =~ s/(X)/&rand_char($1)/eg;
  if ($mode{using_tempdir}) {
    $temp_name = ($ENV{TMPDIR} || '/tmp') . "/$temp_name";
  }
  # warn $temp_name;
  if ($mode{dir}) {
    last if mkdir $temp_name;
  } else {
    if (sysopen my $fh, $temp_name, O_WRONLY | O_CREAT | O_EXCL) {
      close $fh;
      last;
    }
  }
  $try_count--;
}

die "make temp failed: $temp_name" if $try_count == 0;

if ($mode{unsafe}) {
  if ($mode{dir}) {
    rmdir $temp_name or die $!;
  } else {
    unlink $temp_name or die $!;
  }
}

print "$temp_name\n";

sub rand_char() {
  my @chars = ('a'..'z', 'A'..'Z', 0..9);
  return $chars[rand(scalar @chars)];
}
TAP on C++
◆F99a.q8oVE: 2008/06/23 00:39:30

Test Anything Protocol - TAP ですが、なんとなく C++ で実装してみました。

tap.hpp

#ifndef TAP_HPP_526c07e9e0a11dc15e7838c85f7e46780782392d
#define TAP_HPP_526c07e9e0a11dc15e7838c85f7e46780782392d

#include <string>
#include <iostream>

namespace tap {
    size_t tests__ = 0;
    size_t numof_tested__ = 0;

    void tests(size_t n) {
        tests__ = n;
        std::cout << "1.." << n << std::endl;
    }

    void ok_notok__(bool is_ok, const std::string& name) {
        std::cout << (is_ok ? "ok " : "not ok ") << ++numof_tested__ << " - " << name << std::endl;
    }

    template <typename T, typename U> void is__(const std::string& file, size_t line,
            T got, U expected, const std::string& name = "") {
        if (got != expected) {
            ok_notok__(false, name);
            std::cerr
                << "#   Failed test '" << name << "'\n"
                << "#   at " << file << " line " << line << ".\n"
                << "#          got: '" << got << "'\n"
                << "#     expected: '" << expected << "'" << std::endl;
        } else {
            ok_notok__(true, name);
        }
    }

    template <typename T, typename U> void isnt__(const std::string& file, size_t line,
            T got, U expected, const std::string& name = "") {
        if (got == expected) {
            ok_notok__(false, name);
            std::cerr
                << "#   Failed test '" << name << "'\n"
                << "#   at " << file << " line " << line << ".\n"
                << "#     '" << got << "'\n"
                << "#         ne\n"
                << "#     '" << expected << "'" << std::endl;
        } else {
            ok_notok__(true, name);
        }
    }

    void fail__(const std::string& file, size_t line, const std::string& name) {
        ok_notok__(false, name);
        std::cerr
            << "#   Failed test '" << name << "'\n"
            << "#   at " << file << " line " << line << std::endl;
    }

    void diag__(const std::string& d) {
        std::cerr << "# " << d << std::endl;
    }
}

#define is(g, e, n) tap::is__(__FILE__, __LINE__, (g), (e), (n))
#define isnt(g, e, n) tap::isnt__(__FILE__, __LINE__, (g), (e), (n))
#define fail(n) tap::fail__(__FILE__, __LINE__, (n))
#define diag(d) tap::diag__((d))

#endif

こんな風に使います。

#include "tap.hpp"

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    tap::tests(6);
    is(1, 3, "hoge");
    string hoge = "hoge";
    string geho = "hoge";
    isnt(hoge, geho, "hoge");
    isnt(0, 0, "hoge");
    fail("asdf");
    is(0, 0, "asf");
    diag("asdf");
    return 0;
}
実行すると...。
% g++ -Wall -Wextra test.cpp && ./a.out
1..6
not ok 1 - hoge
#   Failed test 'hoge'
#   at test.cpp line 10.
#          got: '1'
#     expected: '3'
not ok 2 - hoge
#   Failed test 'hoge'
#   at test.cpp line 13.
#     'hoge'
#         ne
#     'hoge'
not ok 3 - hoge
#   Failed test 'hoge'
#   at test.cpp line 14.
#     '0'
#         ne
#     '0'
not ok 4 - asdf
#   Failed test 'asdf'
#   at test.cpp line 15
ok 5 - asf
# asdf

a.t を用意して...。

#!/bin/sh
./a.out
% prove -v ./a.t
./a......
1..6
not ok 1 - hoge
not ok 2 - hoge
not ok 3 - hoge
not ok 4 - asdf
ok 5 - asf
#   Failed test 'hoge'
#   at test.cpp line 10.
#          got: '1'
#     expected: '3'
#   Failed test 'hoge'
#   at test.cpp line 13.
#     'hoge'
#         ne
#     'hoge'
#   Failed test 'hoge'
#   at test.cpp line 14.
#     '0'
#         ne
#     '0'
#   Failed test 'asdf'
#   at test.cpp line 15
# asdf
 Failed 5/6 subtests

Test Summary Report
-------------------
./a.t (Wstat: 0 Tests: 5 Failed: 4)
  Failed tests:  1-4
  Parse errors: Bad plan.  You planned 6 tests but ran 5.
Files=1, Tests=5,  0 wallclock secs ( 0.03 usr +  0.01 sys =  0.04 CPU)
Result: FAIL
[1]    3716 exit 1     prove -v ./a.t

こうなる。

freeHG にあげときました。BSL1.0 です。utils: Manifest

テストに失敗したときの戻り値を...には、まだ対応していません。

GNU/Linux で Expert Mouse を使うメモ
◆F99a.q8oVE: 2008/06/22 21:38:21

EM7 用 /etc/X11/xorg.conf 設定メモ

KENSINGTON 64325 EXPERT MOUSE OPTICALKENSINGTON 64325 EXPERT MOUSE OPTICAL

Section "InputDevice"
    Identifier     "em7"
    Driver         "mouse"
    Option         "CorePointer"
    Option         "Protocol" "auto"
    Option         "Device" "/dev/input/mice"
    Option         "Buttons" "9"
    Option         "Emulate3Buttons" "true"
    Option         "EmulateWheelButton" "8"
    Option         "EmulateWheel" "true"
    Option         "YAxisMapping" "4 5"
    Option         "XAxisMapping" "6 7"
  # Option    "DragLockButtons" "8"
EndSection

これで、右奥のボタンを押しながらボールを転がすことでスクロール可能に。

加えて Firefox の設定を以下にする(about:config で)と、横スクロールもできるようになる。Firerox 3 だと標準でこの設定になってるっぽい。

  • mousewheel.horizscroll.withnokey.action = 0
  • mousewheel.horizscroll.withnokey.numlines = 1
  • mousewheel.horizscroll.withnokey.sysnumlines = true
GNOME Do - Gnome 版 QuickSilver 見たいな奴
◆F99a.q8oVE: 2008/06/01 14:56:17
GNOME Do

タイトルどおり、Gnome 版 QuickSilver 見たいな奴 GNOME Do です。

インストールは↓

% sudo aptitude install gnome-do

起動は

% gnome-do

ショートカットキーで起動するようにするといいですね。自分は、C-\で起動するようにしてしています。

Gnome でも mumbles を使って Growl っぽく twitter のつぶやきを表示してみた
◆F99a.q8oVE: 2008/05/21 20:49:10

Gnome でも Growl っぽく twitter を流し見したいなぁと思っていたところ、mumbles というものをみつけたので Growl のマネをしてみた! という記録です。

ちなみに、Mac は持ってません。

まず、mumbles っていうのは DBus 経由で飛んできた通知を、growl っぽく表示する奴です。 mumbles-project.org » mumbles

これを使うと、Pidgin 側の DBus プラグインを有効にすることによって、IM に流れてきたついったったーのつぶやきを growl っぽく表示することができます。

しかし、標準では twitter から流れてきたつぶやきには Pidgin のアイコンがついて寂しいので、ついったったーのアイコンを表示するパッチを書いてみました。

mumbles pidgin plugin mod

まず、以下から mumbles をダウンロードしてインストールします。 mumbles-project.org » Download

で、パッチをダウンロード。 mumbles_pidgin_twitter.tar.gz

展開したら、pidgin_twitter.patch 内の _twitter_id に twitter の ID と、_twitter_pass に twitter のパスワードを入力してください。パスワードとかは、アイコンの URL をもらってくるときに API を叩くので使います。

あとは、make && make install で OK.

あと、標準のテーマでは文字がアイコンにかぶってしまうので、こんな感じに /usr/share/mumbles/themes/default/config.xml を改造しています。

<mumbles-theme name='default' version='1.0'>
        <width>250</width>
        <height>80</height>
        <spacing>10</spacing>
        <icon>
                <x_pos>10</x_pos>
                <y_pos>30</y_pos>
        </icon>
        <text>
                <title>
                        <font>
                                <family>Sans</family>
                                <color>#fff</color>
                                <size>12</size>
                        </font>
                        <width>250</width>
                        <height>20</height>
                        <padding>
                                <left>15</left>
                                <right>5</right>
                                <upper>8</upper>
                                <lower>2</lower>
                        </padding>
                </title>
                <message>
                        <font>
                                <family>Sans</family>
                                <color>#fff</color>
                                <size>8</size>
                        </font>
                        <width>250</width>
                        <height>60</height>
                        <padding>
                                <left>60</left>
                                <right>5</right>
                                <upper>5</upper>
                                <lower>5</lower>
                        </padding>
                </message>
        </text>
</mumbles-theme>
Skype version 2.0.0.43 Beta for Linux を入れた
◆F99a.q8oVE: 2008/02/17 22:07:15

Skype 2.0.0.43 Beta for Linux が出ていたので入れてみました。

言語で日本語を選べるようになってました。

っと、これだけじゃアレなんで、私が使っている Ubuntu (Gutsy)マシンでのインストール方法の説明でも。

次のリンクから手動でダウンロードしてインストールしてもいいのですが、ここは違う手段でいきましょう。 Download the latest version of Skype for Linux

Ubuntu (Gutsy) でのインストール

Medibuntu - Community Ubuntu Documentation を見ながら、Repository に Medibuntu を加えます。

具体的には、リンク先に書いてあるように以下で OK.

% sudo wget http://www.medibuntu.org/sources.list.d/gutsy.list -O /etc/apt/sources.list.d/medibuntu.list
% wget -q http://packages.medibuntu.org/medibuntu-key.gpg -O- | sudo apt-key add - && sudo apt-get update
実際のインストールは、
% sudo aptitude install skype
でできます。

Skype version 2.0.0.43 Beta for Linux Release note 勝手に日本語訳

ところで、今回のベータ版の変更点なんですが、結構量があります。ちまちま訳してたんですが、力尽きました。 とりあえず、貼っておきます。

LinuxSkype/ReleaseNotes - Skype Developer Zone

6.02.2008, Skype version 2.0.0.43 Beta for Linux

  • feature: ビデオコールで X11オーバレイ出力をサポート(Xv 無しで OK)
  • feature: チャットでハイライト場所への自動スクロール
  • feature: コンタクトカードの通話ボタンをクリックして押しつづける(ボタンを放さずに1秒ほど)と SkypeOut 用メニュー(自宅電話番号宛とか)を表示
  • feature: 電話がかかってきて表示されたポップアップの通話ボタンをクリックして押しつづけると、カンファレンスコールに招待できる
  • feature: コンタクトの追加/検索ボタンを押しつづけると、追加検索のオプションを表示
  • feature: イベント履歴にチャットのトピックをプリロード
  • feature: コンタクトの誕生日通知は、誕生日に表示((今までは規則はわかんないけど誕生日とずれて表示されてた)
  • feature: 日本語、イタリア語、コリアン、Lithuanian, ポルトガル語(ブラジル語), スペイン語、タイ語が使えるように
  • bugfix: API: CHAT CREATE でからのウィンドーを開かないように
  • bugfix: API: CALL コマンドには OK で答えないように
  • bugfix: API: CALL skypenameA, skypenameB で、ちゃんとカンファレンスコールが開始されるように
  • bugfix: ビデオデバイスをすでに存在しないものから変更可能に
  • bugfix: 1対1のチャットでは、コンタクトカードを常に大きめに表示する用に
  • bugfix: すでに表示されているチャットウィンドをさらに開こうとすると、それをアクティブに
  • bugfix: 赤い×印(停止用)をファイル転送が終わったら緑の奴に変更
  • bugfix: チャットでの検索失敗エラーダイアログは、チャットウィンドの真ん中に表示
  • bugfix: チャットメンバーリストではキー入力を無効に
  • bugfix: チャットウィンドーでスクロールバーをクリックしても、インプットエリアからのフォーカスを奪わないように
  • bugfix: ミュート状態をちゃんと表示
  • bugfix: DBUS のチェックボックスが画面外に行ってたのを修正
  • bugfix: カンファレンスコールから、カンファレンスコールを招待できないように
  • bugfix: /leave コマンドでは、いちいち確認ダイアログを出さないように
  • bugfix: ファイルパスのスペースが2重にエスケープされていたのを修正
  • bugfix: 最後のコンタクトカードを閉じても現在のインデックスを残す((?))
  • bugfix: SkypeOut 番号を追加・変更時に前の番号を消さないように((?))
  • bugfix: トピック変更時に、エスケープして送信していたのを修正
  • bugfix: 誕生日通知に年齢は表示しないように
  • bugfix: ホスト以外はカンファレンスコールに新たに人を招待できないように
  • bugfix: 招待ダイアログを<ESC>で閉じるように
  • bugfix: エラーダイアログを<ESC>で閉じるように
  • bugfix: イベント履歴とコンタクトリストを行き来しても、コンタクトリストの表示フィルターをリセットしないように
  • bugfix: ファイル転送をキャンセルしたら、ファイル受信数が更新されてなかったのを修正
  • bugfix: ボイスメールが失敗またはキャンセルされたときは、コール失敗と表示するように
  • bugfix: 保留メッセージとスピーキングインジケーターが重なるのを修正
  • bugfix: [Shift]+[方向キー], [Ctrl]+[方向キー]をメインリストで使ったときの動作を修正
  • bugfix: PSTN 番号の表示名をすごく短いものに変更するとクラッシュしていたのを修正
  • bugfix: カンファレンスコールがかかってきたときにクラッシュしていたのを修正
  • bugfix: SkypeOut ダイアログに短い電話番号を入力するとクラッシュしていたのを修正
  • bugfix: プロファイルビューアを閉じるときに問題があったのを修正
  • bugfix: Fix for a layout drawing bug in transfer window when adding to expanded transfer groups.
  • bugfix: Fix for issues with holding calls and duration continuing
  • bugfix: Fix for listview layout breakage when window is sized at minimum.
  • bugfix: Fix for menus appearing below the mouse cursor on buttons.
  • bugfix: Fix for tooltips disappearing elsewhere in the client during a call with technical call info enabled.
  • bugfix: Fix for topic editing bar remaining open after window switch.
  • bugfix: Fix minimum size being invalid in Invite users to chat dialog.
  • bugfix: Fix mute button and tooltip in fullscreen video widget.
  • bugfix: Fix some memory leaks and crashes related to historical calls.
  • bugfix: Fix stray selection area visible after clearing selection in chat.
  • bugfix: Hide Video button during a conference call.
  • bugfix: If you hangup on a conference call participant whilst sending them a voicemail, they couldn't be invited again.
  • bugfix: Invite user to chat dialog should be centred on the chat.
  • bugfix: Listboxes in Options Dialog should stretch.
  • bugfix: Maintain avatar background colour during a sending-only video call.
  • bugfix: Make Ctrl-Space toggle the selection of the current contact on the contact list.
  • bugfix: Make Ctrl-V work when opening Call Ordinary Phones dialog.
  • bugfix: Make Speaking indicator a bit more reliable during status changes.
  • bugfix: Mouse cursor needs to be updated after moving over a link in chat and using the mouse wheel to scroll.
  • bugfix: Numbers in Skype chats open in user's browser instead of calling in Skype.
  • bugfix: Open file paths in file browser, not Web browser.
  • bugfix: Pasting a new mood message with the middle mouse button wouldn't save.
  • bugfix: Prevent empty new events panel bug to do with Calls/Birthdays.
  • bugfix: Ringing sound may not stop if inviting an incoming call to a conference call fails.
  • bugfix: Remember file transfer window location and size.
  • bugfix: Remove 25fps video send limit due to uvc driver fix.
  • bugfix: Remove over-complicated contact menu call actions.
  • bugfix: Removed 8) B) b) emoticon definitions.
  • bugfix: Scrollbar shouldn't be scrollable when the chat window is empty.
  • bugfix: Search dialog could be resized below valid minimum size.
  • bugfix: Select previous name in Rename Contact when opening dialog.
  • bugfix: Sending an empty message to the API could crash the client.
  • bugfix: Show contact's name instead of ellipses when shortening chat history.
  • bugfix: Show if a 1:1 call is held in the window title.
  • bugfix: Turning Auto-Away/NA option off would not save correctly. (#SCL-308)
  • bugfix: Update chat window when message is delivered/undelivered to correctly redraw layout.
  • bugfix: Update video preview to new device if applying changes in options dialog.
  • bugfix: Wrap words correctly in chat input box.
[C++] template で2進数表記(改)
◆F99a.q8oVE: 2007/10/14 14:38:37

2進数表記がはやってるみたいですね。

そこで、テンプレート版を頭に0付けても大丈夫なようにしてみました。ただ、マクロにするとネームスペースからはみ出ちゃうのがちょっとなぁ。

#include <boost/config.hpp>

namespace util {
template <unsigned char x>
struct binary_number_check {
    typedef binary_number_check<x> self;
    typedef typename self::invalid_binary_number error;
};

template <> struct binary_number_check<0> {};
template <> struct binary_number_check<1> {};

template <unsigned long b>
struct binary_number : binary_number_check<b % 8> {
    BOOST_STATIC_CONSTANT(int, value = (binary_number<b / 8>::value << 1) + (b % 8));
};

template <>
struct binary_number<0> {
    BOOST_STATIC_CONSTANT(int, value = 0);
};

#define B(b) binary_number<0 ## b>::value
}
こんなふうにして使います。
#include <boost/static_assert.hpp>

#include "util/binary.hpp"

int main(void) {
    BOOST_STATIC_ASSERT(util::B(0) == 0);
    BOOST_STATIC_ASSERT(util::B(00) == 0);
    BOOST_STATIC_ASSERT(util::B(1) == 1);
    BOOST_STATIC_ASSERT(util::B(10) == 2);
    BOOST_STATIC_ASSERT(util::B(010) == 2);
    BOOST_STATIC_ASSERT(util::B(00000100) == 4);
    BOOST_STATIC_ASSERT(util::B(00001000) == 8);
    BOOST_STATIC_ASSERT(util::B(00010000) == 16);
    BOOST_STATIC_ASSERT(util::B(00100000) == 32);
    BOOST_STATIC_ASSERT(util::B(01000000) == 64);
    BOOST_STATIC_ASSERT(util::B(10000000) == 128);
    BOOST_STATIC_ASSERT(util::B(11111111) == 255);

    return 0;
}
NAS キット CG-NSC4500GT (HDD Bank TERA) 購入、セットアップ記
◆F99a.q8oVE: 2007/09/09 00:54:28

Note PC 購入を機に、Note PC、メイン PC 共通してアクセスできるストレージが欲しいなぁと思い NAS を購入してしまいました。

どの NAS が良いかと色々悩んでいたところ、デジ埋さんとこ (デジモノに埋もれる日々: ホットスワップに NFS 対応まで - Promise から HDD×4台搭載可能な NAS キット) の記事を見てこれはいいと思い、調べたところ corega が OEM で出してたのでそっちのほうにしました。

「CG-NSC4500GT」製品情報| 株式会社コレガ

詳細は、リンク先をご覧いただくとして、NAS キットだから HDD の組み合わせを自分で選べるところが good. で、早速購入。

セットアップ

CG-NSC4500GT 本体の他に、LAN ケーブルと電源ケーブル、HDD 取付用のレール、そして、PC からセットアップする時用の CD-ROM が付属していました。

画像は携帯電話で撮影したものなんであんまりきれいでないですが、ふた?を開けたところです。 CG-NSC4500GT

ここに取り付けるために、HDD にレールを取り付けます。今回は、HDT725032VLA360 (320G SATA300 7200) を2台用意しました。これで、RAID1を構築しようと思います。 HDT725032VLA360 (320G SATA300 7200) x2

取り付け! CG-NSC4500GT

っと、ここで問題発生。 power cable プラグが...。

変換プラグを買ってきて、電源 on! HDD 認識と同時にピーッと鳴って、起動完了です。 CG-NSC4500GT

Linux マシンから読み書きできるようにする

Windows から扱う方法は省略して、Linux で mount する方法を書いていきます。

まず、CG-NSC4500GT 側の設定で適宜ディレクトリを作成し、NFS サービスを有効にします。mount するマシンの IP アドレスを入力して許可をあたえるところがあるのでそこも設定します。

まぁ、ここで単純にマウントしても良いんですが、いろいろ利点があるので autofs を使ってマウントするようにしてみましょう。

% sudo aptitude install autofs
で autofs をインストールして、/etc/auto.master に以下を追記します。
/mnt    /etc/auto.mnt --timeout=600
CG-NSC4500GT の IP アドレスが192.168.0.3で、MAIN っていうディレクトリを作ってたとして
rhino -fstype=nfs,rw,hard,intr,nosuid,tcp,rsize=32768,wsize=32768 192.168.0.3:/VOLUME1/MAIN
頭から、"マウントポイント オプション IP アドレス:/ボリューム名/ディレクトリ" です。

オプションについては、man mount あたりで調べてください。

なんか、再起動しないといけなかった記憶があるんで再起動すると、/mnt/rhino にアクセスすると自動でマウントされるようになります。

% sudo ln -s /mnt/rhino /rhino

でリンクを貼っとくのが良いかもですね。

corega 4BAY RAID 対応 LAN 接続ハードディスクケース「HDD Bank TERA」(NAS ディスクレスモデル) corega CG-NSC4500GT
corega 4BAY RAID 対応 LAN 接続ハードディスクケース「HDD Bank TERA」(NAS ディスクレスモデル) corega CG-NSC4500GT
メールを効率化! - Open subject を使ってみよう with quicktext on thunderbird
◆F99a.q8oVE: 2007/08/11 00:24:12

このような記事を読みました。 OpenSubject──メールによる会議を可能にする技法 - ITmedia Biz.ID

詳しくは直接読んでもらうとして、この記事では、OpenSubject という、メールの件名にアルファベット 3 文字を付けることで効率化をはかるという提案が紹介されています。

これは、なかなか面白そうな試みです。 ですが、こんなに略語を覚えられそうに無い...ので、Thunderbird の拡張機能 Quicktext :: Thunderbird Add-ons でリストを表示するようにしてみました。 以下に、スクリーンショットを貼ってみます。 Open subject on quicktext "How About This"をクリックで、"HAT: "が件名として設定されました。

テンプレートをアップロードしましたので、よかったら使ってみてください。 http://www.f99aq8ove.net/arts/etc/open_subject.xml あらかじめ、Thunderbird に Quicktext をインストールした状態で、"ツール -> アドオン"から Quicktext の設定を表示し、インポートボタンでインポート出来ると思います。

Powered by ◆F99a.q8oVE.