我想定义一个与 longtable 环境非常相似的新环境,因此我尝试了以下步骤:
\documentclass{report}
\usepackage{caption}
\usepackage{longtable}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{colortbl}
%% Defining the examplebox environment
\definecolor{examplebox}{gray}{0.95} %define the examplebox color
\newcounter{examplebox}
\newcommand*{\exampleboxautorefname}{Example box}
\newenvironment{examplebox}{
\refstepcounter{examplebox}
\addtocounter{table}{-1}
\renewcommand*\tablename{Example box}\longtable
}{\endlongtable}
\begin{document}
\autoref{box:test} is the label of this examplebox.\\
The current counter for examplebox is \theexamplebox.
\begin{examplebox}{|c|} \hline
\rowcolor{examplebox} Hello there.\\ \hline
\caption{Caption of this example box.}
\label{box:test}
\end{examplebox}
The current counter for examplebox is now \theexamplebox.
\begin{table}[h]
\begin{center}
\begin{tabular}{| c c c |}
\hline
1&2&3\\ \hline
4&5&6\\ \hline
\end{tabular}
\caption{Random table caption}
\end{center}
\end{table}
The current counter for examplebox is still \theexamplebox.
\end{document}
这将给出标题“示例框 0:此示例框的标题”。在示例框之后,计数器已增加到 1,因此示例框的计数器似乎有效。但是,环境遵循表计数器,使用 \autoref 给出的是“表 0”而不是“示例框 0”。
如何让 examplebox 使用定义的计数器并将其包含在 autoref 命令中?有人能帮我吗?
提前致谢!
蒂姆
答案1
在你的例子中,它看起来examplebox
只是一个带有彩色背景的盒子,在这种情况下,专用的盒子包装就像tcolorbox
,mdframed
或者framed
可能是比自制longtable
环境更好的选择。
无论如何,ltcaption
看起来\LTcaptype
很有希望。为了能够使用它,我们可以在newfloat
包的帮助下定义一个新的浮点类型。\DeclareFloatingEnvironment{examplebox}
已经定义了一个新的计数器和环境,因此我们只需要为重新定义它longtable
。
\documentclass{report}
\usepackage{caption}
\usepackage{longtable}
\usepackage[table]{xcolor}
\usepackage{newfloat}
\usepackage{hyperref}
\definecolor{examplebox}{gray}{0.95}
\DeclareFloatingEnvironment{examplebox}[Example box][List of example boxes]
\newcommand*{\exampleboxautorefname}{Example box}
\renewenvironment{examplebox}{%
\renewcommand\LTcaptype{examplebox}%
\longtable}
{\endlongtable}
\begin{document}
\autoref{box:test} is the label of this examplebox.
The current counter for examplebox is \theexamplebox.
\begin{examplebox}{|c|} \hline
\rowcolor{examplebox} Hello there.\\ \hline
\caption{Caption of this example box.}
\label{box:test}
\end{examplebox}
The current counter for examplebox is now \theexamplebox.
\begin{table}[h]
\begin{center}
\begin{tabular}{| c c c |}
\hline
1&2&3\\ \hline
4&5&6\\ \hline
\end{tabular}
\caption{Random table caption}
\end{center}
\end{table}
The current counter for examplebox is still \theexamplebox.
\end{document}
答案2
意识到longtable
- 使用-counter
table
。 - 导致
\caption
-command 为表格列表 (.lot 文件) 写入条目并使用 -countertable
。
这些方面都“硬连线”到环境中longtable
,以及longtable
由 超链接包裹。
换句话说:
不幸的是\usecounter
,没有\uselistof
forlongtable
环境。
有了示例框,你可能希望
- 使用除
table
-counter之外的其他计数器 - 不要将示例框的条目合并到表格列表中,而是要有一个单独的示例框列表。
由于事情在某种程度上是“硬连线的”长桌-package,如果你想要准确,你需要派生你自己的样式文件/你自己的包,其中包含你自己的 -environment 变体,longtable
其中每次出现的 -counter 用法table
都被 -counter 用法替换examplebox
,并且每次写入 .lot 文件的尝试都被写入 list-of-exampleboxes 文件(下面示例中的 .loEB 文件)的尝试替换。
该包还应考虑由超链接-包裹。
如果你不想准确,你可以在examplebox
-环境中
- 使用 -counter 的基础结构重定向
table
到使用 -counter 的基础结构examplebox
。请注意,像 这样的宏\hyper@makecurrent
,它直接使用计数器名称来派生超链接锚点的名称,需要进行修补,以便它们产生 -counter 名称的使用table
并将其替换为 -counter 名称的使用examplebox
。 - 将写入 .lot 文件重定向为写入另一个文件,例如 .loEB 文件。为了实现这一点,
\addcontentsline
可以修补宏以产生条目应转到 .lot 文件/文件的情况\ext@table
。
我自发地看到了这种重定向方法不准确的两个重要原因:
这种重定向方法会破坏您的环境内部除使用计数器和/或为表列表/.lot 文件写入条目的环境
examplebox
之外的其他事物的嵌套。examplebox
table
这种重定向方法可能会破坏
\autoref
表和其他东西,其中计数器table
用于为自动引用发生/在环境“内部”发生的情况创建相应的引用标签examplebox
。
因此,经验法则是:使用下面的代码时,不要嵌套表格和其他使用-counter 的东西table
,或者不要写入examplebox
-environment 内的表格列表的东西。
如果你可以接受这一点,这里有一些代码:
\documentclass{report}
\usepackage{caption}
\usepackage{longtable}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{colortbl}
\makeatletter
%% Use examplebox-stuff instead of table-stuff:
%%
%% Inside the examplebox-environment
%%
%% - \hyper@makecurrent needs to redirect using the table-counter
%% to using the examplebox-counter. The following things are needed
%% for patching \hyper@makecurrent inside the examplebox environment:
\newcommand\MySavedhyper@makecurrent{}%
\AtBeginDocument{\let\MySavedhyper@makecurrent=\hyper@makecurrent}%
\newcommand\Mytablestring{table}%
\newcommand\MyPatchedhyper@makecurrent[1]{%
\begingroup
\long\def\@tempa{#1}%
\expandafter\endgroup
\ifx\@tempa\Mytablestring
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\MySavedhyper@makecurrent{examplebox}}%
{\MySavedhyper@makecurrent{#1}}%
}%
%% - \addcontentsline needs to redirect writing to the lot-file
%% to writing to the loEB-file (list of Example Boxes).
%% The following things are needed for patching \addcontentsline
%% inside the examplebox environment:
\newcommand\MySavedAddcontentsline{}%
\AtBeginDocument{\let\MySavedAddcontentsline=\addcontentsline}%
\newcommand\Mylotstring{lot}%
\newcommand\Mylotstringb{\csname ext@table\endcsname}%
\newcommand\MyPatchedAddcontentsline[1]{%
\begingroup
\long\def\@tempa{#1}%
\ifx\@tempa\Mylotstring
\expandafter\@secondoftwo
\else
\expandafter\@firstofone
\fi
{%
\ifx\@tempa\Mylotstringb
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi
{\endgroup\MySavedAddcontentsline{#1}}%
}%
{\endgroup\MySavedAddcontentsline{loEB}}%
}%
%%
%% \ExampleboxStuffInsteadOfTableStuff performs redirecting and patching.
%%
\newcommand\ExampleboxStuffInsteadOfTableStuff{%
% Redirect LaTeX 2e-kernel-counter-infrastructure-stuff of
% the table counter to the examplebox counter
\let\c@table=\c@examplebox
\let\thetable=\theexamplebox
\let\p@table=\p@examplebox
\let\cl@table=\cl@examplebox
% Redirect hyperref-counter-infrastructure-stuff and \autoref-stuff
% of the table counter to the examplebox counter:
\let\theHtable=\theHexamplebox
% \let\tableautorefname=\exampleboxautorefname
\let\tablename=\exampleboxname %<- in case \tableautorefname is undefined,
% this will break \autoref-erencing tables
% inside the examplebox-environment!
% patch for hyperref's longtable patch =
% patch \hyper@makecurrent to crank out usage of the table-counter:
\let\hyper@makecurrent=\MyPatchedhyper@makecurrent
% patch \addcontentsline to crank out usage of lot:
\let\addcontentsline=\MyPatchedAddcontentsline
}%
%% examplebox environment
%%
\definecolor{examplebox}{gray}{0.95} %define the examplebox color
\newcounter{examplebox}
\newcommand*{\exampleboxautorefname}{Example box}
\newcommand*{\exampleboxname}{Example box}
\newcommand*\listexampleboxname{List of example boxes}%
\newenvironment{examplebox}{%
\ExampleboxStuffInsteadOfTableStuff
\longtable
}{\endlongtable}
%% \listofexampleboxes
%%
\newcommand\listofexampleboxes{%
\if@twocolumn
\@restonecoltrue
\onecolumn
\else
\@restonecolfalse
\fi
\chapter*{\listexampleboxname}%
\@mkboth{\MakeUppercase\listexampleboxname}%
{\MakeUppercase\listexampleboxname}%
\@starttoc{loEB}%
\if@restonecol\twocolumn\fi
}%
\makeatother
\begin{document}
\listoftables\newpage
\listofexampleboxes\newpage
\autoref{box:test} is the label of this examplebox.\\
The current counter for examplebox is \theexamplebox.
% A column of type p{<width>} from the array package is
% used to make enumerate and itemize work.
\begin{examplebox}{|p{5cm}|} \hline
\rowcolor{examplebox}%
\label{box:test}%
\begin{itemize}
\item A
\item B
\item C
\end{itemize}
\begin{enumerate}
\item A
\item B
\item C
\end{enumerate}
Hello there.\\ \hline
\caption{Caption of this example box.}
\end{examplebox}
The current counter for examplebox is now \theexamplebox.
\begin{table}[h]
\begin{center}
\begin{tabular}{| c c c |}
\hline
1&2&3\\ \hline
4&5&6\\ \hline
\end{tabular}
\caption{Random table caption}
\end{center}
\end{table}
The current counter for examplebox is still \theexamplebox.
\end{document}