我一直在互联网上寻找,试图弄清楚如何自动设置一个宏,使部分包含其名称的标签(或基于其名称的内容,如果空格或其他内容有问题,即如果我定义\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
。