我想扩展\label
和\ref
命令,以便不仅提供章节编号,还提供某种标题。
我想到的是这样的:
\documentclass{article}
\usepackage{xparse}
\makeatother
\let\oldlabel\label
\def\Ref#1{see~\ref{#1}~(\csname l@#1\endcsname)}
\DeclareDocumentCommand{\label}{m o}%
{
\oldlabel{#1}
\IfValueTF{#2}%
{\expandafter\gdef\csname l@#1\endcsname{#2}}
{}
}
\makeatother
\begin{document}
\section{Intro}\label{intro}[Introduction]
Some text referencing \Ref{intro} or \Ref{outro}
\section{Outro}\label{outro}[Outro]
blah...
\end{document}
但是,如果我将 \Ref 与前向引用一起使用,则会出错,因为\l@outro
尚未定义。我想通过将这些\gdef
s 写入辅助文件并在第二次 latex 运行时将其包含在文档开头来解决这个问题。
因此,我的问题是:1)如何正确地将\gdef
s 写入辅助文件,例如\jobname
.ref ?2)如何安全地读取辅助文件?(它可能尚不存在......)
由于可以使用,因此未定义命令的问题不成问题\@ifundefined
。但我们假设到目前为止所有标签都指定了可选参数。
感谢您的帮助!
答案1
我弄清楚了如何使用 newfile 包来达到我的目的。
\documentclass{article}
\usepackage{xparse,ifthen}
\usepackage{newfile,hyperref}
\makeatother
\AtBeginDocument{%
\newoutputstream{refs}
\let\oldlabel\label
\let\oldsect\section
\DeclareDocumentCommand{\label}{m o}%
{
\oldlabel{#1}
\IfValueTF{#2}%
{%
\addtostream{refs}{\protect\DeclareDocumentCommand{\string\l@#1}{}{#2}}
}
{}
}
\def\Ref#1{see~\ref{#1}~(\expandafter\ifx\csname l@#1\endcsname\undefined{??}\else{\csname l@#1\endcsname}\fi)}
\def\section#1\label#2{\oldsect{#1}\label{#2}[#1]}}
\makeatother
\begin{document}
\IfFileExists{\jobname.ref}{\input{\jobname.ref}}{}
\openoutputfile{\jobname.ref}{refs}
\addtostream{refs}{\protect\makeatletter}
\section{Intro}\label{intro}
Some text referencing \Ref{intro} or \Ref{outro}
\section{Outro}\label{outro}
blah... see \pageref{intro} or \autoref{intro}
\addtostream{refs}{\protect\makeatother}
\closeoutputstream{refs}
\end{document}
最后,我重新定义了命令\section#1\label#2
,将章节标题存储#1
到其中\l@#2
,以供稍后使用\Ref
。当然,最后我也需要重新定义\chapter
等\subsection
。
如果您有任何进一步的改进或发现一些错误,请告诉我。