golden-luckyの日記

ツイッターより長くなるやつ

%.texという名前のファイルをLaTeXで処理する方法

ふつう、コマンドの引数にファイル名を指定すれば、そのコマンドの実行プロセスに標準入力経由でファイルの中身が渡されると思いますよね。 ところがplatexとかpdftexなどのコマンドは、引数として指定されたものを、すべてTeXトークンであるかのように読み始めます。

ただし、そうやって読み始めるとき、「先頭の文字が \ でない場合だけは、その前に \input がついているとみなす」というルールがあります。 このルールのおかげで、たとえば次のようにコマンドを実行すると…

$ pdftex foo.tex

次のように実行したのと同じことになります。

$ pdftex \\input foo.tex

これはつまり、次のような1行だけを中身として持つファイルをpdftexコマンドに指定して実行したのと同じことです。

\input{foo}

したがって、もし次のようにすれば…

$ pdftex %.tex

次のような1行だけを中身として持つファイルを実行したのと同じことになります。

\input{%}

これらは、事実上同じというレベルでなく、完全に同じです。 なのでpdftexコマンドは、エラーを吐くでもなく、単に \input{ の続きをユーザが入力してくれるのを待ち続けます。

$ pdflatex %.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode

*

この動作の裏をかけば、次のような手順で、%.tex という名前のソースをTeX(以降はpdflatexを例にします)で処理することはできなくはなさそう?

1. `%.tex` の1行めに `\catcode`\%=14` と追記する

\catcode`\%=14
\documentclass{standalone}
\begin{document}
foo
\end{document}

2. pdflatex実行時にファイル名の前に ``\\relax\\catcode\`\\%=12\\input`` と指定する

$ pdflatex \\relax\\catcode\`\\%=12\\input %.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
LaTeX2e <2018-04-01> patch level 5
(./%.tex
(/usr/local/texlive/2018/texmf-dist/tex/latex/standalone/standalone.cls
Document Class: standalone 2018/03/26 v1.3a Class to compile TeX sub-files stan
 dalone
(中略)
Output written on %.pdf (1 page, 8374 bytes).
Transcript written on %.log.

どうしても % を含むファイルをTeXで実行したい場合は、「1をsedにやらせてから2をやる」みたいなシェルスクリプトを書くことになるのかなあ。