2019年2月3日

この例,思いっきり簡略化すると以下でエラーが起こるのと同様ではないかと思う.

\documentclass{article}
\begin{document}
  \halign{#\cr
  \iftrue
    A
    \cr
    X % この行がないとエラーは起こらない.
  \else
    \cr
  \fi
  \cr
}
\end{document}

これを実行すると

! Incomplete \iftrue; all text was ignored after line 7.
なるエラーが発生する.一見\iftrue\else\fiの釣り合いはとれているように見える.しかも「X」がないとエラーは起こらず,なんだか不思議である.

エラーの原因,次のような感じではなかろうか.まず\halignについて思い出しておこう.\halign

\halign{<u1>#<v1>&...&<un>#<vn>\cr % テンプレート行
<A1>&...&<An>\cr % 表の中身1行目
<B1>&...&<Bn>\cr % 表の中身1行目
...
<X1>&...&<Xn>\cr
}
のように使う.これを実行すると,
<u1><A1><v1>...<un><An><vn>
<u1><B1><v1>...<un><Bn><vn>
...
<u1><X1><v1>...<un><An><vn>
のような表組みがされる.

もちろん<ui>,<vi>,<Ai>にはマクロを含めることができる.このマクロ展開のタイミングは原則としては次の通り(だと思う).追記:ZRさんのつぶやきを参考に少し訂正.(まだあまりすっきりわかってない.)

  1. テンプレート行は,&\crを目印として区切られ,内部メモリに格納される.
  2. 次に<A1>を読む.まず展開のみが行われ,先頭に展開不可能なトークンが現れるまで展開が行われる.
  3. <A1>を展開して得られた部分の<v1>が挿入され,トークン化,展開,実行が行われる.このとき&または\crを見たら\endtemplateという特別なトークンを挿入する.これは\outerなマクロとして扱われる.また,この部分に<v1>を挿入する.
  4. \endtemplateに至ったらセルの構築を終了.
  5. 以下繰り返し.

さて,最初の例をこのルールに従って追跡してみよう.

  1. <A1>の先頭行は\iftrueは展開可能である.その次のAは展開できないため,ここまでで展開は終了する.
  2. 次の\crまででで一行目が完成.
  3. 二行目の先頭行はXであり,これは展開不可能.よって何も展開せずに終了.
  4. 二行目を作るために,TeXは読み込みを進める.このとき\elseの後の\crには\outerなマクロ\endtemplateが付随していると見なされる.
  5. ...X\else <\outerなマクロ>となりエラー.

「X」がない場合には,二行目の先頭行が\elseとなり,展開が進み条件分岐が先に完結するためエラーにならない.

0 件のコメント:

コメントを投稿

コメントの追加にはサードパーティーCookieの許可が必要です