1

I want to define a new environment that is very similar to the longtable environment, therefore I tried the following:

\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}

This gives the caption 'Examplebox 0: Caption of this example box.'. After the examplebox, the counter has increased to 1, so the counter of examplebox seems to work. However, the environment folows the Table counter, and using \autoref gives 'Table 0' instead of 'Example box 0'.

How can I get examplebox to use the defined counter and to include this in the autoref command? Can anyone help me out please?

Thanks in advance!

Tim

  • 1
    Welcome to TeX.SX! You could make it slightly easier for people to help you if you did not only show code snippets, but a full compilable example that people can just copy, paste and run. – moewe Jul 16 '18 at 11:30
  • Related tex.stackexchange.com/q/32553/35864 together with your refstepcounter you are already there if you can convince longtable to take the counter value of examplebox inszead of it the table counter. But maybe there is a more elegant method. – moewe Jul 16 '18 at 11:32
  • Maybe ltcaption's \LTcaptype or longtable* can also help you... – moewe Jul 16 '18 at 11:35
  • 1
    I'm not sure if that is only the example from your question, but there arme more elegant ways to obtain a box than longtable. tcolorbox or mdframed spring to mind. – moewe Jul 16 '18 at 11:43
  • 1
    @TimvanDam Found it: tex.stackexchange.com/a/327649/2574 (Originating from comp.text.tex.narkive.com/JrzmR00d/… ) The funny thing: The answer below already uses this approach. It seems I lost track of all the LaTeX things I have done in the past... – user2574 Jul 16 '18 at 19:24
2

In your example it looks as though examplebox is just a box with coloured background in which case dedicated box packages like tcolorbox, mdframed or framed might be a better choice than a self-made longtable environment.

Anyway, ltcaption's \LTcaptype looked promising. To be able to use it I we can define a new float type with help of the newfloat package. \DeclareFloatingEnvironment{examplebox} already defines a new counter and the environment, so that we only need to redefine it for 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}

enter image description here

  • The examplebox should be able to break over multiple pages. Furthermore, I'm editing a book that contains over 100 example boxes currently written witt the the longtable environment. This slight modification seemed the easiest way to change the reference label to Example box. Thanks again! – Tim van Dam Jul 16 '18 at 14:48
  • @TimvanDam tcolorbox can have its boxes broken across pages as well, so that should not be a problem. Of course converting things to a new, cleaner syntax may take a bit of time. Sometimes it pays off, sometimes it doesn't. But please keep it in mind for future projects. – moewe Jul 16 '18 at 15:04
0

Be aware that longtable

  • makes use of the table-counter.
  • causes the \caption-command to write entries for the list of tables (the .lot-file) and to make use of the table-counter.

These aspects are "hard-wired" both into the longtable environment and into the patch for the longtable-environment provided by the hyperref package.

In other words:
Unfortunately there is no \usecounter and no \uselistof for longtable-environments.

With your example-boxes you might wish

  • to use another counter than the table-counter
  • not to have entries for example-boxes merged into the list of tables but to have a separate list of example boxes.

As things are somewhat "hardwired" in the longtable-package, if you want to be accurate, you need to derive your own style-file/your own package, containing your own variant of the longtable-environment where each occurrence of the usage of the table-counter is replaced by usage of the examplebox-counter, and where each attempt at writing to the .lot-file is replaced by attempts at writing to the list-of-exampleboxes-file (.loEB-file in the example below).
That package should also take into account patches as provided by the hyperref-package.

If you don't wish to be accurate, you can within the examplebox-environment

  • redirect using the infrastructure of the table-counter to using the infrastructure of the examplebox-counter. Be aware that macros like \hyper@makecurrent, which use the counter-name directly for deriving names of anchors for hyperlinks, need to be patched so that they crank out the usage of the name of the table-counter and replace it by usage of the name of the examplebox-counter.
  • redirect writing to the .lot-file to writing to another file, e.g., to a .loEB-file. In order to achieve this, the macro \addcontentsline can be patched to crank out cases where entries shall go to the .lot-file / the \ext@table-file.

Spontaneously I see two important reasons why this redirection-approach is not accurate:

  1. This redirection-approach breaks nesting inside your examplebox-environment things other than examplebox-environments that also use the table-counter and/or that also write entries for the list of tables/for the .lot-file.

  2. This redirection-approach might break \autoreferencing tables and other things where the table-counter was used for creating the corresponding referencing-label for cases where the auto-reference is to occur/to take place "inside" the examplebox-environment.

Thus a rule of thumb: With the code below don't nest tables and other things that make use of the table-counter or that do write to the list of tables inside the examplebox-environment.

In case you can live with this, here is some code:

\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}

enter image description here enter image description here enter image description here

  • Thanks for this proposed solution. However, I cannot manage to use enumerate inside this environment, while itemize does not give any problems... Do you have any idea how to overcome this? – Tim van Dam Jul 16 '18 at 20:20
  • @TimvanDam There was a bug in \MyPatchedhyper@makecurrent: Instead of \expandafter@secondoftwo it must be \expandafter\@secondoftwo My apologies. I've edited my answer accordingly. Besides this: For itemize and enumerate I suggest loading the array package and using p{<width>} columns. – Ulrich Diez Jul 17 '18 at 8:33
  • Thanks a lot, it looks even better now. Only I also want the reference label to be 'Example box 1' instead of 'item 1' (top of page 3). This problem only arises when enumerate is used inside the examplebox environment, while itemize works fine... I've searched everywhere and even tried to modify the autoref function, but I didn't get this to work. – Tim van Dam Jul 17 '18 at 8:54
  • @TimvanDam You can probably also do something like \multicolumn{1}{p{5cm}}{\begin{itemize}...\end{itemize}...\begin{enumerate}...\end{enumerate]} Also be aware that the label for the box must come before any other counter is incremented via\refstepcounter as is the case e.g. with enumerate. – Ulrich Diez Jul 17 '18 at 8:56
  • @TimvanDam Inside your examplebox place the referencing-label somewhere where yet no other counter is incremented via \refstepcounter. enumerate does use \refstepcounter and thus does change the info that goes into following referencing-labels. I overlooked that. I just edited my answer so that it shows correct \label-placement. – Ulrich Diez Jul 17 '18 at 8:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.