2

I have been looking all over the internet trying to figure out how to automatically set a macro to make section include a label for its name (or something based on its name if spaces or something is problematic, i.e. if I define \section{related work} I want to be able to use \ref{sec:related work} or maybe \ref{sec:related_work} or something similar

I have also been trying to use section number as a second choice using counters, but I failed miserably. (it seems \arabic cannot be a part of \label{} making this solution not work (perhaps it won't work even with it, I am not sure how counters + macros act, but did not reach this part)

\usepackage{letltxmacro}
\LetLtxMacro{\oldsection}{\section}
\renewcommand{\section}[2][]{\oldsection[#1]{#2}\index{#1}\label{sec:\arabic{section}} 
  • 2
    Related? tex.stackexchange.com/q/62217/134144 – leandriis Jan 30 '18 at 13:04
  • 5
    using the title is I suppose OK although a bit fragile. Using the number would be completely wrong and disable the main reason that latex has \label at all. The whole idea is that you can edit the docuemnt, adding new sections, all the sections renumber and all cross references still work. Your suggestion would have you use \ref{sec:2} which will make the wrong reference if the sections have been changed, – David Carlisle Jan 30 '18 at 13:05
  • @David Carlisle I should have written this in the question, I also think using numbers is a bad practice exactly because of the changes in sections (although still rare). Names I can choose for a label as well as for a section, so I can change the references to the section if I change the specific section. – borgr Jan 30 '18 at 13:56
  • @leandriis related, but unhelpful. Note that, being the closest to what I wanted, the code I write is actually derived from there. – borgr Jan 30 '18 at 13:57
  • 1
    @borgr: Your redefinition will break \section* usages... – user31729 Jan 30 '18 at 16:49
1

This is a good question, but the answer is, don't do it, for several reasons:

  • You'll get funny side effects if you have a command in a section, which are difficult to track down.

  • As David wrote: if you ever change the name of the section, you'll have to track all references, because they include the old name!

Other users faced this issue as well, so it has been solved! I smiled when I read in your question that you searched the internet up and down to figure out how to make labeling easier. If you are not doing rocket science: every time you hit an issue and you seem to be the first person asking this question, you are missing something and therefore you are searching at the wrong place.

Ok, now the solution. Use an advanced editor. Every time I insert a section, my editor offers after finishing the section title to insert a label and uses the first two or three words of the section for it as well as a short identifier for sections. So if I insert

\section{Trump is an open minded person}

the editor will suggest to add

\label{sec:trump-is-an}

and as I'm using Emacs, it also will ask me to seek for professional help.

So it's a question of the editor you are using. Inserting labels works with other commands as well, e.g. tables \label{tab:}, figures `\label{fig:}, equations and so on.

  • The condescending tone in the second paragraph isn't helping anyone, especially since you're not giving a solution for what OP wants. – Najib Idrissi Mar 13 '18 at 12:03
  • @NajibIdrissi Obviously I can't give the OP what he wants: it's not good idea! And the second paragraph is much more important than the rest of the answer: many many questions already have an answer. If you can't find it, you may ask the wrong question. – Keks Dose Mar 13 '18 at 12:15
1

I'm not saying this is a good idea, but the following works:

\documentclass{article}

% \usepackage{hyperref} %% Works now

\usepackage{expl3}

\ExplSyntaxOn
\newcommand\createsafelabelname[1]{%
  {%
    \str_set:Nn\l_labelname_str{#1}%
    \regex_replace_all:nnN{[^a-zA-Z0-9]}{}\l_labelname_str%
    \xdef\safelabelname{\tl_use:N\l_labelname_str}%
  }%
}
\ExplSyntaxOff

\newcommand\safeseclabel[1]{\createsafelabelname{#1}\begingroup\edef\x{\endgroup\noexpand\label{sec:\safelabelname}}\x}

%\let\chaptermarkwithoutlabel\chaptermark
%\renewcommand\chaptermark[1]{\chaptermarkwithoutlabel{#1}\safeseclabel{#1}}
\let\sectionmarkwithoutlabel\sectionmark
\renewcommand\sectionmark[1]{\sectionmarkwithoutlabel{#1}\safeseclabel{#1}}
\let\subsectionmarkwithoutlabel\subsectionmark
\renewcommand\subsectionmark[1]{\subsectionmarkwithoutlabel{#1}\safeseclabel{#1}}

%% Alternative:
% \usepackage{etoolbox}
% \apptocmd{\chaptermark}{\safeseclabel{#1}}{}{}
% \apptocmd{\sectionmark}{\safeseclabel{#1}}{}{}
% \apptocmd{\subsectionmark}{\safeseclabel{#1}}{}{}

\makeatletter
\newcommand*\versionbytitle[1]{\@ifstar{\versionbytitle@aux{#1*}}{\versionbytitle@aux{#1}}}
\newcommand\versionbytitle@aux[2]{\createsafelabelname{#2}\begingroup\edef\x{\endgroup\noexpand#1{sec:\safelabelname}}\x}
\makeatother

\DeclareRobustCommand*\refbytitle{\versionbytitle\ref}
\DeclareRobustCommand*\pagerefbytitle{\versionbytitle\pageref}

\begin{document}

\section{A section containing ~\#{}\LaTeX\ and $\sqrt{2}$}

This is section~\ref{sec:AsectioncontainingLaTeXandsqrt2}, its title contains some nasty characters.
It has a numbered subsection, section~\ref{sec:Differentname}, and an unnumbered one.

This is section~\refbytitle{A section containing ~\#{}\LaTeX\ and $\sqrt{2}$}, its title contains some nasty characters and it starts on page~\pagerefbytitle{A section containing ~\#{}\LaTeX\ and $\sqrt{2}$}.

\subsection[Different name]{A subsection with a different name in the toc}

Filler text.

\end{document}

Here is the result:

enter image description here

You can either refer to a section using \ref{sec:<strippedsectiontitle>}, where <strippedsectiontitle> is the section title with all characters that are not letters or numbers removed. You can also use \refbytitle{<Full section title>}, where <Full section title> is the section title as you provided it before (it will be stripped and then passed to \ref).

I'm using expl3 because it allows me to apply regular expressions to character strings, which I use to remove all characters that are not letters or numbers from the section title before calling \label. You can therefore use this with arbitrarily nasty section titles, as long as you remember to remove everything that is not a letter or a number (or use \refbytitle).

Edit: Apparently the old solution was not compatible with hyperref, but it should be now. Also added \refbytitle.

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.