我正在尝试将选项附加到我正在编写的hyperref
包(例如append.sty
)中。更准确地说,在包中我加载hyperref
包并对其进行调整:
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{append}
[2011/01/11 v0.01]
\RequirePackage{kvoptions}
\RequirePackage{kvsetkeys}
\SetupKeyvalOptions{
family=APP,
prefix=APP@,
setkeys=\kvsetkeys
}
\define@key{APP}{hyperref}{%
\PassOptionsToPackage{#1}{hyperref}%
}
\ProcessKeyvalOptions*
\RequirePackage{hyperref}
\hypersetup{colorlinks,linkcolor=blue}
\endinput
注意这个\hypersetup
宏。定义的选项hyperref
应该在用户加载包时传递来自用户的附加设置;例如:
\documentclass{article}
\usepackage[hyperref={pdfauthor=My Name}]{append}
\begin{document}
Hello world.... \url{www.foo.bar}
\end{document}
这种方法基于这个答案。问题是,在生成的 PDF 中,作者在元数据中的条目是:“MyName”(没有空格)。如果我理解正确的话,这个问题是因为 的\PassOptionsToPackage
行为类似 而发生的\usepackage[OPTIONS]{package}
,并且在包的情况下,hyperref
这是一个问题,\hypersetup
必须使用。
我该如何解决这个问题?
以下是我解决这个问题的两次尝试:
我尝试进行append.sty
如下更改:
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{append}
[2011/01/11 v0.01]
\RequirePackage{kvoptions}
\RequirePackage{kvsetkeys}
\SetupKeyvalOptions{
family=APP,
prefix=APP@,
setkeys=\kvsetkeys
}
\DeclareStringOption{hyperref}
\ProcessKeyvalOptions*
\RequirePackage{hyperref}
\hypersetup{colorlinks,linkcolor=blue,\APP@hyperref}
\endinput
但这会产生一个错误:
!包 kvsetkeys 错误:未定义键“pdfauthor=My Name”。
我的第二次尝试是:
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{append}
[2011/01/11 v0.01]
\RequirePackage{kvoptions}
\RequirePackage{kvsetkeys}
\SetupKeyvalOptions{
family=APP,
prefix=APP@,
setkeys=\kvsetkeys
}
\define@key{APP}{hyperref}{%
\def\in@hyperref{#1}
}
\ProcessKeyvalOptions*
\RequirePackage{hyperref}
\hypersetup{colorlinks,linkcolor=blue,\in@hyperref}
\endinput
我遇到了同样的错误...
编辑:第三次尝试表明问题在于我尝试将选项传递给的方式hyperref
。
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{append}
[2011/01/11 v0.01]
\def\in@hyperref{pdfauthor=My Name}
\RequirePackage{hyperref}
\hypersetup{colorlinks,linkcolor=blue,\in@hyperref}
\endinput
令人惊讶的是,下面的方法有效:
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{append}
[2011/01/11 v0.01]
\def\in@hyperref{My Name}
\RequirePackage{hyperref}
\hypersetup{colorlinks,linkcolor=blue,pdfauthor=\in@hyperref}
\endinput
答案1
以下不起作用的原因
\def\in@hyperref{pdfauthor=My Name}
\hypersetup{colorlinks,linkcolor=blue,\in@hyperref}
但下面确实
\def\in@hyperref{My Name}
\hypersetup{colorlinks,linkcolor=blue,pdfauthor=\in@hyperref}
是因为\hypersetup
首先用逗号分割其参数,然后尝试在 上的逗号之间分割内容=
。如果未找到任何内容,则假定键为无值,因此将整个内容作为键。
在第一个代码=
中里面另一个尚未展开的宏。因此 中的代码\hypersetup
找不到它并\in@hyperref
作为键名。只有这样,这个宏才会真正展开,并且会引发未找到错误,因为没有具有奇怪名称的键pdfauthor=My Name
。
为了使代码正常工作,您需要\in@hyperref
至少先扩展一次。一种方法是使用 TeX 原语\expandafter
,它会先扩展下一个标记后面的标记(例如宏),然后再扩展该标记。这意味着先\expandafter\a\b
扩展\b
,然后\a
扩展。如果\b
是另一个,\expandafter
则整个过程重复。因此,以下方法有效:
\def\in@hyperref{pdfauthor=My Name}
\expandafter\hypersetup\expandafter{\in@hyperref,colorlinks,linkcolor=blue}
这样\hypersetup
就获取到了已经展开的参数{pdfauthor=My Name,colorlinks,linkcolor=blue}
。这里\in@hyperref
还可以包含多个以逗号分隔的 key=value 对。