9

Within a \parbox I can access its width via \linewidth (useful e.g. if I want to place an image as wide as the \parbox). Is there a way of accessing the height of a \parbox when the height is fixed by the optional argument? (Of course the question makes sense only in this case.)

\documentclass{article}

\begin{document}

\setlength{\fboxsep}{-\fboxrule}

\fbox{\parbox{100pt}{Some text, some more text, and \the\linewidth}}

% here I'd like something like \parboxheight or similar
\fbox{\parbox[][100pt][t]{100pt}{Some text, some more text, and \the\linewidth, and the height?}}

\end{document}

enter image description here

campa
  • 31,130
  • \ht can be used. – Display Name Aug 18 '17 at 16:27
  • I don't think so, if I got it right then parbox first puts everything in a box and then unbox this in a box of the requested height. The height argument isn't stored anywhere before the first box is created. So you would have to patch the command or write your own wrapper. – Ulrike Fischer Aug 18 '17 at 16:38
  • @UlrikeFischer Oops, I missed the unboxing bit. So @parboxto will not be useful, then. But another solution might involve doing \let\Lparbox=\parbox and then making a new command \parbox which squirrels away the height argument, if present, and then invokes \Lparbox. – Harald Hanche-Olsen Aug 18 '17 at 16:42

3 Answers3

6

The following solution patches \@iiiparbox to get the height in the second parameter. The value is stored in the dimension register \parboxheight.

If the height is not set, LaTeX uses \relax for this parameter. Then, \parboxheight is set to zero. If you want to know, whether the height parameter was set the optional argument, an additional switch can be used.

Example:

\documentclass{article}

\newdimen\parboxheight

\makeatletter
\newcommand*{\org@iiiparbox}{}
\let\org@iiiparbox\@iiiparbox
\renewcommand*{\@iiiparbox}[2]{%
  \ifx\relax#2%
    \setlength{\parboxheight}{0pt}%
  \else
    \setlength{\parboxheight}{#2}%
  \fi
  \org@iiiparbox{#1}{#2}%
}
\makeatother

\begin{document}

\setlength{\fboxsep}{-\fboxrule}

\fbox{\parbox{100pt}{Some text, some more text, and \the\linewidth}}

\fbox{%
  \parbox[][80pt][t]{100pt}{%
    \raggedright
    Some text, some more text, and width \the\linewidth, %
    and the height \the\parboxheight.%
  }%
}
\end{document}

Result

With switch:

\documentclass{article}

\newif\ifparboxheight
\newdimen\parboxheight

\makeatletter
\newcommand*{\org@iiiparbox}{}
\let\org@iiiparbox\@iiiparbox
\renewcommand*{\@iiiparbox}[2]{%
  \ifx\relax#2%
    \parboxheightfalse
    \setlength{\parboxheight}{0pt}%
  \else
    \parboxheighttrue
    \setlength{\parboxheight}{#2}%
  \fi
  \org@iiiparbox{#1}{#2}%
}
\makeatother


\begin{document}

\setlength{\fboxsep}{-\fboxrule}

\newcommand*{\TestText}{%
  \raggedright
  Some text, some more text. The width is \the\linewidth
  \ifparboxheight
    \ and the height is \the\parboxheight
  \fi
  .%
}

\fbox{\parbox{100pt}{\TestText}}

\fbox{\parbox[][80pt][t]{100pt}{\TestText}}

\end{document}

Result with switch

Heiko Oberdiek
  • 271,626
4

The dimension is in argument #2 to \@iiiparbox, so we can patch \parbox in order to save the argument in a length register.

\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\newlength{\parboxtodim}
\patchcmd{\@iiiparbox}
  {\hsize}
  {\ifx\relax#2\else\setlength{\parboxtodim}{#2}\fi\hsize}
  {}{}
\makeatother

\begin{document}

\setlength{\fboxsep}{-\fboxrule}

\fbox{\parbox{100pt}{Some text, some more text, and \the\linewidth}}

% here I'd like something like \parboxheight or similar
\fbox{\parbox[][200pt][t]{100pt}{%
  Some text, some more text, and \the\linewidth, and \the\parboxtodim
}}

\end{document}

enter image description here

egreg
  • 1,121,712
3
\documentclass{standalone}
\newbox\mybox
\savebox\mybox{\parbox{100pt}{This is a test.}}
\begin{document}
\the\ht\mybox\ and \the\wd\mybox
\end{document}

enter image description here

Display Name
  • 46,933
  • 2
    He wanted access to the declared height from within the parbox itself. So this doesn't answer the question. Admittedly, you had to read between the lines a bit to get that. – Harald Hanche-Olsen Aug 18 '17 at 16:36