将选项附加到 hyperref

将选项附加到 hyperref

我正在尝试将选项附加到我正在编写的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 对。

相关内容