HOME > 電算 > KabiWord 貧文書入門

KabiWord 貧文書入門

わたくしの、わたくしによる、わたくしのための、再利用可能性が低い文書向け組版スクリプト。テキスト書類を Postscript に変換する。主に sed を利用。「原稿に赤字で指定を書いて印刷屋さんに持っていくと、ゲラが出てくるよ」そんなプリミティブな雰囲気。(主に Ubuntu 10.04 で、ghostscript が日本語フォントを使える状態で使っております)。

いきさつ

ほんの短かい文書を印刷しようと思って、ふと考えた。この文書は LaTeX で印刷するほどのものではない。しかし、a2ps や mpage では足りない。Emacs には ps-print-buffer などの日本語を印刷できるコマンドがあるが、どうもうまく使いこなせない。troff はいい選択肢なのだが、今の私が使っている troff は日本語を処理してくれない。何かやっつけ仕事にちょうどいい清書方法はないか。私がやりたいことは、簡単なことである。一行の文字数、一ページの字数、上と左のマージン、フォントサイズを指定して日本語を印刷したいというだけだ。ところが、これが確実かつ手軽にできるアプリケーションというのは、意外なほど見当らない。

そこで、一歩下がって考えてみた。Postscript は、基本的にはテキストファイルだから、テキスト処理だけで組版ができるはずである。そこで、テキストファイルを処理してポストスクリプト・ファイルにするスクリプトを書くことにした。sed を選んだのは、スクリプトを書くことを、パズルのように楽しみたかったからだ。

最初の課題をクリアしてしまうと、私はもっと欲が出てきた。タイトルの文字を大きくしたり、ちょっとした図をはさみ込んだり、一部をゴシック体にしたり、難しい漢字にルビをふるなどということも、できないことではあるまい。最初のスクリプトとは別に、いくつかまた sed のスクリプトを書いた。そして、これらをパイプでつなげて使うことにした。これは、案外うまくいった。ポストスクリプトと sed は予想していたよりは相性が良かった。

最後にそれらのスクリプトをまとめて実行するラッパーをシェル・スクリプトとして書いて、このささやかな清書計画に区切りをつけることにした。(ラッパーを使えば、デフォルト値を変えるために、いちいち sed スクリプトを編集しないで、コマンドライン・オプションとしてこれを与えることができる)。そして、これらのスクリプトをまとめて、KabiWord と呼ぶことに決めた。この名前なら、「文書はワードで作ってください」と言われたときに便利なはずだ :-)

準備

KabiWord の機能のいくつかは、一般の sed ではなく GNU sed を必要とし、troff のコードを埋め込むためには groff, eqn と ps2eps を必要とする。ラッパーを使うには、Bourne Shell か互換性のあるシェル必要で、ほかに basename やら cat やら expr やらが必要になる。出来上がったポストスクリプト・ファイルを見るためには、ghostscript などのポストスクリプト・インタープリタが /Ryumin-Light-UniJIS-UTF8-H と /GothicBBB-Medium-UniJIS-UTF8-H を使えるようにセットアップされていなくてはならない(代替フォントでもよい)。ps2pdf などがあれば、簡単に pdf 化することができる。

現在のところ KabiWord を構成するファイルは、

kabiword.sh (以下のスクリプトへのラッパー)
base.sed(基本組版)
emph.sed(装飾的なタグの処理)
embedeps.sed(eps ファイルの埋め込み)
embedtroff.sed(troff の eqn 書式を解決)
header.sed(ヘッダの付加)
line.sed(アンダーラインや表罫線)
ruby.sed(ルビ)
(いずれも GPL)

であり、すべて同じディレクトリに入れればインストール完了。sed スクリプトへのラッパーである kabiword.sh というシェルスクリプトを利用することを前提に、KabiWord の機能を概観する。(もし、ラッパー kabiword.sh を使わずにsed のスクリプトを個別に適用するなら、base.sed を一番先に適用すること。あとのスクリプトはどんな順番で使ってもいいし、使わなくてもよい)

