TransWikia.com

ToC bibliography section hyperref doesn't work with sectsty and biblatex

TeX - LaTeX Asked on October 4, 2021

I need section titles to be uppercase. I’ve done this with sectsty, but have recently discovered an issue that it causes. In the table of contents, clicking on "References" does not bring me to the section, and there’s the following warning:

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

For the LoF I can use phantomsection and addcontentsline, but when the bibliography is empty printbibliography doesn’t output a section, which would break this method (unless there’s way of detecting if a printbibliography command outputs nothing).

MWE:

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}selectfontscshapeMakeUppercase} % 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
clearpagesection{First}
begin{figure}[H]caption{Caption parencite{2people}}end{figure}
clearpageprintbibliography[heading=bibintoc]
clearpagelistoffigures
%cleardoublepage % Using these instead of tocbibind fixes the LoF link in the ToC
%phantomsectionaddcontentsline{toc}{section}{listfigurename}
%listoffigures

end{document}

2 Answers

An alternative way of capitalizing the section titles that doesn't disrupt hyperref can be used:

ExplSyntaxOn
let@oldsectionsection
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

At least for the article class, you can style the section titles directly without 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@oldsectionsection
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@oldcontentslinecontentsline
defcontentsline#1#2{%
    expandafterifxcsname l@#1endcsnamel@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
clearpagesection{First Section}
begin{figure}[H]caption{caption text parencite{2people}}end{figure}
clearpageprintbibliography[heading=bibintoc]
clearpagelistoffigures

end{document}

Correct answer by TakingItCasual on October 4, 2021

As Ulrike Fischer explained in the comments the MakeUppercase at the end of sectionfont applies to its complete argument and effectively disables hyperref's anchor. That's why you need manual phantomsections.

You could define a new heading type mybibintoc

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

and use that printbibliography[heading=mybibintoc].

This redefines the bibliography heading to automatically include phantomsection. With that definition the link anchor will point to after the heading though, which you may find undesirable.

You could switch the order round a bit and move the section*{#1}% to after addcontentsline, but then the label could again attach to the wrong thing. If you are starting a new page before the bibliography anyway, the safest would be to include the clearpage in the heading definition. Then the anchor is always good.

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

MWE

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}selectfontscshapeMakeUppercase} % 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
clearpagesection{First}
begin{figure}[H]caption{Caption parencite{sigfridsson}}end{figure}
%clearpagesection*{Second}addcontentsline{toc}{section}{Second}
lipsum[1-3] 
lllorem lllorem lllorem Lorem.
printbibliography [heading=mybibintoc]
%clearpagelistoffigures
%cleardoublepage % Using these instead of tocbibind fixes the LoF link in the ToC
%phantomsectionaddcontentsline{toc}{section}{listfigurename}
%listoffigures

end{document}

Answered by moewe on October 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP