旧字・旧仮名遣い変換 Web サービス misima RESTful Web Service の GNU Emacs 向けクライアントの例として,先日は call-
今日は URL パッケージに基づく Emacs Lisp について記す。筆者の Emacs Lisp 開発・試験環境は GNU Emacs 24.3.1 (x86_64-apple-darwin), Mac OS X 10.9.2 Mavericks である。なお,サーバ側の実装については,弊サイト記事『JAX-RS - misima RESTful Web Service の実装』を参照。
GNU Emacs 24 URL パッケージ
URL パッケージは Emacs 22 辺りから Emacs 標準となった。Lisp ファイルは lisp/
Emacs Lisp Web プログラミングでの基本的な使い方は,以下のとおりに整理できるだろう。
- url-request-method に HTTP メソッドをセット
- url-request-extra-headers に Content-Type 等のヘッダ情報を alist 形式でセット
- url-request-data に送信すべきデータをセット
- url-retrieve URL CALLBACK(非同期)もしくは url-retrieve-synchronously URL(同期)関数を発行して,Web アクセスを実行
- 関数のリターンとしてレスポンスが指定バッファに出力されるので,当該バッファの必要な情報を編集し,結果をバッファに挿入
この過程で,文字列の URL エンコーディング,MIME 変換,Cookie 操作,プロキシ接続等が必要になる場合がある。URL パッケージはそのための機能も備えている。詳細は URL Programmer's Manual を参照のこと。
misimaRESTful.el 実装
misima RESTful Web Service クライアントの設計は以下のとおりである。
- リージョン・テキスト(選択テキスト)から RESTful Web サーバに送信する XML データを組立てる
- UTF-8 で外部と通信するので,XML データを UTF-8 にエンコードする(Emacs 上では内部エンコードでデータが管理されていて,そのままでは文字化けしてしまう)
- 変換対象テキストのエンティティを XML セーフに("<", ">", "&", """ をそれぞれ "<", ">", "&", """ に置換)する
- misima RESTful Web Service に XML データを同期 POST する
- サーバ・レスポンス内容が格納されたバッファから変換結果テキストを切り出し,リージョン・テキストを置換する
- ユーザ指定のオプションで変換出来るインタラクティブ関数とともに LaTeX 用変換関数等オプション出来合いの関数を用意する
misima RESTful Web Service GNU Emacs クライアント lisp コード misimaRESTful.
;; -*- coding: utf-8; mode: emacs-lisp; -*- ;; misima RESTful Web Service Emacs Client ;; Copyright(c) 2014 isao yasuda, All Rights Reserved ;; ユーザ設定変数 (defvar misimaRestUri "http://yasuda.homeip.net:8080/misimaRest/misima/convert" "misima RESTful Web Service URI") (defvar misimaOpts "-q -kyitl -s c" "変換オプション misima options for conversion") (defvar misimaUcode "noxinsomniae201402" "ユーザ認証コード Usercode for misima RESTful Web Service authentication") ;; XML固定値 (setq misima-rest-xml-a "<?xml version=\"1.0\" encoding=\"UTF-8\"?><misimaRESTful><misimaParam>") (setq misima-rest-xml-b "</misimaParam><misimaTarget>") (setq misima-rest-xml-c "</misimaTarget><misimaUsercode>") (setq misima-rest-xml-d "</misimaUsercode></misimaRESTful>") ;; misima RESTful Web Service 変換 ;; - misima-rest-region: misimaOpts 値によって変換 ;; - misima-rest-old-invert-region: 仮名反転付 ;; - misima-rest-old-latex-region: LaTeX変換付 ;; misima-rest-region (defun misima-rest-region (beg end) "リージョンテキストを旧字・旧仮名遣い表記に変換する" (interactive "r") (setq convopt misimaOpts) (misima-convert beg end convopt)) ;; misima-rest-old-invert-region (defun misima-rest-old-invert-region (beg end) "リージョンテキストを旧字・旧仮名遣い・仮名反転表記に変換する" (interactive "r") (setq convopt "-q -kyitnl -s c") (misima-convert beg end convopt)) ;; misima-rest-old-latex-region (defun misima-rest-old-latex-region (beg end) "リージョンテキストを旧字・旧仮名遣い表記・多言語LaTeX形式に変換する" (interactive "r") (setq convopt "-q -kyit -s a -x farT") (misima-convert beg end convopt)) ;; misima-rest-latex-region (defun misima-rest-latex-region (beg end) "リージョンテキストを多言語LaTeX形式に変換する" (interactive "r") (setq convopt "-q -x arT") (misima-convert beg end convopt)) ;; misima-convert (defun misima-convert (beg end convopt) "misima RESTful Web Service Convert" ;; リージョンテキストを変数に格納 (setq misimaTarget (url-insert-entities-in-string ;; <>&" entities replace (buffer-substring beg end))) ;; XMLを組立て (setq misimaXml (concat misima-rest-xml-a convopt ;; 変換オプション misima-rest-xml-b misimaTarget ;; 変換対象テキスト misima-rest-xml-c misimaUcode ;; ユーザ認証コード misima-rest-xml-d)) ;; リージョンをキルリングに切り出す (kill-region beg end) ;; misima RESTful Web Service に POST する (let ((url-request-method "POST") ;; POST method (url-request-extra-headers ;; Request Headerに `(("Content-Type" . "text/xml"))) ;; Content-Type セット (url-request-data ;; 送信XMLをUTF-8 (encode-coding-string misimaXml 'utf-8))) ;; エンコードしてセット ;; 同期 POST し,レスポンスを buffer に格納 (let ((buffer (url-retrieve-synchronously misimaRestUri)) (resp nil)) ;; 変換結果文字列 初期値 nil (save-excursion (set-buffer buffer) (goto-char (point-min)) ;; バッファ先頭に位置づけ (re-search-forward "^$" nil 'move) ;; 空行までカーソルを進める ;; 空行の次の文字からバッファ末尾まで切り出し,UTF-8デコードし,変換結果を取得 (setq resp (decode-coding-string (buffer-substring-no-properties (+ (point) 1) (point-max)) 'utf-8)) (kill-buffer (current-buffer))) ;; バッファに変換結果を挿入 (insert resp)) ;; 終了メッセージをミニバッファに表示 (message "The text before conversion was stored in the kill-ring")) ) ;; end of misima-convert ;; (provide 'misimaRESTful)
処理の中核は,url-retrieve-synchronously 関数のところである。この関数は url-request-* 変数にバインドした内容で URL リソースを取得し,そのレスポンス(レスポンス・コード,日時,サービスデータなど accept した内容すべて)を書き出したバッファを返す。let 関数でそれを一時バッファに納め,save-
タイムアウトやエラー発生時の処理をさぼっている。もし予期しない事態になったら,C-g で強制停止させ,C-/ アンドゥーでテキストを戻す。
misimaRESTful.el では,利用者が M-x 関数名 でインタラクティブに呼び出せる,変換オプションの異なる 4 の変換用関数を定義している。
- misima-rest-region: misimaOpts 変数に設定したオプションで変換する。指定できるオプションについては,『Emacs から「misima 旧仮名遣い・旧字変換」を使う』に記したものと同じである(当該ページは SOAP クライアントのためのものなので,-u SOAPサーバ オプションは misima RESTful Web Service では使用出来ない)。
misimaOpts 利用者設定のないデフォルトでは,旧字,旧仮名遣い,用語用字,単純補正,繰返符号,簡体字-繁体字の各変換を行う - misima-rest-old-invert-region: 旧字,旧仮名遣い,用語用字,単純補正,繰返符号,簡体字-繁体字の各変換,及び仮名反転を行う
- misima-rest-old-latex-region: 旧字,旧仮名遣い,用語用字,単純補正,繰返符号の各変換とともに,多言語文字の LaTeX 形式(欧文・漢文訓点,くノ字点,キリル命令,タイ語ワードブレーク挿入)への変換を行う。旧字・旧仮名遣い変換抑止指定時も強制変換を行う
- misima-rest-latex-region: 多言語文字の LaTeX 形式への変換を行う(旧字・旧仮名遣い関連変換は行わない)
設置
misimaRESTful.el を Emacs Lisp のパスの通ったところに格納した上で,.emacs
;; misima RESTful Web Service (require 'misimaRESTful) (setq misimaRestUri "http://yasuda.homeip.net:8080/misimaRest/misima/convert") (setq misimaOpts "-s c -l -q") ;; オプション例(旧字変換,簡体字-繁体字変換のみ) (setq misimaUcode "noxinsomniae201402") ;; 暫定ユーザ認証コード
プロキシ設定
URL パッケージはプロキシへの配慮もある。url-proxy-services 変数にプロトコル,ホスト名:ポート番号を alist 形式で設定しておくと,プロキシ経由でリソースを取得する。プロキシのユーザ,パスワードの問い合わせがミニバッファでなされ,これに応えることでプロキシ認証を行う。
もし,プロキシ認証を自動化したい場合は,url-proxy-basic-auth-storage 変数に ユーザ名:パスワード の形式の文字列を base64 変換したものを指定しておく。base64 形式を得るには,(base64-encode-string "ユーザ名:パスワード") を評価(ここでの「評価」とは GNU Emacs Lisp 用語であって,Emacs の lisp インタープリタに解釈させること。閉じ括弧の直後にカーソルを位置づけ C-x C-e を入力する)すればよい。ミニバッファないし *Messages* バッファにそれが表示される。
.emacs プロキシの設定は次のようになる。ホスト名(proxy.
;; プロキシ設定 (setq url-proxy-services '(("http" . "proxy.example.com:8080") ("ftp" . "proxy.example.com:8080") ;; プロキシを経由しないホストを正規表現で指定できる ("no_proxy" . "^.*example.com"))) ;; ユーザ名・パスワードを自動応答させる場合以下も設定する ;; (base64-encode-string "username:password") を評価して得られる ;; dXNlcm5hbWU6cGFzc3dvcmQ= を指定する (setq url-proxy-basic-auth-storage '(("proxy.example.com:8080" ("Proxy" . "dXNlcm5hbWU6cGFzc3dvcmQ="))))
LaTeX 変換
misima RESTful Web Service サーバのバックエンド misimaserver
misimaRESTful.el にも,misima-
日本語 LaTeX も大いに進化し,TeXLive-2013 パッケージに標準として組込まれ欧文用とほぼ同等の UTF-8 入力の欧文組版が出来る(ヘブライ語のような逆書字方向を組むための e-TeX 拡張もなされた)ようになっただけでなく,upTeX, LuaTeX-ja 等のプロジェクトによって Unicode のいわゆるサロゲート・ペア領域にある漢字すらも UTF-8 エンコードで直接原稿に入力して組版が出来るようになっている。従って,misima RESTful Web Service の LaTeX 変換機能は,ある意味で,すでに時代遅れの機能である。
しかしながら,misima RESTful Web Service LaTeX 変換機能には,最新 LaTeX だけでは不可能な機能を備えている。
- タイ語ワードブレーク挿入機能
- タイ語は分かち書きしない書記方法である一方,改行位置を単語の切れ目で行わなければならないという正書法を持つ。タイ語文字列を判定し,swath タイ語ワードブレーク解析ユーティリティを用いてワードブレーク命令を挿入する。変換結果出力形式に関し,UTF-8 または Thai-TIS620 十六進形式のいずれかを選択出来る。
- 教会スラヴ語 SlavTeX 表記サポート
- 拙作の OldSlav 教会スラヴ語 LaTeX Babel 言語オプションは,モスクワ大学の A. スレプーヒン教授が開発した SlavTeX 教会スラヴ語ノーテーションと互換性のある記法をサポートしている。これは現代キリル文字と記号によって,気息記号,略語符,アクセントなど複雑な文字修飾を有する教会スラヴ語書記方法を表現するものである。misima 教会スラヴ語変換機能は,SlavTeX 表記を ASCII 文字のみからなる OldSlav 命令に変換する。misima -x s オプションまたは <utf82tex_s> タグでこれを行う。misima-
rest- old- latex- region 関数では -x s を付加していないので,タグで指示しなければならない。 - キリル文字命令変換
- misima はキリル文字に関しては,デフォルトでは OT2 アスキー記法(たとえば,キリル文字 Б をラテン・アルファベット B で記述する)に変換する。キリル文字のインプットメソッドを持たなかったり,エディタがキリルフォントを満足に表示できなかったりした,かつての日本語 LaTeX 環境では,ロシア語を出力するにこれが一般的な方法だった。しかし OT2 キリルフォントエンコーディングはハイフネーションパターンを個別に調整しなければならなかったり,アウトラインフォントが TeXLive 標準に組込まれていないなど,問題が多い。misima 変換オプションに -x r を指定するか,もしくは <utf82tex_r> をマークアップすることにより,キリル文字を \cyrxx 命令形式に変換する。これによりバージョンの古い platex でも,ロシア語,ウクライナ語などメジャーなキリル言語は T2A エンコーディングを用いてハイフネーション含めきちんと欧文として処理出来るようになる。タグで制御することで教会スラヴ語との混在文書においても変換を区別することが出来る。
misima- rest- old- latex- region では, -x r で変換を行うオプション指定になっている。 - 中国語簡体字,中国語繁体字,韓国語ハンチャ振り分け機能
- Unicode CJK 文字標準では,日本語,中国語,韓国語の文字が同じコードポイントに包摂されている場合がある。たとえば「骨」(U+9AA8)。しかし各国での印字伝統では独自のグリフを用いており,タイプセットもそれに準じて出力し分けたいものである。変換対象の原稿に <utf82tex_
c>, <utf82tex_ t>, <utf82tex_ k> をマークアップしておくと,漢字を,それぞれ \UTFC (または \CIDC), \UTFT (または \CIDT), \UTFK (または CIDK)に,選択的に置換する。 \UTFx, \CIDx 命令は OTF パッケージ(齋藤氏作成 VFont 及び文字組マクロ集。TeX Live 2013 に収録されている)のマクロである。 - 漢文訓点記述簡易化
- 藤田眞作先生による sfkanbun.
sty は縦書きモードで訓点・送り仮名付き漢文をタイプセットするための素晴らしいパッケージである。misima はこのパッケージの命令記述を簡略化して行うことを支援する。漢文訓点記法の詳細については『misima TeX 変換の活用 — 和文・古典籍,多言語,中韓文,漢文』を参照されたい。 sfkanbun. sty マクロは,藤田先生の LaTeX ページからダウンロードできる。 - くノ字点変換機能
- 「いろいろな」を「いろ\/な」,「さまざまな」を「さま\/"(濁点付き)な」のように表示する,旧い縦組和文独特の繰返符号を「くノ字点」という。「いろ\ajKunoji{}な」,「さま\ajDKunoji{}な」のように,繰返し部分を OTF くノ字点命令で置き換える。
以下に,サンプル原稿をあげる。
% -*- coding: utf-8; mode: latex; -*- % $Id: multilingua.tex 148 2014-03-31 15:46:07Z isao $ \documentclass[b5paper]{jsarticle} \usepackage[utf8x]{inputenc}% ucs Unicode macro \usepackage[T2A,T1]{fontenc} \usepackage[thai, % タイ語 vietnam, % ヴェトナム語 polutonikogreek, % 古典ギリシア語 russian, % ロシア語 oldchurchslavonic,% 教会スラヴ語 nippon % 日本語 ]{babel}% Babel 多言語 %\usepackage{thswitch}% ThaiLaTeX encoding switch: TeX Live では不要 \usepackage[deluxe,expert,multi,jis2004]{otf}% OTF 和文(齋藤氏) \usepackage{sfkanbun,furiknkt}% 漢文訓点・縦組振仮名パッケージ(藤田先生) \usepackage{plext}% \renewcommand{\baselinestretch}{1} % OldSlav フォントを少し大きめに出力 \DeclareFontFamily{LST}{cmr}{}% \DeclareFontShape{LST}{cmr}{m}{n}{<-> s * [1.20] fslavrm}{}% \begin{document} \hspace{3zw}% {\gtfamily misima RESTful Web Service 旧仮名・旧字・\LaTeX{}多言語変換}   \vspace{1em}% \begin{minipage}{.85\textwidth} (ヨハネ伝福音書) 太初に言あり、言は神と偕にあり、言は神なりき。\par %<misima_noop> 旧字・旧仮名変換しない (-x f 指定でTeX変換は強制的に行う) %<utf82tex_c> 簡体字中文変換 (约翰福音 简体中文) 太初有道、道与 神同在、道就是 神。\par %</utf82tex_c> %<utf82tex_t> 繁体字中文変換 (約翰福音 繁體中文) 太初有道、道與 神同在、道就是 神。\par %</utf82tex_t> %<utf82tex_k> 韓国語変換 (요한복음) 태초에 말씀이 계시니라.\par %</utf82tex_k></misima_noop> \selectlanguage{polutonikogreek} \textlatin{(Greek)} Ἐν ἀρχῇ ἦν ὁ λόγος, καὶ ὁ λόγος ἦν πρὸς τὸν Θεόν, καὶ Θεὸς ἦν ὁ λόγος.\par \selectlanguage{russian} (Russian) В начале было Слово, и Слово было у Бога, и Слово было Бог.\par \selectlanguage{oldchurchslavonic} \textlatin{(ChurchSlavonic)} %<utf82tex_s> OldSlav 教会スラヴ語変換指定 Въ нач'алѣ б`ѣ сл'ово, <и сл'ово б`ѣ къ б_гу, <и б_гъ б`ѣ сл'ово.\par %</utf82tex_s> \selectlanguage{nippon}% タイ語:~% \selectlanguage{thai}% \def\wbr{\hskip0pt plus0.6pt minus0.6pt\relax}%タイ語ワードブレーク \fontencoding{LTH}\fontfamily{norasi}\selectfont% ศิลปะไทยมีลักษณะเฉพาะตัวค่อนข้างสูง โดยมีความกลมกลืนและคล้ายคลึงกับศิลปวัฒนธรรมเพื่อนบ้านอยู่บ้าง \selectlanguage{nippon}% ヴェトナム語:~% %<utf82tex_n>%変換しない(UTF-8そのままでOK) \selectlanguage{vietnam} Phần ``Những câu hỏi và giải đáp thường gặp'' được nêu ra ở đây nhằm mục đích thu thập những câu hỏi thường gặp trong thực tế và những lời giải đáp thích hợp nhất của nó. \end{minipage} %</utf82tex_n> \vspace{2em} \selectlanguage{nippon}% \begin{minipage}<t>[20zw]{17zw} 【縦書きモード】 \vspace{1zw} {\large 森鴎外はこう言い,内田百間を団扇であおいだ。 僕は黙っていますよ。 彼はこうごうしかった。 } \vspace{1zw} 【漢文】 {\large %<misima_kanbun> 子曰ハク,盍なんゾ3ルト各々言ハ2爾なんぢノ志ヲ1.% %</misima_kanbun> } \end{minipage} \end{document}
原稿では,ヴェトナム語だけは,ダブルアクセント付きヴェトナム文字を platex がそのまま処理出来るので,
中国語の部分は旧字・旧仮名遣い変換を施すと日本の旧漢字変換がなされるため,旧字・旧仮名遣い変換を抑止する指定(<misima_
misima の独自タグは変換後テキストには出力されない。とはいえ,LaTeX 原稿に記述するに際して LaTeX コメント部分に独立してマークアップしておくのがよい。
GNU Emacs 上で \begin{document} 以降をリージョン設定し,
図 1. LaTeX 変換実行前
図 2. LaTeX 変換実行後
変換後の LaTeX 原稿を処理した PDF: multilingua.
図 3. LaTeX 処理結果
中国語出力(図 4.)に関して,「神」(Unicode コードポイントは U+795E)の字体や句読点の位置について,簡体字,繁体字の間で微妙な違いがあることがわかる。
図 4. 簡体中文と繁体中文の出力
参考文献
URL パッケージは最近のバージョンでサポートされたもので,詳しいマニュアルはインターネット・リソース URL Programmer's Manual を参照いただきたい。Emacs Lisp プログラミングそのものについて座右に置くべき書物は以下である。
LaTeX 関連では奥村先生の『美文書作成入門』第6版が一番のお勧めである。最新事情について,基礎から応用まで幅広く解説した定評ある書籍である。利用者のことを第一に考えた,たいへん良心的な参考書で,長く支持されているシリーズであることが頷ける。
上で触れたように,トリッキーな工夫をせずとも多言語関連の組版が容易になった現在,『美文書作成入門』第6版ではそれまで付録にあった多言語組版解説が割愛された。もっとビビッドな話題が出て来ているのだから当然である。多言語組版の基本的概念については旧第5版が参考になると思う。
『The LaTeX コンパニオン』は LaTeX 第三世代のパッケージ解説本としてリファンレンス的存在になっている。少し古びてしまったが解説の質の高さは「さすが開発者が書いた本」だけのことはある。
藤田眞作先生の本と掲載マクロは和文印刷伝統の理解を深めたい利用者には必携のものである。次の本は,漢文訓点,ふりがな,和歌・俳句の倍取り,割書・割注,ぶら下げ,国語の試験問題などの話題について書いた奥深い書籍である。「入門」となっているが内容は極めて高度なもので,私見では「初心者立入り禁止」。
日本語 LaTeX も Unicode 対応が進むなか,内部 JIS コードの LaTeX を前提とした本書のマクロ記述は upTeX では動作しないものもある。「だから本書は時代遅れ」,なのではなく,「だから藤田マクロの動く旧い LaTeX を捨てられない」,というのが私の正直なところなんである。
[ 2015/02/02 付記 ]
misima RESTful Web Service は 2014/12 より友人のためだけの限定公開といたしました。上記ユーザ認証コードでは動作しません。