当我使用下面的代码或 chaprange 包时,超链接包和目录出现了问题

当我使用下面的代码或 chaprange 包时,超链接包和目录出现了问题
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newif\if@chap@enddc
  \@chap@enddctrue
\let\ltx@@chapter\@chapter
\def\@chapter[#1]#2{%
  \ltx@@chapter[#1]{#2}
  \expandafter\label{chap:\thechapter}}%
\let\ltx@toc\tableofcontents
\renewcommand\tableofcontents{%
  \ltx@toc
  \let\ltx@chapter\chapter
  \renewcommand{\chapter}{%
    \expandafter\label{prenextchap:\thechapter}
    \ltx@chapter}}%
\let\ltx@enddocument\enddocument
\renewcommand\enddocument{%
  \if@chap@enddc\expandafter\label{prenextchap:\thechapter}\fi
  \ltx@enddocument}%
\newcommand\chaprange{%
  \expandafter\pageref{chap:\thechapter}--\expandafter\pageref{prenextchap:\thechapter}}%
\let\ltx@addcontentsline\addcontentsline
\newcommand{\CR@addcontentsline}[3]{%
  \edef\@tempa{\detokenize{chapter}}
  \edef\@tempb{\detokenize{#2}}
  \ifx\@tempa\@tempb
    \let\CR@thepage\chaprange
  \else
    \let\CR@thepage\thepage
  \fi
  \addtocontents{#1}{\protect\contentsline{#2}{#3}{\CR@thepage}}}%
\newcommand\chaprangeon{\let\addcontentsline\CR@addcontentsline}
\newcommand\chaprangeoff{\let\addcontentsline\ltx@addcontentsline}
\newcommand\breakchaprange{%
  \expandafter\label{prenextchap:\thechapter}
  \let\addcontentsline\ltx@addcontentsline
  \@chap@enddcfalse}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\g@addto@macro\mainmatter{\chaprangeon}
\g@addto@macro\backmatter{\breakchaprange}
\makeatother

答案1

旧代码\addtocontents直接调用,绕过了 的逻辑hyperref。这会破坏 LaTeX,因此此解决方案改为调用完整的\addcontentsline,但用\thepage替换\chaprange\patchcmd使用etoolbox

章节范围 + 超链接

由于代码量很大,我建议将其放在一个单独的文件中,作为一个包。为此,在与文档相同的目录中,创建一个名为的新文件,hchaprange.sty并向其中添加以下代码:

\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{hchaprange}[2021/05/21 hchaprange v1.0]

% Change page number of chapters in table of contents to a page range
% Source (original idea):
%   https://tex.stackexchange.com/questions/145021/chapterwise-page-range-in-the-toc/145206#145206
% Source (hyperref modification): 
%   https://tex.stackexchange.com/questions/597707/when-i-used-the-code-below-or-the-package-chaprange-then-it-gave-me-a-problem-w?noredirect=1#comment1498939_597707

\RequirePackage{etoolbox}
\expandafter\newif\csname ifishyperrefloaded\endcsname

\@ifpackageloaded{hyperref}{
    \ishyperrefloadedtrue
}{
    \AtBeginDocument{
        \unless\ifx\texorpdfstring\undefinedcmd
            \ishyperrefloadedtrue
        \fi
    }
}

% Classic label expands too, but I prefer to do the expansion explicitly
\def\xlabel#1{%
    \edef\labelcontent{#1}%
    \expandafter\label\expandafter{\labelcontent}%
}

\expandafter\newif\csname if@chap@enddc\endcsname
\@chap@enddctrue
\let\ltx@@chapter\@chapter

\def\@chapter[#1]#2{
    \ltx@@chapter[#1]{#2}
    \xlabel{chap:\csname thechapter\endcsname}
}

\let\ltx@toc\tableofcontents
\renewcommand\tableofcontents{
    \ltx@toc
    \let\ltx@chapter\chapter
    \renewcommand{\chapter}{
        \xlabel{prenextchap:\csname thechapter\endcsname}
        \ltx@chapter
    }
}

\let\ltx@enddocument\enddocument
\renewcommand\enddocument{
    \if@chap@enddc
        \xlabel{prenextchap:\csname thechapter\endcsname}
    \fi
    \ltx@enddocument
}
\newcommand\chaprange{%
    \ifishyperrefloaded
        \pageref*{chap:\csname thechapter\endcsname}--%
        \pageref*{prenextchap:\csname thechapter\endcsname}%
    \else
        \pageref{chap:\csname thechapter\endcsname}--%
        \pageref{prenextchap:\csname thechapter\endcsname}%
    \fi
}%

\AtBeginDocument{
    \let\ltx@addcontentsline\addcontentsline

    \newcommand{\CR@addcontentsline}[3]{
        \edef\@tempa{chapter}
        \edef\@tempb{#2}
        \let\tempcontentsline\ltx@addcontentsline
        %
        \ifx\@tempa\@tempb
            \patchcmd{\tempcontentsline}{\thepage}{\chaprange}{}{
                \PackageWarning{ChangeChapterHyperref}{Couldn't patch command to chaprange!}
            }
        \fi
        \tempcontentsline{#1}{#2}{#3}
    }
}

\newcommand\chaprangeon{
    \let\addcontentsline\CR@addcontentsline
}
\newcommand\chaprangeoff{
    \let\addcontentsline\ltx@addcontentsline
}

\newcommand\breakchaprange{
    \xlabel{prenextchap:\csname thechapter\endcsname}
    \let\addcontentsline\ltx@addcontentsline
    \@chap@enddcfalse
}

\g@addto@macro\mainmatter{\chaprangeon}
\g@addto@macro\backmatter{\breakchaprange}

现在您可以在文档中使用

\documentclass{book}
\usepackage{lipsum}

\usepackage{hchaprange}
\usepackage{hyperref}

\begin{document}
\tableofcontents

\mainmatter

\chapter{Title 1}\label{sec:sometest}
\lipsum

\section{Subtitle 1}
\lipsum

\chapter{Title 2}
\lipsum\lipsum

\chapter{Title 3}
\lipsum\lipsum\lipsum

\backmatter
\addcontentsline{toc}{chapter}{References}
\null

\appendix
\chapter{Additional Content}
\end{document}

这应该能解决问题!希望你对此感到满意!我花了相当长一段时间,因为有\thepage一段时间一直在捣鼓(结果它得到了非常特殊的处理)。但后来我了解了这个方便的\patchcmd命令。

相关内容