如何逐个将值插入到 hypersetup 中

如何逐个将值插入到 hypersetup 中

所以我的文档中有这个。

\documentclass[a4paper,12pt]{article}
\usepackage{hyperref}
\hypersetup{
  pdfborder=0 0 0,
  pdfinfo={
    Author={Me},
    Creator={Me},
    Title={The title},
    Subject={A subject},
    Producer={LaTeX}
  }
}

我如何逐个设置这些值(作者、创建者、标题等)并将它们插入?因此,这就是我想要使用它的方式:

\documentclass{foo}

\fooauthor{Me}
\footitle{A Title}
...

然后以某种方式将其插入.cls文件或某个.sty文件中:

\hypersetup{
  pdfborder=0 0 0,
  pdfinfo={
    Author={@fooauthor},
    Creator={@fooauthor},
    Title={@footitle}
    ...
  }
}

如何做这样的事情?

答案1

您没有说明可以使用什么 TeX 扩展(ε-TeX、、\expanded...)。

因此,我的第一个例子根本没有使用任何扩展。

\romannumeral0相反,在这个例子中,发生了大量的扩展。

-expansion的要点\romannumeral0是:

\romannumeral收集数字和终止空格标记,以查找要转换为罗马符号的数字。
扩张可扩展令牌不受抑制但在寻找更多数字或要转换的数字的终止空格标记时触发。
终止构成要转换的数字的数字序列的空格标记将被默默丢弃。
如果数字转换是不积极\romannumeral0将默默地吞下构成数字的数字序列,然后不交付任何令牌作为回报。

因此,您可以很好地(ab?)使用它\romannumeral来在搜索更多数字或终止数字序列的空格标记时触发大量的扩展和参数交换工作,只要确保最终找到的数字不是正数即可。

\documentclass[a4paper,12pt]{article}
\usepackage{hyperref}

\makeatletter