バージョン番号がないのは、ごく私的なものなので、適宜だまって改訂しているから(ヒドイなこれ。少しは履歴を書くか……)。そして、一度にすべてのスクリプトをダウンロードしないと不整合が生じるなり〜

2011-7-26(Tue) EPS 埋め込みスクリプトの改善

2011-7-26(Tue) アンダーライン専用タグ定義追加

2011-7-26(Tue) troff タグ中に > を書く方法を定義

2011-7-13(Wed) EPS 埋め込みスクリプトの改善

2011-7-13(Wed) アンダーラインや表罫線を引けるようにした

基本的な組版

KabiWord は、原稿にある改行は改行のまま、空白は空白のまま出力する。また、改行や空白が自動的に作られることはない。これは、あらかじめテキストエディタなどで原稿を書くときに一行の字数を揃えることを前提にしている。不便なようであるが、やっつけ仕事においては、改行や空白で思い通りのスペースを作り出せるということは悪くないだろうと思う。また、あらかじめエスケープしておかなければならない文字はなく、文脈によって文字が違った意味に解釈されることもない。

ラッパー kabiword.sh は、引数にテキストファイルのパスをとり、ポストスクリプトファイルを生成する。テキストファイルのコーディングシステムは、UTF-8 が期待されている。

$ ls
input.txt
$ sh kabiword.sh input.txt
$ ls
input.txt
input.ps

オプションのうちで基本的なものは、

-n 一ページの行数(自然数)デフォルトは 45
-p 文字サイズ(小数。単位はポイント)デフォルトは 10
-d 行送り(小数。行送り÷文字サイズ)デフォルトは 1.5
-u 上マージン(小数。単位はポイント)デフォルトは 100
-l 左マージン(小数。単位はポイント)デフォルトは 80
-f 標準フォント(mincho または gothic)デフォルトは mincho

である(今のところ、ペーパーサイズは A4 ポートレート固定)。先に述べた通り、行の長さは原稿となるテキストファイルの改行場所によって決まる。

               五重塔

                           幸田露伴

木理美しき槻胴、縁にはわざと赤樫を用ひた
る岩畳作りの長火鉢に對ひて話し敵もなくた
だ一人、少しは淋しさうに坐り居る三十前後
の女

という原稿は、そのまま

のように出力される。

文字の装飾

KabiWord は、いくつかのタグを定義していて、これを使うとちょっとしたワープロまがいな清書が可能となる。

<Nm> 標準フォントサイズの N 倍のサイズをもつ明朝体に切り替え(N は正の小数)
<Ng> 標準フォントサイズの N 倍のサイズをもつゴシック体に切り替え(N は正の小数)
<+Nl> 標準行送りの 1+N 倍の行送りにする(N は 0 以外の小数)
<-Nl> 標準行送りの 1-N 倍の行送りにする(N は 0 以外の小数)

タグは一行の中におさめなくてはいけない。また、タグは直後にある文字から行末までに対してのみ効果を発揮する。だから、複数行に対しての指定は、各行で一回ずつ行わなくてはならない。

               <2m>五重塔

                           <1.2g>幸田露伴

木理美しき槻胴、縁にはわざと赤樫を用ひた
る岩畳作りの長火鉢に對ひて話し敵もなくた
だ一人、少しは淋しさうに坐り居る三十前後
の女

という原稿は、

のように出力される。

ルビ

ルビをつけるには、

<r STRING> タグに後続する文字上方に、標準フォントサイズの1/2の大きさでルビ STRING を印刷する。

というタグが用意されている。このタグは、ルビの開始ポイントを指定するだけで、対象となる本文中の文字列とそれ以上の深い関連づけはない。

kabiword.sh はオプションとして

-r ルビの大きさ。標準フォントサイズに対する比率。デフォルトは 0.5

を受け取る

               <2m>五重塔

                           <1.2g>幸田露伴

