2012/04/14

互い違いに行を並べ換えるelisp


例えば↓(例1)のように日本語(上3行)と中国語(下3行)が並んでいるとします。
1行目の日本語の翻訳が4行目に、
2行目のが5行目に来ます。
全部の行数をn行、任意の日本語の行を第i行とすると、
それに対応する中国語は(n/2) + i 行目に来ます。

(例1)
わたしは田中です。
田中さんは日本人です。
田中さんは会社員です。
我是田中。
田中是日本人。
田中是公司職員。

これをリージョン指定して、実行してやれば、
(例2)のように日本語と中国語が交互に並びます。

(例2)
わたしは田中です。
(我是田中。)
田中さんは日本人です。
(田中是日本人。)
田中さんは会社員です。
(田中是公司職員。)

elispは以下のような感じです。

 1: (defun kougo (beg end)
 2:    "行を交互に並べ換える"
 3:    (interactive "r")
 4:    (let* ((i) 
 5:           (mylist (split-string (buffer-substring beg end) "\n"))
 6:           (half-len (/ (length mylist) 2))) ; リストの要素数の半分をここで計算しておく
 7:      (kill-region beg end);元のリストは消してしまう。
 8:      (loop for i from 0 to (- half-len 1) 
 9:            do (insert (format "%s\n(%s)\n" 
10:                               (nth i mylist)
11:                               (nth (+ i half-len) mylist))))))


今回学んだのは、リージョンで囲んだ部分を文字列(string)として取り出す方法です。
要点は3つあって、

  1. 関数定義の行の引数、(beg end) を記述します。

  2. (interactive "r") と記述します。

  3. (buffer-substring beg end) として文字列として取り出します。

この関数では、(buffer-substring) で取り出した文字列を、
(split-string)でリストに変換し、
そのリストの要素を互い違いに(insert)できるように、
loopを回しています。

今回も長い時間はまってしまったのですが、
まず、リージョンを文字列として取り出す方法を見つけるのに時間がかかりました。
(すみません、低レベルです(^^;)

あと、let ではなくlet*を使用する点。
ローカル変数同士に関連性がある場合、
例えば上のプログラムのように、自分で定義したmylistというローカル変数に基き、
別のhalf-lenというローカル変数を定義するような場合には、
let*を使わなければならないようです。

ところで、私はPerlからelispに乗り換えたのですが、
最初Perlの配列のようなものが見当らなくて、大変困っていました。
ですが、リストと(nth)という関数があればPerlの配列の操作と同じだと気付き、
以後elispが謎でなくなりました。

2012/04/09

現在のJPY/NTDレートをひっぱってきてくれるelisp


台湾のYahoo!のページから為替レートをひっぱってきて、
表示してくれるelispを書きました。
もとのページにはいろいろな銀行の資料が表示されるのですが、
一番安く日本円を売ってくれる台湾銀行のものを表示してくれるようにしました。


(defun jpy-twd-now ()
  (interactive)
  (insert
   (format "\n%s  JPY/TWD (台湾銀行)  %s\n"
           (current-time-string)
           (replace-regexp-in-string
            "^\\(\\(.*\n\\)*\\).+?台灣銀行.+\n.+?>\\(.+?\\)<.+\n.+?>\\(.+?\\)<.+\n\\(\\(.*\n\\)*\\)$" 
            "売:\\3   買:\\4"
            (shell-command-to-string "lynx -source http://tw.money.yahoo.com/currency_foreign2bank/currency/JPY/sort/-buy")))))
(global-set-key "\C-c\C-y" 'jpy-twd-now)


↓こんなふうに表示してくれます。

Mon Apr 9 23:29:04 2012 JPY/TWD (台湾銀行) 売:0.36590 買:0.35520


正規表現でずいぶんハマってしまいました。
もっと高速で動かす方法があればご教授ください!
おねがいします。