在几个标点符号处中断内联方程

在几个标点符号处中断内联方程

我正在尝试定义一个命令,该命令自动允许在内联方程式中的几个标点符号处换行 - 我知道\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}

得到期望的结果:

<code>breakpunc</code> 结果

但是,当我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{}{}{}

在此处输入图片描述

相关内容