2011年6月29日水曜日

emacs 23 (その5)

前回に unicode の合字を全部 OFF としましたが。JIS X 0213 には合字を用いないと unicode で表現できない文字が25文字ほどあります。今回はこれについての対応を考えます。

emacs 23.3 のデフォルトでは、これらの文字については JIS X 0213 から unicode(内部コード)への変換は行われていないようです。EUC-JIS-2004 などにより、これらの文字を読み込んだ場合には、unicode に変換されず外字的な扱いでそのまま内部に保管されます。逆に unicode でこれらの文字に相当する文字組み合わせがあった場合も EUC-JIS-2004 に変換することはできずセーブ不能な文字が含まれているとしてエラーにます。

これに対応するために Emacs の日本語環境には jisx0213-to-unicode, unicode-to-jisx0213 という変換テーブルがデフォルトで定義されいます。これを使えばうまくいくはず....

だったのですが....... この変換表 translate-region などでは、きちんと使用できるのですが、なぜか文字コードの translation-table に設定しても正常に動かないという問題があります。バグか仕様の変更に対応できていないか何かだと思われます。

ということで、このテーブルは個人環境で再定義してしまうことにしました。続きのところに書いておきます。

2011年6月27日月曜日

emacs 23 (その4)

次は特殊な文字を無効化します。Unicode には Combining Character といって複数の文字を合わせて合字を作る機能があります。ドイツ語とかで A と ¨(うむらうと)を合わせて Ä (A Umlaut) を作成するとか、もっと複雑なアラビア系の文字やインド系の文字で使用されます。

JIS X 0213 にはこの unicode の合字に対応するダイアクリティカルマーク等が含まれていますが、日本語を扱う時には(ほとんど)不要な機能ですので OFF にしてしまいましょう。以下の設定で全バッファで合字の機能を OFF にできます。
(global-auto-composition-mode 0)
実は他にも特殊な機能を持った2文字があります。
  • JIS第3水準 09区02点 U+00A0 NO BREAK SPACE
  • JIS第3水準 09区09点 U+00AD SOFT HYPHEN
欧文(ISO 8859 や Unicode)ではそれぞれ、「改行禁止の空白」、「行末に来た時だけ可視化されるハイフン」という意味になりますす。Emacs ではこの2文字を特殊な扱いをします。

端末上で使用した場合には半角/全角の問題などで表示が崩れる原因になることもあるので、これらも単なる全角の文字として扱うことにします。
(setq nobreak-char-display nil)
この設定を見つけるのには苦労しました。OFF にする機能はあると思ったのですが、その変数名がわからなくて、思わず c の source から探してしまいました。

2011年6月25日土曜日

emacs 23 (その3)

