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?

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

2 Answers 2

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}%
    }%
}   
0
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

3
  • 2
    +1 for the "I wouldn't recommend..." note (well and the 'slick' solution).
    – Skillmon
    May 30, 2017 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. May 30, 2017 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, 2017 at 13:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .