使角色在巨集中處於活動狀態

使角色在巨集中處於活動狀態

我以為我很聰明,所以我把這段程式碼本地允許將內聯數學中斷到巨集中:

\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在掃描 的 body時, ,in\def,尚未將 catcode 設為 13,掃描後 catcode 將被保存,因此不會受到定義主體內的 catcode 更改的影響,因此 TeX 會抱怨控制序列後失踪/def。使用 Plain TeX 代替 LaTeX 可以給出更直觀的錯誤訊息:

! Missing control sequence inserted.
<inserted text> 
                \inaccessible 
<to be read again> 
                   ,
\MakeCommaBreakable ... {,} \catcode `\,=13 \def ,
                                                  {\ifmmode \OldComma \discr...
l.12 \MakeCommaBreakable

我假設你想要一個可破壞的命令,但是 only 存在一些問題\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

相關內容