2

I defined a command to create a section with a label. Depending on whether only one or both arguments are used, the section name and label can be different. I created the following MWE:

\documentclass{article}
\usepackage{xifthen}

\newcommand{\labeledsection}[2][]{%
    \section{#2}%
    \label{\ifthenelse{\isempty{#1}}{#2}{#1}}%
}   

\begin{document}
    \labeledsection{Section 1 name}
    Section should be: 'Section 1 name'\\
    Label should be: 'Section 1 name'

    \labeledsection[Section 2 label]{Section 2 name}
    Section should be: 'Section 2 name'\\
    Label should be: 'Section 2 label'
\end{document}

When I try to compile it, I get the following error messages:

Line 10: Undefined control sequence. \labeledsection{Section 1 name}
Line 10: Undefined control sequence. \labeledsection{Section 1 name}
Line 10: Illegal parameter number in definition of \reserved@a. \labeledsection{Section 1 name}
Line 10: Extra \or. \labeledsection{Section 1 name}
Line 10: Illegal parameter number in definition of \reserved@a. \labeledsection{Section 1 name}
Line 10: Undefined control sequence. \labeledsection{Section 1 name}
Line 10: Undefined control sequence. \labeledsection{Section 1 name}
Line 10: Illegal parameter number in definition of \reserved@a. \labeledsection{Section 1 name}
Line 10: Undefined control sequence. \labeledsection{Section 1 name}
Line 10: Paragraph ended before \@sect was complete. \labeledsection{Section 1 name}
Line 10: Illegal parameter number in definition of \reserved@a. \labeledsection{Section 1 name}
Line 10: Undefined control sequence. \labeledsection{Section 1 name}
Line 10: Paragraph ended before \@sect was complete. \labeledsection{Section 1 name}
Line 10: Extra \or. \labeledsection{Section 1 name}
Line 10: Undefined control sequence. \labeledsection{Section 1 name}
Line 10: Undefined control sequence. \labeledsection{Section 1 name}
Line 10: Illegal parameter number in definition of \reserved@a. \labeledsection{Section 1 name}
Line 10: Missing \endcsname inserted. \labeledsection{Section 1 name}
Line 10: Missing \endcsname inserted. \labeledsection{Section 1 name}
Line 10: Missing \endcsname inserted. \labeledsection{Section 1 name}
Line 10: Argument of \@sect has an extra }. \labeledsection{Section 1 name}
Line 10: Paragraph ended before \@sect was complete. \labeledsection{Section 1 name}
Line 10: Extra }, or forgotten \endgroup. \labeledsection{Section 1 name}
Line 10: Extra }, or forgotten \endgroup. \labeledsection{Section 1 name}
Line 10: Missing control sequence inserted. \labeledsection{Section 1 name}
Line 10: Extra \endcsname. \labeledsection{Section 1 name}
Line 10: Missing control sequence inserted. \labeledsection{Section 1 name}
Line 10: Missing control sequence inserted. \labeledsection{Section 1 name}
Line 17: Use of \par doesn't match its definition. \end{document}
Line 17: You can't use `\prevdepth' in horizontal mode. \end{document}
Line 17: Missing number, treated as zero. \end{document}
Line 17: Illegal unit of measure (pt inserted). \end{document}
Line 17: Use of \par doesn't match its definition. \end{document}
Line 17: Improper \prevdepth. \end{document}
Line 17: You can't use `\prevdepth' in horizontal mode. \end{document}
Line 17: Use of \par doesn't match its definition. \end{document}
Line 17: Missing \endcsname inserted. \end{document}
Line 17: Missing \endcsname inserted. \end{document}
Line 17: Argument of \@gobble has an extra }. \end{document}
Line 17: Paragraph ended before \@gobble was complete. \end{document}
Line 17: Use of \par doesn't match its definition. \end{document}
Line 17: Missing } inserted. \end{document}
Line 17: Use of \par doesn't match its definition. \end{document}
Line 17: Extra \endgroup. \end{document}
: Emergency stop.

I already know the error comes from \ifthenelse{\isempty{#1}}{#2}{#1} in the \label command, but what do I need to do to make the command work?

  • When I try to compile your MWE I get an error because \isempty is undefined. – Skillmon May 30 '17 at 11:45
3

I removed the xifthen and used \ifx\relax#1\relax instead.

\documentclass{article}

\newcommand{\labeledsection}[2][]{%
    \section{#2}%
    \ifx\relax#1\relax%
        \label{#2}%
    \else%
        \label{#1}%
    \fi%
}

\begin{document}
    \labeledsection{Section 1 name}
    Section should be: 'Section 1 name'\\
    Label should be: 'Section 1 name'\\
    Referencing: \ref{Section 1 name}

    \labeledsection[Section 2 label]{Section 2 name}
    Section should be: 'Section 2 name'\\
    Label should be: 'Section 2 label'\\
    Referencing: \ref{Section 2 label}
\end{document}

enter image description here

You could use your \ifthenelse-approach this way:

\usepackage{xifthen}
\newcommand{\labeledsection}[2][]{%
    \section{#2}%
    \ifthenelse{\isempty{#1}}{%
        \label{#2}%
    }{%
        \label{#1}%
    }%
}   
4

The argument to \label should fully expand to a string, which \ifthenelse doesn't.

I wouldn't recommend such an approach for a couple of reasons:

  1. you'd get into troubles as soon as you change a section title;

  2. using the title as a label makes for clumsy usage of \ref.

Anyway, here's a slick way to do it:

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\labeledsection}{O{#2}m}{%
  \section{#2}%
  \label{#1}%
}   

\begin{document}

\labeledsection{Section 1 name}
Section should be: 'Section 1 name'\\
Label should be: 'Section 1 name'

\labeledsection[Section 2 label]{Section 2 name}
Section should be: 'Section 2 name'\\
Label should be: 'Section 2 label'

\section{References}

\ref{Section 1 name} and \ref{Section 2 label}

\end{document}

The argument list specifies an optional argument having as default value the mandatory argument.

enter image description here

I can think to a situation in which this could be useful, though. Suppose you're discussing galaxies and have descriptions of them scattered through the document. For some reason, you want to cross-reference them by number. The optional argument is useful in case the galaxy's name has special characters in it.

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{xparse}
\usepackage{cleveref}

\NewDocumentCommand{\galaxy}{O{#2}m}{%
  \refstepcounter{galaxy}%
  \item[(\thegalaxy) #2]%
  \label{galaxy:#1}%
}
\newcounter{galaxy}
\crefname{galaxy}{galaxy}{galaxies}

\begin{document}

\begin{description}
\galaxy{Andromeda} is a nearby galaxy

\galaxy[Ooc]{Ööç} is a distant galaxy
\end{description}

Galaxy \cref{galaxy:Andromeda} is big, while \cref{galaxy:Ooc} is small.

\begin{description}
\galaxy{Aquarius} is a dwarf galaxy
\end{description}

Can you see \cref{galaxy:Aquarius} or \cref{galaxy:Andromeda,galaxy:Ooc}?

\end{document}

enter image description here

  • 1
    +1 for the "I wouldn't recommend..." note (well and the 'slick' solution). – Skillmon May 30 '17 at 12:16
  • Yeah, you're right. Using the titles as lables really isn't optimal. Especially when you need to rename one... I hadn't really thought of that. Anyways, thanks for the quick help and the explanation. – Robin Hartmann May 30 '17 at 12:19
  • @RobinHartmann I didn't think to that either. Anyway, this might have uses for other situations; I'll add an example. – egreg May 30 '17 at 13:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.