\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
命令。