Einen Charakter in einem Makro aktivieren

Einen Charakter in einem Makro aktivieren

Ich dachte, ich bin schlau, also habe ichdieser Codeum lokal Unterbrechungen innerhalb der Inline-Mathematik in einem Makro zuzulassen:

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

Dies schlägt nun fehl. Erster Fehler:

! Missing control sequence inserted.
<inserted text> 
                \inaccessible 
l.14    \MakeCommaBreakable

Was verursacht diesen Fehler?

Antwort1

Der Trick besteht darin, das Komma zu machenmathematik aktiv

Auf diese Weise kann der Befehl\MakeCommaBreakable richtig ausgeführt werdeninnendie Formel, daher ist die Wirkung der mathematischen Aktivierung begrenzt.

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

Bildbeschreibung hier eingeben

Was ist das Problem mit Ihrem Code?

Erstens, selbst wenn es behoben ist, machen Sie das Komma auf der äußeren Ebene aktiv, was keingute Sache. Aber das ist nicht der Hauptgrund: Wenn TeX die Definition von liest \MakeBreakableComma, wird der Ersetzungstext tokenisiert und ,hat den Kategoriecode 12, sodass er nicht folgen kann \def.

Mit dem \lowercaseTrick erkennt TeX ein aktives Komma, da \lowercasesich die Kategoriecodes nicht ändern.

DukönnteMachen Sie das Komma aktiv statt nur mathematisch aktiv, aber ich würde es nicht empfehlen, denn wenn es aktiv ist, können Sie es beispielsweise nicht in Optionsspezifikationen verwenden. Ein mathematisch aktives Zeichen nimmt stattdessen nur dann das „aktive Gewand“ an, wenn TeX mathematische Codes untersucht.

Der Vollständigkeit halber könnte man auch \MakeBreakableCommaauf der äußeren Ebene platzieren, undalleKommas in mathematischen Formeln würden umbrechbar: definitiv nicht empfohlen, da Sie nichts wie zerstören möchten f(x,y).

Antwort2

Als \def\MakeCommaBreakableder Text von gescannt wurde, war ,in \def,noch nicht der Catcode auf 13 gesetzt. Nach dem Scannen wäre der Catcode gespeichert und somit nicht von Catcode-Änderungen im Definitionstext betroffen. TeX würde daher melden, dass die Steuersequenz nach fehlt /def. Die Verwendung von Plain TeX anstelle von LaTeX kann eine intuitivere Fehlermeldung ergeben:

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

Ich nehme an, Sie möchten einen Befehl zum Unterbrechen, aber es gibt ein Problem mit only \discretionary{}{}{}, dass TeX fast immer das überfüllte Feld bemängelt, wenn in einer Zeile kein dehnbarer Raum (Klebstoff) vorhanden ist. Je nach Bedarf möchten Sie diesen Kleber vielleicht oder vielleicht auch nicht oder ändern die Größe.

Der richtige Weg könnte sein:

\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

verwandte Informationen