5

I have a simple Latex code

\documentclass{article}
\usepackage[many,listings]{tcolorbox}
\usepackage{lipsum}

\tcbset{
box1/.style={
    boxrule=1pt,
    breakable,
    enhanced,
    boxsep=0.25ex,
    left=8pt,
    right=8pt,
    arc=0mm,
    colback=yellow!15,
    colframe=red,
before=\par\vspace{12pt plus 3pt minus 3pt},
after=\par\vspace{6pt plus 2pt minus 2pt},
}
}

\begin{document}

\lipsum[1]

\begin{tcolorbox}[box1]
 Praesent eget sem vel leo ultrices bibendum. Aenean
faucibus. Morbi dolor nulla, malesuada eu
\end{tcolorbox}

\lipsum[2]

\end{document}

I get the following PDF file

enter image description here

I would like to get a tcolorbox that is automatically adjusted to the current text size (text with multiple rows), so that the last lines of the text is full and box is centered, as is shown on picture below

enter image description here

I can make this if I manually adjust the skip from the left and right sides of the box

\begin{tcolorbox}[box1,left skip=20mm, right skip=20mm]
 Praesent eget sem vel leo ultrices bibendum. Aenean
faucibus. Morbi dolor nulla, malesuada eu
\end{tcolorbox}

I suppose that is possible to do. Please, if anyone knows the solution to help me.

  • 3
    option width allows to define box width and center centers the box on corresponding line. I've no idea how to force last line to fill the box. – Ignasi Jan 16 '18 at 8:13
4

What I have done

If the width of your text is less than the max width possible, I take the width of your text as the width of the tcolorbox.

Otherwise, I have divided the total width of your text by the max width possible to get the number of lines your text requires (the result is rounded to the greater nearest integer). This is a very row method because LaTeX surely applies a more sophisticated algorithm.

As max width possible I used the line width minus the width of the right/left gaps (8pt+8pt), of the boxrules (1pt+1pt) and of the boxseps (.25ex+.25ex) but, of course, you could choose a different max width.

Afterwards, I divided the total width of the text by the number of lines to get a width the closest possible to the width which fits the text. Because of the row method stated before I added a little buffer (customizable, it is an optional parameter of the command \mytcb I created, with the default of 1pt) to avoid an ending line with only a word.

Eventually, I defined an inter-word stretching, by soulpackage, to make the last row fill the little gap that remains without using it, of course also these parameters could be changed:

\sodef{\mystreching}{}{0pt}{2pt plus 1 fill minus 1pt}{0pt}

Warning

I'm sure my solution doesn't always works, but I hope you can solve the (I hope residual) wrong cases by modifying the optional parameter.

\documentclass{article}
\usepackage[many,listings]{tcolorbox}
\usepackage{lipsum}
\usepackage{ifthen}
\usepackage{calc}
\usepackage{soul}
\sodef{\mystreching}{}{0pt}{2pt plus 1 fill minus 1pt}{0pt}
\tcbset{
box1/.style={
    boxrule=1pt,
    breakable,
    text width=\widthofmytcb,
    center,
    enhanced,
    boxsep=0.25ex,
    left=8pt,
    right=8pt,
    arc=0mm,
    colback=yellow!15,
    colframe=red,
before=\par\vspace{12pt plus 3pt minus 3pt},
after=\par\vspace{6pt plus 2pt minus 2pt},
}
}
\newlength{\widthofmytext}
\newlength{\widthofmytcb}
\newlength{\maxwidthpossible}
\pgfmathsetlength{\maxwidthpossible}{\linewidth-18pt-.5ex}%
\newcommand{\mytcb}[2][1pt]{%
    \settowidth{\widthofmytext}{#2}%
    \ifthenelse{\lengthtest{\widthofmytext<\maxwidthpossible}}{% then
        \setlength{\widthofmytcb}{\widthofmytext}%
        }{% else
        \pgfmathparse{int(\widthofmytext/\maxwidthpossible)+1}%
        \edef\numberoflines{\pgfmathresult}%
        \pgfmathsetlength{\widthofmytcb}{\widthofmytext/\numberoflines+#1}%
        }%
    \begin{tcolorbox}[box1]
     \mystreching{#2}
    \end{tcolorbox}%
    }

\begin{document}
\lipsum[1]

\mytcb{Praesent eget sem vel leo ultrices bibendum. Aenean
faucibus. Morbi dolor nulla, malesuada eu}

\mytcb{One row} 

\mytcb{Two rows Two rows Two rows Two rows Two rows Two rows Two rows 
Two rows}

\mytcb{Three rows Three rows Three rows Three rows Three rows Three rows 
Three rows Three rows Three rows Three rows Three rows Three rows Three rows}

\mytcb{Four rows Four rows Four rows Four rows Four rows Four rows Four rows
Four rows Four rows Four rows Four rows Four rows Four rows Four rows 
Four rows Four rows Four rows Four rows Four rows Four rows Four rows 
Four rows Four rows Four rows Four rows}

\lipsum[2]

\end{document}

enter image description here

| improve this answer | |

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.