1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

『苦しみのTeX言語プログラミング』をLaTeXで楽しむ方法

Last updated at Posted at 2025-05-28

今から1年前の技術書典技術書典16)において『苦しみのTeX言語プログラミング』という本(著者はやまいも氏)が出展されました。

タイトルや表紙絵を見た感じ、トッテモ楽しそう(苦しそう)な本ですね。この記事では本書を利用して「LaTeXでTeX言語を楽しむ(苦しむ)方法」について解説します。

この記事ではTeX言語関連の用語を『苦しみのTeX言語プログラミング』に合わせています。そのため私がいつも使っている用語体系と異なる場合があります。

『苦しみ』がスバラシイ話

本書の一番スバラシイ点は、何といっても​「絶版でないこと」​でしょう(えっ:astonished:

TeX言語を学習しようと考えた人なら知っていると思いますが、TeX言語の参考書の定番として挙げられている本は大概が絶版になっています。今ではAmazonで古本が入手できるため困難さは少しマシになりましたが、それでも定番の本にはプレミア付き価格が付いていたりします。TeX言語の学習が挫折しやすいことを考え合わせると、手を出しにくいのは確かです。

その点、本書は最近発刊された同人書籍であるため、少なくとも電子書籍ならいつでも確実に入手できます。しかも(電子書籍版は)700円という低価格です。挫折のリスクを恐れる必要なく気軽にTeX言語の学習を始められます。

『苦しみ』をLaTeXで楽しむ話

さてそんなスバラシイ『苦しみのTeX言語プログラミング』ですが、注意点もあります。それは本書がplain TeXを対象としているということです。「TeX言語を学習したい」という人の多くが実際に想定しているのは「LaTeXフォーマット上でのTeX言語」でしょう。もちろん、plain TeXの実行の方法は本の中で説明されています1し、また本書の範囲のTeX言語の説明の“ほぼ全て”はLaTeXでも通用する2ため、plain前提であることはそれほど問題にはならないはずです。ただし本書に載っているプログラムをLaTeXで実行する3には工夫が必要です。​「LaTeXでTeX言語したい」​という人のためにその方法について解説します。

LaTeXで実行する場合に問題になるのは​「\endが使えない」​ということです。plainの\endは「TeXの処理系を終了させる」ための命令であり、本書においてプログラムの終了のために使われています4

plain TeX
\input{stdio}% 本書の'stdin.tex'
\WriteStdout(Hello!)

% \end で終了する
\end

対して、LaTeXでは\endは「環境の終了を表す」命令で、例えば\end{itemize}のように使われるのでした。つまりLaTeXの\endはplainとは別の物であり、\endでプログラムを終了できません。

「LaTeXを終了させる方法」といって思いつくのは\end{document}です。しかしこれは「文書の本文5の終端を示す」ものであるので、これを使うならまず「文書の本文を開始させておく」必要があります。結局、次のように「空の文書を作るコード」を書かないといけないわけです。これはいかにも面倒です。

LaTeX
\input{stdio}
\WriteStdout(Hello!)

% ↓これで終了できる(面倒😟)
\documentclass{article}
\begin{document}
\end{document}

幸いなことに、LaTeXにも「途中で強制終了させる」ための\stopという命令があります。これを実行すると、まだ\documentclassが実行される前6であってもLaTeXを終了できます。結局、本書のプログラムをLaTeXで実行させたい場合は\endの代わりに \stop と書けばいいことになります。

LaTeX
\input{stdio}
\WriteStdout(Hello!)

% LaTeXでは \end の代わりに \stop で終了する😃
\stop

もし「plainとLaTeXの両方で同じプログラムのファイルを実行させたい」という場合は、以下のコードをどこかに書く(例えばstdio.texの末尾に追記する)といいでしょう。

\ifx \stop\undefined \let \stop = \end \fi

このコード7を実行すると、plainでもLaTeXでも\stopで終了できるようになります。

LaTeXのチョットいい話

これまで「LaTeX上でTeX言語を楽しむ(苦しむ)方法」を説明しました。実は、TeX言語のプログラミングを行うのにLaTeXを使うと、plainを使うときに比べてメリットがあります。それは「LaTeX独自のプログラミング用の機能が使える」という点です。

LaTeXの標準入出力の話

ここではLaTeXの標準入出力関連の命令を紹介します。\ReadStdin\WriteStdoutの代わりにこれらの命令を利用することでstdio.texの読込を省略できます。

  • \typeout{‹出力トークン列›}: 引数の‹出力トークン列›(を展開8したもの)を端末に出力する。
    ※要するにWriteStdout(‹出力トークン列›)と同じ。

  • \typein[\制御トークン]{出力トークン列}: まず‹出力トークン列›を出力して、その後に端末からの入力を待つ。入力を(入力プロセッサで)トークン列に変換した上で、\制御トークンを「そのトークン列に展開されるマクロ」として定義する。
    ※最初に出力があることを除いてReadStdin(\制御トークン)と同じ。

例えば、本書のリスト1.2(hello.tex)と同等9のプログラムを、LaTeX上ではstdio.texを使わずに次のように書けます。

hello.tex
% 端末からの入力を \Name に代入
\typein[\Name]{What is your name?}

% 文字列を出力
\typeout{Hello, \Name.}

% LaTeXなので \stop で終了
\stop

ifthenパッケージする話

LaTeX上で条件分岐を行うためのパッケージとしてifthenパッケージがありますが、このifthenはTeX言語のプログラムを書くときにも利用できます。TeX言語の生の条件分岐やループ構成よりも使いやすいかも知れません。

ただし本書のような「組版しないTeX言語のプログラム」を書く時には注意すべき点があります。LaTeX文書の中でパッケージを読むには普通は\usepackage命令を使うわけですが、\documentclassをまだ実行していない状態でパッケージを読み込みたい場合は\usepackageは使えず、代わりに \RequirePackage という命令を使う10必要があります。

例えば、本書のリスト4.8の中の\CheckInRange\ifthenelseを用いて次のように明快に書くことができます。

% \RequirePackage でパッケージを読み込む
\RequirePackage{ifthen}

\def \CheckInRange(#1<=#2<=#3){
    \ifthenelse {\NOT #2<#1 \AND \NOT #3<#2} {
         \InRangetrue
    }{
         \InRangefalse
    }
}

また、リスト5.2の中の\RepeatImplは以下のように\whiledoを利用したループで書けます。

\RequirePackage{ifthen}

\def \RepeatImpl{
    \whiledo {\LoopCount > 0} {
        \LoopBody
        \advance \LoopCount by -1
    }
}

まとめ

冒頭で技術書典の話をしましたが、5月31日から11「技術書典18」が開催されます。開催期間中であれば『苦しみのTeX言語プログラミング』の紙書籍が入手可能です12

またTeX言語に関していうと、技術書典18では新刊の『作ってわかるTeX言語』という本(著者はだめぽラボ)も出展されます。

「TeX言語に少し関心があるけど、参考書が入手困難だから手が出しづらかった…」という人には今は絶好のタイミングといえます。技術書典18を契機にして、素敵:scream:なTeX言語の世界に足を踏み入れてみましょう!:information_desk_person:

  1. コマンドシェル上の実行を前提としているため単に「lualatexの代わりにluatexを実行する」というだけの話ですが。

  2. 本書の「はじめに」の節の注釈では「plain TeXのコア」と書かれています。恐らく『TeX by Topic』の「‘core’ of plain TeX」と同じ概念を指しているのでしょう。

  3. つまりplatexとかpdflatexとかlualatexとかの、いつも文書を組版するときに使っているコマンドを使うということです。なお、本書は「組版をせずに端末に何かを出力するプログラムを作る」というコンセプトのため、文書作製用の統合環境(LaTeX Workshop)を利用することは難しいと思います。

  4. 実際にはほとんどのコード例に\endは書かれていませんが、これがないとTeXが終了しないので、読者が適宜\endを補う想定なのでしょう。

  5. 文書の本文を表すのが「document環境」であり、その終了を示すのが\end{document}です。

  6. ちなみに、\documentclassの実行前にLaTeXを終了させた場合は補助ファイル(.aux)は出力されません。

  7. このコードは「\stopが未定義(つまりplain上での実行である)ならば\endと同義に定義する」という動作を表します。

  8. ここでの展開のルールは\WriteStdoutと同じ(実は\edefと同じ)です。厳密にいうと異なる点がある(\typeoutの方は“LaTeXレベルの保護”が有効になる)のですが、本書のレベルでは気にしなくていいでしょう。

  9. ただし\typeinは入力の前に何か出力する必要があるため、ここではWhat is your name?を出力しました。この点だけ元のhello.texと異なります。

  10. \RequirePackage命令の書式は\usepackageと全く同じです。なお、そもそも「\documentclassより前にパッケージを読む」こと自体がLaTeXではかなり特殊な状況なので、そういう使い方に対応していないパッケージもあることに注意してください。(ifthenパッケージは対応しています。)

  11. オフライン(リアル会場)での開催は6月1日(日曜)です。

  12. まあ、BOOTHではいつでも紙書籍が入手できるようですが。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?