4

I am writing a document class. I'd like that table environments are automatically transformed with tcolorboxes. Specifically, I'd like that the code \begin{table} ... \end{table} produces a table looking like the second table (i.e., the one using a tcolorbox). Note that this requires to recover the caption and the label.

enter image description here

\documentclass{article}

\usepackage{tcolorbox,xcolor}
\newtcolorbox[blend into=tables]{tablebox}[1][]{%
  float=htb,
  sharp corners,
  colback=blue!5,
  colframe=blue!50!darkgray,
  capture=hbox,every float=\centering,#1}

\begin{document}

Table \ref{temperatures} uses a tcolorbox.

\begin{table}
  \caption{My table}\label{temperatures}
  \begin{center}
    \begin{tabular}{ll}
      \hline
      Paris & 21 degrees\\
      Berlin & 19 degrees\\
      \hline
    \end{tabular}
  \end{center}    
\end{table}


\begin{tablebox}[title={My table}, label={temperatures},code={\par\medskip}]
  \begin{tabular}{ll}
    \hline
    Paris & 21 degrees\\
    Berlin & 19 degrees\\
    \hline
  \end{tabular}
\end{tablebox}

\end{document}
8
+100

This is an attempt to talk you out of this. But let me start with an in principle working prototype example.

\documentclass{article}
\usepackage{environ}
\usepackage{tcolorbox,xcolor}
\newtcolorbox[blend into=tables]{tablebox}[1][]{%
  float=htb,
  sharp corners,
  colback=blue!5,
  colframe=blue!50!darkgray,
  capture=hbox,every float=\centering,#1}
\makeatletter
\newsavebox\TabB@x
\newif\ifTab@hasTitle
\newif\ifTab@hasLabel
\tcbset{tab@title/.code={\ifTab@hasTitle
\tcbset{title=#1}%
\fi},tab@label/.code={\ifTab@hasLabel
\tcbset{label=#1}%
\fi}}
\NewEnviron{Table}[1][]{\begingroup
\gdef\@gtempa{\relax}%
\gdef\@gtempb{\relax}%
\global\Tab@hasTitlefalse
\global\Tab@hasLabelfalse
\renewcommand\caption[1]{\global\Tab@hasTitletrue\gdef\@gtempa{##1}}%
\renewcommand\label[1]{\global\Tab@hasLabeltrue\gdef\@gtempb{##1}}%
\begin{lrbox}\TabB@x
\BODY
\end{lrbox}%
\global\setbox\TabB@x\box\TabB@x
\endgroup
\begin{tablebox}[tab@title=\@gtempa, tab@label=\@gtempb,code={\par\medskip}]
\usebox\TabB@x
\end{tablebox}}
\makeatother

\begin{document}

Table \ref{temperatures} uses a tcolorbox.

\begin{Table}
  \caption{My table}
  \label{temperatures}
  %\begin{center}
    \begin{tabular}{ll}
      \hline
      Paris & 21 degrees\\
      Berlin & 19 degrees\\
      \hline
    \end{tabular}
  %\end{center}    
\end{Table}

Table \ref{lowtemperatures} has no title.

\begin{Table}
  \label{lowtemperatures}
    \begin{tabular}{ll}
      \hline
      Paris & 21 degrees\\
      Berlin & 19 degrees\\
      \hline
    \end{tabular}
\end{Table}

\begin{Table}
  \caption{Another table}
  \label{hightemperatures}
    \begin{tabular}{ll}
      \hline
      Paris & 21 degrees\\
      Berlin & 19 degrees\\
      \hline
    \end{tabular}
\end{Table}



% \begin{table}
%   \caption{My table}\label{temperatures}
%   \begin{center}
%     \begin{tabular}{ll}
%       \hline
%       Paris & 21 degrees\\
%       Berlin & 19 degrees\\
%       \hline
%     \end{tabular}
%   \end{center}    
% \end{table}
% 
% 
% \begin{tablebox}[title={My table}, label={temperatures},code={\par\medskip}]
%   \tcbset{title=pft}%
%   \begin{tabular}{ll}
%     \hline
%     Paris & 21 degrees\\
%     Berlin & 19 degrees\\
%     \hline
%   \end{tabular}
% \end{tablebox}
% 
\end{document}

enter image description here

So this works in principle. (Obviously I was not courageous enough to touch the table environment with a lower-case t, but in principle one could.) One could make \begin{center}...\end{center} work, too, by redefining \center and \endcenter, say, or putting the stuff in some appropriate box.

I did not do that for a reason: to show that there are things which work fine in one environment but less so in another. Trying to tackle all possible cases with LaTeX methods is very hard, or impossible, i.e. one will always find places where this breaks.

This is not to say that one cannot do a very good job at redefining these things. I just do not think one can do a perfect job. If you really want to go that way, here is a prototype that works in principle and shows one possible direction to go.

| improve this answer | |
  • 1
    Thanks for that. When there is no \caption, the table has "label" for the title. Is it possible to fix this? – user94293 May 22 at 6:16
  • 1
    @user94293 Good point! Yes, one can fix that one. Please see the update. – user194703 May 22 at 6:31
  • 1
    By default (if option detach title is not used), tcolorbox stores the value passed to title option in \kvtcb@title, and detects if \kvtcb@title is empty when output. So you can store the argument of \caption directly in \kvtcb@title and skip the if-empty test. – muzimuzhi Z May 22 at 10:14
  • 1
    @muzimuzhiZ Thanks for the suggestion! Yes, that is certainly a great trick. (At the same time it shows even more that there are pitfalls, what if some user decides to detach the title? What I want to say is that by redefining things you lose a lot of options. I have not even mentioned the possibility that some may want to use the caption package with \captionsetup{...}, which is yet another example of something that won't work with these hacks. So I personally would just use the OP's nice tablebox as is.) – user194703 May 22 at 18:10
  • @Schrödinger'scat Makes sense. Thanks for explaining. – muzimuzhi Z May 23 at 4:15

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.