Warum ist mein Makro in einem Titel fragil? Kann ich es stabiler machen?

Warum ist mein Makro in einem Titel fragil? Kann ich es stabiler machen?

Der folgende Code stoppt die Kompilierung, auch wenn die Ausgabe korrekt ist, wenn die Meldung ignoriert wird.

Warum ist mein Makro fragil? Kann ich es stabiler machen?

\documentclass[12pt,a4paper]{article}

\makeatletter
    \def\txtIf{\@ifstar\tnsalgo@txtIf@star\tnsalgo@txtIf@no@star}
    \def\tnsalgo@txtIf@no@star{\textbf{Si}}
    \def\tnsalgo@txtIf@star{\texttt{Si}}
\makeatother


\begin{document}

\subsubsection{Conditional: \protect\txtIf{}} % <-- OK

\subsubsection{Conditional: \txtIf{}}         % <-- KO

\end{document}

Protokoll :

This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020) (preloaded format=pdflatex 2020.9.12)  12 SEP 2020 13:22
entering extended mode
 \write18 enabled.
 file:line:error style messages enabled.
 %&-line parsing enabled.
**pdftex-titel-pb.tex
(./pdftex-titel-pb.tex
LaTeX2e <2020-02-02> patch level 5
L3 programming layer <2020-09-06>
(/usr/local/texlive/2020/texmf-dist/tex/latex/base/article.cls
Document Class: article 2019/12/20 v1.4l Standard LaTeX document class
(/usr/local/texlive/2020/texmf-dist/tex/latex/base/size12.clo
File: size12.clo 2019/12/20 v1.4l Standard LaTeX file (size option)
)
\c@part=\count168
\c@section=\count169
\c@subsection=\count170
\c@subsubsection=\count171
\c@paragraph=\count172
\c@subparagraph=\count173
\c@figure=\count174
\c@table=\count175
\abovecaptionskip=\skip47
\belowcaptionskip=\skip48
\bibindent=\dimen134
)
(/usr/local/texlive/2020/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
File: l3backend-pdftex.def 2020-09-11 L3 backend support: PDF output (pdfTeX)
\l__kernel_color_stack_int=\count176
\l__pdf_internal_box=\box45
)
(./pdftex-titel-pb.aux)
\openout1 = `pdftex-titel-pb.aux'.

LaTeX Font Info:    Checking defaults for OML/cmm/m/it on input line 11.
LaTeX Font Info:    ... okay on input line 11.
LaTeX Font Info:    Checking defaults for OMS/cmsy/m/n on input line 11.
LaTeX Font Info:    ... okay on input line 11.
LaTeX Font Info:    Checking defaults for OT1/cmr/m/n on input line 11.
LaTeX Font Info:    ... okay on input line 11.
LaTeX Font Info:    Checking defaults for T1/cmr/m/n on input line 11.
LaTeX Font Info:    ... okay on input line 11.
LaTeX Font Info:    Checking defaults for TS1/cmr/m/n on input line 11.
LaTeX Font Info:    ... okay on input line 11.
LaTeX Font Info:    Checking defaults for OMX/cmex/m/n on input line 11.
LaTeX Font Info:    ... okay on input line 11.
LaTeX Font Info:    Checking defaults for U/cmr/m/n on input line 11.
LaTeX Font Info:    ... okay on input line 11.

./pdftex-titel-pb.tex:13: Argument of \@sect has an extra }.
<inserted text> 
                \par 
l.13 \subsubsection{Conditional: \txtIf{}}
                                          
? 
Runaway argument?
{\normalfont \normalsize \bfseries }{\@firstoftwo {\tnsalgo@txtIf@star \ETC.
./pdftex-titel-pb.tex:13: Paragraph ended before \@sect was complete.
<to be read again> 
                   \par 
l.13 \subsubsection{Conditional: \txtIf{}}
                                          
? 
[1

{/usr/local/texlive/2020/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
(./pdftex-titel-pb.aux) ) 
Here is how much of TeX's memory you used:
 378 strings out of 480876
 6653 string characters out of 5907597
 243537 words of memory out of 5000000
 16086 multiletter control sequences out of 15000+600000
 535693 words of font info for 31 fonts, out of 8000000 for 9000
 1141 hyphenation exceptions out of 8191
 24i,4n,25p,181b,114s stack positions out of 5000i,500n,10000p,200000b,80000s
</usr/local/texlive/2020/texmf-dist/fonts/type1/public
/amsfonts/cm/cmbx12.pfb></usr/local/texlive/2020/texmf-dist/fonts/type1/public/
amsfonts/cm/cmr12.pfb>
Output written on pdftex-titel-pb.pdf (1 page, 17436 bytes).
PDF statistics:
 16 PDF objects out of 1000 (max. 8388607)
 10 compressed objects within 1 object stream
 0 named destinations out of 1000 (max. 500000)
 1 words of extra memory for PDF output out of 10000 (max. 10000000)


Antwort1

Eine ausführliche Diskussion darüber, was einen Befehl „robust“ oder „fragil“ macht, finden Sie unterWas ist der Unterschied zwischen fragilen und robusten Befehlen?

Neben dem \protectArgument „ing“ eines fragilen Befehls, wie Sie es in tun \subsubsection{Conditional: \protect\txtIf{}}, gibt es (mindestens) zwei Möglichkeiten, wie Sie den betreffenden Befehl erfolgreich in das Argument eines „beweglichen“ Befehls einfügen können:

  • Machen Sie den Befehl von Anfang an robust, indem Sie ihn mit \DeclareRobustCommandstatt mit entweder \defoder definieren \newcommand.

  • Machen Sie den Befehl robust, nachdem er erstellt wurde, indem Sie das etoolboxPaket laden und ausführen

    \robustify{\fragilecommand}
    

    Z.B, \robustify{\txtIf}.

verwandte Informationen