この連載もついに200回、リニューアル前を含めると16年ほど続いているわけだが、OS Xの中身は大きく変わった。数えあげればキリはないが、FinderやDockはもちろんのこと、Mail.appやPreview.appといった最初期から存在するアプリケーションも機能的には別モノに近い。我らがTerminalもまた然りだ。

これまで何度か触れてきたが、筆者は"枯れた"文書作成システムを利用している。「LaTeX(ラテフ)」だ。企画書などクライアントに提出するものはもちろん、名刺や年賀状の宛名など細々としたものまで、テキストを主体とする文書のほとんどはLaTeXで用意している。文書を一種のコードで記述するわけだから、ソフトのアップデートによる互換性喪失は一切なし、NEXTSTEP 3.3Jの頃に作成したソース(TeXファイル)をいまだに使い回しているほどだ。

しかし、印刷システムは一変した。Public Beta以来LPRを採用してきたOS Xは、Jaguar(v10.2)のとき「CUPS(Common Unix Printing System)」に変更している。いまやLinuxやFreeBSDなど他のUNIX系OSでもお馴染みのCUPSだが、大々的に採用したのはOS Xが最初。CUPSの開発元を買収してOS Xへのインテグレーションを開始したほどだから、当時の気合いが伺えるというものだ。

LPRとの一部互換性やネットワーク透過の管理機能など、CUPSの特長はこの15年でほぼ語り尽くされた感はあるが、先日なにかの拍子に「cupsfilter」コマンドの存在を思い出した。"ペーパーレス社会"が進展したためか、以前に比べプリンタ周りをあれこれすることは減ったし、LaTeXで生成したDVIファイルも「dvipdfmx」でPDFに変換するようになったため、CUPSの存在をあまり意識しなくなっていたのだ。

とはいえ、なかなか使い勝手のいいこのコマンド。TerminalからPDFを生成するには、なかなか魅力的な機能を備えている。かんたんかつ実用的な使いかたから、LaTeX使いならばニヤリとする使いかたまで、紹介してみよう。

最近LaTeXで作成した、Raspberry Pi用オーディオケースの説明書。筆者はワープロソフトやDTPソフトよりLaTeXが性に合う

プレインテキストをPDFに変換

手はじめは、プレインテキストのPDF変換がいいだろう。cupsfilterデフォルトのPPDファイルを使う場合、エンコード形式はUTF-8でなければならないが、そこさえクリアしていれば「TextEdit」などのアプリケーションを使わずとも、プレインテキストから直接PDFを生成できる。

この場合の使いかたはかんたん、プレインテキストを引数とし、リダイレクトによりPDFを生成すればいい。カレントディレクトリにUTF-8エンコードの「sample.txt」があるとき、以下のとおり実行すれば「out.pdf」を得られるはずだ。

ただし、1行あたりの最大字数は全角換算で58字であり、超えた部分は折り返されずに溢れたままとなってしまう。適当な位置に改行を入れつつ利用せねばならないことは、かなりのマイナスポイントといえるだろう。

$ cupsfilter sample.txt > out.pdf

このように、リダイレクトでプレインテキストからPDFを生成する

1行で全角換算58字を超えたぶんについては溢れてしまうため、適当な位置で改行しておかなければならない

自作フィルタでDVIファイルをPDFに変換

cupsfilterに限らず、CUPSでは印刷対象ファイルのMIMEタイプをチェックし、どのフィルタを使い出力処理するかを決定する。プレインテキストの場合、ファイル先頭1KBが印刷可能な文字であることを判断材料としており、それはCUPSのMIMEタイプ定義ファイル(/usr/share/cups/mime/mime.types)に記載されている。

このMIMEタイプは、/etc/cupsに「.types」ファイルを用意することで追加できる。さらに「.convs」ファイルも用意すれば、「*.types」で定義したMIMEタイプで使用するフィルタを指定できる。

そう、筆者が考えたのは、dvipsを利用してDVIファイルをPDFに変換するフィルタ。高機能なdvipdfmxがある現在、車輪の再発明という気がしないでもないが、cupsfilterのカスタマイズには格好の材料といえる。

用意したファイルは、以下の3つ。「string(0,<F702>)」のうち「F702」はDVIファイルの先頭2バイトであり、これでDVIファイルを識別できる。local.convsでは、DVIファイルのMIMEタイプが検出されると、/usr/libexec/cups/filterディレクトリに置いたシェルスクリプト「dvi2ps」が呼び出される、というものだ。

このシェルスクリプトは引数をとることができるが、その内訳はcupsfilterを実行したときに出力されるデバッグメッセージで確認できる。この「dvi2ps」では、第4引数(印刷枚数)と第6引数(入力するファイル名)だけを利用しているが、タイトル(第3引数)なども設定可能だ。

・/etc/cups/local.types

application/x-dvi dvi string(0,<F702>)


・/etc/cups/local.convs

application/x-dvi application/postscript 40 dvi2ps


・/usr/libexec/cups/filter/dvi2ps(chmodで実行権限を与えること)

#!/bin/bash

maisuu="$4"
file="$6"

if [[ -z $file ]]; then
    /Applications/UpTeX.app/Contents/Resources/TEX/texbin/dvips -q -C $maisuu -f
else
    /Applications/UpTeX.app/Contents/Resources/TEX/texbin/dvips -q -C $maisuu -o - "$file"
fi

これで、CUPSを再起動すればcupsfilterコマンドでDVIファイルをPDFに変換できるようになる。筆者の名刺の裏面(英語、カスタムフォント不使用)で試したところ、ほぼ一瞬で処理は完了。プロパティで調べると、ファイルサイズに差はあるものの(フォントの処理は同様にType 1フォントのビルトイン)、dvipdfxmで生成したものと外観に違いはない。macOS組み込みのPS→PDF変換フィルタ(Apple pstopdffilter)はCJKフォントに対応しないため、日本語文書は文字化けしてしまうが、英文であれば問題なく使えそうだ。

追加したMIMEタイプ(application/x-dvi)がきちんと検出されていることがわかる

macOS組み込みのフィルタでは日本語を含むPSファイルを扱えないが、英文であればcupsfilterでも処理できる