4

I am trying to define a command which automatically allows linebreaks inside inline equations at several punctuation characters — I am aware of \allowbreak but don’t want to manually insert it; here, I am dealing with the comma and the semicolon.

Following this thread, I wrote the following:

\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}

which gives the desired result:

<code>breakpunc</code> result

However, when I load the babel package with French language, the TeX engine enters an infinite loop during compilation. I am not familiar with category codes but, in all likelihood, there is a conflict between frenchb and the way I make the characters , and ; active and redefine them. I noticed that everything seems to be fine if I only deal with the comma in the command \breakpunc.

I am willing to make a local redefinition of the characters , and ; so there might be a “better” and cleaner solution to achieve what I want, a solution which would not conflict with what other packages make with those characters. My question is: do you know one?

MarcRdC
  • 379
  • The breqn package also provides support for breaking displayed math. –  Dec 13 '12 at 18:08
  • @MarcvanDongen Seems a bit too much for my concern and mainly focuses on “displayed math expressions”. – MarcRdC Dec 13 '12 at 18:16

1 Answers1

3

You go into infinite loop because the French module of babel activates the semicolon and so your \gdef;{...} is overridden.

Just delay the activation:

\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}

You seem to be too worried about spurious spaces. Don't. ;-)

Here we use the fact that the active semicolon, when not in horizontal mode, expands to \string;, which is precisely what's needed for the \mathcode`\;=\string"8000 trick to work. This is a bit slower than the other code, but is independent of the global status of the semicolon or the comma as active characters.

Using \penalty0 is more efficient than \discretionary{}{}{}.

enter image description here

egreg
  • 1,121,712
  • O.K., I get it more or less. Thank you very much. Why \let rather than \def inside \lowercase? And, yes, I hate spurious spaces; they fooled me in the past. :-) – MarcRdC Dec 13 '12 at 20:53
  • 1
    @MarcROGERdeCAMPAGNOLLE \let is just more efficient, we spare one expansion at each use of the math active comma or semicolon. – egreg Dec 13 '12 at 20:58