Check with if and usage of section*

You didn't count \expandafters well. Your test file should be:

\documentclass{article}

\newcommand\mySection[2]{
    \ifnum #2=1 
    \expandafter\section
    \else\expandafter\section\expandafter*%
    \fi
    {#1}
}

\begin{document}
    test
\mySection{title}{1}
\mySection{title}{0}

\end{document}

The general rule: the \expandafters chain must touch the \else in the first part of condition and the \fi in the second part.


Let's look at \if..\else..\fi-conditionals:

Expanding the \if... of an \if..\else..\fi while the \if..-condition is fulfilled yields evaluation and removal of the tokens that are needed for finding out whether the \if..-condition is fulfilled.

E.g., expanding the \ifnum of

\ifnum1=1 equal\else different\fi

yields: equal \else different\fi .

In further processing equal is carried out. After that \else is carried out/expanded.

The result of carrying out/expanding \else is removing the subsequent tokens including the matching \fi.

The previous sentence rephrased in other words:
Expanding the \else of an \if..\else..\fi while the \if..-condition is fulfilled yields removal of the tokens that form the "false"-branch and removal of the matching \fi.

E.g., (click the image to enlarge)

enter image description here

yields: (click the image to enlarge)

enter image description here

yields: (click the image to enlarge)

enter image description here

Expanding the \if.. of an \if..\else..\fi while the \if..-condition is not fulfilled yields evaluation and removal of the tokens that are needed for finding out whether the \if..-condition is fulfilled and removal of all tokens that form the "true"-branch, including the \else-token that marks the end of the "true"-branch.

(Expansion of the \else of an \if..\else..\fi while the \if..-condition is not fulfilled does not occur: As just said: In this case the token \else is removed as the marker of the end of the "true"-branch. As it is removed it cannot be expanded.)

E.g., expanding the \ifnum of

\ifnum1=2 equal\else different\fi

yields: different\fi.

different is carried out. After that \fi is carried out=expanded=removed.

Be aware that the term "evaluation" in the phrase "evaluation and removal of the tokens that are needed for finding out whether the \if..-condition is fulfilled" with some \if..-conditionals subsumes expansion of expandable tokens—this is the case, e.g., with \if and \ifcat—and with some \if..-conditionals does not subsume expansion of expandable tokens—this is the case, e.g., with \ifx. With some \if..-conditionals—e.g., \ifhmode, \ifvmode, \ifmmode, \ifinner— no tokens at all are needed for finding out whether the \if..-condition is fulfilled.


Let's look at your definition of \mySection:

\newcommand\mySection[2]{
    \ifnum #2=1 
    \expandafter\expandafter\expandafter\section
    \else\section*
    \fi
    {#1}
}

With your code in case of #2 being 0 the tokens forming the "true"-branch of \mySection's \ifnum..\else..\fi are discarded whereby the token \else denotes the end of the "true"-branch and is discarded, too. The tokens behind the \else forming the "false"-branch are not discarded but are carried out. The token \fi belonging to \mySection's \ifnum..\else..\fi is not removed from the input-stack before carrying out \section*. Therefore the argument of \section* will be the token \fi, not the sequence {#1}. Expanding the \section-macro/expanding macros underlying the \section-macro means replacing the control-sequence-token in question by its definition-text while inserting the arguments for the parameters. Hereby the \fi coming as \section*'s argument erroneously matches up some \if..-⟨some parameter #1/#2/whatever⟩-\else-\fi-expression coming from the definition-text of some macro underlying the \section-command. Thus the \else behind ⟨some parameter #1/#2/whatever⟩ is considered an extra \else.
(The \fi behind what is considered an extra \else is not considered an extra \fi but "helps" matching things up instead of the \fi belonging to \mySection's \ifnum..\else..\fi which is consumed as \section*'s argument.)

With your code in case of #2 being 1 the first \expandafter-chain (consisting of the 1st and the 3rd \expandafter) "hits" the \else. Therefore \else gets expanded (and hereby removed) which yields the discarding of the entire "false"-branch including the \fi which marks the end of the "false"-branch. The second \expandafter-chain (consisting of the second \expandafter) then "hits" the { of {#1} which has no effect as { is not expandable.


In case #2=1 have TeX remove the * of the sequence \section* via \@firstoftwo:

\documentclass{aricle}

\makeatletter
\newcommand\mySection[2]{%
  \ifnum#2=1 \expandafter\@firstoftwo\fi\section*{#1}%
}%
\makeatother

\begin{document}
    test
\mySection{title}{1}
\mySection{title}{0}

\end{document}

If you don't like \expandafter you can \exchange \@firstoftwo and \fi:

\documentclass{article}

\makeatletter
\newcommand\exchange[2]{#2#1}%
\newcommand\mySection[2]{%
  \ifnum #2=1 \exchange\@firstoftwo\fi\section*{#1}%
}%
\makeatother

\begin{document}
    test
\mySection{title}{1}
\mySection{title}{0}

\end{document}

A standard way to do this job is

\documentclass{article}

\makeatletter
\newcommand\mySection[2]{%
  \ifnum #2=1
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\section}{\section*}{#1}%
}
\makeatother

\begin{document}

test
\mySection{title}{1}
\mySection{title}{0}

\end{document}

so the conditional is completely removed before choosing the desired path.

There are many other ways, even some that require no \expandafter.

\documentclass{article}
\usepackage{etoolbox}

\newcommand\mySection[2]{%
  \ifnumcomp{#2}{=}{1}{\section}{\section*}{#1}%
}

\begin{document}

test
\mySection{title}{1}
\mySection{title}{0}

\end{document}

Without packages (but a fairly recent LaTeX kernel)

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand\mySection{mm}
 {
  \int_compare:nTF {#2=1}{\section}{\section*}{#1}
 }
\ExplSyntaxOff

\begin{document}

test
\mySection{title}{1}
\mySection{title}{0}

\end{document}

The last one can be extended to support the optional argument.

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand\mySection{O{#2}mm}
 {
  \int_compare:nTF {#3=1}{\section[#1]}{\section*}{#2}
 }
\ExplSyntaxOff

\begin{document}

\tableofcontents

\mySection[short title for toc]{title}{1}
\mySection{title}{0}

\end{document}

Tags:

Macros