\newcommand\Exchange[2]{#2#1}%    

% Be aware that two consecutive hashes in the definition-text of a macro will be collapsed 
% into a single hash within the result of expanding that macro.
% Therefore something must be done for having hashes doubled within the macros that serve as
% place-holders for values of variables:
\newcommand\definemacrowithhashdoubling[2]{%
  \expandafter\Exchange\expandafter{%
     \expandafter\toks@\expandafter{\the\toks@}%
  }{%
    \toks@{#2}%
    \@ifdefinable#1{\edef#1{\the\toks@}}%
  }%
}%

\newcommand\foopdfborder[1]{\definemacrowithhashdoubling\@foopdfborder{#1}}%
\newcommand\fooauthor[1]{\definemacrowithhashdoubling\@fooauthor{#1}}%
\newcommand\foocreator[1]{\definemacrowithhashdoubling\@foocreator{#1}}%
\newcommand\footitle[1]{\definemacrowithhashdoubling\@footitle{#1}}%
\newcommand\foosubject[1]{\definemacrowithhashdoubling\@foosubject{#1}}%
\newcommand\fooproducer[1]{\definemacrowithhashdoubling\@fooproducer{#1}}%

% \DeliverHyperSetupKeyValList delivers keyval-list for \hypersetup according
% to the definitions of \@foopdfborder, \@fooauthor, \@foocreator, \@footitle, 
% \@foosubject and \@fooproducer.
%
% Due to \romannumeral0-/\Exchange-expansion-trickery, the result is delivered
% after triggering two expansion-steps/after two "hits" with \expandafter:
%
\newcommand\DeliverHyperSetupKeyValList{%
  \romannumeral0%
  \expandafter\Exchange\expandafter{%
    \romannumeral0%
    \csname @\@ifundefined{@fooauthor}{%
      \@ifundefined{@foocreator}{%
        \@ifundefined{@footitle}{%
          first%
        }{second}%
      }{second}%
    }{second}oftwo\endcsname{ }{%
      \expandafter\Exchange\expandafter{\expandafter{\romannumeral0%
        \expandafter\Exchange\expandafter{%
          \romannumeral0\@ifundefined{@footitle}{ %
          }{\expandafter\Exchange\expandafter{\expandafter{\@footitle}}{ Title=},}%
        }{%
          \expandafter\Exchange\expandafter{%
            \romannumeral0\@ifundefined{@foocreator}{ %
            }{\expandafter\Exchange\expandafter{\expandafter{\@foocreator}}{ Creator=},}%
          }{%
            \expandafter\Exchange\expandafter{%
              \romannumeral0\@ifundefined{@fooauthor}{ %
              }{\expandafter\Exchange\expandafter{\expandafter{\@fooauthor}}{ Author=},}%
            }{%
              \expandafter\Exchange\expandafter{%
                \romannumeral0\@ifundefined{@foosubject}{ %
                }{\expandafter\Exchange\expandafter{\expandafter{\@foosubject}}{ Subject=},}%
              }{%
                \expandafter\Exchange\expandafter{%
                  \romannumeral0\@ifundefined{@fooproducer}{ %
                  }{\expandafter\Exchange\expandafter{\expandafter{\@fooproducer}}{ Producer=},}%
                }{ }%
              }%
            }%
          }%
        }%
      }}{ pdfinfo=},%
    }%
  }{%
    \expandafter\Exchange\expandafter{%
      \romannumeral0\@ifundefined{@foopdfborder}{ %
      }{\expandafter\Exchange\expandafter{\expandafter{\@foopdfborder}}{ pdfborder=},}%
    }{ }%
  }%
}%
\makeatother

\foopdfborder{0 0 0}
\fooauthor{Me}
\foocreator{Me}
\footitle{The title}
\foosubject{A subject}
\fooproducer{LaTeX}

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\test
\expandafter\expandafter\expandafter{\DeliverHyperSetupKeyValList}%

\show\test

\expandafter\expandafter\expandafter\hypersetup
\expandafter\expandafter\expandafter{\DeliverHyperSetupKeyValList}%

\begin{document}

Some text.

\end{document}

如果有可用的带有 -primitive 的 ε-TeX-extensions \unexpanded,则可以结合\edef\unexpanded定义一个临时宏并将其扩展传递给\hypersetup

\documentclass[a4paper,12pt]{article}
\usepackage{hyperref}

\makeatletter

\newcommand\Exchange[2]{#2#1}%    

% Be aware that two consecutive hashes in the definition-text of a macro will be collapsed 
% into a single hash within the result of expanding that macro.
% Therefore something must be done for having hashes doubled within the macros that serve as
% place-holders for values of variables:
\newcommand\definemacrowithhashdoubling[2]{\@ifdefinable#1{\edef#1{\unexpanded{#2}}}}%

\newcommand\foopdfborder[1]{\definemacrowithhashdoubling\@foopdfborder{#1}}%
\newcommand\fooauthor[1]{\definemacrowithhashdoubling\@fooauthor{#1}}%
\newcommand\foocreator[1]{\definemacrowithhashdoubling\@foocreator{#1}}%
\newcommand\footitle[1]{\definemacrowithhashdoubling\@footitle{#1}}%
\newcommand\foosubject[1]{\definemacrowithhashdoubling\@foosubject{#1}}%
\newcommand\fooproducer[1]{\definemacrowithhashdoubling\@fooproducer{#1}}%

% \DefineMyHyperSetupTempMacro defines the macro \MyHyperSetupTempMacro
% to expand to a keyval-list for \hypersetup according
% to the definitions of \@foopdfborder, \@fooauthor, \@foocreator, \@footitle, 
% \@foosubject and \@fooproducer.
%
\newcommand\DefineMyHyperSetupTempMacro{%
  \edef\MyHyperSetupTempMacro{%
    \@ifundefined{@foopdfborder}{}{pdfborder={\unexpanded\expandafter{\@foopdfborder}},}%
    \csname @\@ifundefined{@fooauthor}{%
      \@ifundefined{@foocreator}{%
        \@ifundefined{@footitle}{%
          first%
        }{second}%
      }{second}%
    }{second}oftwo\endcsname{}{%
      pdfinfo={%
        \@ifundefined{@fooproducer}{}{Producer={\unexpanded\expandafter{\@fooproducer}},}%
        \@ifundefined{@foosubject}{}{Subject={\unexpanded\expandafter{\@foosubject}},}%
        \@ifundefined{@fooauthor}{}{Author={\unexpanded\expandafter{\@fooauthor}},}%
        \@ifundefined{@foocreator}{}{Creator={\unexpanded\expandafter{\@foocreator}},}%
        \@ifundefined{@footitle}{}{Title={\unexpanded\expandafter{\@footitle}},}%
      },%
    }%
  }%
}%
\makeatother

\foopdfborder{0 0 0}
\fooauthor{Me}
\foocreator{Me}
\footitle{The title}
\foosubject{A subject}
\fooproducer{LaTeX}

\DefineMyHyperSetupTempMacro

\show\MyHyperSetupTempMacro

\expandafter\hypersetup\expandafter{\MyHyperSetupTempMacro}%

\begin{document}

Some text.

\end{document}

如果除了 ε-TeX 扩展之外\expanded还有 -primitive 可用,则可以结合使用\unexpanded\expanded不用临时宏 - 这是第一个示例的较短实现:

\documentclass[a4paper,12pt]{article}
\usepackage{hyperref}

\makeatletter

\newcommand\Exchange[2]{#2#1}%    

% Be aware that two consecutive hashes in the definition-text of a macro will be collapsed 
% into a single hash within the result of expanding that macro.
% Therefore something must be done for having hashes doubled within the macros that serve as
% place-holders for values of variables:
\newcommand\definemacrowithhashdoubling[2]{\@ifdefinable#1{\edef#1{\unexpanded{#2}}}}%

\newcommand\foopdfborder[1]{\definemacrowithhashdoubling\@foopdfborder{#1}}%
\newcommand\fooauthor[1]{\definemacrowithhashdoubling\@fooauthor{#1}}%
\newcommand\foocreator[1]{\definemacrowithhashdoubling\@foocreator{#1}}%
\newcommand\footitle[1]{\definemacrowithhashdoubling\@footitle{#1}}%
\newcommand\foosubject[1]{\definemacrowithhashdoubling\@foosubject{#1}}%
\newcommand\fooproducer[1]{\definemacrowithhashdoubling\@fooproducer{#1}}%

% \DeliverHyperSetupKeyValList delivers keyval-list for \hypersetup according
% to the definitions of \@foopdfborder, \@fooauthor, \@foocreator, \@footitle, 
% \@foosubject and \@fooproducer.
%
% Due to \romannumeral0-/\Exchange-expansion-trickery, the result is delivered
% after triggering two expansion-steps/after two "hits" with \expandafter:
%
\newcommand\DeliverHyperSetupKeyValList{%
  \romannumeral0\expandafter\Exchange\expandafter{%
    \expanded{%
      \@ifundefined{@foopdfborder}{}{pdfborder={\unexpanded\expandafter{\@foopdfborder}},}%
      \csname @\@ifundefined{@fooauthor}{%
        \@ifundefined{@foocreator}{%
          \@ifundefined{@footitle}{%
            first%
          }{second}%
        }{second}%
      }{second}oftwo\endcsname{}{%
        pdfinfo={%
          \@ifundefined{@fooproducer}{}{Producer={\unexpanded\expandafter{\@fooproducer}},}%
          \@ifundefined{@foosubject}{}{Subject={\unexpanded\expandafter{\@foosubject}},}%
          \@ifundefined{@fooauthor}{}{Author={\unexpanded\expandafter{\@fooauthor}},}%
          \@ifundefined{@foocreator}{}{Creator={\unexpanded\expandafter{\@foocreator}},}%
          \@ifundefined{@footitle}{}{Title={\unexpanded\expandafter{\@footitle}},}%
        },%
      }%
    }%
  }{ }%
}%
\makeatother

\foopdfborder{0 0 0}
\fooauthor{Me}
\foocreator{Me}
\footitle{The title}
\foosubject{A subject}
\fooproducer{LaTeX}

\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\test
\expandafter\expandafter\expandafter{\DeliverHyperSetupKeyValList}%

\show\test

\expandafter\expandafter\expandafter\hypersetup
\expandafter\expandafter\expandafter{\DeliverHyperSetupKeyValList}%

\begin{document}

Some text.

\end{document}

相关内容