3

The follwoing code stops the compilation even if the output is the good one if the message are ignored.

Why my macro is fragile? Can I make here more solid ?

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

Log :

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)

projetmbc
  • 13,315

1 Answers1

4

For an in-depth discussion of what makes a command "robust" or "fragile", see What is the difference between Fragile and Robust commands?

In addition to \protecting a fragile command, as you do in \subsubsection{Conditional: \protect\txtIf{}}, there are (at least) two ways you can succeed in placing the command in question in the argument of a "moving" command:

  • Make the command robust from the outset, by defining with \DeclareRobustCommand instead of with either \def or \newcommand.

  • Make the command robust after it's been created, by loading the etoolbox package and executing

    \robustify{\fragilecommand}
    

    E.g., \robustify{\txtIf}.

Mico
  • 506,678
  • 2
    The LaTeX kernel defines, since 2015, \MakeRobust, which has the same effect as defining the command with \DeclareRobustCommand (as long as it was defined with \newcommand, of course, otherwise it just adds the usual \protect\command␣ mechanism) – Phelype Oleinik Sep 12 '20 at 11:52
  • 1
    @PhelypeOleinik - Thanks. I suppose I had a good reason for writing "there are (at least) two ways". :-) There's also \protected\def, \protected@edef, and problably a few others. Real quick: does \MakeRobust work on an already-existing command (à la \robustify) or on new commands as well? – Mico Sep 12 '20 at 11:57
  • 1
    I would use \NewDocumentCommand from the xparse package to define the command, commands defined with it are always robust (and xparse makes it easier to define a starred variant). – Ulrike Fischer Sep 12 '20 at 12:00
  • 1
    @Mico I know, I just had to advertise it, since I recently made some changes to make it exactly like \DeclareRobustCommand ;-) (and note that \protected@edef is entirely different from \protected\edef). Yes, \MakeRobust is quite similar to \robustify, except that it applies LaTeX2e's \protect mechanism to the macro, while etoolbox applies e-TeX's \protected. But the macro has to be already defined for it to work. – Phelype Oleinik Sep 12 '20 at 12:03
  • 4
    @PhelypeOleinik you should write an article about it :-) – Ulrike Fischer Sep 12 '20 at 12:05
  • @UlrikeFischer - I've made the answer a community wiki; please feel free to modify or add to it as you see fit. – Mico Sep 12 '20 at 12:23
  • @PhelypeOleinik - I've made the answer a community wiki; please feel free to modify or add to it as you see fit. – Mico Sep 12 '20 at 12:24