文房清玩の最近のブログ記事

今日のお休み,屋根裏部屋,私の自称書斎のお掃除をした。本当は年末にするはずだったが,LaTeX, FreeBSD のインストールに夢中になってしまった。愛用の Mac,書架,オーディオなど,私の道楽で蓄積された品々の埃を払い,煙草のヤニでべとついた表面をアルカリ洗浄液で拭き清めた。

オーディオ機器はいまやアンプ(YAMAHA C-2 プリ,B-6 パワー),アナログ・プレーヤ(Technics SL-01),CD プレーヤ(Pioneer DV-S646A),スピーカ(YAMAHA NS-1 Classic)しか使わなくなってしまった。これらは古いものばかりであるためか,最近再生音の歪みが気になるようになり,そろそろ修理かと思っていた。ケーブルを外し,接点を専用オイルで磨いた。スピーカ・コードの末端を剥いて接触部を新しくした。狭い部屋に無理して押し込んでいるところに,機器の裏側への結線は面倒この上ない。これは CD,これはチューナ,これはレコード ... と行き先をタグしつつ,プリアンプに繋いでゆく。とくに YAMAHA の B-6 パワーアンプはピラミッド型の特殊な形をした優れものなんだけど,ピラミッドの裾のわずかな間隙からスピーカ・コードを食わせるのがなかなかうまくゆかずチョーイライラ。なんとか終わって接続の動作確認をする。

再生音の歪みがキレイに解消した。完全復活。これだから 1 年に 1 回は接点のメンテナンスをしなくちゃいけない。バッハのヴァイオリン LP,ビル・エヴァンスのピアノトリオ CD を聴く。やっぱり YAMAHA・Technics 製の古い再生装置(もう 30 年モノなのだ)は,音に艶があっていいなあ,とひとり悦に入る。
 

3f_audio_1.jpg

普段聞いていない FM/AM チューナ(KENWOOD KT-5020),BS チューナ(SONY SAT-100RX),予備のアンプ(Technics 70A プリ,60A パワー)にも通電した。SONY 製のカセットデッキ(TC-K555ESX)と MD レコーダ(MDS-E55)が壊れていた。機械動作の多い機器は,使っていないといつの間にかこのザマである。まあ,いまはもう必要性も限りなく小さそうなので捨て置くことに。
 

3f_audio_2.jpg

3f_audio_3.jpg

息子が iPod に曲を入れたいので Mac を貸してくれとやってきた。私が中学・高校生のころはオーディオやカメラが欲しくて堪らなかったが,最近の子供はこれらにまったく興味を示さないようである。なによりゲーム機,携帯電話,iPod の最新機種に物欲が働く。音楽は iPod などのポータブルオーディオで楽しむだけで十分なのである。iPod ひとつあれば,あとはとにかく好きなアーティストの CD をレンタルしまくって,金をかけず音楽を楽しんでいる。「使わなくなったアンプをやろうか,Technics 製の昔の高級機だぞ」と言っても,「場所とるからイラネー」とにべもない。「お父さんはスピーカから出てくるよい音響で音楽を聴かないとダメなんだよな」と言っても,まったく理解されない。ま,金をかけずとにかくたくさん新曲を聴きたいという音楽の楽しみ方としては,息子のほうがしごく合理的なんである。オヤジの道楽はつまらないところに執心しているのかも。

FreeBSD インストール大会 5 日目。Emacs 最新版の導入に取り組む。ChangeLog 2010.1.12 の履歴も新しい 23.1.91 である。

Emacs の開発最新版はかつて Emacs-CVS と呼んでいたと思う。だが昨年末,バージョン管理システムが Bazaar に変更され,これに伴いいまやチェックアウトを bzr コマンドで行うようになった。「伽藍からバザールに」という訳か。Download and Install Bazaar から FreeBSD 向けアーカイブ bzr-2.0.3.tar.gz をダウンロードし,展開後のディレクトリで python setup.py install を実行するとインストールできる。Python 2.4 以上が必要である。

Emacs 最新の trunk の取得は以下のとおり。bzr branch に恐ろしく時間が掛かる。CVS のころが偲ばれるほどである。bzr 実行のたびに No handlers could be found for logger "bzr" が出て煩い場合,$HOME/.bzr.log に書き込み権限を付加すれば解消すると思う。

% bzr branch --stacked http://bzr.savannah.gnu.org/r/emacs/trunk emacs-trunk
% cd emacs-trunk
% bzr pull

このあと,Emacs をビルドする。INSTALL ドキュメントによれば,./configure はオプションなしでよいようである。gmake が終了したら,./src/emacs -q & で,できたてのモジュールの動作確認をする。OK なら,スーパユーザで gmake install

% ./configure
% gmake
% ./src/emacs -q &
% sudo gmake install

そのあとは,site-lisp をバックアップからコピーし,Mew だけを再度インストールし直した(Mew は実行ファイルも提供しているため)。今回は,珍しく,なにも問題がなく終了した。

* * *

娘の受験準備で小論文・面接の練習に付き合う。こういうことに対しても,きちんと「準備」をし,父や母を掴まえて練習しようとする態度は,私よりも妻に似たようである。そう,「準備」をしたかどうかが大事なのである。私も会社訪問してくる就活学生の面接官をやったことがあるが,「当社のどこに興味をもったのか」など,聞かれて当たり前のことにも,内容を整理して応えられないヤツがいる。こちらは立派な意見を聞きたいのではなく「あらかじめ準備しているかどうか」をチェックしているだけなのに。

「自分のよいところを PR してください」,「本校を志望する理由はなんですか?」など基本中の基本にはじまり,「2009 年を象徴する漢字はなんだったか知っていますか? また,あなたにとっての 2009 年の漢字はなんですか?」,「2009 年に日本で起こったことでなにがいちばん大きな出来事だと思いますか?」,「地球温暖化のなにが問題だと理解していますか?」など時事問題についても質問。とにかく相手の顔をちゃんと見てハキハキ応えること。「夜なにを着て寝ていますか?」---「そういうご質問にはお応えできません」。そうそう,それでよい。

FreeBSD インストール大会 4 日目,会社にゆく直前に統計処理ソフト R-2.10.1 のビルドを仕込んだ。make config-recursive であらかじめ前提パッケージ含めたオプション設定を行ってから make すると,例外が起こらない限り問い合わせをせず最後まで突っ走る。

R は数値計算ライブラリ ATLAS オプションを付けると,ATLAS のコンパイルが延々と続く。さっき帰宅して確認したら,まだ動いている。生成時間において,Java,Emacs,LaTeX の数段上を行くパッケージである。モジュールが多いということはそれだけ関わる人間の裾野の広大さを示している。コンパイルに,できたてほやほやの gcc/g++ 4.4 や Fortran 95 など,コンパイラ成果の最先端を要求する。じつは Java,LaTeX,テキストエディタなんかよりも科学技術の本質的発展に貢献しているソフトウェアだということが,こういうところでわかるのである(?)。

* * *

いまテレビでは,ハイチの大地震と,民主党小沢幹事長のカネ疑惑でもちきり。

ハイチは国民の 1/3 が壊滅的被害にみまわれたと聞いた。死者は数十万人とのこと。貧困に苦しむ国がさらに天災の追い討ちにさらされるなんて,言葉もない。地理的にも近い米国が空母まで動員して救助・復興支援に乗り出しているのを朝のニュースでみた。

小沢さんの件は,政治主導などと「おこがましい」ことを宣う政治家を,官僚がいよいよ牢屋にブチ込んで,従来の権力を誇示しようと動き出した,ということだと思う。ウラ献金問題に絡んで立件されるとなると,小沢さんはハメられたも同然。産経新聞が大喜びしている。でも,小沢さんはこれを乗り切れば本当に権力を掌握したということになるのかな。日本は官僚権力絶大国家の代表なので,ちょっと不謹慎ながら,ここらでひとつ政治家が官僚を打ち破り,「法に則って」粛正する様をみてみたい,というのが私の正直なところなんである。これで本当に「政治主導」が実現されつつあるのかどうかがわかるからである。でも,マスコミも裁判所も官僚になびくこの国では無理だと思う。

ptexlive を IBM ThinkPad X40 FreeBSD 6.2-RELEASE に組込んだら ttf2tfm などが 7.0 でビルドされていてリンクエラーとなった,ということもあり,2 年ぶりくらいにバージョンアップすることにした。X40 はフロッピーも CD-ROM ドライブも付いてないので,今回も pxeboot でネットワークインストールを行った(最近の FreeBSD には USB メモリ・スティックに boot loader を格納してインストールする手段もある)。まず 7.2-RELEASE を入れたんだけど,インストール後の設定ドキュメントを FreeBSD サイトで調べていたら,なんと 8.0 がリリースされていることがわかり,7.2 から freebsd-update まで実行しなければならなかった。

今回悩んだのは,いつものとおりというか,やはり X11 の設定であった。前回と同様に Xorg -configure で自動生成した config を X -config xorg.conf.new で試験するとエラーで落ちる。この config にはスクリーン定義が 2 セットあって,要するにマルチスクリーンが前提のようなコードになっていた。これをひとつに減らして,再度実行。ところが真っ黒な画面が出てマウスを動かしてもウンともスンとも反応しない。6.2 のときは Intel i810 ビデオチップ用のドライバを使っていたが,どうも Xorg の新しい版では intel ドライバに統合されてなくなっていた。これが原因と考え,なんとかうまく動かす方法を Google で探しまくったが,まるで見当たらない。ええ?,こんなメジャーなビデオチップが動かないなんてノート PC じゃ使えないも同然じゃねえかと,FreeBSD の暢気モードが少し頭に来たところであった。

新しい Xorg 7.4 を FreeBSD 7 以降で動かすには,/etc/rc.conf

dbus_enable="YES"
hald_enable="YES"

を書いておくというのは,調べがついていた(moused_enable="YES" 行があれば,これをコメントアウトしておくこと)。これを追加してリブートしてもブラック画面が出る。試しに,X -config xorg.conf.new ではなく,config なしでいきなり startx を入れたら,なんとすんなり動いて twm のあの飾り気のないターミナルがふたつ現われた。つまり・・・ブラックアウトしているように見えた画面は,ひとつも X クライアントを起動していない X11 の地に過ぎないという訳だったのである。それなら真っ暗な画面にしないで少しは色気を出せよ!とまあ怒りが頂点に達したところで,このブラックユーモアに充ちた不親切さこそ UNIX だと改めて合点がゆき,その後はひとり笑い転げる始末であった。

改めて FreeBSD Handbook を読むとちゃんと書いてある。きちんとドキュメントを読むこと。少なくとも ISO 8859-1 英語版(日本語版はメンテナンスがまったく追い付いておらず,FreeBSD 最新版に関しては記述が信用できない)の FreeBSD Handbook/usr/ports/UPDATING には必ず目を通すこと。

Starting with Xorg 7.4 and above, this test produces a black screen which may make it difficult to diagnose whether X11 is working properly. The older behavior is still available by using the retro option:
  # Xorg -config xorg.conf.new -retro

いま,井原西鶴の『好色五人女』を読みながら,愛用のアプリをしこしこ導入しているところである。面倒な Java と Emacs は夜中に実行・放置を目論む。なんか年末・年初は LaTeX,FreeBSD と大物のインストール大会になってしまった。大いなる時間の無駄だけど,どうせまた 2 年はこの版と付き合うのだろうから,しようがない。

[※ 1/13 付記]

その後,hald が CPU を占有してしまうという問題が発覚し,hal-0.5.13_12 にバージョンアップすることでこれが解消された。しかし,このため,ports-current への入換え,依存関係パッケージの更新にえらい時間がかかってしまった。FreeBSD をインストーラで導入した直後に,FreeBSD の ftp サイトから最新 ports をダウンロードして,入換えておくことを強くお勧めする。この場合,インストール・パッケージの少ない時点で portupgrade -a -r を実行しておく。その後に愛用のアプリをインストールしよう。

もうひとつ注意事項。hald,dbus 環境では,CapsLock と Ctrl キーを入換えるなどの定義は,従来のように xorg.confXkbOptions 設定や xmodmap では効かなくなった。/usr/local/etc/hal/fdi/policy/ 下に xxxxx.fdi (xxxxxx は任意) というファイルに,以下のような XML を書いておかないといけない。

<?xml version="1.0" encoding="ISO-8859-1"?>
<deviceinfo version="0.2">
  <device>
    <match key="info.capabilities" contains="input.keyboard">
      <merge key="input.x11_options.XkbOptions" type="string">ctrl:swapcaps</merge>
    </match>
  </device>
</deviceinfo>

