使用 AtEndPreamble 钩子加载包时出错

使用 AtEndPreamble 钩子加载包时出错

考虑以下(并非如此)的 MWE:

\documentclass{article}
\usepackage[style=authoryear-comp,backend=biber]{biblatex}
\addbibresource{biblatex-examples.bib}

\makeatletter
% Load xpatch and hyperref
\@ifpackageloaded{xpatch}{}{\usepackage{xpatch}}
\AtEndPreamble{\@ifpackageloaded{hyperref}{}{\usepackage{hyperref}}}
\makeatother

% Combine label and labelyear links
\xpatchbibmacro{cite}
  {\usebibmacro{cite:label}%
   \setunit{\addspace}%
   \usebibmacro{cite:labelyear+extrayear}}
  {\printtext[bibhyperref]{%
     \DeclareFieldAlias{bibhyperref}{default}%
     \usebibmacro{cite:label}%
     \setunit{\addspace}%
     \usebibmacro{cite:labelyear+extrayear}}}{}{}

% Include labelname in labelyear link
\xpatchbibmacro{cite}
  {\printnames{labelname}%
   \setunit{\nameyeardelim}%
   \usebibmacro{cite:labelyear+extrayear}}
  {\printtext[bibhyperref]{%
     \DeclareFieldAlias{bibhyperref}{default}%
     \printnames{labelname}%
     \setunit{\nameyeardelim}%
     \usebibmacro{cite:labelyear+extrayear}}}{}{}

% Access hyperref's citation link start/end commands
\makeatletter
\protected\def\blx@imc@biblinkstart{%
  \@ifnextchar[%]
    {\blx@biblinkstart}
    {\blx@biblinkstart[\abx@field@entrykey]}}
\def\blx@biblinkstart[#1]{%
  \blx@sfsave\hyper@natlinkstart{\the\c@refsection @#1}\blx@sfrest}
\protected\def\blx@imc@biblinkend{%
  \blx@sfsave\hyper@natlinkend\blx@sfrest}
\blx@regimcs{\biblinkstart \biblinkend}
\makeatother

\newbool{cbx:link}

% Include parentheses around labelyear in \textcite only in
% single citations without pre- and postnotes
\def\iflinkparens{%
  \ifboolexpr{ test {\ifnumequal{\value{multicitetotal}}{0}} and
               test {\ifnumequal{\value{citetotal}}{1}} and
               test {\iffieldundef{prenote}} and
               test {\iffieldundef{postnote}} }}

%  FIXME: The following part of the code fails in beamer hence we remove it
\makeatletter
\@ifclassloaded{beamer}{}{%
\xpatchbibmacro{textcite}
  {\printnames{labelname}}
  {\iflinkparens
     {\DeclareFieldAlias{bibhyperref}{default}%
      \global\booltrue{cbx:link}\biblinkstart%
      \printnames{labelname}}
     {\printtext[bibhyperref]{\printnames{labelname}}}}{}{}
}
\makeatother

\xpatchbibmacro{textcite}
  {\usebibmacro{cite:label}}
  {\iflinkparens
     {\DeclareFieldAlias{bibhyperref}{default}%
      \global\booltrue{cbx:link}\biblinkstart%
      \usebibmacro{cite:label}}
     {\usebibmacro{cite:label}}}{}{}

\xpretobibmacro{textcite:postnote}
  {\ifbool{cbx:link}% patch 2.7+
     {\ifbool{cbx:parens}
        {\bibcloseparen\global\boolfalse{cbx:parens}}
        {}%
         \biblinkend\global\boolfalse{cbx:link}}
        {}}
  {}
  {\xpatchbibmacro{textcite}% patch earlier releases
     {\setunit{%
        \ifbool{cbx:parens}
          {\bibcloseparen\global\boolfalse{cbx:parens}}
          {}%
        \multicitedelim}}
     {\ifbool{cbx:link}
        {\ifbool{cbx:parens}
           {\bibcloseparen\global\boolfalse{cbx:parens}}
           {}%
         \biblinkend\global\boolfalse{cbx:link}}
        {}%
      \setunit{%
        \ifbool{cbx:parens}
          {\bibcloseparen\global\boolfalse{cbx:parens}}
          {}%
        \multicitedelim}}
     {}{}}
% \usepackage[hyperfootnotes=false]{hyperref}

\begin{document}
\textcite{knuth:ct:e}
\end{document}

为什么如果我用 加载hyperref\AtEndPreamble{\@ifpackageloaded{hyperref}{}{\usepackage{hyperref}}},就会出现一堆错误,就好像 hyperref 没有加载一样,而如果我之前用 加载它,包就会正确begin{document}加载\usepackage[hyperfootnotes=false]{hyperref},错误就会消失?

基本上我想要实现的是,当且仅当 hyperref 之前没有加载过的情况下,才在序言末尾加载它。

答案1

基本上我想要实现的是,当且仅当 hyperref 之前没有加载过的情况下,才在序言末尾加载它。

这更容易实现,只需

\usepackage{hyperref}

在序言的最后。

LaTeX 不会两次加载包,因此如果尚未加载,它将加载 hyperref,否则不执行任何操作。

相关内容