我有一份包含几千张图表的复杂文档(其中大部分都是细微的变体,但有一些是关键的)。我想制作一个图表列表 (lof),其中只选择性地包含个别图表,将其他图表集中在一起,并完全省略一些图表。我的一些标题是浮点数,其他标题使用 caption 包中的 captionof。
例如:
1.2 这就是国王..................................5
1.5 这是女王..................9
1.16-1.66 各种公主...............12-88
大部分操作都很容易。我可以通过向标题发送一个空白替代参数来省略我想要的条目。我还可以手动向 lof 发送包含一系列图号的条目(用于排除的条目)。
然而困难的是找到一种方法
a) 将页面范围(对应于图形范围)打入 lof 的页码部分。b) 格式化图形范围,使其与其余图形编号对齐(我使用 titletoc)
下面是 MWE 迄今为止的结果图像
\documentclass[a4paper]{book}
\usepackage{caption}
\begin{document}
\listoffigures
\chapter{Bloo}
\begin{figure}[htb]
\caption[]{This is God and does not appear in lof}
\label{fig:first}
\end{figure}
\clearpage
\begin{figure}[htb]
\caption[This is the king]{King}
\label{fig:second}
\end{figure}
\clearpage
\begin{center}
\captionof{figure}[This is the queen]{Queen}
\label{fig:third}
\end{center}
\clearpage
\begin{center}
\captionof{figure}[]{Does not appear in lof}
\label{fig:fourth}
\end{center}
\clearpage
\begin{center}
\captionof{figure}[]{Princess 1}
\label{fig:fifth}
\end{center}
\clearpage
\begin{center}
\captionof{figure}[]{Princess 2}
\label{fig:sixth}
\end{center}
\addcontentsline{lof}{section}{\ref{fig:fifth}--\ref{fig:sixth} Various princesses page numbers wrong want a range}
\end{document}
编辑:自从发帖以来,我意识到我可以做到
\addtocontents{lof}{\protect \contentsline {figure}{\numberline {\ref{fig:fifth}--\ref{fig:sixth}}{\ignorespaces Various princesses}}{\pageref{fig:fifth}--\pageref{fig:sixth}}}
从而产生巨大的产出。
我暂时将这个问题留在这里,希望它能激发更好的解决方案或帮助其他人。
答案1
这是一个概念验证,不需要太多摆弄;您可以使用\ref
s 和\pageref
s 自己构建“组合 LoF 标题条目”:
\documentclass{article}
\usepackage{lipsum}
\usepackage{caption,graphicx}
\usepackage{tocloft}
\cftsetpnumwidth{3em}
\begin{document}
\sloppy% Just for this example
\listoffigures
\section{Document body}
% Some image within the document body
\begin{figure}[ht]
\centering
\includegraphics[width=1cm]{example-image}
\caption{Example image}
\end{figure}
\appendix
\section{Appendix}
\captionsetup[figure]{list=no}
% First image in Appendix
\begin{figure}[ht]
\centering
\includegraphics[width=1cm]{example-image}
\caption{First image in Appendix}
\label{fig:first-image}
\end{figure}
\lipsum[1-50]% A whole bunch more images
\lipsum[1-50]% A whole bunch more images
\lipsum[1-50]% A whole bunch more images
\addtocounter{figure}{50}% Just for this example
% Last image in Appendix
\begin{figure}[ht]
\centering
\includegraphics[width=1cm]{example-image}
\caption{Last image in Appendix}
\label{fig:last-image}
\end{figure}
% Insert combined LoF entry
\addtocontents{lof}{%
\protect\contentsline{figure}
{\protect\numberline{\protect\ref{fig:first-image}--\protect\ref{fig:last-image}}% Image range
A collection of images}% Collection title
{\protect\pageref{fig:first-image}--\protect\pageref{fig:last-image}}% Page range
{}% ...for hyperref
}
\end{document}
如果由于图形范围较大而需要自然缩进内容条目,则只需删除\protect\numberline
条目并插入适当的空格:
% Insert combined LoF entry
\addtocontents{lof}{%
\protect\contentsline{figure}
{\protect\ref{fig:first-image}--\protect\ref{fig:last-image} % Image range
A collection of images}% Collection title
{\protect\pageref{fig:first-image}--\protect\pageref{fig:last-image}}% Page range
{}% ...for hyperref
}
以上内容兼容hyperref
。
答案2
由于您已经手动输出了\contentsline
指令,因此您可以稍微自动化一下该过程。将其添加到序言中:
\makeatletter
\def\beginfigrange#1{%initiates the start of the figure range
\label{#1}
\edef\dummy{\noexpand\figrangestartpage{\thepage}}
\expandafter\gdef\dummy
\gdef\figrangestartlbl{#1}}
\def\endfigrange#1#2{%ends the figure range and writes the \contentsline to the aux
\label{#1}
\@ifundefined{r@#1}{}{%
\edef\dummylabel{\figrangestartlbl}
\immediate\write\@auxout{\noexpand\@writefile {lof}{\noexpand\contentsline{figure}{\noexpand\numberline {\noexpand\ref{\dummylabel}--\ref{#1}}\ignorespaces #2}{\figrangestartpage --\thepage}}}}
\gdef\figrangestartpage{\relax}
\gdef\figrangestartlbl{\relax}}
\renewcommand\l@figure{\@dottedtocline{1}{1.5em}{5em}}
\makeatother
然后,代替\label{fig:XX}
图形环境中的,\beginfigrange{fig:XX}
在第一个图形环境和\endfigrange{fig:YY}{List of Figures description}
最后一个图形环境中调用。
例如:
\begin{center}
\captionof{figure}[]{Princess 1}
%\label{fig:fifth}
\beginfigrange{fig:fifth}
\end{center}
和
\begin{center}
\captionof{figure}[]{Princess 2}
%\label{fig:sixth}
\endfigrange{fig:sixth}{Various princesses page numbers wrong want a range}
\end{center}
来自您的 MWE。
该\l@figure
宏用于格式化图形列表中的行,因此对其进行了重新定义。
编辑:
for不会立即调用,因此第一次调用时将导致错误\write
。后续运行应该没问题。此行可防止出现此初始错误。\label
\endfigrange
\@ifundefined{r@#1}{}{%
答案3
我不喜欢隐藏\label{fig:XX}
,而我的第一个答案却隐藏了 。遵循惯例的替代方法是使用\thefigure
来提取必要的图形标识符,而不是使用标签键。这允许第一个宏充当“标志”,并消除第二个宏中的潜在引用错误。此外,我还加入了一个检查,以便hyperref
如果已加载,则图形列表条目将链接到范围内的第一个图形。
\documentclass[a4paper]{book}
\usepackage{caption}
\usepackage{hyperref}
\makeatletter
\def\beginfigrange{%initiates the start of the figure range
\edef\dummy{\noexpand\figrangestartpage{\thepage}}
\expandafter\gdef\dummy
\edef\dummy{\noexpand\figrangestartlbl{\thefigure}}
\expandafter\gdef\dummy
%added to use the same reference key as hyperref; will work for \caption, \captionof, and with the hypertexnames=false option
\expandafter\ifx\expandafter\relax\usinghyperref\relax%saves the current hyperlink if hyperref is used
\gdef\hyperapp{\relax}
\else
\edef\dummy{\expandafter\noexpand\expandafter\hyperapp{\@currentHref}}
\expandafter\gdef\dummy
\fi}
\def\endfigrange#1{%ends the figure range and writes the \contentsline to the aux
\edef\dummylabel{\figrangestartlbl}
\edef\dummy{\thefigure}
\immediate\write\@auxout{\noexpand\@writefile{lof}{\noexpand\contentsline{figure}{\noexpand\numberline {\dummylabel--\dummy}{\ignorespaces #1}}{\figrangestartpage --\thepage}{\hyperapp}}}
\gdef\figrangestartpage{\relax}
\gdef\figrangestartlbl{\relax}
\gdef\hyperapp{\relax}}
\renewcommand\l@figure{\@dottedtocline{1}{1.5em}{5em}}
\AtBeginDocument{%Defined such that \usinghyperref = \relax if not using hyperref
\@ifpackageloaded{hyperref}
{\gdef\usinghyperref{true}}
{\gdef\usinghyperref{\relax}}}
\makeatother
使用:
\begin{center}
\captionof{figure}[]{Princess 1}
\label{fig:fifth}
\beginfigrange
\end{center}
和:
\begin{center}
\captionof{figure}[]{Princess 2}
\label{fig:sixth}
\endfigrange{Various princesses page numbers wrong want a range}
\end{center}
变体:
添加到序言中(带有\usepackage{keyval}
),
\makeatletter
\AtBeginDocument{%
%keyvalues for the new second option of caption and captionof
\define@key{runfig}{beginrange}[true]{\def\runfig@beginrange{#1}}
\define@key{runfig}{endrange}[Figure range LOF entry]{\def\runfig@endrange{#1}}
\def\runfigdefaults{\setkeys{runfig}{beginrange={\relax}, endrange={\relax}}}
\gdef\figrangestartlbl{\relax}%use the label as a flag to indicate if the current figure is within a running fig; if so, it will not be in the list of figures.
%redefine \caption and \captionof
\let\@oldcaption=\caption
\let\@oldcaptionof=\captionof
\def\caption{\@ifstar{\@newcapstar}{\@newcapnostar}}
\def\@newcapnostar{\@ifnextchar[{\@newcapnostaropa}{\@newcapnostarnoop}}
\def\@newcapnostaropa[#1]{\@ifnextchar[{\@newcapnostaropaa[#1]}{\@newcapnostaropab[#1]}}
\def\@newcapnostaropab[#1]#2{\@newcapnostaropaa[#1][]{#2}}
\def\@newcapnostarnoop#1{\@newcapnostaropaa[][]{#1}}
\def\@newcapnostaropaa[#1][#2]#3{%
\runfigdefaults
\setkeys{runfig}{#2}
\expandafter\ifx\expandafter\relax\runfig@beginrange\relax%not beginfigrange
\expandafter\ifx\expandafter\relax\runfig@endrange\relax%not endfigrange
\expandafter\if\expandafter\relax\figrangestartlbl\relax%not running...default caption behavior
\@oldcaption[#1]{#3}
\else%is running, exclude from LOF
\@oldcaption[]{#3}
\fi
\else%is endfigrange
\@oldcaption[]{#3}
\endfigrange{\runfig@endrange}
\fi
\else%is beginfigrange
\@oldcaption[]{#3}
\beginfigrange
\fi
}
\def\@newcapstar{\@oldcaption}%the second option is not enabled for the starred variant
%redefine captionof
\def\captionof{\@ifstar{\@newcapofstar}{\@newcapofnostar}}
\def\@newcapofnostar#1{\@ifnextchar[{\@newcapofnostaropa#1}{\@newcapofnostarnoop#1}}
\def\@newcapofnostaropa#1[#2]{\@ifnextchar[{\@newcapofnostaropaa#1[#2]}{\@newcapofnostaropab#1[#2]}}
\def\@newcapofnostaropab#1[#2]#3{\@newcapofnostaropaa#1[#2][]#3}
\def\@newcapofnostarnoop#1#2{\@newcapofnostaropaa#1[][]#2}
\def\@newcapofnostaropaa#1[#2][#3]#4{%
\runfigdefaults
\setkeys{runfig}{#3}
\expandafter\ifx\expandafter\relax\runfig@beginrange\relax%not beginfigrange
\expandafter\ifx\expandafter\relax\runfig@endrange\relax%not endfigrange
\expandafter\if\expandafter\relax\figrangestartlbl\relax%not running...default caption behavior
\@oldcaptionof{#1}[#2]{#4}
\else%is running, exclude from LOF
\@oldcaptionof{#1}[]{#4}
\fi
\else%is endfigrange
{\@oldcaptionof{#1}[]{#4}}%\captionof calls caption, which resets keys (hence group)
\endfigrange{\runfig@endrange}
\fi
\else%is beginfigrange
\@oldcaptionof{#1}[]{#4}
\beginfigrange
\fi
}
\def\@newcapstar{\@oldcaptionof}%the second option is not enabled for the starred variant
}
\makeatother
这将重新定义\caption
并\captionof
具有第二个可选参数,该参数控制运行图形范围。这里的优点是所有标题都会正常定义,然后可以添加第二个参数,而不必重新定义它们之间的图形标题。用法如下所示:
\begin{center}
\captionof{figure}[][beginrange]{Princess 1}
\label{fig:fifth}
%\beginfigrange
\end{center}
和
\begin{center}
\captionof{figure}[][endrange=Various princess page numbers wrong want a range]{Princess 2}
\label{fig:sixth}
%\endfigrange{Various princesses page numbers wrong want a range}
\end{center}