次は文字幅を設定することにします。emacs は文字ごとに文字幅をコンフィグが可能な設計になっていて、例えば
(aset char-width-table ?♡ 2)
のようにすればハートマーク "♡" の文字幅が 2 に設定できます。ユニコードの番号を使用して以下のよに設定することも可能です。
(aset char-width-table #x2661 2)
この例だと同じく ♡ U+2661 の文字幅が 2 になります。

この方法で一文字づつ詳細に設定していくこもできますが、便利な仕組みが準備されています。例えば
(setq cjk-char-width-table-list
  '((ja_JP nil (japanese-jisx0213.2004-1 (#x2121 . #x2D7E))
               (japanese-jisx0212 (#x2121 . #x2F7E))
               (cp932-2-byte (#x8140 . #x879F)))
    (zh_CN nil (chinese-gb2312 (#x2121 . #x297E)))
    (zh_HK nil (big5-hkscs (#xA140 . #xA3FE) (#xC6A0 . #xC8FE)))
    (zh_TW nil (big5 (#xA140 . #xA3FE))
               (chinese-cns11643-1 (#x2121 . #x427E)))
    (ko_KR nil (korean-ksc5601 (#x2121 . #x2C7E)))
    (CJK   nil (japanese-jisx0213.2004-1 (#x2121 . #x2D7E))
               (japanese-jisx0212 (#x2121 . #x2F7E))
               (cp932-2-byte (#x8140 . #x879F))
               (chinese-gb2312 (#x2121 . #x297E))
               (big5-hkscs (#xA140 . #xA3FE) (#xC6A0 . #xC8FE))
               (big5 (#xA140 . #xA3FE))
               (chinese-cns11643-1 (#x2121 . #x427E))
               (korean-ksc5601 (#x2121 . #x2C7E)))
    (none  nil)))

(use-cjk-char-width-table 'ja_JP)
のような設定で書いておけば JIS X 0213 と JIS X 0212 の全ての文字が全角になります。(JIS X 0213 は JIS X 0208 を包含しているので当然、第一、第二水準も全角になります)。

互換性に気を使った非常に良いやり方ですね。さすがです。一方でユニコード規定での CJK 文字幅を実現するのは面倒なのですが。

この設定で文字コードの範囲指定が全文字(2121〜7E7E)でなく中途半端な数字で終っているのは漢字はデフォルトで全角なので、先頭に非漢字の部分だけを指定してやれば良いからです。数を少なくすることで少しでも起動速度が速くなることを期待しています。(第四水準の指定をしていないのも同じ理由です。第四水準には漢字しかないので)。


これだけで終らないところが悩ましい.... 続く。

2011年6月24日金曜日

emacs 23 (その2)

とりあえず、日本語の文字処理を修正する前に emacs の基本的な設定をしておく。

私は Emacs を端末の中で使用するできるだけシンプルなエディタとして使用したいので余計な機能は極力削っておく。起動メッセージも、メニューも、カラーも、カーソル位置もいらない。

(setq inhibit-startup-echo-area-message "username")
(setq inhibit-startup-screen t)
(setq initial-scratch-message nil)
(setq next-screen-context-lines 3)
(setq line-move-visual nil)
(setq transient-mark-mode nil)
(setq line-number-mode nil)
(setq next-line-add-newlines nil)
(global-font-lock-mode 0)
(menu-bar-mode 0)
(tool-bar-mode 0)
(scroll-bar-mode 0)
(tty-color-clear)

(setq enable-recursive-minibuffers t)
(put 'narrow-to-region 'disabled nil)
(put 'narrow-to-page 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)

(add-hook 'after-change-major-mode-hook
          (lambda () (if (string= major-mode "fundamental-mode")
                         (local-set-key "\t" 'self-insert-command))))

とりあえず、こんなものだろうか。
何か忘れている気がするけど、まあいいか。

2011年6月22日水曜日

emacs 23 (その1)

次は Emacs の話にしよう。

emacs-23 から内部コードが基本的にユニコードになりました。実際にはユニコードと従来の文字集合の両方を内部コードとして持って扱うことができる設計になっているようです。文字の幅も柔軟な設計になっているみたい。

さすが Emacs と言いたいところですが、少しは問題が出ます。その内容と私が取った対策などを順次説明してみようかと思います。

まずは基本通り日本語環境を設定してみる。私はほとんど ssh でログインして端末エミュレータの中で emacs -nw で使用しているので、X のフォントの設定とかは特に気にしなくても大丈夫。UTF-8 を使うとしたら基本はこんな感じかな?

(toggle-enable-multibyte-characters 1)
(set-language-environment "Japanese")
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-file-name-coding-system 'utf-8)
(set-selection-coding-system 'ctext)
(setq sendmail-coding-system 'iso-2022-jp)
JIS X 0213 を使うのならば 'utf-8 の所を 'euc-jis-2004 にすれば良いはず。

結果これだけでも、それなりに使えるのだけど、デフォルトでは文字幅がやっぱり変だな。他にも、いくつか気になる所がある。

ということで続く。

2011年6月20日月曜日

GNU screen JIS X 0213/UTF-8 拡張パッチの内部実装

説明ではくて単な愚痴ですが、パッチが何故がぐちゃぐちゃなのかを書いておきます。

GNU screen は最近は更新はされていないようですが、既に UTF-8 にも ISO-2022/EUC/SJIS にも対応しているので JIS X 0213 に対応させるのも簡単だろうという軽い気持ちで作業を始めたのですが、色々と大変なことに。

2011年6月19日日曜日

screen JIS X 0213/UTF-8拡張パッチの使い方

文字コードに eucjp を指定した場合には EUC-JP, EUC-JISX0213, EUC-JIS-2004 から自動判別されます。

文字コードに sjis を指定した場合には Shift_JIS, Shift_JISX0213, Shift-JIS-2004 から自動判別されます。

文字コードに iso7 を指定すると ISO-2022 7bit 方式で JIS X 0213 が使えます。

もちろん今まで通り文字コード utf8 も使えますが、基本面(BMP)以外の文字も使えるように拡張しています。utfwidth コマンドで文字幅を指定可能してください。

utfwidth normal …… Unicode の基本文字幅。
utfwidth cjk …… Unicode の CJK 文字幅。
utfwidth ja …… 日本語互換文字幅(eucjp や sjis と同じ幅になる)。

おまけで cp932 という文字コードも指定できるようにしました。

GNU screen の文字コード指定

パッチの使い方を説明する前に GNU screen の文字コードについて簡単におさらい。GNU screen では2種類に場所に文字コードを指定できます。

1種類目は screen のウィンドウごとに持っている文字コードです。ウィンドウというのは screen 個々の画面のことで中で動いているシェル/プログラムが使用する文字コードだと思えばわかり易かな。ctrl-a ctrl-c とかで新規に作成して ctrl-a ctrl-n とかで切り換えるやつです。(emacs や shell との相性が悪いので当然キーは ctrl-a から別のものに変えていますが、いちおうデフォルトの ctrl-a で説明)。スクリーンはウィンドウごとに別々の文字コード指定できます。ctrl-a : encoding utf8 とかすればそのウィンドウの文字コードを変更できます。ウィンドウの文字コードのデフォルトは ~/.screenrc に defencoding で指定します。

2種類目は端末文字コードです。これは screen に接続している端末エミュレータ文字コードで、使用しているや xterm の putty とかの文字コードになります。ウィンドウと端末の文字コードが異なる場合には screen は文字コードの変換をしながら入出力を行います。例えば ssh でログインした先のサーバが UTF-8環境で、使用している端末エミュレータが EUC-JP の場合には ctrl-a : encoding utf8 eucjp とすることで、表示は UTF-8 ⇒ EUC-JP 変換され、キー入力は EUC-JP ⇒ UTF-8 変換されます。

ctrl-a : encoding . eucjp とすることで端末側の文字コードだけを変更することもでます(ドットが重要)。デフォルトは screen -x で接続する時に環境変数LANGや termcap等から取得されます。

知っておくと異った文字コード環境で作業する時に便利です。

GNU screen JIS X 0213 /UTF-8 拡張パッチ

GNU screen に JIS X 0213 の対応を追加するパッチです。その絡みで UTF-8 で基本面以外の文字も使えるように拡張しています。ついでに CP932 にも対応してみました。

何というか場当たり的な修正を繰り返してきた結果の、ぐちゃぐちゃパッチなので公開しようかどうか悩んだのですが、ついでなので公開してしまいます。(読んでて気持ちが悪くなっても責任は持てません。)

ダウンロード: screen-4.0.3.ext01.patch.gz

注意: いろいろバグが残っている気がします。ベータ版とかそんな気分で使用してください。

2011年6月18日土曜日

jless utf-8 パッチ 使い方

特に使い方を説明する必要もないかもしれませんが、今まで通り環境変数で

JLESSCHARSET=japanese-euc

として使用すれば、入力が UTF-8 の場合も自動判別して EUC-JP に変換して表示します。同様な感じで

JLESSCHARSET=japanese-utf8

とかすれば入力の日本語文字コードを自動判別して UTF-8 に変換して表示します。
他に環境変数 JLESSUTFWIDTH という機能を追加してユニコードの文字幅を変更できるようにしました。

JLESSUTFWIDTH=normal …… ユニコードの通常文字幅
JLESSUTFWIDTH=cjk …… ユニコードのCJK字幅
JLESSUTFWIDTH=ja …… 日本語の互換文字幅(EUCやSJIと同じ幅)

mlterm や xterm で使用する場合は設定によって normal や cjk を、先の kterm パッチと併用する場合には ja を指定しておくと良いでしょう。
その他の細かい点が気になる人は README.ext.jp を読んでください。

このパッチを作成した理由ですが、UTF-8 とその他の日本語文字コードを同時に使いたい時は PAGER として lv とかを使っている人が多いのかと思います。
私はもう手が less の多機能に慣れてしまっているので、less と jless を状況によって使い分けたりしていたのですが面倒になったのでパッチを作成しました。
あと前に書いユニコードの文字幅問題があって、オリジナルの less は UTF-8 の文字幅として、ユニコードの通常文字幅のみを前提にしていという問題に対応したいといのもありました。