Einen Befehl robust (unzerstörbar) machen

Einen Befehl robust (unzerstörbar) machen

Wenn Sie \blettermit definieren \DeclareRobustCommand\bletter[1]{\textbf{#1}}, funktioniert es auch innerhalb von Abschnittsbefehlen einwandfrei. Wenn Sie es jedoch in einem \edefoder \xdef-Befehl verwenden möchten, \bletterwird es nicht funktionieren (außer wenn Sie definieren \let\protect\noexpand). Das bedeutet:

\xdef\boldyletter{\bletter{y}}wird eine Fehlermeldung ausgeben.

Gibt es einen Befehl zum Definieren stets ununterbrochener Befehle?

Antwort1

Sie können

\NewDocumentCommand\bletter{m}{\textbf{#1}} 

wodurch eine E-Tex- \protectedDefinition erstellt wird, die sich nicht in eine Edef erweitern lässt.

Sie sollten es jedoch nie \xdefbei unbekanntem Latex-Input verwenden. \protected@xdefDann sind die robusten LaTeX-Befehle geschützt.

Antwort2

\protected\defVerwenden Sie zur Deklaration Ihres Makros einfach Primitive \bletter:

\protected\def\bletter#1{\textbf{#1}}

Die \protectedMakros werden während \edef, \xdef, \write, \messageusw. nicht erweitert.

Antwort3

Entschuldigen Sie, dass ich meine Frage selbst beantworte, aber ich habe keine Ahnung, wie ich meine Lösung mit der Community teilen kann.

\def\RJDeclareRobustCommand#1% #1 name of new command, #2 same instructions as \newcommand
 {%
  \gdef#1%
   {%
    \begingroup%
     \let\relax\aftergroup% this has to be redefined before processing \csname @\string#1\endcsname
     \ifx\aftergroup\relax% this is false in expandations
      \expandafter\aftergroup\csname RJ@\expandafter\@gobble\string#1\endcsname%
     \else%  \expandafter\aftergroup\expandafter\noexpand\csname\expandafter\@gobble\string#1@RJ\endcsname%
     \fi%
    \endgroup%
   }%
  \expandafter\gdef\csname\expandafter\@gobble\string#1@RJ\endcsname%
   {%
    \begingroup%
     \let\relax\aftergroup% this has to be redefined before processing \csname @\string#1\endcsname
     \ifx\aftergroup\relax% this is false in expandations
      \expandafter\aftergroup\csname RJ@\expandafter\@gobble\string#1\endcsname%
     \else%
      \expandafter\aftergroup\expandafter\aftergroup\expandafter\aftergroup%
       \expandafter\noexpand\csname\expandafter\@gobble\string#1@RJ\endcsname%
     \fi%
    \endgroup%
   }%
%  read the instructions (see \new@command)
  \expandafter\new@command\csname RJ@\expandafter\@gobble\string#1\endcsname%
 }%
%

\RJDeclareRobustCommand\bletter[1]{\textbf{#1}}wird robust sein.

\xdef\boldyletter{\bletter{y}}funktioniert auch im Befehl einwandfrei \xdef\boldxyletter{x\boldyletter}}.

Antwort4

Vielen Dank für die sehr hilfreichen Antworten. Sie waren auch für mich eine Herausforderung, die ich gerne angenommen habe.

Um einen neuen Befehl in einer Kapitelüberschrift verwenden zu können, ist es unter anderem notwendig, den Befehl in \pdfstringdef hinzuzufügen und neu zu definieren. Dies war in meinem alten Code nicht berücksichtigt. Beim Hinzufügen dieser Anforderung konnte ich den Code auch optimieren.

Unten sehen Sie ein Testbeispiel mit dem neuen Code. Neue Befehle, nicht deren Argumente, werden in Lesezeichen ignoriert.

\documentclass[a4paper,12pt]{report}
\RequirePackage[pdftex,colorlinks,linkcolor=blue,%
                urlcolor=blue,bookmarksnumbered]{hyperref}
%
\makeatletter
%
\let\RJ@aftergroup\aftergroup%
\let\RJ@begingroup\begingroup%
\let\RJ@endgroup\endgroup%
\let\RJ@let\let%
%
\@ifundefined{pdfstringdefPreHook}{}%
 {%
  \gdef\Addpdfstringdef#1%
   {%
    \global\@temptokena\expandafter%
     {\pdfstringdefPreHook#1}%
    \xdef\pdfstringdefPreHook{\the\@temptokena}%
   }%     
%     
  \Addpdfstringdef%
   {%
    \let\RJ@aftergroup\@empty%
    \let\RJ@begingroup\@empty%
    \let\RJ@endgroup\@empty%
    \let\RJ@let\@empty%%
   }%  
 }% 
%
\def\RJ@DRCentry#1%
 {%
  \RJ@begingroup%
   \RJ@let\relax\RJ@aftergroup%
   \ifx\RJ@aftergroup\relax% 
    \expandafter\RJ@aftergroup\csname RJ@\expandafter\@gobble\string#1\endcsname%
   \else%
    \expandafter\noexpand\csname RJ\expandafter\@gobble\string#1JR\endcsname%
   \fi%
  \RJ@endgroup%
 }%
%
\def\RJ@DeclareRobustCommand#1% #1 name of new command, #2 same instructions as \newcommand
 {%
  \gdef#1%
   {%
    \ifx\RJ@aftergroup\@empty%
    \else%
     \expandafter\RJ@DRCentry\expandafter#1%  
    \fi%
   }%
%
  \expandafter\gdef\csname RJ\expandafter\@gobble\string#1JR\endcsname%
   {%
    \ifx\RJ@aftergroup\relax%
     \gdef\next{\RJ@DRCentry{#1}}%
     \RJ@aftergroup\next%
    \else%
     \expandafter\noexpand\csname RJ\expandafter\@gobble\string#1JR\endcsname%
    \fi%
   }%
%
  \@ifundefined{pdfstringdefPreHook}{}%
   {%
    \expandafter\Addpdfstringdef\expandafter%
     {\expandafter\let\csname RJ\expandafter\@gobble\string#1JR\endcsname\@empty}%
     }%
    \expandafter\new@command\csname RJ@\expandafter\@gobble\string#1\endcsname%
 }%
%
\RJ@DeclareRobustCommand\iletter[1]{\textit{\huge #1}}%
%
\xdef\yiletter{\iletter{y}}%
\xdef\xyiletter{\iletter{x}\yiletter}%
\xdef\xyziletter{\xyiletter\iletter{z}}%
\xdef\jiletter{\iletter{j\iletter{i}}}%

\begin{document}

 \tableofcontents

 \newpage

 test \iletter{j\iletter{i}}, \jiletter{} test \iletter{a}, \yiletter, \xyiletter, \xyziletter{} test

 \section{italic \iletter{y}, \xyziletter}

  The following chapter heading is for comparison purposes only .

 \section{italic \textit{\huge y}, \textit{\huge xyz}}

  more text

\end{document}

verwandte Informationen