木理<r うるは>美しき<r けやきどう>槻 胴、縁にはわざと<r あかがし>赤樫を用ひた
る岩畳作りの長火鉢に對ひて話し敵もなくた
だ一人、少しは淋しさうに坐り居る三十前後
の女

画像の埋め込み

画像を埋め込むのには

<eps FILENAME> eps ファイルをそのまま埋め込む

というタグが使える。eps ファイルの内容は、左下がタグ直前のポイントに位置するよう配置される。本文が図形にまわりこむなど、画像と本文と重ならないための配慮は一切ない。したがって、空行や空白文字を用いて本文の原稿に画像挿入用のスペースを確保する必要がある

(なお、この仕組みは完全ではない。特に、image オペレーター後に続く表現の中に、偶然、特定の DSC コメントと見倣すごとができる文字列が出現すると、失敗する。)

               <2m>五重塔

                           <1.2g>幸田露伴

<r もくめ>木理<r うるは>美しき<r けやきどう>槻 胴、縁にはわざと<r あかがし>赤樫を用ひた
る岩畳作りの長火鉢に對ひて話し敵もなくた



     <eps nagahibachi.eps>
        <-0.5l><0.9g>長火鉢
だ一人、少しは淋しさうに坐り居る三十前後
の女

タグによる図や式の挿入が、カレントポイントを進めないというのは、<eps ...> タグでも同様で、文中に埋め込もうが、独立した行を与えようが、図や式を出力するスペースは地の文で空白文字や空行を使って空けておかなくてはならない。

数式の埋め込み

数式を処理する独自の仕組みは持っていない。しかし、

<troff EQN式> troff の eqn プリプロセッサ用の書式で書いた数式を画像として埋め込む

というタグを使って、troff の数式用プリプロセッサ eqn の書式を書くことができる。式の表現は eqn で処理されたあと、groff -ms で処理されてポストスクリプトとなり、それが ps2eps で EPS にされ、最終的に出力されるポストスクリプト・ファイルに張り込まれる(これらのプロセスは GNU sed の e コマンドから起動される)。挿入位置は、<troff> タグの直前である。

ただし、> は &gt; と表現しなくてはいけない。これは、タグの終了を示す > と区別するためであり、troff タグの中でのみ通じるローカルなことである。なお、< は &lt; と書いてもよいが、< でもかまわない。

<1.2g>1 から 5 まで足す

ふつうに書くと、
1+2+3+4+5=15 こうなる。
troff を使うと、
<troff 1+2+3+4+5=15>                  こうなる。
では、troff を使って             
<troff Sigma> で表現してみよう。

     <troff sum from n=1 to 5 n = 15>
という感じだね。

ヘッダ

ヘッダをつけるには、kabiword.sh にオプション

-e ヘッダ文字列 (%p がページ番号に置き換わる) デフォルトは "Page %p"

を与える。ヘッダは、本文一行目より三行上、右端が 42 文字目の左端にそろうように印刷される。なお、1 ページ目には印刷されない。

アンダーラインと表

KabiWord では、表というオブジェクトは存在せず、スペースや改行で本文中に揃えられた文字列アイテムに、線分を重ねるだけである。線分は始点にタグを挿入し、タグの値として線分の長さを指定する。

<x- N> 「基本フォントサイズ*N/2」の長さの線分を右に向かって引く。始点の Y 方向は文字下端に一致
<x^ N>  同上、ただし、始点の Y 方向は前行との中間に一致
<x_ N>  同上、ただし、始点の Y 方向は前行との中間に一致
<y- N> 「基本フォントサイズ*N/2」の長さの線分を下に向かって引く。始点の Y 方向は文字下端に一致
<y^ N>  同上、ただし、始点の Y 方向は前行との中間に一致
<y_ N>  同上、ただし、始点の Y 方向は前行との中間に一致

