TeX – Function Determining the Length of Text Usable with Internal Units

boxeslengths

Is there a way to define a function \horizontallengthof returning the length of a piece of text in internal units? I would like to be able to use it anywhere where something of that sort is required, for example like p{\horizontallengthof{this particular piece of text}} (in a table specification) or \hspace{\horizontallengthof{this particular piece of text}}.


I am hesitant to post a particular use case, since I am interested in a generic solution instead of workarounds for particular situations. But here is one (with calc's \widthof standing in for \horizontallengthof):

\documentclass{article}
\usepackage{fixltx2e}
\usepackage{calc}

\begin{document}

\begin{tabular}{p{0em}@{\hspace{1.0em}\quad}l@{\qquad}l}
  \(\bullet\) & \(x = y\) & \(z = w\) \\
  \(\bullet\) & \(a = b\) & \(c = d\) \\
\end{tabular}

\begin{tabular}{p{\widthof{\(\bullet\)}}@{\hspace{1.0em}\quad}l@{\qquad}l}
  \(\bullet\) & \(x = y\) & \(z = w\) \\
  \(\bullet\) & \(a = b\) & \(c = d\) \\
\end{tabular}

\begin{tabular}{p{\widthof{\(\bullet\)}}@{\hspace{1.0em-\widthof{\(\bullet\)}}\quad}l@{\qquad}l}
  \(\bullet\) & \(x = y\) & \(z = w\) \\
  \(\bullet\) & \(a = b\) & \(c = d\) \\
\end{tabular}

\end{document}

With the suggestion to add fixltx2e, this compiles properly, but I'd like the second table to have the same appearance (spacing-wise) as the first one, while giving me no Overfull \hbox warnings. Table 3 is a failed attempt at achieving this.

One reason why I didn't initially post this is that I didn't want any potential workarounds to this distract from a general (and imho needed) solution.

Best Answer

Hmm arguably this is a calc and/or LaTeX bug.

using calc and \widthof would work in most of the places you mention (as in LaTeX2e such places explicitly changed to use \setlength internally so that they would work with calc. However \hspace appears to have escaped that conversion, the following patch fixes that.....

\documentclass{article}

\usepackage{calc} 

\makeatletter
\def\@hspace#1{\begingroup\setlength\dimen@{#1}\hskip\dimen@\endgroup}
\makeatother

\begin{document}

 a\hspace{\widthof{some text}}b 

\end{document}

The above answers the original question, but the later edits have clarified that this is not needed at all. \widthof is a relatively expensive operation and doing every row just to make space to insert the same text you measured is really just torturing your computer for no real gain. The formulation in the second table matches the version you gave in the first without the over full boxes and without measuring anything.

enter image description here

\documentclass{article}
\usepackage{fixltx2e}
\usepackage{calc}

\begin{document}

\begin{tabular}{p{0em}@{\hspace{1.0em}\quad}l@{\qquad}l}
  \(\bullet\) & \(x = y\) & \(z = w\) \\
  \(\bullet\) & \(a = b\) & \(c = d\) \\
\end{tabular}

\begin{tabular}{@{\hspace\tabcolsep\rlap{$\bullet$}\hspace{1.0em}\quad}l@{\qquad}l}
   \(x = y\) & \(z = w\) \\
   \(a = b\) & \(c = d\) \\
\end{tabular}

\end{document}