如何自动将节名称定义为标签

如何自动将节名称定义为标签

我一直在互联网上寻找,试图弄清楚如何自动设置一个宏,使部分包含其名称的标签(或基于其名称的内容,如果空格或其他内容有问题,即如果我定义\section{related work}我希望能够使用\ref{sec:related work}或可能\ref{sec:related_work}或类似的东西

我也一直在尝试使用部分编号作为使用计数器的第二选择,但是我失败了。(它似乎\arabic不能成为使该解决方案不起作用的一部分\label{}(也许即使有了它也不会起作用,我不确定计数器+宏如何起作用,但没有达到这一部分)

\usepackage{letltxmacro}
\LetLtxMacro{\oldsection}{\section}
\renewcommand{\section}[2][]{\oldsection[#1]{#2}\index{#1}\label{sec:\arabic{section}} 

答案1

这是一个好问题,但答案是不要这样做,原因如下:

  • 如果您在某个部分中有一个难以追踪的命令,那么您会得到奇怪的副作用。

  • 正如大卫所写的:如果您更改了该部分的名称,您将必须跟踪所有引用,因为它们包含旧名称!

其他用户也遇到了这个问题,所以已经解决了!当我看到你的问题时,我笑了,你在网上搜索了好久,想弄清楚如何让标签更容易。如果你不是在做火箭科学:每次你遇到问题,你似乎都是第一个问这个问题的人,你就错过了一些东西,因此你在错误的地方搜索。

好的,现在来谈谈解决方案。使用高级编辑器。每次我插入一个部分时,我的编辑器都会在完成部分标题后提供插入标签的功能,并使用部分的前两个或三个单词以及部分的简短标识符。因此,如果我插入

\section{Trump is an open minded person}

编辑将建议添加

\label{sec:trump-is-an}

而且由于我正在使用 Emacs,它还会要求我寻求专业帮助。

所以这是你使用的编辑器的问题。插入标签也适用于其他命令,例如表格\label{tab:}、图形 `\label{fig:}、方程式等等。

答案2

我并不是说这是一个好主意,但是以下方法可行:

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

结果如下:

在此处输入图片描述

您可以使用 引用某个部分\ref{sec:<strippedsectiontitle>},其中<strippedsectiontitle>是删除了所有非字母或数字字符的部分标题。您也可以使用\refbytitle{<Full section title>},其中<Full section title>是您之前提供的部分标题(它将被删除然后传递给\ref)。

我之所以使用 ,expl3是因为它允许我将正则表达式应用于字符串,我使用它在调用 之前从节标题中删除所有非字母或数字的字符\label。因此,您可以将其用于任意令人讨厌的节标题,只要您记得删除所有非字母或数字的内容(或使用\refbytitle)。

编辑:显然,旧解决方案与 hyperref 不兼容,但现在应该兼容了。还添加了\refbytitle

相关内容