我希望创建一个(隐藏)标签,其中存储一些文本,并通过引用它来检索文本,而无需获取实际链接。例如:
\customlabel{refname}{some text} \getcaption{refname}
应该给予
some text
但some text
不应可点击,它必须是文本。事实上,我需要它类似于\ifstrequals{\getcaption{refname}}{foo}{\dothis}{\dothat}
(提供etoolbox
)所以\getcaption
应该真正返回纯的文本。
在定义自定义标签它显示了如何定义一个隐藏的标签,并提供自定义链接标题,hyperref
但未加载:(参见伊恩·汤普森的回答)
\documentclass{article}
\makeatletter
\newcommand{\customlabel}[2]{%
\protected@write \@auxout {}{\string \newlabel {#1}{{#2}{}}}}
\makeatother
\begin{document}
\customlabel{refname}{some text} \ref{refname}
\end{document}
输出结果some text
与预期一致。
但是hyperref
加载后,此方法不起作用。Henrik Bøgelund Lavstsen 建议
\documentclass{article}
\usepackage{hyperref}
\makeatletter
\newcommand{\customlabel}[2]{%
\protected@write \@auxout {}{\string \newlabel {#1}{{#2}{\thepage}{#2}{#1}{}} }%
\hypertarget{#1}{#2}}
\makeatother
\begin{document}
\customlabel{refname}{some text} \ref{refname}
\end{document}
但这样得到的结果是some text some text
,即标签不是“隐藏”的。当然\ref
(扮演 的角色\getcaption
)不会简单地返回some text
,这意味着\ifstrequal{\ref{refname}}{some text}{yes}{no}
得到的结果是no
。
如果标题只是一个数字,则可以使用\getrefnumber
(来自refcount
)作为\getcaption
命令,但我不知道\getrefnumber
存储文本是任意字符串的替代方法。
笔记:我之所以要使用标签(或者更一般地说,将文本存储在外部文件中),是因为存储的文本必须在文档中可访问前存储的位置。即文本必须存储在外部文件中,并在下一次 LaTeX 运行中检索。我不想为每次\customlabel
调用创建一个文件,因为我必须使用它 1000 次,并且不想要 1000 个辅助文件。这就是为什么我认为使用标签是最好的选择。
答案1
为什么不简单地使用\ref
-\label
机制?
\documentclass{article}
\usepackage{hyperref}
\makeatletter
\newcommand{\customlabel}[2]{%
\phantomsection
\def\@currentlabel{\unexpanded{#2}}\label{#1}%
}
\makeatother
\begin{document}
\customlabel{refname}{som\'e text} \ref{refname}
\end{document}
重音只是为了表明它不会造成问题(因为\unexpanded
)。
如果您不想要链接,那么请使用\ref*
而不是\ref
。
允许检查已保存文本的版本:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{refcount}
\usepackage{hyperref}
\makeatletter
\newcommand{\customlabel}[2]{%
\csname phantomsection\endcsname
\def\@currentlabel{%
\bartodo{\unexpanded{#2}}%
}%
\label{#1}%
}
\protected\def\bartodo#1{#1}
\newcommand{\checklabel}[2]{%
\begingroup
\let\bartodo\detokenize
\begingroup\edef\x{\endgroup
\noexpand\ifstrequal{\getrefnumber{#1}}{\detokenize{#2}}}%
\x{\aftergroup\@firstoftwo}{\aftergroup\@secondoftwo}%
\endgroup
}
\makeatother
\begin{document}
\customlabel{refname}{som\'e text} \ref*{refname}
\customlabel{newname}{text}
\checklabel{newname}{text}{YES}{NO}
\checklabel{refname}{som\'e text}{YES}{NO}
\checklabel{refname}{some text}{YES}{NO}
\end{document}
如果保存的文本只是用于以后数字测试的数字,则可以使用一种更简单的方法:
\documentclass{article}
\usepackage{etoolbox}
\usepackage{refcount}
\usepackage{hyperref}
\makeatletter
\newcommand{\customlabel}[2]{%
\def\@currentlabel{#2}%
\label{#1}%
}
\newcommand{\checklabel}[4]{%
\begingroup\edef\x{\endgroup
\noexpand\ifnumequal{\getrefnumber{#1}}{#2}}%
\x{#3}{#4}%
}
\makeatother
\begin{document}
\customlabel{refname}{22}
\customlabel{newname}{42}
\checklabel{newname}{42}{YES}{NO}
\checklabel{refname}{22}{YES}{NO}
\checklabel{refname}{42}{YES}{NO}
\end{document}
答案2
下面的例子使用了zref
引用系统。它定义了一个新属性custom
,将其设置为所需的内容。\customlabel
然后将内容存储在.aux
文件中。\customref
以可扩展的方式提取值,因此可以在 中使用\ifstrequals
。如果引用未定义,则可扩展版本无法发出警告,因此将此部分放入宏 中\customused
,该宏通知 LaTeX 引用确实已被使用。如果引用未定义,则会打印警告。
\documentclass{article}
\usepackage{zref-base}
\makeatletter
\zref@newprop{custom}{}
\newcommand*{\customlabel}[2]{%
\@bsphack
\zref@setcurrent{custom}{#2}%
\zref@labelbyprops{#1}{custom}%
\@esphack
}
\newcommand*{\customref}[1]{%
\zref@extractdefault{#1}{custom}{}% last argument is default
}
\newcommand*{\customused}[1]{%
\zref@refused{#1}%
}
\makeatletter
\begin{document}
\customlabel{refname}{some text} \customref{refname}\customused{refname}
\end{document}
答案3
假设您正在使用 e-TeX,您可以利用它\pdfstrcmp
扩展检查字符串:
这是一些常规文本。存储的标题是一些文本。Do
: that
Do: this
\documentclass{article}
\newcommand{\customlabel}[1]{\expandafter\gdef\csname#1\endcsname}
\newcommand{\getcaption}[1]{\expandafter\csname #1\endcsname}
\newcommand{\ifstrequal}[4]{% \ifstrequal{<stringA>}{<stringB>}{<true>}{<false>}
\ifnum\pdfstrcmp{#1}{#2}=0
#3% #1 = #2
\else
#4% #1 != #2
\fi}
\begin{document}
\customlabel{refname}{some text}% Store some text in 'refname'
This is some regular text. The stored caption is \getcaption{refname}.
Do: \ifstrequal{\getcaption{refname}}{foo}{this}{that}
Do: \ifstrequal{\getcaption{refname}}{some text}{this}{that}
\end{document}