Larghezza regola tcolorbox con tabella all'interno

Aug 20 2020

Apparentemente, il boxrulecomando non ha effetto con un potenziato tcolorboxche ha una tabularx all'interno.

Come posso specificare la larghezza della cornice intorno al tabularx?

Ecco il MWE:

\documentclass{article}
\usepackage[skins]{tcolorbox}
\usepackage{array,tabularx}
\usepackage{colortbl}
\begin{document}

% \usepackage{array,tabularx}
% \usepackage{colortbl} - or - \usepackage[table]{xcolor}
\tcbset{enhanced,fonttitle=\bfseries\large,fontupper=\normalsize\sffamily,
    colback=yellow!10!white,colframe=red!50!black,colbacktitle=red!30!white,
    coltitle=black,center title,
    boxrule=10pt, % NO EFFECT
}
\begin{tcolorbox}[tabularx*={\arrayrulewidth0.5mm}{X|X|X},title=My table]
    One
    & Two
    & Three \\\hline\hline
    1000.00 & 2000.00 & 3000.00\\\hline
    2000.00 & 3000.00 & 4000.00
\end{tcolorbox}

% EDIT : with a multicolumn as 1st cell this does not compile anymore
\begin{tcolorbox}[boxrule=2pt,tabularx*={\arrayrulewidth2pt}{YY|YY|YY},
    title=My table
    ]
    \multicolumn{2}{c|}{title}
    &   \multicolumn{2}{c|}{title}
    &   \multicolumn{2}{c}{title} \\\hline
    2 & d & 3 & e & 4 & f \\\hline
    title & \multicolumn{3}{|l|}{h} & \multicolumn{1}{c|}{title} & j \\
\end{tcolorbox}

\end{document}

EDIT: la prima risposta va bene per la prima tabella nel MWE, ma sto usando una multicolumnprima cella e questo porta un Misplaces \omiterrore. MWE è stato modificato con la tabella problematica.

Risposte

6 Marijn Aug 20 2020 at 19:05

La definizione dello tabularxstile ha come ambientazione il boxruleessere 0.5mm. È possibile sovrascrivere l'impostazione copiando lo stile dall'origine e rimuovendo questa parte:

\documentclass{article}
\usepackage[skins]{tcolorbox}
\usepackage{array,tabularx}
\usepackage{colortbl}
\begin{document}