これは私の X40 英語キーボードの場合である。106/109 日本語キーボードの場合は <merge key="input.x11_options.XkbModel" type="string">jp106</merge> も,XkbOptions 設定行とともに必要である。

大晦日の晩は寒さが厳しかった。今日の元日,なんとものどかな一日だった。

夜中に ptetex3-20090610, upTeX-0.28 のインストールを試みたが,ぼろぼろエラーが出て,あきらめて寝た。今日,落ち着いて ptetex3-20090610 下にある LOG ファイルをチェックして問題対処を試みた。xdvik のコンパイル・リンクにおいて FT_xxx の関数参照のエラーで落ちていて,その後トチ狂ったようである。すでに Mac OS X にある Freetype2 ライブラリの版と不整合を起こしているようだったので,freetype-2.3.5 にバージョン・アップし,再試行したらうまく通った。make test の縦書き試験で FT_OpenType_Validate is disabled なるワーニングが出てエラー停止するが,最終成果物は dvipdfmx による PDF でよいので,これは放置。LaTeX のような大規模のシステムの初期インストールは一筋縄ではいかない。

/usr/local/teTeX/ 下をごっそり再インストールするつもりで臨んだので,ghostscript も入れ直し。いままで 8.54 を使っていたのだが,日本語の取り扱いの点から 7.07 に版を落とすことにした。山田泰司さんという方が公開なさっている "Welcome to ~taiji at gyve" サイトから Mac OS ヒラギノ,中国語 OpenType フォントを使うためのパッチを適用し,gs-7.07 で縦組でもヒラギノの高品質フォントを利用できるようになった。山田さんに感謝。

ホコリまみれだった再生装置 YAMAHA のアンプ C-2x, B-2x, Technics SL-01 アナログ・プレーヤ,DENON DCD-1650AR CD プレーヤも大掃除でピカピカにした。のどかな元日にお気に入りのレコードを二枚聴く。

一枚はモーツァルトのディヴェルティメント K.563,ウィーン弦楽三重奏団による独 CALIG 盤 CD。この名曲は名手ソリストが集った名盤が数あるけれど,私はこの Wiener Streichtrio の演奏がイチオシなんである。彼らはモーツァルト以外にも,ベートーヴェン,シェーンベルク,ウェーベルン,クルシェネクの弦楽三重奏曲の端正な録音を残している。ウィーンの演奏家は由緒ある一方で古くさいイメージが先行するけれども,アルバン・ベルク四重奏団のような現代音楽にも優れた室内楽演奏家が突然変異的に登場する。現在は廃盤になってしまったのが惜しい。

いま一枚は韓国のヴァイオリニスト・チョン・キョンファのヴァイオリン独奏,アンドレ・プレヴィン指揮ロンドン交響楽団の演奏によるプロコフィエフのヴァイオリン協奏曲第一番,第二番。昔,キングから出ていたロンドン・レーベルの LP である。第一番は,早春の胎動の悦びとほのかな頽廃が感じられるモダニズムの傑作である。私はこれを聴くと,雪解けの泥が瑞々しい札幌を思い出す。いまも CD で入手できると思う。
 

2009_ganjitu_records.jpg

あけましておめでとうございます。

30, 31 日と大掃除をやり,重いものを何度も動かして,体のふしぶしが痛い。今年は,子供たちが受験なので帰省はせず,家で寝正月。年末恒例の紅白歌合戦を家族皆で観る。ゆく年くる年あたりから年越し蕎麦を食う。子供たちが CDTV(カウントダウン TV: 人気アーティストたちが出演するミュージック番組)にわいわい騒いでいる横で,TeX Q and A に書き込んだり,一大決心で LaTeX システムのバージョンアップに挑む。

ptexlive を入れようかと思ったが,パス情報がいままでとまったく変わり,upLaTeX との共存が面倒臭そうだったので,やっぱり ptetex3 + upLaTeX にした。今回,あらゆるパッケージを最新版にしようとして,/usr/local/teTeX 配下をばっさり消してクリーンインストールしようとしたが,うまくいかない。upTeX のスクリプトでそれなりのところまでいくはずだと思ったが,コマンドが見つからないとのエラーがぼろぼろ出てまったくダメである。いま,ptetex3 だけをまずは組込んで,upLaTeX パッチはそのあとにするのでどうか実行中。

PTA 会報の LaTeX 文書作成において A4 2 ページを 2 UP で A3 見開きの版面に結合する必要があり,これまで Adobe Acrobat 7.0 で 2 UP 印刷を行うことで対処していた。この場合,A4 文書の余白を適度に切り落とさないと Acrobat が自動で余白を取るため,もとの文書が若干縮小される問題があり,事前に余白調整を手作業で実施していた。

今日,久しぶりに TeX Q & A を見ていたら,pdfpages パッケージの話題が出ていて,その存在を思い出した。このスタイルファイルによって,上記の面倒な調整なしに一発で A3 結合ができるようになった。

pdfpages.sty は外部 PDF ファイルを LaTeX 文書に挿入する命令を提供する。ただし,pLaTeX2e では動作せず,pdfLaTeX での利用が前提なので少々残念ではある。しかし,今回,pLaTeX2e から生成した PDF を再配置・結合するだけの目的であるので,この制約で困ることはまったくなかった。このパッケージの主要な用途は n UP か面付けであって,他の日本語 LaTeX ユーザもおそらく困らないはずである。

A4 縦 2 ページ(portrait)文書 a4.pdf を A3 横 1 ページ(landscape)に合成し,次のページに A3 横 1 ページの別文書 a3.pdf を同じ版面で結合する例を示す。

pdfpages 処理イメージ: tgif + Illustrator にて作成
A4 縦 2p と A3 横 1p を A3 横 2p に合成する
% pdfpage.sty サンプル(pdflatex で処理すること)
\documentclass{article}
\usepackage[paper=a3paper,landscape=true]{geometry}%
%\usepackage[draft]{pdfpages}% 確認用
\usepackage[final]{pdfpages}% 本番用
\begin{document}
% A4 2 頁を A3 見開き 1 枚にマージ
\includepdf[nup=2x1,pages={1-2}]{a4.pdf}%
% A3 はそのまま次の頁にマージ
\includepdf{a3.pdf}%
\end{document}

\usepackage[オプション]{pdfpages} をプリアンブルに記述する。オプションで draft を指定すると,挿入する PDF のページ枠だけを出力する。確認用である。デフォルトは final(PDF そのものを挿入する)である。\includepdf 命令が外部 PDF ファイル挿入のコントロール・シーケンスである。a4.pdf ファイルを指定する行は,横 2 x 縦 1 の 2 UP でレイアウトする指示(nup オプション)である。pages オプションをきちんと指定しないと 1 ページ目しか処理されない。

例では geometry.sty も読込むように指定している。これは,pdfLaTeX の article.cls ドキュメントクラスには A3 用紙の版面が定義されておらず,A3 出力が独力では難しく,geometry パッケージの機能を使うことにしたからである(pLaTeX2e・奥村先生の jsarticle.cls は a3paper をサポートしている)。

pdfpages パッケージはこのほかに,ページ縮小や,レイアウトマージン調整,版面の回転など様々な機能を備えている。詳細はパッケージのマニュアルを参照されたい。

うちは娘の中学校の PTA の役員をやらさせられている。文化祭をテーマとした PTA 会報を出すというので,妻がその作成を担当し,私がパソコンで文書データを作るということになった。これまでの会報文書データに雛形はなく,好き勝手に作ってよいとのことだったので,LaTeX で制作することにした。

私にとって,LaTeX 文書作成はもちろん趣味の領域でもあり,ロシア語,パッケージドキュメントの組版以外は,まじめに実用文書を組んだ試しが数えるほどしかない。そもそも LaTeX というソフトウェアは科学技術論文,一般書籍の組版に最適化されており,いわゆる DTP 要素の強い会報には向かない,とわかっていた。それでも LaTeX が好きなので,敢えて LaTeX で挑戦。multicolumn でスッキリしたレイアウト設計を基本とした。掲載写真とそれに付加するコメントとを整列させる命令や,未入手原稿のエリアを指定文字数分確保する命令など,いくつかマクロを書いた。外部からの要請で文書を作るとなると,これまであまり注力しなかったグラフィックス関係の組方で悩むことが多く,インターネットの情報を探索しつつ解決し,結構勉強になった。

過去の会報は A3 用紙の表にページ 1 と 4,裏にぶち抜きのページ 2 と 3 を配置する和綴イメージだった。これを中折にすると 1 枚だけの右綴小冊子となる訳だ。今回の版面設計も,これに合わせることにした。A3 横 2 ページ(見開きで 4 ページ)のファイルを作るのに,まず A4 縦の 2 ページ,A3 横の 1 ページ(見開き 2 ページ)を個別に LaTeX で組版し,PDF を生成した。Adobe Acrobat 7.0 を用いて,A4 縦 PDF の余白編集をしたあと A3 横見開きに合成した(2 UP 印刷)。A4 縦見開き合成 PDF と A3 横 PDF を,A3 横 2 ページ(見開きで合計 4 ページ)の PDF 1 ファイルに纏めて成果物とした。dvipdfmx による個別 PDF ファイルの合成には,pdftk ユーティリティを用いた。Acrobat 7.0 にも PDF 合成機能があるが,これだと文字の欠落が出てしまったので使わなかった(この原因が dvipdfmx にあるのか Adobe Acrobat にあるのかは不明)。

画像に文字をオーバーレイさせる方法を知ったのは今回の収穫。簡単にそのメモをここでしるしておく。

写真にコメントなどを上書きしてレイアウトしたいとき,Microsoft Word ではテキストボックスを画像の上に作成してテキストを入力し,枠と塗りつぶしを消去すればこれができる。LaTeX の場合は overpic パッケージにより実現可能である。teTeX ならはじめからインストールされているようである。

overpic.sty は graphicx パッケージを前提とする。プリアンブルには,次のように指定しておく。

\usepackage[dvips]{graphicx}% dvipdfmx なら dvipdfm オプション
\usepackage[abs]{overpic}

overpic 環境のなかで,ベースとなる画像ファイルを指定し,それに重ね打ちする文字を \put 命令でレイアウトする,というのが使い方の基本である。\put 命令にテキストを位置づける座標を指定する。その値の調整がやっかいではあるが,overpic 環境のオプションに grid を指定すれば,位置グリッドが確認できるので,これをもとに,\put(x 座標, y 座標) を決める。y 座標は文字ボックスのベースラインをポイントすることに注意。

簡単な例として,楽譜を背景にした合唱発表会の曲目一覧を作ってみた。背景画像は,デジカメで撮影した楽譜(バッハ・無伴奏パルティータ 2 番)の写真を Adobe Photoshop, Illustrator で加工し,EPS 形式で保存したものである。テキストの着色には color.sty を使用した。グリッド付と,それを外した本来の組版成果を示す。

overpic_test.jpg

原稿は以下のとおり。\put 命令で重ねる文字列は,複数の段落をなす場合を想定し,\parbox 命令に入れている。

