7

I am trying to append options to hyperref inside a package (say append.sty) I'm writing. More precisely, in the package I load the hyperref package and I tune it:

\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

Note the \hypersetup macro. The defined option hyperref should pass additional setups from the user when she loads the package; for example:

\documentclass{article}
\usepackage[hyperref={pdfauthor=My Name}]{append}
\begin{document}
Hello world.... \url{www.foo.bar}
\end{document}

This approach is based on this answer. The problem is that in the resulting PDF, the author's entry in the metadata is: "MyName" (without the space). If I understand correctly, this problem occurs since \PassOptionsToPackage acts like \usepackage[OPTIONS]{package}, and in the case of the package hyperref this is a problem and \hypersetup has to be used.

How could I solve this issue?

Here are two attempts of mine to tackle the issue:

I tried to change append.sty as follow:

\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

But this yields an error:

! Package kvsetkeys Error: Undefined key `pdfauthor=My Name'.

My second attempt is:

\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

and I get the same error...

EDIT: A third attempt suggests that the problem is the way I try to pass options to 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

Surprisingly, the following works:

\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
    Note that \usepackage[hyperref={pdfauthor={My Name}}]{append} does work with your original code. – Andrew Swann Feb 10 '15 at 13:43
  • 2
    Wouldn't it be much much more easy to set the metadata after the package has been loaded? Either by using hypersetup or by using a wrapper command. – Johannes_B Oct 29 '15 at 19:22
  • It is possible to load hyperref (or many other packages) using \AtEndPreamble from the etoolbox package. I do this all the time. Then, hyperref does not load until the user has had the opportunity to do things (such as set the author) in the Preamble. You can also precede loading hyperref with your own macro, which will set default values if the user did not set them. – user139954 Dec 16 '17 at 16:57
2

The reason the following does not work

\def\in@hyperref{pdfauthor=My Name}
\hypersetup{colorlinks,linkcolor=blue,\in@hyperref}

but the following does

\def\in@hyperref{My Name}
\hypersetup{colorlinks,linkcolor=blue,pdfauthor=\in@hyperref}

is because \hypersetup splits its argument first for commas and then tries to split the content between the commas on a =. If none is found it assumes a valueless key and therefor takes the whole content as key.

In the first code the = is inside another macro which is not yet expanded. Therefor the code in \hypersetup can't find it and takes \in@hyperref as keyname. Only then this macro is actually expanded and an not-found error is raised as there is no key with the strange name pdfauthor=My Name.

In order to make the code working you need to expand \in@hyperref first at least once. One way to do this is to use the TeX primitive \expandafter, which expands the token (e.g. macro) behind the next token before that one is expanded. This means \expandafter\a\b expands \b first, then \a is expanded. If \b is another \expandafter the whole thing repeats. So the following works:

\def\in@hyperref{pdfauthor=My Name}
\expandafter\hypersetup\expandafter{\in@hyperref,colorlinks,linkcolor=blue}

This way \hypersetup gets the already expanded argument {pdfauthor=My Name,colorlinks,linkcolor=blue}. Here \in@hyperref can also include multiple comma-separated key=value pairs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.