私は自分が賢いと思っていたのでこのコードインライン数式内の改行をマクロ内でローカルに許可するには:
\documentclass{article}
\def\MakeCommaBreakable{%
\def\OldComma{,}
\catcode`\,=13
\def,{%
\ifmmode%
\OldComma\discretionary{}{}{}%
\else%
\OldComma%
\fi%
}%
}
\begin{document}
\MakeCommaBreakable
$xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx$
\end{document}
さて、これは失敗します。最初のエラー:
! Missing control sequence inserted.
<inserted text>
\inaccessible
l.14 \MakeCommaBreakable
このエラーの原因は何ですか?
答え1
コツはコンマを数学アクティブ
こうすることで、コマンドは\MakeCommaBreakable
適切に実行され内部数式なので、数学活性化の効果は限定されます。
\documentclass{article}
\usepackage{amsmath}
\newcommand{\MakeCommaBreakable}{%
\mathchardef\normalcomma=\mathcode`,
\begingroup\lccode`~=`,\lowercase{\endgroup\let~}\BreakableComma
\mathcode`,="8000
}
\newcommand{\BreakableComma}{%
\normalcomma\mspace{0mu plus 6mu}\penalty0
}
\begin{document}
$\MakeCommaBreakable xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx,
xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx,
xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx$
\end{document}
コードに何が問題なのですか?
まず、たとえ固定されていたとしても、外側のレベルでコンマをアクティブにしているので、良いことしかし、これが主な理由ではありません。TeX が の定義を読み込むと\MakeBreakableComma
、置換テキストはトークン化され、,
カテゴリ コード 12 を持つため、 に従うことができません\def
。
このトリックを使用すると、カテゴリ コードが変更されない\lowercase
ため、TeX はアクティブなコンマを認識します。\lowercase
あなたかもしれないカンマをアクティブにする代わりに数式をアクティブにすることもできますが、アクティブにすると、たとえばオプションの指定で使用できなくなるため、お勧めしません。数式アクティブ文字は、TeX が数式コードを調べるときにのみ「アクティブ ドレス」を身に付けます。
完全性のために、外側のレベルにも配置し\MakeBreakableComma
、全て数式内のカンマは分割可能になります。 のようなものを分割したくないので、絶対にお勧めしませんf(x,y)
。
答え2
\def\MakeCommaBreakable
の本体がスキャンされた時点では、,
の\def,
catcode はまだ 13 に設定されていません。 のスキャン後に catcode が保存されるため、定義本体内の catcode の変更による影響を受けません。そのため、TeX は の後に制御シーケンスが欠落しているとエラーを出します/def
。LaTeX の代わりに Plain TeX を使用すると、より直感的なエラー メッセージが表示されます。
! Missing control sequence inserted.
<inserted text>
\inaccessible
<to be read again>
,
\MakeCommaBreakable ... {,} \catcode `\,=13 \def ,
{\ifmmode \OldComma \discr...
l.12 \MakeCommaBreakable
ブレーク可能なコマンドを取得したいのだと思いますが、 のみでは問題があります。\discretionary{}{}{}
行に伸縮可能なスペース (グルー) がない場合、TeX はほとんどの場合、オーバーフル ボックスを報告します。 ニーズに応じて、グルーが必要かどうか、またはそのサイズを変更するかどうかが決まります。
正しい方法は次のとおりです。
\bgroup
% make sure it is defined before catcode change to prevent infinite expand
\gdef\OldComma{,}
\catcode`\,=13
\gdef\MakeCommaBreakable{%
\catcode`\,=13
\def,{%
\ifmmode
% You don't need to place % after control token, because
% TeX already ignores them.
% Also, consider use math glue to give some adjustable spacing, otherwise
% TeX would almost always report overfull box for a long line like this
\OldComma\>\allowbreak
\else
\OldComma
\fi
}%
}
\egroup
\MakeCommaBreakable
$xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx, xxx$
\bye