我正在尝试定义一个命令,该命令自动允许在内联方程式中的几个标点符号处换行 - 我知道\allowbreak
但不想手动插入它;在这里,我正在处理逗号和分号。
下列的此主题,我写了以下内容:
\documentclass{article}
\makeatletter
\mathchardef\m@thcomma\mathcode`\,
\mathchardef\m@thsemicolon\mathcode`\;
{
\catcode`,=\active
\catcode`;=\active
\gdef,{\m@thcomma\discretionary{}{}{}}
\gdef;{\m@thsemicolon\discretionary{}{}{}}
}
\makeatother
\newcommand*{\breakpunc}[1]{%
\begingroup%
\mathcode`\,=\string"8000%
\mathcode`\;=\string"8000%
#1%
\endgroup%
}
\begin{document}
%
\framebox{%
\parbox{1cm}{%
\( \breakpunc{a, b, c; d, e, f} \)%
}%
}\quad%
%
\framebox{%
\parbox{1.5cm}{%
\( \breakpunc{a, b, c; d, e, f} \)%
}%
}%
%
\end{document}
得到期望的结果:
但是,当我babel
使用法语加载包时,TeX 引擎在编译期间会进入无限循环。我不熟悉类别代码,但很可能与frenchb
我创建字符,
并;
激活和重新定义它们的方式存在冲突。我注意到,如果我只处理命令中的逗号,一切似乎都很好\breakpunc
。
我愿意对字符进行局部重新定义,
,;
因此可能存在一个“更好”且更清晰的解决方案来实现我想要的,该解决方案不会与其他软件包使用这些字符所做的事情发生冲突。我的问题是:您知道吗?
答案1
您进入了无限循环,因为法语模块babel
激活了分号,所以您的\gdef;{...}
被覆盖了。
只需延迟激活:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\makeatletter
\mathchardef\m@thcomma\mathcode`\,
\mathchardef\m@thsemicolon\mathcode`\;
\def\m@thc@mma{\m@thcomma\penalty\z@}
\def\m@thsemic@lon{\m@thsemicolon\penalty\z@}
\newcommand*{\breakpunc}[1]{%
\begingroup
\mathcode`\,=\string"8000
\mathcode`\;=\string"8000
\begingroup\lccode`~=`,\lowercase{\endgroup\let~\m@thc@mma}%
\begingroup\lccode`~=`;\lowercase{\endgroup\let~\m@thsemic@lon}%
#1%
\endgroup
}
\makeatother
\begin{document}
\framebox{%
\parbox{1cm}{
\( \breakpunc{a, b, c; d, e, f} \)
}%
}\quad
\framebox{%
\parbox{1.5cm}{
\( \breakpunc{a, b, c; d, e, f} \)
}%
}
\end{document}
您似乎太担心虚假空格了。别担心。;-)
这里我们利用了这样一个事实:当非水平模式时,活动的分号会扩展为\string;
,这正是技巧奏效所需要的\mathcode`\;=\string"8000
。这比其他代码慢一点,但与分号或逗号作为活动字符的全局状态无关。
使用\penalty0
比 更有效率\discretionary{}{}{}
。