¿Por qué mi macro es frágil en un título? ¿Puedo hacerlo más sólido?

¿Por qué mi macro es frágil en un título? ¿Puedo hacerlo más sólido?

El siguiente código detiene la compilación incluso si el resultado es bueno si se ignora el mensaje.

¿Por qué mi macro es frágil? ¿Puedo hacer que aquí sea más sólido?

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

Registro :

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)


Respuesta1

Para una discusión en profundidad de lo que hace que un comando sea "robusto" o "frágil", consulte¿Cuál es la diferencia entre comandos frágiles y robustos?

Además de \protectejecutar un comando frágil, como lo hace en \subsubsection{Conditional: \protect\txtIf{}}, hay (al menos) dos formas de lograr colocar el comando en cuestión en el argumento de un comando "en movimiento":

  • Haga que el comando sea robusto desde el principio, definiendo with \DeclareRobustCommanden lugar de with \defo \newcommand.

  • Haga que el comando sea robusto después de haber sido creado, cargando el etoolboxpaquete y ejecutando

    \robustify{\fragilecommand}
    

    P.ej, \robustify{\txtIf}.

información relacionada