% \usepackage{array,tabularx}
% \usepackage{colortbl} - or - \usepackage[table]{xcolor}
\tcbset{enhanced,fonttitle=\bfseries\large,fontupper=\normalsize\sffamily,
    colback=yellow!10!white,colframe=red!50!black,colbacktitle=red!30!white,
    coltitle=black,center title,
    boxrule=10pt, % NO EFFECT
}
\makeatletter
\tcbset{tabularx*/.style 2 args={%
    boxsep=\z@,top=\z@,bottom=\z@,leftupper=\z@,rightupper=\z@,
    toptitle=1mm,bottomtitle=1mm,% boxrule setting here removed
    before upper={\arrayrulecolor{tcbcol@frame}\def\arraystretch{1.1}#1%
      \tcb@hack@currenvir\tabularx{\linewidth}{#2}},
    after upper=\endtabularx\arrayrulecolor{black}}}
\makeatother
\begin{tcolorbox}[tabularx*={\arrayrulewidth0.5mm}{X|X|X},title=My table]
    One
    & Two
    & Three \\\hline\hline
    1000.00 & 2000.00 & 3000.00\\\hline
    2000.00 & 3000.00 & 4000.00
\end{tcolorbox}
\end{document}

Risultato:

Modifica: nelle versioni più recenti tcolorboxla definizione è leggermente cambiata. In tal caso la nuova definizione dovrebbe essere la seguente:

\tcbset{tabularx*/.style 2 args={%
    boxsep=\z@,top=\z@,bottom=\z@,leftupper=\z@,rightupper=\z@,
    toptitle=1mm,bottomtitle=1mm,
    before upper*={%
      \let\tcb@CT@arc@save\CT@arc@%
      \arrayrulecolor{tcbcolframe}\def\arraystretch{1.1}#1%
      \tcb@hack@currenvir\tabularx{\linewidth}{#2}},
    after upper*={\endtabularx\global\let\CT@arc@\tcb@CT@arc@save}%
  }
}
muzimuzhiZ Aug 21 2020 at 08:01

Se la necessità è di modificare il valore di boxrulespecificato da opzione tabularx*, allora tabularx*/.append style={boxrule=<dimen>}è più semplice, in cui .append styleè uno dei pgfkeysgestori predefiniti .

Esempio completo:

\documentclass{article}
\usepackage[skins]{tcolorbox}
\usepackage{array,tabularx}
\usepackage{colortbl}

\tcbset{
    enhanced,
    fonttitle=\bfseries\large,
    fontupper=\normalsize\sffamily,
    colback=yellow!10!white,
    colframe=red!50!black,
    colbacktitle=red!30!white,
    coltitle=black,
    center title,
    % change boxrule set by "tabularx*", by default it's 0.5mm
    tabularx*/.append style={boxrule=10pt}
}

\begin{document}
\begin{tcolorbox}[tabularx*={\arrayrulewidth0.5mm}{X|X|X}, title=My table]
    One
    & Two
    & Three \\\hline\hline
    1000.00 & 2000.00 & 3000.00\\\hline
    2000.00 & 3000.00 & 4000.00
\end{tcolorbox}
\end{document}

Aggiornare

Solo per divertimento. Qui viene definito un nuovo pgfkeysgestore .patch code={<search>}{<replace>}utilizzato internamente \xpatchcmddal xpatchpacchetto.

\documentclass{article}
\usepackage{tcolorbox}
\usepackage{xpatch}

\usepackage{array,tabularx}
\usepackage{colortbl}

\makeatletter
% usage:
%   <key>/.patch code={search}{replace}
% similar to def of /handlers/.add code/.code 2 args={...}
\pgfkeys{/handlers/.patch/.code 2 args=%
  % Find out, whether with args or not.
  \pgfkeysifdefined{\pgfkeyscurrentpath/.@args}%
  {% Yes, so add to body and reuse args
    \pgfkeyspatchvalue{\pgfkeyscurrentpath/.@body}{#1}{#2}%
    % Redefine code
    {%
      \pgfkeysgetvalue{\pgfkeyscurrentpath/.@args}{\pgfkeys@tempargs}%
      \pgfkeysgetvalue{\pgfkeyscurrentpath/.@body}{\pgfkeys@tempbody}%
      \def\pgfkeys@marshal{\expandafter\gdef\expandafter\pgfkeys@global@temp\pgfkeys@tempargs}%
      \expandafter\pgfkeys@marshal\expandafter{\pgfkeys@tempbody}%
    }%
    \pgfkeysifdefined{\pgfkeyscurrentpath/.@@body}{%
      % support for \pgfkeysndefargs:
      \pgfkeyslet{\pgfkeyscurrentpath/.@@body}{\pgfkeys@global@temp}%
    }{%
      % support for \pgfkeysdefargs:
      \pgfkeyslet{\pgfkeyscurrentpath/.@cmd}{\pgfkeys@global@temp}%
    }%
  }{% No, so single argument (simple \pgfkeysdef). Redefine accordingly.
    \edef\pgf@expanded@path{\pgfkeyscurrentpath}%
    {%
      \pgfkeysifdefined{\pgf@expanded@path/.@cmd}{%
        \expandafter\expandafter\expandafter\pgfkeys@temptoks
        \expandafter\expandafter\expandafter{%
        \csname pgfk@\pgf@expanded@path/.@body\endcsname}%
      }{%
        \expandafter\pgfkeys@temptoks\expandafter{%
        \expandafter\pgfkeyssetvalue\expandafter{\pgf@expanded@path}{##1}}%
      }%
      \edef\pgfkeys@temp{\the\pgfkeys@temptoks}%
      \pgfkeyspatchvalue\pgfkeys@temp{#1}{#2}%
      \global\let\pgfkeys@global@temp\pgfkeys@temp
    }%
    \def\pgf@temp{\pgfkeyssetvalue{\pgf@expanded@path/.@body}}%
    \expandafter\pgf@temp\expandafter{\pgfkeys@global@temp}%
    \expandafter\long\expandafter\def\expandafter\pgfkeys@temp\expandafter##\expandafter1\expandafter\pgfeov\expandafter{\pgfkeys@global@temp}%
    \pgfkeyslet{\pgf@expanded@path/.@cmd}\pgfkeys@temp
  }%  
}

% usage:
%   \pgfkeyspatchvalue{<key>}{<search>}{<replace>}
% similar to \pgfkeysaddvalue
\long\def\pgfkeyspatchvalue#1#2#3{%
  \pgfkeysifdefined{#1}{%
    \expandafter\xpatchcmd\csname pgfk@#1\endcsname{#2}{#3}{}
      {\PackageError{pgfkeys}{Patching for key #1 fails}}%
  }{}%
}
\makeatother


\begin{document}

\tcbset{
  colframe=black!25,
  colbacktitle=black!75
}

\begin{tcolorbox}[boxrule=5pt, tabularx*={\arrayrulewidth0.5mm}{X|X|X}, title=Before patching]
  One     & Two     & Three   \\ \hline\hline
  1000.00 & 2000.00 & 3000.00 \\ \hline
  2000.00 & 3000.00 & 4000.00
\end{tcolorbox}

% patch option "tabularx*", remove "boxrule=0.5mm"
\tcbset{
  tabularx*/.patch={boxrule=0.5mm}{}
}

\begin{tcolorbox}[boxrule=5pt, tabularx*={\arrayrulewidth0.5mm}{X|X|X}, title=After patching]
  One     & Two     & Three   \\ \hline\hline
  1000.00 & 2000.00 & 3000.00 \\ \hline
  2000.00 & 3000.00 & 4000.00
\end{tcolorbox}

\end{document}