T-F-S / tcolorbox

A LaTeX package to create highly customizable colored boxes.
http://www.ctan.org/pkg/tcolorbox
LaTeX Project Public License v1.3c
213 stars 15 forks source link

`varwidth upper` almost resets horizontal alignment of upper part #247

Closed muzimuzhi closed 9 months ago

muzimuzhi commented 9 months ago

varwidth upper wraps the upper part in a varwidth environment. Inside varwidth, \leftskip, \rightskip, and \parfillskip are reset (similar to minipage, through \@arrayparboxrestore), hence varwidth upper will almost reset horizontal alignment of upper part set by halign or similar options.

https://github.com/T-F-S/tcolorbox/blob/6d98db4263c612279cca47efde22d1ef8404e573/tex/latex/tcolorbox/tcolorbox.sty#L684-L686

Reinserting \kvtcb@halignupper at the beginning of that varwidth environment content seems to work.

One limitation is that, if alignment analogy to plain TeX is used (which sets, e.g., \leftskip to a skip containing em value), at the time of executing the two \kvtcb@halignupper, current font size should be the same.

\documentclass{article}
\usepackage{tcolorbox}
\usepackage{varwidth}

\tcbset{nobeforeafter}

\begin{document}

\subsection*{Before}
\begin{tcolorbox}[hbox, halign=flush center, halign title=flush center, title=Single-line]
  content
\end{tcolorbox}
\quad
\begin{tcolorbox}[hbox, halign=flush center, halign title=flush center, title={Multi-line, actual}, varwidth upper=.3\linewidth]
  content content content
\end{tcolorbox}
\quad
\begin{tcolorbox}[hbox, halign=flush center, halign title=flush center, title={Multi-line, expected}, varwidth upper=.3\linewidth]
  \centering content content content
\end{tcolorbox}

\subsection*{After}
\makeatletter
\tcbset{
  varwidth upper/.style={%
    before upper={%
      \tcbdimto\tcb@w@upper{#1-(\kvtcb@left@rule+\kvtcb@right@rule+(\kvtcb@boxsep)*2+\kvtcb@leftupper+\kvtcb@rightupper)}%
      \begin{varwidth}{\tcb@w@upper}%
      \kvtcb@halignupper % <<< added
    },
    after upper={\end{varwidth}}
  },%
  varwidth upper/.default=\kvtcb@width,
}
\makeatother

\begin{tcolorbox}[hbox, halign=flush center, halign title=flush center, title=Single-line]
  content
\end{tcolorbox}
\quad
\begin{tcolorbox}[hbox, halign=flush center, halign title=flush center, title={Multi-line, actual}, varwidth upper=.3\linewidth]
  content content content
\end{tcolorbox}
\end{document}

image

Testing all feasible alignment values

```tex \documentclass{article} \usepackage{tcolorbox} \usepackage{varwidth} \usepackage[margin=.5in, landscape]{geometry} \usepackage{pgffor} \tcbuselibrary{hooks} \tcbset{ nobeforeafter, width=.165\linewidth, box align=top, fonttitle=\bfseries\large } \parindent=0pt \begin{document} \foreach \options in {% {adjusted title=\alignment}, {adjusted title=with \texttt{varwidth upper}, hbox, varwidth upper},% {adjusted title=alignment reinserted, hbox, varwidth upper, before upper app={\UseName{kvtcb@halignupper}}}% } {% \foreach \alignment in {% flush center,flush left,flush right,center,left,right } {% \begin{tcolorbox}[ halign/.expand once=\alignment, /utils/exec={\expandafter\pgfkeysalso\expandafter{\options}} ] This is a demonstration text for showing how line breaking works. \end{tcolorbox} } \par } \end{document} ```

image

muzimuzhi commented 9 months ago

In a similar situation, where text fill option wraps the upper part in another layer of minipage, \kvtcb@halignupper is already reinserted right after the inner minipage. See line 693 below: https://github.com/T-F-S/tcolorbox/blob/6d98db4263c612279cca47efde22d1ef8404e573/tex/latex/tcolorbox/tcolorbox.sty#L687-L694

T-F-S commented 9 months ago

varwidth upper should respect the alignment settings. I will correct this for the next version. Thank you!

T-F-S commented 9 months ago

Fixed with https://github.com/T-F-S/tcolorbox/releases/tag/v6.1.0