% -*- coding: utf-8; -*-
% 合唱発表会曲目一覧(overpic.sty の試験)
%                      (c) 2009, Isao YASUDA, All Rights Reserved.
\documentclass[b5paper]{jsarticle}
\usepackage[dvips]{graphicx,color}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[abs]{overpic}
\pagestyle{empty}
\definecolor{blue}{cmyk}{0.94,0.54,0,0}% NavyBlue
\def\baselinestretch{0.8}%
\begin{document}
\parindent=0pt\relax%
\begin{minipage}[t]{80mm}
  \begin{overpic}[width=80mm]{musicnote.eps}% 画像指定。試験時 grid を指定
    \put(35,245){% 文字テキストの座標を指定
    \parbox[t]{6cm}{% 重ね打ちする内容
    \parindent=0pt\relax%
    \hspace{5zw}{\gtfamily 合唱発表会曲目}\\[1.1zw]
    \small\bfseries\color{blue}%
    \makebox[9zw][l]{1学年\quad 夢の世界を}\\
    \makebox[9zw][l]{\qquad 1--1\quad 夜汽車}\\
    \makebox[9zw][l]{\qquad 1--2\quad この地球のどこかで}\\
    \makebox[9zw][l]{\qquad 1--3\quad Let's search for tomorrow}\\[.5zw]
    \makebox[9zw][l]{2学年\quad COSMOS}\\
    \makebox[9zw][l]{\qquad 2--1\quad 明日に渡れ}\\
    \makebox[9zw][l]{\qquad 2--2\quad 遠い日の歌}\\
    \makebox[9zw][l]{\qquad 2--3\quad 時の旅人}\\
    \makebox[9zw][l]{\qquad 2--4\quad 予感}\\[.5zw]
    \makebox[9zw][l]{3学年\quad 信じる}\\
    \makebox[9zw][l]{\qquad 3--1\quad 君とみた海}\\
    \makebox[9zw][l]{\qquad 3--2\quad IN TERRA PAX}\\
    \makebox[9zw][l]{\qquad 3--3\quad 虹}\\[.5zw]
    \makebox[9zw][l]{昼休み合唱団}\\
    \makebox[9zw][l]{\qquad 青いベンチ}\\
    \makebox[9zw][l]{\qquad 瑠璃色の地球}\\
    \makebox[9zw][l]{\qquad 手紙}\\[.5zw]
    \makebox[9zw][l]{PTA\,\&\,職員}\\
    \makebox[9zw][l]{\qquad 君をのせて}%
    }}%
  \end{overpic}
\end{minipage}
\end{document}

今回 LaTeX で作成した文書は,おおむね妻の眼に適うものになった。とはいえ,LaTeX で文書を作ると,和文の斜体がないなどの事情について,ワープロのマナーに慣れた人から「え,どうして?」テキな不満をぶつけられることがある。和文には斜体という組方の伝統がないからと説明しても,どうも納得してもらえない。まあよい。LaTeX の版面の素晴らしさに惚れ込んでしまうと,吹出しやら,和文の斜体強調やら,波形下線やら,倍角文字やら,ボックス枠線やらが下品な装飾に見えて来るから不思議である。

Mew 6.2.52 on Emacs-23 を使いはじめて,ロシア語メールの Subject が全角キリル文字(さざなみ日本語フォントにあるキリル文字)で表示されることに気づいた。メール本文は問題ない。外国語はそれ用のフォントでないと醜いし,幅広だと情報量も落ちてしまう。Mew-dist や Mule-ja メーリングリストに問い合わせたところ,次のようなことが判明した。

Mew の Summary(メール一覧表示)では,多言語対応のため,CTEXT(X11 Compound Text)コーディングシステムを採用している。一方,Emacs はバッファを CTEXT で符号化する際に,エスケープシーケンスに包む個別の文字コードを優先順位を付けて選択する。日本語環境では,標準は japanese-jisx0208 が優先される。このため,バッファのキリル文字は,国際標準 ISO 8859-5 キリルではなく,JIS で定義されたキリル文字コードにエンコードされる。この結果,Summary の表示は JIS コード用の日本語フォントが使われた。

つまり対策は,その文字コードの優先順位を,ISO 8859-5 が japanese-jisx0208 よりも高くなるように指示してやればよいということになる。そのための関数 set-charset-priority がある,とメーリングリストで教えていただいた。Emacs の info で set-charset-priority 関数仕様を調べて,優先度設定コードを .emacs に追加したら,DejaVu フォント・半角のキリル文字で Summary 表示できるようになった。ギリシア語も同じ構造に嵌るので,greek-iso8859-7 も追加しておいた。また,キリル文字は width が 2 のため Subject エリアの空白数が文字数分不足することで,Summary のレイアウトがいびつになってしまう。width を 1 に設定し,キリル文字数と width を合わせるコードも入れた。これらの .emacs 対策コードは以下のとおり。

;; iso-8859-5 優先
(set-charset-priority
 'cyrillic-iso8859-5
 'greek-iso8859-7
 'mule-unicode-0100-24ff
 'japanese-jisx0208
)
;; キリル・ギリシア文字の width を 1 に
;; (Mew Summary レイアウト不正対策。Unicode-cyrillic は不要)
;;; iso-8859-5 キリル文字
(map-charset-chars
 (lambda
   (range ignore)
   (set-char-table-range char-width-table range 1))
 'cyrillic-iso8859-5)
;;; iso-8859-7 ギリシア文字
(map-charset-chars
 (lambda
   (range ignore)
   (set-char-table-range char-width-table range 1))
 'greek-iso8859-7)

前に書いた記事「Emacs 22.0.50 の Ctext」で CTEXT のエスケープシーケンスが変わってしまったことに触れた。この要因について今回わかったという収穫もある。上記の設定により,エスケープシーケンス X"1b2d4c" + ISO 8859-5 文字コードでキリル文字を CTEXT 符号化することができるようになった。

※ 2009/09/05
漢字フォントキリル文字が Unicode フォントに変更されたスナップショットを以下に示す。

mew-ctext-problem.jpg

外国語で文書を作成する際,なくてはならないのがスペルチェッカである。私は FreeBSD において,GNU Emacs 上で ispell + ロシア語辞書を昔から愛用してきた。Emacs は,比較的容易な設定変更で多言語スペルチェックもできるという意味で,秀丸,サクラ,WZ など日本で圧倒的に支持されている和製テキストエディタが太刀打ちできないくらい強力である。これこそ世界中の人々によって鍛えられている強みである。UNIX 文化の典型である Emacs は,ドキュメントをよく読まないと使いこなすのは難しい。しかし,外国語テキスト抜きでは計算機生活ができないユーザーにとって Emacs は,苦労も多いが得られることも多大なソフトウェアなのである。

最近,Unicode でテキストファイルを作成することが一般的になりつつある。Emacs 上で用いるスペルチェッカについても,UTF-8 テキストを取り扱うことのできる GNU Aspell を Emacs 付属の lisp プログラム ispell.el からドライブする形態で,スペルチェックを行う方式が主流のようである。

一般に日本語サイトでは,Emacs スペルチェッカ環境の整備方法について英語に関するリソースばかりで,ロシア語のような ASCII 範囲外の文字を使用する言語に関する活用情報を見かけることが極端に少ない。あったとしても,設定内容に踏み込んだ説明がまったくなく,応用の効かないものが多い。

そこで本稿では,もう少し言語を増やして環境構築を行う方法をしるす。UTF-8 エンコーディングで文書を作成しつつ,ロシア語,英語,フランス語,ドイツ語を切替えて利用できるようにするための導入記録である。先日,Mac OS X Tiger での Emacs-CVS 23.1.50 のインストールメモを書き,GNU Aspell のロシア語環境についても合わせて触れた。本稿の記述はこれと一部重複するところがある。

圧倒的シェアを誇る Windows 環境で説明する。Windows で動作する GNU Emacs である Meadow 開発最新版 3.01-dev から,Aspell-0.60 を使う前提である。私の試したのは Windows XP SP3 である。Windows Vista でもほぼ同じオペレーションで導入できるものと考える。露・英・独・仏語で Aspell を使えるようにすれば,第二外国語として多くのひとが選択する外国語をカバーする訳で,私のような「特殊辺境言語」ロシア語を学ぶ者のみならず,いろんな方の役に立つと考える。英語は標準であるとしても,その他の辞書とその設定は必要なものを選択すればよいように説明するつもりである。

Meadow で Aspell を使うには Cygwin 環境でインストールしたモジュールを使うのがよい。Aspell には Win32 ネイティブで動作する版も存在するが,辞書の追加のし易さから,ここでは Cygwin 版(Cygwin 用というのではなく,単に Cygwin 環境で make された Aspell パッケージと理解してほしい)を前提とする。Cygwin とは簡単にいえば Windows で動作する UNIX 疑似環境である。

以下の説明では Meadow のコマンド操作は Emacs の伝統的表記を用いている。C-x は Ctrl + x キー,M-x は Alt + x キー(Esc のあとに x キー押下でもよい),RET はリターンキーを示している。

  1. Cygwin の導入

    以下の Aspell 利用環境の構築の前に,Cygwin パッケージをインストールしておく。セットアップ・プログラム setup.exe をダウンロード・実行し,指示に従って行けば,簡単にインストールできる。 Cygwin インストーラはパッケージ選択メニューから同時にインストールするソフトウェアを選択できる。このとき,Aspell(0.60.5-1)GNU Make(3.81-2)Wget にチェックを付けてインストールしておく。その他,GNU C/C++ コンパイラ(gcc4-core 4.3.2,gcc4-g++ 4.3.2)も入れておきたい。本稿では Cygwin を C:\cygwin にインストールしたものと仮定して説明をする。別の場所にした場合は読み換えること。

    Cygwin のインストールが終了したら,ユーザーのホームディレクトリを決めて,そのフォルダ・パスを環境変数 HOME に登録しておく(「システム」→「詳細設定」タブ→「環境変数(N)」)。ここでの説明は C:\home をホームディレクトリと仮定して説明する。Cygwin シェルでは $HOME~/ でホームディレクトリのパス参照が可能である。

  2. Meadow-3.01-dev の導入

    Meadow-3.01-dev についても,日本語 Netinstall: setup-ja.exe を入手して,インストールしておく。インタフェースは Cygwin とほぼ同じで,操作はしごく簡単である。同様に,Emacs 外部パッケージを選択インストールができる。apel(10.7-1)mule-fonts 多言語 BDF フォント(1.0-4)を必ず選択して導入しておく。

    ここでは Meadow は C:\meadow 以下にインストールされたものと仮定する。また Meadow の初期設定ファイル .emacs$HOME ディレクトリに格納されたものとする。

    Emacs 外部パッケージ一覧において ispell パッケージを選択する必要はない。もし選択する場合は,ispell パッケージの auto-autoloads.el と,本稿の .emacs 設定とが競合する問題があるため,前者をロードしないような操作を施す必要がある(後述)。

    Emacs 外部パッケージをあまりに欲張って選択・インストールすると,各パッケージの自動設定プログラム auto-autoloads.el が相互に競合を起こして,.emacs 初期設定処理中にエラーが発生し,うまく動かなかったりすることがある。このため,まずは必要最小限のパッケージで所期の目的を確認しつつ安定動作させたのち,追加して行くことをお勧めする。もし,初期処理中にエラーが発生したら,*Messages* バッファに出力されたメッセージを確認し,エラーの原因となったパッケージ auto-autoloads.el の存在するフォルダ(C:\meadow\packages\pkginfo の下にある)を別の場所に移動させると,問題を回避できることがある。このようにしたとしても,.emacs 設定をしかるべく記述すればパッケージを利用することができる。

  3. Meadow 言語環境の設定

    本稿での Aspell 設定は Unicode 環境を想定したものである。Meadow の言語環境も Unicode に最適化された設定にしておくこととする。以下の内容を .emacs に追加する。

    (set-language-environment "Japanese")
    (set-default-coding-systems 'utf-8-dos)
    (set-buffer-file-coding-system 'utf-8-dos)
    (set-selection-coding-system 'utf-16le-dos)
    (prefer-coding-system 'utf-8)
    

    set-selection-coding-system 関数の設定は IE 等の他の Windows アプリケーションとの間でテキストをコピー・ペースト(Emacs 用語でいえば,キル・ヤンク)するために必要である(UTF-16 Little Endian を指定している)。この記述がないと,ASCII 以外のあらゆる文字列のコピー・ペーストが文字化けを来す。こんな設定はデフォルトにすべきもののように思われるが,現在の開発版 Meadow 3.01-dev では明示的に記述する必要がある。

    その他,Meadow-3 の多言語環境一般の設定(BDF フォント,インプットメソッド等)については,弊サイト記事『Windows Meadow 3.00』を参考にしてほしい。

  4. 辞書のダウンロード・解凍

    GNU Aspell ホームページ http://aspell.net/ にある辞書アーカイブへのリンクから,以下の辞書アーカイブをダウンロードする。

    ダウンロードしたら,Cygwin シェルの ~/tmp(Windows パスは C:\home\tmp)下に解凍しておく。tar.bz2 アーカイブを処理できるアーカイバ(lhaplus 等)が必要である。Cygwin シェルでダウンロード,解凍するなら,次のようにすればよい。ロシア語辞書の例であるが,これを英,仏,独についても繰返し行う。

    $ mkdir -p ~/tmp
    $ cd ~/tmp
    $ wget -nH -nd \
    ftp://ftp.gnu.org/gnu/aspell/dict/ru/aspell6-ru-0.99f7-1.tar.bz2
    $ tar jxvf aspell6-ru-0.99f7-1.tar.bz2
    
  5. 辞書の組込み

    Aspell 辞書のインストールは Cygwin のシェルで実施する。以下のロシア語辞書のオペレーションを英・仏・独語用辞書についても同様に行う。いずれも,各言語用辞書の解凍ディレクトリにおいて,./configure,make,make install を順次実行するだけである。

    $ cd ~/tmp/aspell6-ru-0.99f7-1/
    $ ./configure
    $ make
    $ make install
    
  6. ispell auto-autoloads.el の移動

    Meadow Netinstall で ispell パッケージを選択してインストールすると,ispell 用の自動設定 elisp: auto-autoloads.elC:\meadow\packages\pkginfo\ispell フォルダ下に組込まれ,Meadow が起動するたびに自動的にロードされる。この auto-autoloads.el は,本稿の Aspell 用 .emacs 設定(後述)を反古にしてしまう。このため,ispell 設定用の auto-autoloads.el がロードされないよう,pkginfo フォルダから ispell フォルダを別の場所に移動させておく

  7. Aspell 用 .emacs の調整

    Aspell スペルチェックの設定 elisp を 初期設定ファイル .emacs に追加する。すなわち,以下のテキストをコピーして,.emacs にペーストすればよい。ただし,このテキストには,露・独・仏語の文字が含まれるため,ペーストして格納する前に,必ず C-x RET f utf-8 RET としてバッファ・コーディングシステムを UTF-8 に設定しておく。.emacs に エンコーディング指示を書き込んでいる場合は,これも utf-8 に書き換えておく。.emacs を修正・格納したら,Meadow を再起動すれば,定義が有効になる。

    ;;
    ;;  Aspell -- spell-checking UTF-8 text -- .emacs に追加する elisp
    ;;    based on "Настройка проверки правописания Ispell" by KOSTAFEY
    ;;    (see http://kostafey.blogspot.com/2009/07/emacs-aspell.html)
    ;;
    ;;  注意: .emacs を UTF-8 エンコーディングとすること。 
    ;;  - C-x RET f utf-8 RET で .emacs バッファを UTF-8 にする。
    ;;  - .emacs 先頭に -*- mode: emacs-lisp; coding: utf-8; -*- を記述しておく。
    ;;
    (require 'flyspell)
    (require 'ispell)
    (setq
     ispell-program-name "c:/cygwin/bin/aspell.exe" ;; ユーザー環境に依存
     ispell-dictionary-alist 
     '(
       ;;【ispell-dictionary-alist 指定パラメータ概略】
       ;; 1. Dictionary name: 辞書名
       ;; 2. Case characters (regex): 対象文字セット(正規表現)
       ;; 3. Non case characters (regex): 非対象文字セット(正規表現)
       ;; 4. Other characters (regex): 単語構成特殊文字(正規表現)
       ;; 5. Many other characters (bool): 単語構成特殊文字複合有無(t or nil)
       ;; 6. ispell Arg (list): Aspell コマンド引数リスト("A" "B" "C") → "aspell A B C"
       ;; 7. Extended character mode (const ~tex, ~nroff, etc. or nil): チェックモード
       ;; 8. Coding System: コーディングシステム
       ("English"                       ; English
        "[a-zA-Z]" 
        "[^a-zA-Z]" 
        "[']" nil ("-d" "en") nil iso-8859-1)
       ("Russian"                       ; Russian
        "[АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя]"
        "[^АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя]"
        "[-]" nil ("-d" "ru-yeyo") nil utf-8)
       ("German"                        ; German
        "[a-zA-ZäöüÄÖÜß]"
        "[^a-zA-ZäöüÄÖÜß]"
        "[']" t ("-d" "de_DE") nil utf-8)
       ("French"                        ; French
        "[a-zA-ZçàâéèêëîïôûüÇÀÂÉÈÊËÎÏÔÛÜ]"
        "[^a-zA-ZçàâéèêëîïôûüÇÀÂÉÈÊËÎÏÔÛÜ]"
        "[']" t ("-d" "fr_FR") nil utf-8)
       (nil                             ; Default
        "[A-Za-z]"
        "[^A-Za-z]"
        "[']" nil ("-C") nil iso-8859-1)
       )
     ;; ロシア語を標準とする
     flyspell-default-dictionary "Russian"
     ispell-dictionary "Russian"
     ispell-local-dictionary "Russian"
     ;; Aspell に渡す付加オプション: 高速モード,UTF-8 インタフェース
     ;; see Aspell Manual: http://aspell.net/man-html/index.html
     ispell-extra-args '("--sug-mode=ultra" "--encoding=UTF-8")
    )
     
    ;;; 不正単語ハイライト表示フェース(デフォルト)
    (setq ispell-highlight-face 'flyspell-incorrect)
    ;;; Text-mode で flyspell を自動起動
    (add-hook 'text-mode-hook 'flyspell-mode)
    ;;; check 前のウェイト秒数
    (setq flyspell-delay 1)
     
    ;;; 各国語用切替関数の定義
    ;;; Russian, English, French, German in ispell-dictionary-alist
    ;;;; Flyspel
    ;;;; ロシア語
    (defun flyspell-russian ()
      (interactive)
      (flyspell-mode t)
      (ispell-change-dictionary "Russian")
      (flyspell-buffer)
      (message "Russian dictionary - Spell Checking completed."))
     
    ;;;; 英語
    (defun flyspell-english ()
      (interactive)
      (flyspell-mode t)
      (ispell-change-dictionary "English")
      (flyspell-buffer)
      (message "English dictionary - Spell Checking completed."))
     
    ;;;; 仏語
    (defun flyspell-french ()
      (interactive)
      (flyspell-mode t)
      (ispell-change-dictionary "French")
      (flyspell-buffer)
      (message "French dictionary - Spell Checking completed."))
     
    ;;;; 独語
    (defun flyspell-german ()
      (interactive)
      (flyspell-mode t)
      (ispell-change-dictionary "German")
      (flyspell-buffer)
      (message "German dictionary - Spell Checking completed."))
     
    ;;;; Ispell-buffer
    ;;;; ロシア語
    (defun ispell-russian ()
     "Russian aspell for UTF-8"
     (interactive)
     (ispell-change-dictionary "Russian")
     (ispell-buffer))
     
    ;;;; 英語
    (defun ispell-english ()
     "English aspell for UTF-8"
     (interactive)
     (ispell-change-dictionary "English")
     (ispell-buffer))
     
    ;;;; 仏語
    (defun ispell-french ()
     "French aspell for UTF-8"
     (interactive)
     (ispell-change-dictionary "French")
     (ispell-buffer))
     
    ;;;; 独語
    (defun ispell-german ()
     "German aspell for UTF-8"
     (interactive)
     (ispell-change-dictionary "German")
     (ispell-buffer))
     
    ;; ファンクションキー
    (global-set-key [(control f1)] 'ispell-word)
    (global-set-key [(control f2)] 'ispell-region)
    (global-set-key [(control f3)] 'ispell-buffer)
    

    Cygwin,Aspell を本稿の前提パス C:\cygwin 配下とは違う場所にインストールしている場合,ispell-program-name のパス指定を修正しなければならない。上記 elisp が目的とする機能は以下のとおりである。

    • Aspell 露・英・仏・独辞書名をそれぞれ,RussianEnglishFrenchGerman として定義する。先頭は大文字にしてある。
    • スペルチェック対象の各国語エンコーディングを UTF-8 とする。
    • Text mode で flyspell-mode を自動的に起動する(text-mode-hook)。flyspell はカーソル位置の単語に,もしくは単語入力のつど,誤りがあれば,赤く強調表示をする(正確には,オレンジレッド,ボールド,下線付き。これは flyspell-incorrect フェースに定義されている)。辞書に適合している単語は通常の表示である。ここで Text mode とは,通常の .txt プレーンテキストのみならず HTML, LaTeX などをも対象としたテキスト形式編集モード(html-mode,LaTeX-mode 等)のことを指している。
    • 標準辞書はロシア語としている。他の言語辞書に切替えるには,M-x ispell-change-dictionary RET French(切替えたい辞書名) RET とする。以下の flyspell-言語名 もしくは ispell-言語名 のユーザー関数を使うと,その過程で辞書が切替わる。
    • M-x flyspell-russian RET によって露語辞書に切替え flyspell チェックを行う。
    • M-x flyspell-english RET によって英語辞書に切替え flyspell チェックを行う。
    • M-x flyspell-french RET によって仏語辞書に切替え flyspell チェックを行う。
    • M-x flyspell-german RET によって独語辞書に切替え flyspell チェックを行う。
    • M-x ispell-russian RET によって露語辞書に切替え ispell-buffer チェックを行う。
    • M-x ispell-english RET によって英語辞書に切替え ispell-buffer チェックを行う。
    • M-x ispell-french RET によって仏語辞書に切替え ispell-buffer チェックを行う。
    • M-x ispell-german RET によって独語辞書に切替え ispell-buffer チェックを行う。
    • C-f1 によって,現在選択されている辞書で ispell-word を実行する。ispell-word 関数はカーソル位置の単語をチェックし,誤りがあれば別バッファに候補を表示する。
    • C-f2 によって,現在選択されている辞書で ispell-region を実行する。ispell-region 関数はテキスト・リージョン(選択範囲テキスト)に対してスペルチェックを実行し,ミススペルの語を強調表示するとともに別バッファに訂正候補を表示し,ユーザー応答を促す処理を繰り返す。
    • C-f3 によって,現在選択されている辞書で ispell-buffer を実行する。ispell-buffer 関数は編集バッファ全体に対してチェックを行う。

    各国語辞書はそれぞれの言語の方言・正書法に応じて複数用意されている。それは Aspell コマンド引数リスト,例えば,ロシア語辞書定義の ("-d" "ru-yeyo") のうちの "ru-yeyo" の部分に指定することができる。-d は Aspell の辞書を指定する引数であり,それに引き続いて辞書名を指定する訳である。このロシア語用定義で指定されている ru-yeyo は,е(イェ)と ё(イョ)のいずれの表記にも対応できる辞書である。つまり твердый でも,твёрдый でもチェックできる指定である。仮に,ru-ye を指定すると,твёрдый が綴り誤りとしてチェックアウトされる。この方法で指定できる辞書のオプションは,各国語辞書パッケージに添付されている README に説明がある。必ずこれを読んで,ユーザー自身の目的に応じた辞書を("-d" "辞書名") に指定してほしい。

    デフォルト選択辞書をロシア語にしている。別の言語を設定したいのならば,上記 elisp 中の変数 flyspell-default-dictionaryispell-dictionaryispell-local-dictionary の各オペランドを "Russian" ではなく "German" 等の辞書名に書き換えればよい。

    この Aspell 用 elisp 設定は,Windows Meadow のみならず,FreeBSD,Linux,Mac OS X の Emacs でも有効である。もちろん,ispell-program-name のパス指定を使用環境に応じて書き換える必要がある。

  8. 非アクティブ・モード行表示不正対策

    Meadow 標準設定では,非アクティブのモード行(バッファの下にあるステータス表示行)のキリル文字が文字化け(いわゆる「豆腐」)で表示されてしまう。これは Meadow において modeline-inactive 属性のフェース・フォントが,キリル文字を含まないデフォルト・フォントに設定されているためである。この対策として set-face-font 関数によって modeline-inactive 属性に用いるフォントセットを mule-fonts16 に再設定すればよい。M-x set-face-font RET modeline-inactive RET mule-fonts16 RET を実行するとよい。いちいちこれを入力するのが面倒であれば,mule-fonts パッケージ C:\meadow\packages\pkginfo\mule-fonts\auto-autoloads.el を Meadow で開いて,最後尾に以下を追加して格納し,Meadow を再起動すればよい。対策前後を図 1 に示す。

    (set-face-font 'modeline-inactive "mule-fonts16")
    

    なお,この定義は .emacs に記述できない。フォントセット mule-fonts16 は .emacs よりあとで読込まれる mule-fonts\auto-autoloads.el で定義されているからである。

    m-04-modline-zengo.jpg

    図 1. 非アクティブ・モード行キリル文字問題対策


Meadow 3.01-dev における GNU Aspell 露・英・仏・独辞書環境設定は以上のとおりである。図 2 に,ispell-buffer によってロシア語テキストをスペルチェックするスクリーンショットを示す。

m-08-ru-buffer.jpg

図 2. ispell-buffer ロシア語スペルチェック

今回,露・英・仏・独四カ国語を切替える設定を示したけれども,ユーザーにとって不要な言語を削る設定はそれほど難しくないと思う。C-f1 などのショートハンドについても,global-set-key 関数によって,好みのキーに割り当ててもらいたい。

ここで対象にしなかった言語についても,Aspell でサポートされている言語ならば,辞書追加を同じように実施し,上記 elisp の ispell-dictionary-alist に辞書エントリを追加すればよい。エントリの 8 つのパラメータについて上記 elisp 中にもコメントとして概略仕様を簡単にしるしておいたので参考にしてほしい。また,標準 ispell 辞書用の定義が ispell.el にあるので,これを参考に Aspell 用を定義してもよい。詳しくは開発者によるマニュアルを参照のこと(M-x describe-variable RET ispell-dictionary-alist RET から参照できる)。

複数の言語が混在した文書のスペルチェックは当然ながら辞書を切替えながら実施することになる。仏語辞書が選択されているとき独語テキスト部分で誤りと判断される単語が大量に出てしまうのは致し方ない(図 3. フランス語辞書選択時と,図 4. ドイツ語辞書選択時の画面を比較せよ)。ロシア語辞書の場合は,ispell-dictionary-alist 定義によって,キリル文字のみが対象文字セットに指定されているため,ASCII 文字からなる単語には反応しない。

m-10-flys-fr.jpg

図 3. フランス語辞書使用時

m-11-flys-de.jpg

図 4. ドイツ語辞書使用時

FreeBSD にも Emacs-CVS をインストールした。Emacs 22 の Mew 5.1 draft-mode(メールを書くときのモード)でメールを書いているときに flyspell がうまく動作しないので,どうしたものか悩んだためである。FreeBSD でもバージョンアップしてみることにした。Mew も 6.2 が公開されていた。ふたつともいっしょにバージョンアップした。Mew の X-mailer から Emacs 23 において Mule バージョンも「賢木」から「花散里」になったことを知った。日本人による Emacs コントリビューションの最大の成果である Mule は,『源氏物語』の巻名でバージョンを表現する習わしである。

これで,Mew の draft-mode でも flyspell が動作するようになった。ところが,今度は Wnn7 のかな漢字変換において「候補が 1 つも作れませんでした」とミニバッファに出て,漢字変換ができない。なんじゃこりゃー! もうサイテー! オレはインスコ・ヲタクじゃねーのに,余計なことさせんなー! 調べたところ,Wnn7 elisp: wnn7egg は Emacs 23 ではそもそもうまく動かないらしい。

捨てる神あれば拾う神あり。この問題でパッチが公開されていることをここで知った。最新の Emacs 23.1.50.2 でもこのパッチが有効かどうか少し疑問であったが,ダメ元で試してみた。wnn7-elisp-el-1.02-1.patch.gz をダウンロード。オムロンのサイトにある wnn7egg v1.02 ソースアーカイブをダウンロード・展開したものに対して,このパッチを適用する。オペレーションは以下のとおり。

% cd ~/tmp
% wget -nH -nd \
http://www.omronsoft.co.jp/SP/pcunix/wnn7/support/modules/wnn7egg/wnn7-elisp-el-1.02-1.tgz
% tar zxvf wnn7-elisp-el-1.02-1.tgz
% cd wnn7egg
% wget -nH -nd ftp://ftp.jpl.org/pub/elisp/wnn7-elisp-el-1.02-1.patch.gz
% gunzip wnn7-elisp-el-1.02-1.patch.gz
% patch < wnn7-elisp-el-1.02-1.patch
% su -m
# mv /usr/local/share/emacs/site-lisp/wnn7egg ~/tmp/wnn7egg.bak
# cp -R wnn7/elisp/emacs20 /usr/local/share/emacs/site-lisp/wnn7egg
# exit

これで,かな漢字変換ができるようになった。M-x egg-use-input-predict による Wnn7 入力予測機能への切替えも OK であった。

※ 09.8.28 付記
Mew のバージョンについて,Emacs-23 では Mew-6.2.52 以降を使う。Mew 作者は 6.2.52 で Emacs-23 対応のバグを fix したという。たしかに,Mew-6.2 では draft-mode でのテキスト入力が異常に遅く使い物にならなかったが,6.2.52 で改善されていた。

今日,自宅の Windows XP に JIS X 0213:2004(所謂 JIS 2004)対応のMS明朝,MSゴシックのフォント,さらにメイリオ・フォントを導入した。ずいぶん前に,JIS X 0213 について書いたとき,なによりもこの規格でなされた 168 字の字体変更をこき下ろした。けれども,Utf82TeX CJK 統合漢字拡張 B 対応を行ったこともあり,「標準」に追随して行かざるをえないなあという気持ちが強くなったのである。たとえ愚かな君主の決めた愚かな法律・標準であっても,発効すれば文句を言いながらも従うしかありません。「標準」とはそのようなものである。

IE 7 で葛原妙子の「葛」は,もと 葛 だったのが 葛正字体 になった。これはこれで正しい。

しかし,考えれば考えるほど,この JIS 2004 の字体変更の理屈が理解できない。この変更は,国語審議会の答申「表外漢字字体表」に示されている「印刷標準字体」に合わせたものである。それはそれで立派な理由かも知れないが,いまさら国語審議会の尻馬に乗ってどうする,という疑問も否めないのである。この表外漢字字体で「印刷標準字体」として認定された文字は新聞等の出現度数調査に基づいているとのことである。でも,文字の構成要素を度外視した原理・原則(一貫性)がいまひとつよくわからないのである。でもって JIS 2004 字体変更の「必然性」がどうも納得できないのだ。

「疼」は 疼疼正字体 に変えたのに,「冬」はなぜ 冬 のままで 冬正字体 にしないのか。「辻」について,辻 さんは結構いるのに 辻正字体 が標準というのは常識的に解せない。「辻」,「逢」を二点しんにょうにするなら,「道」,「遠」なども正字体にしたらどうかね。などなど。

「冬」,「道」,「遠」はこれが「印刷標準字体」ということなので変更しない訳である。でも,上例のとおり一貫性に欠ける。確かに,「標準」に一貫性が必要であるという訳ではない。だとしても,いままでの文字形を否定する(「変更」は過去の否定なのである)ほどの必然性があるとはとても思われない。

通常,ものごとの取り決めというものは,いったん決定されると,それ自体に不良(目的とする仕様に適合しない事象)が見いだされない限り,なかなか「変更」されないものである。新しい要請に対しては,「追加・拡張」がなされるのが通例だろう。JIS もこれらの変更後の字体を「追加」すればよかったのではないだろうか。なぜなら,「変更」は過去の規範に則っていた者が自らの資産も「変更」を強いられる一方,「追加・拡張」ならば己の事情によってそれを無視できるからである。

この JIS の愚かな自己否定のおかげで企業・官公庁・自治体のシステムは,本当は別のサービス向上の機能追加をしなければならないのに,文字の取り扱いについて「本当に」余計な改修を強いられているのである。この不況のなか全国津々浦々で進行中のこういう「塵も積もれば山となる」調達は,誰からも税金のムダ遣いと言われないのが面白い。しかも、このシステム改造は,JIS 2004 の恩恵を活かすというのではなく,JIS 2004 文字(文字コードなんかになんの頓着もないユーザは Windows Vista の新 IME で知らず知らず入力してしまうのである)がシステムに入って来ないようにブロックするものが大半である。笑ってしまう。JIS が足を引っ張っているのは明らかなのだ。「どうする? 企業情報システムの『JIS X 0213:2004』対応:ITpro」などを参照のこと。

JIS の字体変更は JIS 2004 にはじまった訳ではなく,JIS 83 においてすでに前例がある。どうも JIS は自己否定が好きなようである。これを見ていると,戦後間もないころの国語・国字改革の自己否定(現代仮名遣い,漢字制限)を連想させ,ほんと,日本国の標準策定というものの懲りない性格に呆れてしまうのである(私は現代仮名遣いを否定している訳ではありません)。そのうち,4 年くらいしたら,JIS はまた面白い改訂をしてくれるだろう。こんなことをしていたら,Unicode コンソーシアムが独自に CJK 漢字標準を整備し,日本国の JIS 標準が置いて行かれる --- これがいちばん起こりそうなことだと思う。

自己否定 --- これは,地震ですべてが崩壊し,すべてを一から作り直そうとしてしまう,地震国のお国柄なのだろうか。

私は個人的には文書作成を LaTeX で行う。LaTeX では,JIS X 0208(所謂 JIS 第一・第二水準)で足りない文字を Adobe_Japan1 コードに準拠して出力する方式が,広く浸透している。JIS 2004 の字体変更も Adobe_Japan1 の CID コードのおかげで cmap をちょちょいと変えて対応できる。JIS などの多様な意見を取りまとめなければならないお役所仕事よりも,Adobe という企業が印刷現場の要請に基づき一貫したポリシー(商業印刷の現場でほしいと思う文字を「追加」して行くポリシーだと思う)で作り上げた「標準」のほうが,よっぽど有用だと思う次第である。

※ 以上のとおり,さんざんぱら,JIS 2004 を批判しているのだけど,そうはいっても JIS の活動全般に懐疑を示すものではもちろんない。JIS はわが国のインダストリアル・スタンダードを決める責任ある機関である。上記のような問題は,その功績に比べると誠に微々たる話である。JIS で活動している研究者,企業人はわが国の斯界の権威であり,真に尊敬に値する人達である。私の軽口を大目に見てください。

* * *

上記字体変更の例で使用した文字の画像は LaTeX で出力した文字を,dvips, Ghostscript で png に変換したものである。コマンドラインから文字画像を生成するシェルスクリプトを書いた。以下に掲載しておくので,同じような課題がある場合にお使いください。OTF パッケージが必要。

#!/bin/sh
# tex2image: convert LaTeX command to image file
# コマンドラインの LaTeX 命令を画像(png, eps)出力する。
#                         coded by isao yasuda, July 27 2009.
 
if [ $# -lt 3 ]; then
    echo "usage: `basename $0` -e|-p out-file-base 'LaTeX fragment'"
    exit 1
fi
 
case $1 in
    # アウトライン EPS
    -e) CONV="gs -dNOPAUSE -dBATCH -dSAFER -sDEVICE=epswrite \
              -r9600 -sOutputFile=$2.eps $2-wk.eps"
        echo "Outlined EPS file genetation to $2.eps"
        break;;
    # PNG 
    -p) CONV="gs -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pngalpha \
              -dEPSCrop -r72 -dTextAlphaBits=4 -dGraphicsAlphaBits=4 \
              -sOutputFile=$2.png $2-wk.eps"
        echo "PNG file genetation to $2.png"
        break;;
    # それ以外はエラー
     *) echo "$1 unknown option."
        exit 1;;
esac
 
echo "% 文字画像生成テンプレート
\documentclass[12pt]{jsarticle}
\usepackage[dvips]{graphicx,color}
\usepackage[multi,deluxe,expert]{otf}
\pagestyle{empty}
\begin{document}
\parindent=0pt
$3% こいつを LaTeX 処理
\end{document}" > $2.tex
 
# pLaTeX UTF-8 処理
platex --kanji=utf8 $2.tex
if [ $? -ne 0 ]; then
    echo "LaTeX error $2.tex."
    exit 1
fi
 
# dvips でまず普通の EPS にする
dvips -E -D 9600 $2.dvi -o $2-wk.eps
if [ $? -ne 0 ]; then
    echo "dvips error $2.dvi."
    exit 1
fi
 
# 画像変換
$CONV
 
# 後始末
rm -f $2-wk.eps $2.dvi $2.log $2.aux $2.tex
echo "done."

これを例えば tex2image というファイル名で,パスの通ったことろに UTF-8 エンコードで格納し,実行属性を付与する(chmod +x tex2image)。

tex2image -p ファイルベース名 'LaTeXコマンド'

とすると,LaTeXコマンド を処理した文字列が ファイルベース名.png という名の png 画像で生成される。LaTeXコマンド に前後のアポストロフィを付加しないと,特殊文字,空白文字を記述できないので注意。

png 画像はアルファ・チャンネルをもつ透過画像なので,背景色に追従可能である。文字そのものを着色したければ,LaTeX コマンドに "\textcolor{色名}{文字}" を指定すればよい。オプションを -e とすると文字のアウトラインを取った EPS 画像で出力する。ベクトル画像なので,Illustrator などで拡大編集してもギザギザで汚れはしないはずである。独自に必要な LaTeX スタイルがあれば,テンプレートに \usepackage 命令などを追加してほしい。dvips,Ghostscript がアウトラインフォントを拾える環境でないと動作しない(要するに,PK ビットマップフォントが混入しているとエラーになる)ので注意。

「葛」の JIS 2004 字体の画像: 葛正字体 の出力は,次のとおりとした。

tex2image -p 1kuzu '\LARGE\CID{7652}'

とあるロシア通の方と LaTeX や Meadow についてメールをやりとりする機会があった。その方は Windows Meadow 3 を使っておられるのだが,ロシア語を編集する際,24 ドットフォントが利用できないとのことであった。

私は普段 X11 でしか Emacs を使わず,BDF フォントの設定で 14, 16, 24 の各サイズで多言語表示できるようにしている。また,24 ドットフォントだと Emacs の画面サイズが巨大になり,かなりの高解像度でモニターを使用していないと煩い。16 ドットフォントが使えれば十分だと私は思っていた。そういう事情で,私には彼の悩みがいまひとつ解らなかった。私の Windows Meadow 環境で確認したところ,Meadow 3.00 の BDF フォントパッケージ mule-fonts では,たしかに 16 ドット表示しかできない設定になっていた。Meadow のフォント設定は UNIX X11 Emacs とはまったく違う。

mule-fonts パッケージ添付の elisp,BDF フォントのリストを確認し,これに足りない BDF ファイルを補い,elisp コードを追加することにより,24 ドットでも編集できるようにしてみた。件の方に差し上げたところ,24 ドットの大きい文字が使えるようになったとよろこんでくれた。同じ問題で困っている方もあるかと思い,せっかくなので,ここにもそのメモをしるしておく。Meadow Netintall インストーラでもって,mule-fonts パッケージがすでに組込まれていることが前提である。

  1. mule-fonts は intlfonts, /efont/, cdacfonts などのさまざまな多言語 BDF フォントを纏めた便利なパッケージである。しかし,/efont/ Unicode 24 ドットフォントを添付していない。まず,24 ドットフォントを追加するため,efont-unicode-bdf-0.4.2.tar.bz2 をダウンロードし,適当なフォルダで解凍する。.tar.bz2(tar のアーカイブを bzip2 で圧縮したもの)を取り扱うことの出来る Windows 用アーカイバ(lhaplus 等)が必要である。
  2. 数ある /efont/ フォントから,b24*.bdf(b24.bdf, b24_b.bdf, b24_i.bdf, b24_bi.bdf)4 ファイル%MEADOW%\packages\fonts\efonts フォルダの下にコピーする。%MEADOW% は Meadow をインストールしたフォルダ名に読み替える。
  3. mule-fonts には初期設定 elisp: auto-autoloads.el が添付されている。Meadow を起動すると自動的にこれが読込まれて,"mule-fonts16" という名のフォントセットが設定される仕組みになっている。これに 24 ドット用のフォントセット "intlefonts-24" を追加した私の版 auto-autoloads.el を用意した。これをダウンロードし,%MEADOW%\packages\pkginfo\mule-fonts\auto-autoloads.el に上書きコピーする。その際,必ずオリジナル auto-autoloads.el のバックアップを取得しておいてほしい。
  4. Meadow を再起動すれば,「Shift + 左クリック」で Font Menue に "intlefonts-24" が追加されているはずである。これを選択すると 24 ドットフォントで編集ができるようになる。/efont/ b24*.bdf は Unicode のラージフォントであり,ロシア語のみならず,古スラヴ語・教会スラヴ語,古典ギリシア語,ヴェトナム語,CJK 統合漢字等々を含んでいる。
  5. いつも 24 ドットを使いたい訳でなく,必要になった時点で設定したい場合は,次のようにすることもできる。intl_efonts_24.el を適当な場所において,M-x load-file RTN 適当な場所/intl_efonts_24.el RTN とすれば,同様に "intlefonts-24" フォントセットが追加される。ただし,この elisp は auto-autoloads.el がすでに読込まれていることが必要なので,.emacs に記述できない(auto-autoloads.el は .emacs のあとで処理されるため)ことに注意してほしい。

Lemmatizer ライブラリのソースコードの解析のために GNU Global を使っている。このツールは,ソースコードの関数や変数がどこで定義されているか,どのファイルで利用されているかを縦横に渡り歩いてブラウズする手段を提供する。grep で必死こいて探すのに比べるとその利便性は天と地ほどの差がある。C, C++, Yacc, Java と PHP4 のプログラミング言語をサポートしている。

Global はコマンドラインのみならず,GNU Emacs,Vim のほか,HTML 変換機能により,ブラウザによってハイパーリンクでソースコード探索できるインタフェースをサポートしている。今日は,FreeBSD で GNU Global 5.7.1 をインストールし,HTML ベースで利用する方法をメモしておく。

FreeBSD には Global の ports が用意されており,導入は簡単である。"cd /usr/ports/devel/global && make install clean" 一発でインストールできる。

ここでは AOT の Source 配下にある .c, .cpp と .h を抽出し,Global で処理する例を説明する。

  1. まずはソースコードの抽出。もともとの AOT ソースの場所を $RML/Source,Global のデータを作成するディレクトリを ~/src/aot とする。
  2. % cd $RML/Source
    % find . -name "*.c" -or -name "*.cpp" -or -name "*.h" > list
    % tar cf - `cat list` | ( cd ~/src/aot ; tar xvf - )
    

  3. gtags コマンドを発行してタグ・データベースを作成する。GPATH, GRTAGS, GSYMS, GTAGS の 4 ファイルが生成される。
  4. % cd ~/src/aot
    % gtags -v
    

  5. htags コマンドで HTML データを作成する。

    • ここでは,検索用の CGI プログラムを http://web-server-host/cgi-bin/global.cgi で,ブラウザからアクセスできるようにしよう。http://web-server-host/ は Web サーバのドキュメントルート URI の例である。実際の URI で読み替える必要がある。同様に,以下のコマンドラインで指定している cgi-bin,HTML 出力のディレクトリについても,運用で決めた場所で読み替えていただきたい。

    • 以下の指定オプションは -a: アルファベット・インデックス,-f: 検索フォーム,-n: 行番号表示,-F: フレーム表示,-I: アイコンリンク使用,-s: シンボルにもアンカー付与,-x: XHTML,-T: ファイルリストを <table> タグ付,-t: タイトルである。

    • オプションに --suggest を指定すると,初心者用のお勧めとして開発者が設定したオプション・セットが選択される。これも十分満足できるものと思う。ただし,5.7 未満の古いバージョンではサポートされていないようである。

    • HTML を生成したら,gtags で作成したタグ・データベースをそのディレクトリ直下にコピーしておく。CGI 検索用である。
  6. % cd ~/src/aot
    % su -m
    # mkdir -p /usr/local/www/apache22/data/aot
    # htags -afnFIsxT -S /usr/local/www/apache22/cgi-bin \
      -t 'AOT Source Tour' /usr/local/www/apache22/data/aot
    # cp G[P-T]* /usr/local/www/apache22/data/aot
    

  7. 生成された HTML データは,運用都合で別ディレクトリに移動すると,gtags で作成したデータベースを参照できず検索 CGI が動作しなくなるので注意しよう。もし Web サーバを外部公開している場合は,.htaccess の認証機能などで閲覧制限を設ける,検索エンジンからの収集を抑止するよう robots.txt に Global データ・ディレクトリを登録する,などセキュリティ上の工夫をしておくことをお勧めする(これは割愛)。

これで,ブラウザから "http://web-server-host/aot/HTML/" にアクセスすると,ソースコード探索ができるはずである。index.html は main 関数を有するプログラムの一覧,アルファベット索引,ソースコードのディレクトリを提示する。ここから,目的とするコードを探索する。

スナップショットを以下に示す。ソースコード中の関数やデータ構造にリンクが設定され渡り歩くことができ,検索ボックスにキーワードを入力して必要な部分を探すことができる。

gloal_ss.jpg

自作のコンコーダンス・ソフトウェアを Lemmatizer C++ クラスライブラリによって見出語でも解析できるようにしようとしている。Lemmatizer についてはふたつのバージョンについて,すでにここで書いた。AOT で公開されている版(「ロシア語形態素解析 lemmatizer」参照)と,lemmtizer.org で公開されている版(「Lemmatizer UTF-8 対応ライブラリ」参照)である。

AOT 版は解析できるロシア語テキストのエンコーディングが Windows CP1251 のみであるのに対し,lemmatizer.org 版はさらに UTF-8 をサポートしている。私は UTF-8 が扱えるということで後者を自作プログラムで使おうと検討していた。しかし,いまひとつ仕様のドキュメントがきちんとしていない。辞書のソースコードを丹念に読むと,なんとなくわかって来るけれども,どうしても不明点が残る。サイト管理者に問い合わせても,なしのつぶてである。その点,AOT 版はロシア語の文法構造について品詞,性・数・格,活動体・不活動体,時制などの解析結果出力仕様が明確である。

さらに AOT 版は,形態素解析ツール Lemmatizer のほか,統辞解析ツール Synan,語彙素抽出ツール Graphan(要するに Tokenizer)をも提供していて,私の知る限り,ロシア語自然言語解析のための最強のツールセットともいえるのである。私のコンコーダンス・ソフトの設計に関しても,UTF-8 でテキストを受入れて,見出語を Lemmatizer から取得するときに iconv ライブラリによって CP1251 にコード変換し,再び UTF-8 に戻せばよい,と考えるようになった。

これらについて調べるうち,じつはコンコーダンス生成ツール DDC(DWDS/Dialing Concordance)をも AOT が提供していることがわかった。ロシア語,英語,ドイツ語(ISO-8859-1)のコンコーダンス解析が可能である。そこで,これらすべてのツール(ここでは 「AOT ツール」と総称する)を FreeBSD にインストールして使ってみた。Linux ならおそらく苦もなく組込みができるのだろうが,BSD ユーザにとってはじつに面倒なので,私の失敗を踏まえたインストール・メモをしるしておく。コマンドラインは tcsh シェルである。

  1. AOT ツールのコンパイルには以下のソフトが必要である。バージョンが古かったり,インストールされていなければ追加導入しておく。最新の FreeBSD なら PCRE 以外ははじめから整備されているはずなので,ここでの説明は割愛する。PCRE については「ロシア語形態素解析 lemmatizer」を参照。( )内に私の試験環境をしるしておく。
  2. - gcc C/C++ コンパイラ 3.2 以上(4.2.1)
    - PCRE C/C++ 正規表現ライブラリ 6.4 以上(7.7 with UTF-8 options)
    - bison 構文解析器 1.875 以上(2.3)
    - flex 字句解析器 2.5.4 以上(2.5.4)
    - gmake GNU Make(3.81)

  3. 以下のアーカイブを AOT скачать 頁からダウンロードする。DDC についてのみ SorceForge から取得する。面倒だが,すべてダウンロードする。DDC を 1.74-1 と 1.80 の 2 版取得するのは,後者にはコンパイル用シェルスクリプトが添付されておらず,直近の古い版のそれを利用するためである(これについては,アーカイブになんの説明もなく,配布がちょっと杜撰ではないかと思う)。そして以下の順に同じディレクトリにおいて解凍する(いろいろややこしい)。ここではインストール・ディレクトリを /usr/local/lib/RML として説明する。
  4. - concord-1.74-1.tar.gz DDC-1.74-1
    - concord-1.80.tar.gz DDC-1.80
    - lemmatizer.tar.gz Lemmatizer
    - rus-src-morph.tar.gz 形態素解析辞書(露)
    - ger-src-morph.tar.gz 形態素解析辞書(独)
    - eng-src-morph.tar.gz 形態素解析辞書(英)
    - graphan.tar.gz Graphan
    - graphan_dicts.tar.gz 語彙素辞書
    - synan.tar.gz Synan
    - rus-syn-dicts.tar.gz 統辞解析用辞書(露)
    - ger-syn-dicts.tar.gz 統辞解析用辞書(独)

  5. 以下のように RML などの環境変数をセットする。これはインストールのみならず,実行時にも必要である。
  6. # setenv RML /usr/local/lib/RML
    # setenv RML_PCRE_LIB /usr/local/lib
    # setenv RML_PCRE_INCLUDE /usr/local/include
    

  7. DDC のアーカイブ concord-1.80 のディレクトリが $RML/ddc-1.8_kai として解凍されているはずである。この直下のファイルをすべて同じディレクトリ構成で $RML/Source の下に上書きコピーする。
  8. # cd $RML/ddc-1.8_kai
    # tar cf - . | ( cd ../Source; tar xvf - )
    

  9. 次にコンパイル用シェルスクリプトの修正を行う。FreeBSD では gmake は /usr/local/bin 下にあるが,AOT ツールのシェルスクリプトは /usr/bin/gmake を指しているので,これを訂正する。FreeBSD の gmake を /usr/bin/gmake にシンボリックリンクしてもよい。
  10. # cd $RML
    # mkdir shwork
    # foreach i (*.sh)
    foreach? cp $i shwork/$i.bak
    foreach? sed 's|/usr/bin/gmake|/usr/local/bin/gmake|' $i > shwork/$i
    foreach? mv $shwork/$i $i
    foreach? end
    #
    

  11. generete_syn_bin.sh 中の 26 行目 Language=`expr substr $i 1 3`Language=`expr $i : '\(...\)'` に書き換える。
  12. $RML/Source/ConcordDaemon/Main.cpp 及び $RML/Source/SynanDaemon/Main.cpp のファイル先頭に以下を追加する。あるいは,私の作ったパッチ bsdpatch$RML 直下に格納して patch -p1 < bsdpatch で適用してもよい。
  13. #include <sys/types.h>
    #include <sys/time.h>
    #include <sys/resource.h>
    #include <signal.h>
    

  14. いよいよ全 AOT ツールのコンパイル,辞書生成を行う。以下,順次添付シェルスクリプトを実行する。長い道のり...
  15. # cd $RML
    # ./compile_morph.sh
    # ./generate_morph_bin.sh Russian
    # ./generate_morph_bin.sh German
    # ./generate_morph_bin.sh English
    # ./gen_graphan_bin.sh Russian
    # ./gen_graphan_bin.sh German
    # ./compile_and_check_graphan.sh Russian
    # ./compile_and_check_graphan.sh German
    # ./compile_synan.sh
    # ./generate_syn_bin.sh Russian
    # ./generate_syn_bin.sh German
    # ./compile_concord.sh
    # ./check_concord.sh Russian
    # ./check_concord.sh German
    # ./check_concord.sh English
    

  16. 上記のそれぞれの実行後,エラーなくコンパイルが終了していることを確認する。synan(統辞解析ツール)のドイツ語チェック("./generate_syn_bin.sh German")でコンペア・エラーが出ても,$RML/test.tmp にドイツ語解析結果が出力されていれば問題ない。私の遭遇した問題からいえば,もしかすると,$RML/Source/SimpleGrammerLib 配下のモジュール・コンパイルで,s_qlex.cpp.tmp に文法不正があるとのエラーが発生するかも知れない。そのときは $RML/Source/SimpleGrammerLib/s_qlex.cpp.tmp をエディタで開いて,251--2 行目を確認し,以下のとおりに修正して,停止したシェルスクリプトから再実行してみてほしい。
  17. #include <FlexLexer.h>  // <-- 次行と繋がっている場合,改行を挿入する。
    int yyFlexLexer::yylex()
    

  18. ヘッダファイル,ライブラリをわかり易い場所にコピーしておく。AOT ツールのライブラリを使った自作プログラムをコンパイルするとき,-I/usr/local/include/RML-L/usr/local/lib/RML を指定すればよい。
  19. # cd $RML/Source
    # foreach i (*)
    foreach? mkdir -p /usr/local/include/RML/$i
    foreach? cp -p $i/*.h /usr/local/include/RML/$i
    foreach? end
    # find . -name "*.a" | xargs -J % cp % $RML
    

以上でインストールは完了である。ライブラリの利用,テストプログラムの実行が可能となる。日を改めて,Synan,DDC など,AOT ツールの簡単な使い方を紹介したいと思う。

妻が札幌から帰ってきた。北大構内,大通り公園,すすきの,下宿のあった北19条近辺など,学生時代の懐かしい場所を散歩してきたらしい。羨ましい。北大クラーク会館のすぐ裏手の,私が住んでいた北6条西8丁目付近は JR の高架化で様変わりしていたという。お土産は懐かしい六花亭のマルセイバターサンド。

今日の晩ご飯は私がビーフシチューを拵えた。肉が足りないので近所のマルエツにお買い物。肉売り場では「好き好きお肉! 好き好きお肉!」という歌が何度も何度も繰り返され,なかなかシチュー用のバラ肉を見つけられなかった私は,チョーイライラ。肉のついでに,安物 780 円のカリフォルニアワインもゲット。シチューは子供たちにも評判だった。

昼は,ロシア人からのメールへの返信文を書いた。北園克衛詩ロシア語訳の問題点をいくつか指摘して,LaTeX で作成した PDF を添付送信した。

* * *

Lemmatizer ライブラリを使った lemmatized コンコーダンスプログラムを設計中。私は O'Reilly から出た G. Satir, D. Brown による入門書で C++ をさらった程度で,この機会にもう少しきちんと勉強しなくちゃとさらに一冊 C++ 本を購入した。柏原正三『美しい C++ プログラミング見本帖』(翔泳社,2004年)。私は C++ のプログラムを何本も書いたけれど,「クラス・型の実装を強化した C」程度に C++ を扱っていた。オブジェクト指向云々も Java ほど気にする必要を感じなかった。それでも動く C++ プログラムが作れる訳である。

本書は C と C++ はまったく別のプログラミング言語であると強く主張する。 printf などの C の標準ライブラリ関数を使ってはいけない,プリプロセッサの #define による記号定数を使ってはいけない,などなど,私にとってびっくりするような指南がなされている。それが「美しい」ということか。でも,ちょっと納得のいかない点もある。

問題は,fprintf( ) 関数が C の入出力ストリームの関数であることです。C++ は C++ 独自の入出力システムとして入出力ストリームをサポートしていますが,それが C の入出力システムの関数と整合するという保証はありません。
柏原正三『美しい C++ プログラミング見本帖』翔泳社,2004年,p. 20.

「整合しない」例をどうして示してくれないの? このため,問題点の問題点たる所以がどこにあるのか,さっぱりわからないのである。C++ が C とは異なる言語だという考え方は正しい。でも,C++ の設計者は C++ を C のスーパーセットと位置付けているのではなかったか。やはり,ソフトウェアに関する日本人の著作は,米国人の足元にも及ばない,と思ってしまった。米国人なら「必ず」,きちんと具体例をあげ己れの命題の根拠を説明する。

まあ,それでも C に凝り固まった私にはこれくらい刺激的なことを言ってくれる本がよいのかも知れない。上記のような納得できない点もあるにせよ,C との違いを懇切に説明してくれる本である。

C++プログラミング入門
グレゴリー・サティア,ダウグ・ブラウン
オライリー・ジャパン

ロシア語形態素解析器 Lemmatizer ライブラリ(Лемматизатор европейских языков)を利用した試験プログラムを書いてみた。Lemmatizer はロシア単語の文法構造と見出し語を解析する。このライブラリは C/C++ のアプリケーションから利用できる。UTF-8 テキストを解析できる点で,多国語混在テクスト中のロシア語解析にも応用可能である。このパッケージは先日紹介したものを少し拡張したもののようである。私は FreeBSD で試験したが,Linux,Mac OS X でも動くと思う。Lemmatizer の各ライブラリは静的ライブラリなので,アプリのプログラム・サイズが大きくなってしまうところが残念である。

【インストール】

インストールには CMake が必要である。FreeBSD なら "cd /usr/ports/devel/cmake && make install clean" で導入可能である。次に Lemmatizer の次の三つのライブラリ・アーカイブをダウンロードページから取得して展開する:libMAFSA-0.2.tar.gz, libturglem-0.2.tar.gz, turglem-russian-0.2.tar.gz。それぞれの展開ディレクトリ直下において,"cmake . ; make; sudo make install" を実行するだけの簡単なものである。turglem-russian-0.2 の make は辞書生成のため,かなりの時間と 100MB 以上のメモリを要するので注意。オペレーションは以下のとおり。

% cd libMAFSA-0.2
% cmake .
% make
% sudo make install
% cd ../libturglem-0.2
% cmake .
% make
% sudo make install
% cd ../turglem-russian-0.2
% cmake .
% make
% sudo make install

【試験プログラム】

Lemmatizer 利用アプリケーション・プログラムの流れは,tl::lemmatizer クラスを生成し,辞書・文法ルールをロードし,解析したい語に対して lemmatize<russian_utf8_adapter> を呼び出す。UTF-8 文字列もそのまま char* に入れればよい(UTF-16 にした wchar_t* などを期待しない)ので面倒がない。解析結果は tl::lem_result クラスに格納されるので,必要な情報をこのクラスから取り出して活用する。サンプルプログラムを参考に私が作成したテストプログラムを,以下に示す。テキストファイルを読込んで,単語を分割し,Lemmatizer に解析させる。単語リストの作成にはもう少しきちんとした(句読点を考慮した)tokenizer が必要だが,ここでは,指定文字で語分割するごく単純な自前の split 関数ですませている。

// -*- coding: utf-8; -*-
// lemtest.cpp: Lemmatizer test programm.
//                                    2009 (c) isao yasuda.
 
#include <turglem/lemmatizer.hpp>
#include <turglem/russian/charset_adapters.hpp>
#include <string>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <stdio.h>
 
using namespace std;
 
// Lemmatizer
void lem_analyze(const tl::lemmatizer &lem, const char *s)
{
    tl::lem_result lr;  // instance for result of lemmatizer analyze.
    size_t sz_lem = lem.lemmatize<russian_utf8_adapter>(s, lr);
 
    if (sz_lem) {
        printf("(lemmatize results: %u)\n", sz_lem);
        for (size_t i = 0; i < sz_lem; i++) {
            printf("    ** %u: paradigm/form = %04d/%02d", i,
                    lem.get_paradigm(lr, i),
                    lem.get_src_form(lr, i)
                );
            string nform = lem.get_text<russian_utf8_adapter>(lr, i, 0);
            printf("\t\t\t\tNormal Form: '%s'\n", nform.c_str());
        }
    } else {
        cout << "Empty result! Check your text." << endl;
    }
}
 
// split 関数: 指定文字で文字列を分割
void split(const string &s, char c, vector<string> &v) {
    string::size_type i = 0;
    string::size_type j = s.find(c);
 
    while (j != string::npos) {
        v.push_back(s.substr(i, j-i));
        i = ++j; j = s.find(c, j);
        if (j == string::npos)
            v.push_back(s.substr(i, s.length()));
    }
}
 
// main
int main(int argc, char **argv)
{
    tl::lemmatizer lem;  // lemmatizer instance
    string buffer;
    ifstream in(argv[1]);
 
    if (!in) {
        cerr << "usage: " << argv[0] << " file-name" << endl;
        return 1;
    }
    // load dict, etc.
    try {
        lem.load_lemmatizer(
            "/usr/local/share/turglem/russian/dict_russian.auto",
            "/usr/local/share/turglem/russian/paradigms_russian.bin",
            "/usr/local/share/turglem/russian/prediction_russian.auto"
            );
    }
    catch (const exception &e) {
        cerr << "Error: " << e.what() << endl;
    }
 
    while (!in.eof()) {
        vector<string> v;
        getline(in, buffer, '\n');
        if (!buffer.c_str()) continue;
        split(buffer, ' ', v);
        cout << buffer << endl;
 
        for (int i = 0; i < v.size(); i++) {
            cout << "  " << i << " input word: " << v[i] << ' ';
            // lemmatizer analyze.
            try {
                if (v[i].c_str()) lem_analyze(lem, v[i].c_str());
            }
            catch (const exception &e) {
                cerr << "Error: " << e.what() << endl;
            }
        }
    }
    return 0;
}

コンパイルは以下のようにする。ライブラリの指定順序が違うとリンクでエラーとなる。

% g++ -I/usr/local/include -L/usr/local/lib -o lemtest lemtest.cpp \
    -lturglem -lturglem-russian -lMAFSA

"lemtest 入力ファイル" で実行する。入力と実行結果を以下に示す。

入力:

Я люблю вас
Саша прочитал книгу на русском языке

実行結果:

Я люблю вас
  0 input word: Я (lemmatize results: 1)
    ** 0: paradigm/form = 2297/00               Normal Form: 'Я'
  1 input word: люблю (lemmatize results: 1)
    ** 0: paradigm/form = 0913/01               Normal Form: 'ЛЮБИТЬ'
  2 input word: вас (lemmatize results: 3)
    ** 0: paradigm/form = 0742/01               Normal Form: 'ВЫ'
    ** 1: paradigm/form = 0742/03               Normal Form: 'ВЫ'
    ** 2: paradigm/form = 0742/05               Normal Form: 'ВЫ'
Саша прочитал книгу на русском языке
  0 input word: Саша (lemmatize results: 1)
    ** 0: paradigm/form = 2485/00               Normal Form: 'САША'
  1 input word: прочитал (lemmatize results: 1)
    ** 0: paradigm/form = 0440/01               Normal Form: 'ПРОЧИТАТЬ'
  2 input word: книгу (lemmatize results: 1)
    ** 0: paradigm/form = 0088/03               Normal Form: 'КНИГА'
  3 input word: на (lemmatize results: 1)
    ** 0: paradigm/form = 0026/00               Normal Form: 'НА'
  4 input word: русском (lemmatize results: 3)
    ** 0: paradigm/form = 0002/06               Normal Form: 'РУССКИЙ'
    ** 1: paradigm/form = 0002/19               Normal Form: 'РУССКИЙ'
    ** 2: paradigm/form = 0313/05               Normal Form: 'РУССКИЙ'
  5 input word: языке (lemmatize results: 2)
    ** 0: paradigm/form = 0010/05               Normal Form: 'ЯЗЫК'
    ** 1: paradigm/form = 0021/05               Normal Form: 'ЯЗЫК'

"paradigm/form" に文法構造が示される。この数値で品詞,性・数・格などが示される。詳細は現在調査中である。"Normal Form" は見出し語である。

自作プログラムから Lemmatizer を呼出す方法の概略を,これで理解できた。そのうち,PCRE や Boost::regex などの正規表現ライブラリと組合わせて,コンコーダンス・プログラム,ロシア語旧正書法変換プログラムなどを開発したいと思っている。

今日,息子の学校の体育祭だった。これで高校最後の大会だということもあり,私はどうしても外せない会議を終わらせたあと,仕事を早退して途中から参観した。心配された雨も降らず,幸いだった。場所は大井町のスポーツの森陸上競技場。東京モノレール・大井競馬場前駅から徒歩数分であった。

羽田空港を飛び立つジェット機が競技場の向こうをひきもきらず旋回していた。海の臭いがした。たとえ人工的な東京のベイエリアでも,体育祭の喧噪と潮風は郷愁をそそるものである。体育委員長の役目を負った息子は,壇上から大声で全校生徒を指揮していた。やるじゃんか。私とはまるで違って,体育会系の気質にどっぷり浸っているのだ。

2009-taiikusai.jpg

日本アニメ好きのイスラエル人がネットで書いていたのを思い出した。曰く「俺の国では空からロケット弾が飛んで来るのに,日本では空からいろんな女の子が降って来る」。また別のイスラエル人の曰く「日本では,水と安全と moe が,タダ同然と聞いていたが本当らしいな。こっちでは考えられん」。ソドムとゴモラの街のように神の劫火によって世界が焼き尽くされるかも知れない,一抹の終末の予感。そんななかで,幸いにも,活発な少年・少女の gymnastics を,とりあえずはまだ眺めていられる。

虛空より美少女たちの降り來たり濕り濕れる賴もしき梅雨。

* * *

Mac OS X Safari 4.0 beta が評判になっているので,インストールしてみた。Safari はシンプルかつ洗練されたデザインと美しい描画で私の愛用のブラウザである。一方でつまらないバグの多い,困ったアプリでもある。4.0 では JavaScript を劇的に高速化したとの話である。確かに少し軽快になった感じがする。タブを開いたときに現われる Top Sites は履歴からスナップショットを一覧してくれて,私はおっと驚いた。

オリガ・セダコヴァ Ольга Александровна Седакова の著した教会スラヴ語辞典を Ozon から入手した。原題は «Словарь трудных слов из богослужения. --- церковнославяно-русские паронимы» М., 2008.(『正教会典礼文献の難語辞典 --- 教会スラヴ・ロシア同語源語』)。本書は,現代ロシア語と同義のようにみえて意味の異なる教会スラヴ語単語の辞典である。日本語でも古語の「をかし」と現代語の「おかしい」とでは意味が違う。そういう異義語を解説した辞典と考えてもらえばよい。

セダコヴァはなにより詩人,西欧文学翻訳家として高名である。一方,モスクワ大学のスラヴ文献学研究科を終えた学者でもあり,このような教会スラヴ語関連の学術的著作もなしている。

本書では,教会スラヴ語に対応するギリシア語が併記されている。西欧語がラテン語から多くの語彙を相続しているとすれば,ロシア語にとってその関係にあるのはギリシア語だからである。キリル文字そのものがギリシア文字を範としているのだ。

黄土色のクロス・ハードカバー装丁は,私の好きなタイプの本。教会スラヴ語のクラシックなフォントが美しい。その引用を LaTeX(upLaTeX)で組版してみた。教会スラヴ語は SlavTeX フォント,ロシア語,ギリシア語はそれぞれ LH フォント,CB フォントのコンピュータ・モダン書体を使用した。LaTeX 原稿 sedakova_slovar_cite.tex組版結果 PDF sedakova_slovar_cite.pdf も置いておく。

sedakova_slovar54.jpg

sedakova_slovar.jpg

BSD で動作するロシア語形態素解析ソフトウェアをかねてから探していた。二つの目的がある。ひとつは,プーシキンのコンコーダンス・プログラムの単語集計において,現行の出現形ではなく lemmatized な見出語でまとめること。いまひとつは,現時点の私の関心事であるロシア語旧正字法について,misima のような新・旧正字法変換のプログラムを書くこと。ロシア語旧正字法も語彙に依存する複雑な特性をもっており,そのためには misima 旧仮名遣い変換における「茶筌」と同じように,ロシア語形態素解析器が必要なのである。さらにその正字法変換ツールの用途としては,LaTeX T2D 旧正字法ロシア語用ハイフネーションパターンの作成を考えている。ここまで成せば,ロシア人にも果たせなかった LaTeX contribution となるはずだ。

FreeBSD russian ports にはそれらしいのが見当たらなかった。"Russian tagset and Russian statistical taggers" サイト(Serge Sharoff 氏による)によれば,インターネットリソースには TreeTagger, SVMTagger などのいわゆる tagger プログラムがいくつか公開されている。でも,残念ながら,私の愛用する FreeBSD,Mac OS X においてコマンドラインから使用できるツールがなかったのである。

ところが昨日,ロシアのサイトを探し回っていて lemmatizer(http://www.aot.ru/)を見つけた。ウクライナ・キエフ大学の Алексей Сокирко(アレクセイ・ソキルコ)によるプログラムである。このサイトでは,Graphematics 書記素解析ツール GraphmatThick,Syntax 統辞解析ツール TestSynan も公開されていて,私はしばらく勉強させてもらおうと思っているところである。lemmatizer は外部データを切り替えることで英語,ロシア語,ドイツ語の解析が可能な形態素解析ツールである。ライブラリとして使用することを主たる目的に書かれたものだが,TestLem という簡易試験ツールも添付している。ロシア語については,かの有名なザリズニャクの文法辞書の考え方に準拠している。Windows 及び Linux 用のアーカイブが用意されている。FreeBSD にもじつは textproc 分類で ports が存在することも判明。そこで早速 FreeBSD と Mac OS X Tiger にインストールしてみた。それぞれ,動作させるのにかなり苦労した。このソフトについて紹介・説明している日本語サイトは皆無のようである。通常の手順では組込みできないので,ここでインストール手順と使い方とを紹介する。

【FreeBSD インストール】

ports が用意されているが,通常の make install clean 発行だけではダメである(ports のバグなのか,説明が足りないのか)。スーパーユーザ権限で以下のオペレーションによってインストールする。これにより,ロシア語,英語,ドイツ語の形態素解析辞書も同時にインストールされる。

# cd /usr/ports/textproc/lemmatizer2
# make
# make install generatemorph installmorph
# cd /var/db/lemmatizer/Dicts/Morph
# chmod a+rx Eng Ger Rus

FreeBSD では lemmatizer の付属プログラムを使用するに先立って,環境変数 RML に辞書の組込みディレクトリ名をセットしておく。.tcshrc にも記述しておくとよい。

% setenv RML /var/db/lemmatizer

【Mac OS X インストール】

Mac OS X については lemmatizer 本体とロシア語辞書のみのインストール方法に留める。もちろん,英語,ドイツ語用の辞書も取り寄せて組込むことができる。詳細は Docs/Morph_UNIX.txt に記載されている。

  1. インストールするディレクトリ(ここでは $HOME/pkg/lemmatizer とする)を作成し,そこに http://www.aot.ru/download.php から lemmatizer.tar.gz と rus-src-morph.tar.gz をダウンロード格納する。
  2. lemmatizer は PCRE(Perl Compatible Regular Expressions)ライブラリを使用する。http://www.pcre.org/ からアーカイブをダウンロードし,これをインストールする。展開したディレクトリにおいて,./configure, make, make install とごく一般的な手順で組込むことができるが,UTF-8 でも使う可能性があるなら configure のオプションに "--enable-utf8 --enable-unicode-properties" を追加してビルドすることをお勧めする(FreeBSD ports は UTF-8 オプション付きで自動的に組込まれる)。
  3. % ./configure --enable-utf8 --enable-unicode-properties
    % make
    % sudo make install
    

  4. 環境変数をセットする。これはインストールのみならず,lemmatizer 利用の際にも必要である。
  5. % setenv RML /Users/isao/pkg/lemmatizer
    % setenv RML_PCRE_LIB /usr/local/lib
    % setenv RML_RCRE_INCLUDE /usr/local/include
    

  6. lemmatizer の C++ コンパイル,リンク用インストーラに定義されたオプションは,そのままでは Mac OS X Tiger ではエラーとなるので,次にこれに訂正を施す。Source/common/common_exe_mak ファイルを以下のように書き換える。
  7. 〔前〕:

    libs_argument := -Wl,--start-group $(pcre_libs) $(subst .$(lib_ext),,$(lib_pathes)) -Wl,--end-group
     
    ifeq ($(libmode), static)
        lib_mode_switch := -static
    endif
    

    〔後〕: -Wl,--start(end)-group, -static オプションを削除

    libs_argument :=  $(pcre_libs) $(subst .$(lib_ext),,$(lib_pathes))
     
    #ifeq ($(libmode), static)
    #    lib_mode_switch := -static
    #endif
    
  8. コンパイル,リンク,辞書生成をスクリプトによって実行する。
  9. % ./compile_morph.sh
    % ./generate_morph_bin.sh Russian
    

  10. $HOME/pkg/lemmatizer/Bin にパスを通しておく。

【使い方】

lemmatizer 付属の TestLem は,lemmatizer ライブラリを用いたテストプログラムである。これで手軽にロシア語テキストの形態素解析を行うことができる。ただし,解析対象ロシア語テキストファイルの作成に際しては,以下の2点に注意する。

  1. ロシア語は Windows cp1251 エンコードで記述する。iconv などのコード変換プログラムを用いて UTF-8 などから変換すればよい。Emacs なら以下のコードを .emacs に記述すれば,cp1251 キリルエンコーディングを直接扱うことができるようになる。
  2. (codepage-setup 1251)
    (define-coding-system-alias 'windows-1251 'cp1251)
    

  3. 1行1単語の形にしておく。このため,通常のテキストファイルを扱う場合は,適当な tokenizer ツールを用いて前処理する形態となるだろう。

試しに,次のようなテキストファイル r.txt を準備するとしよう。

Я
люблю
вас
,
Надя
!

これをコマンドラインにおいて TestLem プログラムで処理する。

% TestLem Russian r.txt
Loading..
read r.txt
process r.txt
Count of words = 6
Time = 0 seconds; 0 ticks
too few words to measure the speed
writing to r.lem

Russian という第一引数はロシア語形態素辞書を指示するものである。English,German とすれば,それぞれ英語,ドイツ語の形態素解析が可能である。ファイル名(r.txt)を省略すると標準入力からテキストを読む。処理結果は,この場合 r.lem というファイル名で生成される。その出力は次のようなものである。

Я -> Я ча#
ЛЮБЛЮ -> ЛЮБИТЬ кб#
ВАС -> ВЫ чучхчч#
, -> , яя#
НАДЯ -> НАДЯ до#
! -> ! яя#

出力結果例においては,ЛЮБЛЮЛЮБИТЬ という不定形をもつ動詞で,一人称・単数・現在形であるということが,"ЛЮБИТЬ кб#" という形式で示されている。"ВЫ чучхчч" は,ВАС という出現形が二人称複数代名詞 ВЫ の生格,対格もしくは前置格であることを示す。このように,文法解析結果は "->" の先に「見出語 xx..#」で示され,文法構造は "кб","чу","до" など二文字からなるニモニックの組合せで示される。語として複数解がある場合は "xx...#" が複数出力される。こうして,語の出現形の lemmatize された見出語と文法構造が得られるのである。コンコーダンスにおいて見出語で出現度数を分析する等の処理が可能となる。

ロシア語文法構造ニモニック,文法略号の意味は Dicts/Morph/rgramtab.tab 及び http://www.aot.ru/technology.html に解説がある。詳細はそちらを参照。

Profile

ISAO。システムエンジニア。昭和 30 年代を懐かしむオヤジ。ロシアに興味があります。
[more], [About our site]

Notice

この文書はフィクションであり,実在する個人,団体等とは一切関係ありません。

文書の記述内容は無保証です。不適切な表現があればコメントにてご指摘ください。

管理者が公序良俗に反すると判断したコメント,トラックバックは,断りなく削除される場合があります。

Links

About this archive

All Entries of Category 文房清玩

Previous: 小道具

Next: 日曜大工

Recent Entries in Main Index.
All Entries in Archive Index.

Web Pages

Powered by Movable Type 4.1