TeXの入出力プリミティブ

TeXの入出力プリミティブ

相互参照などの処理用の簡単なマクロをいくつか書いて、プレーン TeX で使用したいと思います。(Eplain にあるような専用のマクロがすでにあることは知っていますが、自分で別のものを試してみたいと思います。) そのためには、ファイルから読み取る方法とファイルに書き込む方法を知る必要があります。そのようなことを行う TeX プリミティブとは何ですか? どのように機能しますか?

もう一つの質問: TeX は実行中に他のプログラムを「呼び出す」ことができますか? つまり、C 言語にあるシステム関数に相当するものが TeX にあるのでしょうか?

答え1

TeXには、ファイルの読み取りと書き込みのための\readおよび\writeプリミティブがあり、もちろん\inputファイル全体を「ここに」入力することもできます。たとえば、LaTeX の相互参照メカニズムでは が使用されます\writeが、 の使用\read(行単位) を避けて、\input適切に設計されたセカンダリ ファイルで が使用されます。

\input理解するのは簡単なので、と\readに注目してみましょう\write。これらは両方ともファイル ストリームで動作します。ファイル ストリームには番号が与えられますが、通常は を使用して割り当てられます\new...。たとえば、

\newread\myread
\openin\myread=myinput %

\newwrite\mywrite
\immediate\openout\mywrite=myoutput %

\myreadは、 と呼ばれる読み取りと と呼ばれる書き込みを設定します。 :を\mywrite使用していることに注意してください。TeX ページ ビルダーの非同期の性質上、操作が「正しい」場所で行われるようにする必要があります。(詳細は後述します。)\immediate\write\write

2つのストリームを開いている場合、例えば出力に書き込むことができます。2つの書き込みを行う場合、1つは「今すぐ」、もう1つは「遅延」です。

\def\foo{a}
\immediate\write\mywrite{\foo}
\write\mywrite{\foo}
\def\foo{b}
Hello
\bye

結果はmyoutput.tex読む

a
b

これは、\write\mywriteがページが出力されるときにのみ実行される何とかを生成するためです。たとえば、書き込む内容にページ番号が含まれている場合、これは出力段階でのみわかるため、これは便利です。また、 は\writeのように動作することに注意してください。または を\edef使用して回避しない限り、すべてが展開されます。ただし、この展開は操作が実際に実行される瞬間に実行されるため、遅延 を使用する場合はマクロが適切に定義されていることを確認する必要があります。\noexpandtoks\write\write

この\readプリミティブは、(中括弧が一致しない限り) 一度に 1 行ずつ読み取り、通常の TeX の方法でトークン化します。\ifeofのテストを使用して、一度に 1 行ずつファイルをループするように設定できます\myreadが、前述したように、\input相互参照を含むファイルを単純にする方が簡単な場合がよくあります。

システムコールを実行したい場合、「純粋な」TeXはあまり役に立ちません。しかし、Web2cには長い間、システムへのエスケープを可能にする特別な「ストリーム」がありました。\write18これはセキュリティ上のリスクであるため、標準ではこのようなエスケープでは制限されたコマンドセットのみが許可されています。たとえば、次のようにすることができます。

pdftex --shell-escape myfile

すべてエスケープできるようにします。すべてのコードを自分で書いた場合のリスクは、混乱を起こすことだけです。 を実行しても、 TeX には何もフィードバックされません。何らかの方法で、おそらくセカンダリ ファイルを\write18使用して結果を読み取るようにする必要があります。\read

コメントに記載されているように、追加の構文拡張として が使用できます\input|"<command>"。これも によって制限されます\write18が、シェル コマンドからの入力を取得するための拡張可能なメソッドを提供します。

答え2

外部ファイルを介して相互参照を扱う場合のもう 1 つの特別な問題は、このファイルの読み取り、オープン、書き込み、およびクローズの順序です。基本的なスキームは次のとおりです。

\newwrite\fileout  % allocations of the file number

\def...     ... all macros which can be used in the file must be defined
\input file ... input only when file exists (the file doesn't exist at the first run)
            ... this input stores the data from file into internal macros
\immediate\openout\fileout=file  ... this removes the data from file
                                  ... the file has zero length now

... document ... macros used in the document write (typically not immediately) 
                 data to the file

\end ... this closes the file automatically, 
         but if you need to use the data from the file at the end of the document
         (for example the TOC at the end of the document):
\vfil\eject  
\immediate\closeout\fileout
\input file ... this creates the TOC at the end of the file.
\end

上記の図は、このファイルが存在する場合にのみファイルを読み取るマクロを作成する必要があることを示しています。このような目的には、\input次のマクロを使用できます。\softinput

\newread\testin
\def\softinput #1 {\let\next=\relax \openin\testin=#1
   \ifeof\testin \message{Warning: the file #1 does not exist}%
   \else \closein\testin \def\next{\input #1 }\fi
   \next}

関連情報