線分の Y 方向の位置は(それが X軸 方向に引かれるものであれ、Y軸 方向に引かれるものであれ)「前行との中間」「文字下端」「次行との中間」の三つから選ぶことができる(そして、^ や - や _ は、始点の Y 方向の位置を表している)。直線の長さは、フォントサイズの 1/2 を一単位として、0以外の数を指定する(負の数は左側・上側に向かって線分が引かれる)。

アンダーラインは、たんに <x- N> を使えばよい。

線分の太さは、表罫(細い)と裏罫(太い)の二種類を指定でき、表罫がデフォルト。アンダーラインにも適用される。(線分に太さとあありえないなんてツッコまないように)

<omotekei>  以後罫線を 0.2 ポイントにする。効果はそのページが終わるまで。
<urakei>    以後罫線を 1 ポイントにする。効果はそのページが終わるまで。

もっとも簡単で生産性がある表は、

<x_ 27><g>国名           首都
日本           東京
アメリカ       ワシントン

のようにすればよく、

と出力される。もっと生産性が悪くそれほど美しくもない表を作るには、

<x_ 27><x^ 27><y^ 3><g> 国名          <y^ 3> 首都       <y^ 3>
<x_ 27> 日本           東京
<x_ 27> アメリカ       ワシントン

のようにすれば、

のようになる。なお、第 n 行に書いた <x_ any> と、第 n+1 行に書いた <x^ any> は一致する。エディタの入力が読みにくいという向きは、下の「おまけ」を参照(Emacs ユーザ専用の解決法だけど)。

おまけ

KabiWord 用の原稿にタグを挿入すると、原稿が読みらくなる。また、行の横幅をそろえるのも困難になってしまう。そこで、 Emacs 用に、タグを一時的に隠すコマンドを書いてみる。kabiword-hide-tag と、kabiword-show-tag である。kabiword-hide-tag はタグを隠して、隠されたタグがある行を茶色で表示する。この状態で fill 系のコマンドを使うと、Emacs はタグを無視して整形してくれる。kabiword-show-tag は、タグを赤色で表示する。(たぶんオーバレイで書くべきだろうが、めんどくさがってテキスト属性で書いてしまった)

(defface kabiword-hiddentag-face
  `((t (:foreground "#800000")))
  "when having hidden tag")

(defface kabiword-tag-face
  `((t (:foreground "#ff0000")))
  "when having hidden tag")

