ToC 书目部分 hyperref 不适用于 sectsty 和 biblatex

ToC 书目部分 hyperref 不适用于 sectsty 和 biblatex

我需要将章节标题设为大写。我已经用 实现了这一点sectsty,但最近发现了一个问题。在目录中,单击“参考”不会将我带到该章节,并且出现以下警告:

pdfTeX warning (dest): name{section*.2} has been referenced but does not exist, replaced by a fixed one

对于 LoF,我可以使用\phantomsection\addcontentsline,但是当参考书目为空时\printbibliography不会输出任何部分,这会破坏此方法(除非有办法检测\printbibliography命令是否不输出任何内容)。

梅威瑟:

\documentclass[12pt]{article}

\usepackage{float}
\usepackage{csquotes}
\usepackage{biblatex}
\usepackage[nottoc]{tocbibind}
\usepackage{hyperref}
\usepackage{sectsty}
    \allsectionsfont{\fontsize{12pt}{12pt}\selectfont}
    \sectionfont{\fontsize{12pt}{12pt}\selectfont\scshape\MakeUppercase} % Removing this fixes the problem

\begin{filecontents}[overwrite]{\jobname.bib}
@book{2people,
    author = {John Smith1 and Alex Smith2},
    title = {Some Other Thing},
    date = {1971}
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}

\tableofcontents
\clearpage\section{First}
\begin{figure}[H]\caption{Caption \parencite{2people}}\end{figure}
\clearpage\printbibliography[heading=bibintoc]
\clearpage\listoffigures
%\cleardoublepage % Using these instead of tocbibind fixes the LoF link in the ToC
%\phantomsection\addcontentsline{toc}{section}{\listfigurename}
%\listoffigures

\end{document}

答案1

作为乌尔丽克·菲舍尔 在评论中解释末尾\MakeUppercase\sectionfont应用于其完整参数并有效禁用hyperref的锚点。这就是您需要手动\phantomsections 的原因。

您可以定义一个新的标题类型mybibintoc

\makeatletter
\defbibheading{mybibintoc}[\refname]{%
  \section*{#1}%
  \phantomsection
  \addcontentsline{toc}{section}{#1}%
  \@mkboth{\abx@MakeMarkcase{#1}}{\abx@MakeMarkcase{#1}}}
\makeatother

并使用它\printbibliography[heading=mybibintoc]

这将重新定义参考书目标题以自动包含\phantomsection。根据该定义,链接锚点将指向标题之后,但您可能不希望出现这种情况。

您可以稍微改变一下顺序,将 移到\section*{#1}%之后\addcontentsline,但这样标签可能又会附加到错误的内容上。如果您无论如何都要在参考书目之前开始一个新页面,最安全的做法是将 包含\clearpage在标题定义中。这样锚点就始终有效了。

\makeatletter
\defbibheading{mybibintoc}[\refname]{%
  \clearpage
  \phantomsection
  \addcontentsline{toc}{section}{#1}%
  \section*{#1}%
  \@mkboth{\abx@MakeMarkcase{#1}}{\abx@MakeMarkcase{#1}}}
\makeatother

平均能量损失

\documentclass[12pt]{article}

\usepackage{float}
\usepackage{csquotes}
\usepackage{biblatex}
\usepackage[nottoc]{tocbibind}
\usepackage{hyperref}
\usepackage{sectsty}
\allsectionsfont{\fontsize{12pt}{12pt}\selectfont}
\sectionfont{\fontsize{12pt}{12pt}\selectfont\scshape\MakeUppercase} % Removing this fixes the problem

\addbibresource{biblatex-examples.bib}

\makeatletter
\defbibheading{mybibintoc}[\refname]{%
  \clearpage
  \phantomsection
  \addcontentsline{toc}{section}{#1}%
  \section*{#1}%
  \@mkboth{\abx@MakeMarkcase{#1}}{\abx@MakeMarkcase{#1}}}
\makeatother

\usepackage{lipsum}
\newcommand*{\lorem}{lorem ipsum dolor sit amet}
\newcommand*{\lllorem}{\lorem\ \lorem\ \lorem}

\begin{document}

\tableofcontents
\clearpage\section{First}
\begin{figure}[H]\caption{Caption \parencite{sigfridsson}}\end{figure}
%\clearpage\section*{Second}\addcontentsline{toc}{section}{Second}
\lipsum[1-3] 
\lllorem\ \lllorem\ \lllorem\ Lorem.
\printbibliography [heading=mybibintoc]
%\clearpage\listoffigures
%\cleardoublepage % Using these instead of tocbibind fixes the LoF link in the ToC
%\phantomsection\addcontentsline{toc}{section}{\listfigurename}
%\listoffigures

\end{document}

答案2

hyperref可以使用一种不造成干扰的、大写章节标题的替代方法:

\ExplSyntaxOn
\let\@oldsection\section
\RenewDocumentCommand{\section}{ s o m }{
    % \text_uppercase will replace \tl_upper_case in later l3token versions
    \tl_set:Nx\@section_upper{\cs_if_exist:NTF{\text_uppercase:n}
        {\text_uppercase:n{#3}}{\tl_upper_case:n{#3}}}
    \IfBooleanTF{#1}
        {\@oldsection*{\@section_upper}}
        {\IfNoValueTF{#2}
            {\@oldsection{\@section_upper}}
            {\@oldsection[#2]{\@section_upper}}}}
\ExplSyntaxOff

至少对于该类来说article,您可以直接设置章节标题的样式,而无需sectsty.MWE:

\documentclass[12pt]{article}

\usepackage{etoolbox}
\usepackage{xparse}
\usepackage{float}
%\usepackage{csquotes}
\usepackage{biblatex}
\usepackage[nottoc]{tocbibind}
\usepackage{hyperref}

\makeatletter
% Make section/subsection text size same as normal text
\patchcmd{\section}{\Large}{\normalsize}{}{}
\patchcmd{\subsection}{\large}{\normalsize}{}{}
\ExplSyntaxOn
% Capitalize section titles
\let\@oldsection\section
\RenewDocumentCommand{\section}{ s o m }{
    % \text_uppercase will replace \tl_upper_case in later l3token versions
    \tl_set:Nx\@section_upper{\cs_if_exist:NTF{\text_uppercase:n}
        {\text_uppercase:n{#3}}{\tl_upper_case:n{#3}}}
    \IfBooleanTF{#1}
        {\@oldsection*{\@section_upper}}
        {\IfNoValueTF{#2}
            {\@oldsection{\@section_upper}}
            {\@oldsection[#2]{\@section_upper}}}}
\ExplSyntaxOff

% Capitalize section titles in ToC (/a/156917)
\let\@oldcontentsline\contentsline
\def\contentsline#1#2{%
    \expandafter\ifx\csname l@#1\endcsname\l@section
        \expandafter\@firstoftwo
    \else
        \expandafter\@secondoftwo
    \fi
    {\@oldcontentsline{#1}{\MakeUppercase{#2}}}%
    {\@oldcontentsline{#1}{#2}}%
}
\makeatother

\begin{filecontents}[overwrite]{\jobname.bib}
@book{2people,
    author = {John Smith1 and Alex Smith2},
    title = {Some Other Thing},
    date = {1971}
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}

\tableofcontents
\clearpage\section{First Section}
\begin{figure}[H]\caption{caption text \parencite{2people}}\end{figure}
\clearpage\printbibliography[heading=bibintoc]
\clearpage\listoffigures

\end{document}

相关内容