4

Consider the following MWE:

\documentclass{minimal}

\begin{document}
\fbox{some text \vrule{} more text}
\fbox{some text \vrule{} more deep text}
\fbox{some text \vrule{} more $\int$ tall text}
\end{document}

In all three cases, the \vrule stretches to the height of the surrounding box, but doesn't touch the edges of the \fbox because of the \fboxsep.

How can I make the \vrule stretch by an extra \fboxsep on each side? I found this question, but it only covers giving an explicit height to the \vrule, while I'd like to extend it by a given amount, but otherwise let it expand and shrink as appropriate to fill the current box.

Clément
  • 4,004

4 Answers4

6

You can use \smash{\vrule}, but you have to specify the height and depth.

\documentclass{article}
\begin{document}
\sbox0{\fbox{some text more text}}%
\fbox{some text \smash{\vrule height\ht0 depth\dp0} more text}
\sbox0{\fbox{some text more deep text}}%
\fbox{some text \smash{\vrule height\ht0 depth\dp0} more deep text}
\sbox0{\fbox{some text more $\int$ tall text}}%
\fbox{some text \smash{\vrule height\ht0 depth\dp0} more $\int$ tall text}
\end{document}

demo


Or you could just use \struts and make all your \fboxes the same height.

\documentclass{standalone}
\begin{document}
\fbox{\strut some text}\hspace{-\fboxrule}\fbox{\strut some text}
\fbox{\strut some text}\hspace{-\fboxrule}\fbox{\strut more deep text}
\fbox{\strut some text}\hspace{-\fboxrule}\fbox{\strut more $\int$ tall text}
\end{document}

demo2

John Kormylo
  • 79,712
  • 3
  • 50
  • 120
  • This is a great idea. Thanks! For the record, I ended up doing this with a twist: instead of repeating the argument to fbox, I ended up making two new commands: one to draw the vrule, and one to draw the box. The box-drawing one starts by measuring its argument with the vrule-alias set to {}, then prints its argument again, this time with the vrule-alias redefined to make a rule of the appropriate height. – Clément May 14 '19 at 17:37
4

one way is to set \fboxsep to zero and than instead \vrule use accordingly set \rule:

\documentclass{minimal}
\setlength\fboxsep{0pt}
\newcommand\VR{\rule[-0.4\baselineskip]{0.4pt}{1.2\baselineskip} }

\begin{document}
\fbox{ some text \VR qjf more text }
\fbox{ some text \VR more deep text }
\fbox{ some text \VR more $\int$ tall text }
\end{document}

enter image description here

Zarko
  • 296,517
  • I think this only works if you know the size of your box in advance (and all are the same). Ideally, I'd like to preserve the natural heights of the boxes. – Clément May 14 '19 at 03:38
4

Looks like a tabular to me.

\documentclass{article} % see https://tex.stackexchange.com/q/42114/121799
\begin{document}
\begin{tabular}{|l|r|}
\hline
some text & more text\\
\hline
\end{tabular}

\begin{tabular}{|l|r|}
\hline
some text & more deep text\\
\hline
\end{tabular}

\begin{tabular}{|l|r|}
\hline
some text & more $\displaystyle\int$ tall text\\
\hline
\end{tabular}
\end{document}

enter image description here

Of course you can adjust the padding.

\documentclass{article} % see https://tex.stackexchange.com/q/42114/121799
% commands based on
\newcommand{\Tstrut}[1]{\rule{0pt}{#1}}       % "top" strut
\newcommand{\Bstrut}[1]{\rule[-#1]{0pt}{0pt}} % "bottom" strut
\newcommand{\TBstrut}[2]{\Tstrut{#1}\Bstrut{#2}}
\begin{document}
\begin{tabular}{|*{20}{c|}}
\hline
some text & more text\\
\hline
\end{tabular}

\begin{tabular}{|*{20}{c|}}
\hline
\TBstrut{2.5ex}{1.5ex}some text & more deep text\\
\hline
\end{tabular}

\begin{tabular}{|*{20}{c|}}
\hline
\TBstrut{4ex}{3ex}some text & more $\displaystyle\int$ tall text & and more \\[0.5ex]
\hline
\end{tabular}

\end{document}

enter image description here

You can make it a command and as long as you have less than 20 rules e.g.

\documentclass{article} 
\newcommand{\PartitionedBox}[2][20]{\begin{tabular}{|*{#1}{l|}} \hline #2\\ \hline \end{tabular}}
\begin{document}
 \PartitionedBox{123 & abc & xyz}
\end{document}

works. (Thanks to JouleV for suggesting to use the option.)

enter image description here

  • Hah! Very smart. Annoyingly, though, that requires counting the 'columns' at every use. – Clément May 14 '19 at 03:35
  • @Clément Yes, that's a valid point which can be easily addressed. –  May 14 '19 at 07:16
  • Excellent point! I didn't think of it, but of course adding too many columns is a neat trick :) So many good answers :'( ^^ – Clément May 14 '19 at 17:35
4

You can measure the text's natural height and depth, add the current \fboxsep and retypeset with a suitable strut and kerns on either side, by setting also \fboxsep to zero.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\vfbox}{m}
 {
  \clement_vfbox:n { #1 }
 }

\box_new:N \l__clement_vfbox_box
\dim_new:N \l__clement_vfbox_ht_dim
\dim_new:N \l__clement_vfbox_dp_dim
\dim_new:N \l__clement_vfbox_sep_dim

\AtBeginDocument
 {
  \dim_set:Nn \l__clement_vfbox_sep_dim { \fboxsep }
 }

\cs_new:Nn \clement_vfbox_strut:nn
 {
  \vrule height #1 depth #2 width 0pt
 }

\cs_new_protected:Nn \clement_vfbox:n
 {
  \group_begin:
  \dim_set:Nn \fboxsep { \l__clement_vfbox_sep_dim }
  \hbox_set:Nn \l__clement_vfbox_box { #1 }
  \dim_set:Nn \l__clement_vfbox_ht_dim { \box_ht:N \l__clement_vfbox_box + \fboxsep }
  \dim_set:Nn \l__clement_vfbox_dp_dim { \box_dp:N \l__clement_vfbox_box + \fboxsep }
  \dim_set:Nn \fboxsep { 0pt }
  \fbox
   {
    \clement_vfbox_strut:nn { \l__clement_vfbox_ht_dim } { \l__clement_vfbox_dp_dim }
    \kern \l__clement_vfbox_sep_dim
    #1
    \kern \l__clement_vfbox_sep_dim
   }
  \group_end:
 }
\ExplSyntaxOff

\begin{document}

\vfbox{some text \vrule{} more text}
\vfbox{some text \vrule{} more deep text}

\bigskip

\vfbox{some text \vrule{} more $\int$ tall text}
\vfbox{some text \vrule{} more $\displaystyle\int$ tall text}

\bigskip

\vfbox{some text \vrule{} \vfbox{some text \vrule{} other} other}

\end{document}

enter image description here

egreg
  • 1,121,712
  • Thanks a lot. I still have a bit of trouble with ExplSyntax, but I think I understand what this does. Am I correct to think that this solution defines a macro that measures its argument and stores its height and depth in two newly defined lengths, and then typesets the argument with fboxsep set to 0 (thereby allowing the vrule to span the whole box), adding struts and kerns to replicate the original box padding? – Clément May 14 '19 at 17:44