我有一张图片和一张表格,它们需要出现在同一个页面中。我现在的做法是将它们都包裹在一个图形中。我遇到的问题是,我试图引用表格,但 LaTex 一直将其标记为图形。
\documentclass[12pt]{article}
\usepackage[margin=1in]{geometry}
\usepackage[colorlinks]{hyperref}
\usepackage[singlelinecheck=false]{caption}
\usepackage{booktabs}
\usepackage{threeparttable}
\usepackage{graphicx}
\graphicspath{ {./images/} }
\begin{document}
stuff stuff \autoref{table:nmr_nitro} blah blah.
\begin{figure}
\includegraphics[scale=0.4]{3-nitrobenzonitrile.png}
\captionof{figure}{3-Nitrobenzonitrile with hydrogens assignments}
\label{figure:nmr_fig_nitro}
\begin{threeparttable}
\addtocounter{footnote}{1}
\captionof{table}{NMR of 3-nitrobenzonitrile}
\label{table:nmr_nitro}
\begin{tabular}{ c c }
\toprule
\textbf{Some Data} & \textbf{Assignment} \\
\midrule
8.542; 2.0 (2H); m; & A, B \\
7.960; 2.1 (2H); m; & C, D \\
\bottomrule
\end{tabular}
\end{threeparttable}
\end{figure}
\end{document}
我找到了两种解决方案。第一种是使用 manual 而不是 autoref,然后手动标记所有链接。另一种是放在\captionsetup{type=table}
表格标题上方,但这似乎是一种 hack。有没有内置的、流畅的方法来做到这一点?
答案1
TL;DR:\captionsetup{type=table}
放在 之前threeparttable
是正确的做法。不要使用\captionof
,\caption
而要使用 。
详细解释:
内部如何\autoref
工作?它采用超锚点名称的第一部分来确定类型,然后使用该类型显示类型的名称以及通常使用的引用\ref
。
这在处理部分等时非常有效:\section
生成一个以 开头的超级锚点名称,section.
并将该名称的锚点放置在文档中,因此\autoref
将显示类似的内容Section 1
,当单击它时,它将跳转到section.1
放置在\section
命令处的超级锚点。
但在处理像figure
和 这样的浮动环境时table
,情况就变得很糟糕了。\caption
是增加计数器的命令,因此超锚点将在这里生成。这有什么不好呢?由于超锚点位于\caption
,单击链接将跳转到标题而不是浮动环境的开头。尤其是如果标题位于图形内容下方,这不是令人满意的用户体验。
因此,hyperref
(Heiko Oberdiek)的前维护者发明了这个hypcap
包。它提供了一个名为的命令\capstart
,它将执行超级锚点操作并使用\@captype
(=浮动环境的名称)作为类型。通常这可以正常工作。但是当与类似命令结合使用时,\captionof
我们会遇到一个问题:超级锚点名称(包括类型)已由以下命令设置\capstart
:
\documentclass[12pt]{article}
\usepackage[colorlinks]{hyperref}
\usepackage{hypcap,capt-of}
\usepackage{booktabs}
\usepackage{threeparttable}
\begin{document}
stuff stuff \autoref{table:nmr_nitro} blah blah.
\begin{figure}
\capstart % Start of table
\begin{threeparttable}
\addtocounter{footnote}{1}
\captionof{table}{NMR of 3-nitrobenzonitrile}
\label{table:nmr_nitro}
\begin{tabular}{ c c }
\toprule
\textbf{Some Data} & \textbf{Assignment} \\
\midrule
8.542; 2.0 (2H); m; & A, B \\
7.960; 2.1 (2H); m; & C, D \\
\bottomrule
\end{tabular}
\end{threeparttable}
\end{figure}
\end{document}
此文档(未使用该caption
包)导致与您的文档相同的错误结果。该怎么办?由于\capstart
没有参数并使用\@captype
作为类型,我们可以提供类似\capstartof
定义\@captype
并\capstart
随后执行的操作:
\documentclass[12pt]{article}
\usepackage[colorlinks]{hyperref}
\usepackage{hypcap}
\usepackage{booktabs}
\usepackage{threeparttable}
\makeatletter
\newcommand\capstartof[1]{\def\@captype{#1}\capstart}
\makeatother
\begin{document}
stuff stuff \autoref{table:nmr_nitro} blah blah.
\begin{figure}
\capstartof{table}% start of table
\begin{threeparttable}
\addtocounter{footnote}{1}
\caption{NMR of 3-nitrobenzonitrile}
\label{table:nmr_nitro}
\begin{tabular}{ c c }
\toprule
\textbf{Some Data} & \textbf{Assignment} \\
\midrule
8.542; 2.0 (2H); m; & A, B \\
7.960; 2.1 (2H); m; & C, D \\
\bottomrule
\end{tabular}
\end{threeparttable}
\end{figure}
\end{document}
好极了,现在一切都好了!
注意:由于\capstartof
定义\@captype
为table
,我们不再需要\captionof
,而可以使用常规\caption
。
现在回到我的caption
包:它hypcap
实现了该功能,并且默认情况下处于启用状态。可以使用包选项将其关闭hypcap=false
,在这种情况下,它可以解决您的问题。但由于上面描述的“错误的跳转目标”问题,这通常不是人们想要的。该hypcap
功能很好,因为它可以产生良好的超链接目标。
因此,我们需要类似\capstartof
这里的东西,一个注册正确类型(通过定义\@captype
)的命令,生成适当的超锚点等。幸运的是,caption
包中已经提供了这样的命令,它被称为\captionsetup{type=...}
或\setcaptiontype{...}
(通常相同)。每次浮动环境启动时,它都会在内部使用,但在处理像您这样的用例时,需要手动放置它,就像\capstartof
上面的示例文档一样:
\documentclass[12pt]{article}
\usepackage[margin=1in]{geometry}
\usepackage[colorlinks]{hyperref}
\usepackage[singlelinecheck=false]{caption}
\usepackage{booktabs}
\usepackage{threeparttable}
\usepackage[demo]{graphicx}
\graphicspath{ {./images/} }
\begin{document}
stuff stuff \autoref{table:nmr_nitro} blah blah.
\begin{figure}% does \captionsetup{type=figure} internally
\includegraphics[scale=0.4]{3-nitrobenzonitrile.png}
\caption{3-Nitrobenzonitrile with hydrogens assignments}
\label{figure:nmr_fig_nitro}
\captionsetup{type=table}% create new hyper anchor at start of table contents
\begin{threeparttable}
\addtocounter{footnote}{1}
\caption{NMR of 3-nitrobenzonitrile}
\label{table:nmr_nitro}
\begin{tabular}{ c c }
\toprule
\textbf{Some Data} & \textbf{Assignment} \\
\midrule
8.542; 2.0 (2H); m; & A, B \\
7.960; 2.1 (2H); m; & C, D \\
\bottomrule
\end{tabular}
\end{threeparttable}
\end{figure}
\end{document}
总结一下:
\captionsetup{type=table}
这不是黑客行为,而是一个正确的解决方案。这样,不仅排版的名称\autoref
将被修复,而且单击它将跳转到表格内容的开头,而不是图形内容的开头(或表格的标题)。
使用该软件包时一般\captionof
应避免使用。另请参阅:软件包文档的“6.5 hyperref”部分。hyperref
caption
附言:很抱歉这么晚才回复这个问题。因为我不会定期查看 SX 上的所有新问题,而且没有针对我的特定标签caption
软件包没有特定标签,所以我通常会错过与我的软件包相关的大多数问题,或者我后来偶然发现它们,就像这个一样。所以请随时通过电子邮件向我发送 SX 问题的链接,或者在 Gitlab 项目页面上打开一个问题:https://gitlab.com/axelsommerfeldt/caption/issues谢谢!
答案2
这是因为你将表放在了figure
环境中。由于你已经在使用该caption
包,因此你可以执行
\documentclass[12pt]{article}
\usepackage[margin=1in]{geometry}
\usepackage[colorlinks]{hyperref}
\usepackage[singlelinecheck=false]{caption}
\usepackage{booktabs}
\usepackage{threeparttable}
\usepackage{graphicx}
\graphicspath{ {./images/} }
\begin{document}
stuff stuff \autoref{table:nmr_nitro} blah blah.
\noindent
\begin{minipage}{\textwidth}
\centering
\includegraphics[scale=0.4]{example-image-a}
\captionof{figure}{3-Nitrobenzonitrile with hydrogens assignments}
\label{figure:nmr_fig_nitro}
\addtocounter{footnote}{1}
\captionof{table}{NMR of 3-nitrobenzonitrile}
\label{table:nmr_nitro}
\begin{threeparttable}
\begin{tabular}{ c c }
\toprule
\textbf{Some Data} & \textbf{Assignment} \\
\midrule
8.542; 2.0 (2H); m; & A, B \\
7.960; 2.1 (2H); m; & C, D \\
\bottomrule
\end{tabular}
\end{threeparttable}
\end{minipage}
\end{document}