(defun kabiword-hide-tag ()
(interactive)
  (save-excursion
    (let (old-undo-list buffer-undo-list)
      (goto-char (point-min))
      (while (re-search-forward "<[^<>]+>" nil t)
	(put-text-property (match-beginning 0) (match-end 0) 'invisible t)
	(save-excursion
	(put-text-property (progn (beginning-of-line)(point)) (progn (end-of-line)(point))
			   'face 'kabiword-hiddentag-face)))
      (setq buffer-undo-list old-undo-list))))

(defun kabiword-show-tag ()
(interactive)
(let (old-undo-list buffer-undo-list)
  (save-excursion
  (remove-text-properties 1 (point-max) '(invisible nil))
  (put-text-property 1 (point-max) 'face 'default)
  (goto-char (point-min))
  (while (re-search-forward "<[^<>]+>" nil t)
    (add-text-properties (match-beginning 0) (match-end 0) '(face kabiword-tag-face rear-nonsticky font))))
  (setq buffer-undo-list old-undo-list)))

 kabiword-show-tag ↓ ↑ kabiword-hide-tag

 

本当にただのメモ

Ubuntu 10.04 にローカルなことも多いけど、備忘。

[メモ]run   オペレータについて   http://umech.mit.edu/aja/linux/tapedrive.php   の
"Thoughts on the PostScript run operator"

[メモ]evince は見るファイルごとに複数のバックエンドを使い分けている。postscritp を
見るときは、libspectre であり、PDF を見るときは、Poppler らしい。また、libspectreは、
libgs に依存しているという。

[メモ]ps2pdf は、findfont をプロローグ部分のみで行い、各ページで行うことがないよう
にしないとエラーになる。

[メモ]私は Ubuntu 10.04 の上で ghostscript 8.71 と evince 2.30.3 を使っているが、ど
ちらも/var/lib/defoma/gs.d/dirs/fonts/ にある cidfmap と Fontmap いうファイルに定義さ
れた、フォント名と実際のフォントへのパス、それからエイリアスを利用しているようである。
(http://kmuto.jp/d/index.cgi/debian/debian-gs-fonts.htm   に  「Debian  Squeezeでの
Ghostscriptフォント設定方針」という話が載っている)。Ubuntu で defomaとの関係がどうなっ
ているのか、調べていない。

[メモ]ちなみに、私の cidmap ファイルには、以下のような 4 行が含まれている。あれ
やこれやインストールした後でのことなので、素の Ubuntu でこの通りに書いても、うまくい
く保証はない。
1:  /IPAMincho << /FileType /TrueType /Path
    (/usr/share/fonts/truetype/ipafont/ipam.ttf) /SubfontID 0 /CSI [(Japan1) 0]
    >> ;
2:  /IPAGothic << /FileType /TrueType /Path 
    (/usr/share/fonts/truetype/ipafont/ipag.ttf) /SubfontID 0 /CSI [(Japan1) 0]
    >> ;
3:  /Ryumin-Light /IPAMincho ;
4:  /GothicBBB-Medium /IPAGothic ;
私の使っている Ubuntu で、はじめ ghostscript は Ryumin-Light を Sazanami によってで置き換える
ようになっていた。

[メモ]私のところでは、リュウミンライトはIPA明朝
(/usr/share/fonts/truetype/ipafont/ipam.ttf にある)に割り当てられているが、これは欧
文グリフが見やすくない。欧州文字だけ別のフォントにしたい。そのためには IPA 明朝の欧文
グリフだけを差し替えてしまうのが、本道(のような気がする)。IPA 明朝を fontforge で開
いて、欧文文字だけ「編集」→「クリア」して、「エレメント」→「フォントの統合」で欧文
フォントを選択すれば、簡単に二つのフォントを合成できる。このとき、欧文フォントが巨大
になってしまったりするなら、あらかじめ、欧文フォントを開いて「エレメント」→「一般情
報」を開き、「高さ」と「深さ」をIPAフォントに合わせておいてやればよい。しかし、よくわ
からないエラーがたくさん出てうまくいかないことが多い。奥が深くて届かない感じだ。

[メモ]Postscript への EPS 埋め込みの方法については、Adobe が出している
eps_5002.pdf (92年5月1日)という文書の、19ページの Preparation for Including an EPS
File というところを見ればよい。

[メモ]私の Ubuntu には ps2epsi というシェルスクリプトがインストールされている。
ps2eps で BoundingBox がおかしくなるときにも、こいつがちゃんとやってくれることがあっ
た。

[メモ]KabiWord で作成した Postscript ファイルは、ps2pdf で正常に pdf 化することがで
き、これは evince や Adobe のリーダーで読めた。less でテキストだけ読むこともできる。
コピー&ペーストも可能。ただ、Mac の「プレビュー」は、これを読もうとすると落ちてしま
う。CID マップの問題かもしれないが、よくわからない。

[メモ]Postscript はラスタ画像を埋め込むときに jpeg の圧縮方式をサポートしている。
imagemagick と呼ばれる一連のコマンドのうち、convert コマンドで、
$ convert abc.jpg abc.eps2
とすると、jpeg 圧縮を使った eps が作れる。その結果、サイズはほとんど元の jpeg と
変わらない。そして、表示するにも(多くの環境において)時間が短縮される。
$ convert abc.jpg abc.eps
とすると、この圧縮が使われないから注意。
ただ、残念ながら jpeg 圧縮を使うと、sed が予定していない内容がパターンスペースに
入れられることになり、embedeps.sed がうまく機能しないことがある。sed の限界である。
――目次――
HOME雑文写真壁紙馬鹿読書語学
│├英語
│└日本語電算地理
│└白地図ブログ