我需要两个新命令\createreference
和\citereference
来配合使用。它们应按以下示例所示工作:
\createreference{john}{John Q. Citizen}
应将文本“John Q. Citizen”写入文件myreferences.aux
。该文本应以某种方式与相应的条目相关联john
。
\citereference{john}
john
如果找不到任何条目myreferences.aux
(或者文件不存在),则应该打印出“??” 。但是,如果找到了条目,它应该打印出相应的文本(在本例中为“John Q. Citizen”)。
即使在代码中\createreference
出现之后这也应该有效。\citereference
我没有足够的低级专业知识来做到这一点。其他人有吗?
答案1
我不明白你想把文本放在哪里:在主文件中jobname.aux
还是在单独的文件中。如果是前者,那么这是可行的(基本上模仿标准\ref-\label
机制):
\documentclass{article}
\makeatletter
% The command reference writes \newreference into the aux file
\def\createreference#1#2{\@bsphack
\protected@write\@mainaux{}%
{\string\newreference{#1}{#2}}%
\@esphack}
% The command \newreference defines new command named after the first
% argument that produces the second one
\def\newreference#1#2{%
\expandafter\xdef\csname rfr@#1\endcsname{#2}}
% And using the reference
\def\citereference#1{%
\expandafter\ifx\csname rfr@#1\endcsname\relax??\else
\csname rfr@#1\endcsname\fi}
% LaTeX checks at the end of document whether references have
% been changed. If any reference is changed,
% \tempswa is set to true. Here we add \newreference commands
% to the list to be checked.
\AtEndDocument{\def\newreference#1#2{%
\edef\reserved@a{#2}%
\expandafter\ifx\csname rfr@#1\endcsname\reserved@a\else
\@tempswatrue\fi}}
\makeatother
\begin{document}
\createreference{john}{John Q. Citizen}
\citereference{john} and \citereference{george}
\end{document}
更新添加了检查引用是否已更改。
更新 2改为\def
处理\edef
重音
答案2
您可以使用(或者滥用?)标准机制:
\makeatletter
\newcommand{\createreference}[2]{%
\def\@currentlabel{\unexpanded{#2}}\label{#1}}
\newcommand{\citereference}[1]{\ref{#1}}
\makeatother
但我有些怀疑这样做是否正确。如果您也加载,hyperref
最好使用\ref*
而不是\ref
,这样就不会创建链接。
Label(s) may have changed
由于这使用了标准机制,因此当创建新的引用时,就会发出消息。
该.aux
文件的作用是记录每次运行之间可能发生变化的信息。最好在序言中声明john
和之间的固定关联,以便轻松控制所有这些关联:John Q. Citizen
%%% in the preamble
\newcommand{\createassociation}[2]{%
\expandafter\newcommand\csname association@#1\endcsname{#2}}
\newcommand{\citeassociation}[1]{\csname association@#1\endcsname}
\createassociation{john}{John Q. Citizen}
%%% in the document
This is the name: \citeassociation{john}
答案3
zref
默认提供此功能。下面是一个满足您要求的最小示例(lipsum
仅提供虚拟文本,乱数风格):
\documentclass{article}
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\usepackage{zref}% http://ctan.org/pkg/zref
\makeatletter
\newcommand{\createreference}[2]{%
\def\@reftext{#2}% Store contents of reference (#2)
\zref@labelbylist{#1}{special}% Special label writes to .aux
}
\newcommand{\citereference}[1]{%
\zref@extractdefault{#1}{reftext}{\textbf{??}}% Extract reference, or print ??
}
\zref@newlist{special}% Create a new reference list called special
\zref@newprop{reftext}{\@reftext}% Create property reftext that holds \@reftext
\zref@addprop{special}{reftext}% Special reference list holds reftext
\makeatother
\begin{document}
\createreference{john}{John~Q.\ Citizen}
Do you know \citereference{john} or \citereference{susan}?
\lipsum[7]
\createreference{susan}{\textbf{Suzie}~$\textrm{Q}^2$}
Yes, I know \citereference{john} and \citereference{susan}.
\end{document}
您会注意到,引用的文本中保留了格式。以下是\jobname.aux
包含zref
标签的文件的一部分,显示了信息和格式的存储方式:
\zref@newlabel{john}{\reftext{John\nobreakspace {}Q.\ Citizen}}
\zref@newlabel{susan}{\reftext{\textbf {Suzie}\nobreakspace {}$\textrm {Q}^2$}}