# Is there a way to measure the remaining space of a line of text?

I'd like to write the following:

Some long paragraph of text \measureremainder{\whatsleft}\begin{mimipage}{\whatsleft}
stuff
\end{minipage}


so that the minipage takes up exactly the remaining \hsize minus \widthof{Some long paragraph of text}. I tried the following, based on code in TeX by Topic:

\newbox\linebox
\newbox\snapbox
\def\restofline#1{%
\hfill\par\setbox\linebox\lastbox% Fill the line, then pop it off
\ifvoid\linebox%
\else%
\unskip\unpenalty%
\setbox\snapbox\hbox{\unhcopy\linebox}% and reset the line without expanding flexible spaces
\setlength{#1}{\wd\linebox}% Then retrieve the difference between the two settings
\usebox\snapbox% and replace the line with the tightly-set one
\fi%
}


And that kinda works, in raw paragraphs: it will duplicate the initial \parindent, though, if the paragraph is only one line long. But it totally breaks if I try it inside, e.g., an itemize environment:

\begin{itemize}
\item Some text \measurerest{\whatsleft}\showthe\whatsleft
\end{itemize}


Because \lastbox doesn't work in vertical mode.

Two approaches that didn't work: I tried \begin{minipage}{\textwidth plus -1fill}, but minipages take a length, not a dimen, so the stretch factors are ignored. I also tried \hfill\setlength\whatsleft\lastskip, but that returns 0.0pt plus 1.0fill instead of SomeNumberOfpt

Is there a way around the \lastbox-in-vertical mode restrictions? Or a more robust way to force TeX to set glue so it can be measured?

-
What do you want to place in the minipage? If it is for drawing rules (or lines) as in Martin Scharrer's answer, then a \leaders based solution will be simpler. –  Aditya May 9 '11 at 17:47
@Aditya: I just used rules in my answer for indication only. You can please any text in there as you want, which might be what the OP wants. I agree, simple rules can be easier implemented with \leaders, but the OP would have surly mentioned a need for rules, wouldn't he? –  Martin Scharrer May 9 '11 at 18:32
Indeed, it's more than just leaders :) I'm trying to typeset some XML-like markup, and have already created an environment for doing that such that it will automatically wrap and indent attributes properly. Now I need to use that in various places, among them a list environment. So my output is roughly * ALabel: |<tag some attrs | | more attrs> | | <tag2 /> | |</tag> | and I want to let the tags wrap in as wide a space as possible (between the |...| bars) @MartinScharrer's answer seems to work for me :) –  Ben Lerner May 10 '11 at 6:49
meta question: is there a way to mark multi-line text in comments as being pre-formatted, like code snippets above? –  Ben Lerner May 10 '11 at 6:50

You could use TikZ for this by placing an empty TikZ picture in \measureremainder which then measures the distance of its position to the right border of the text area. This requires at least two compiler runs to work. It reuses some code from my answer to How to define a figure size so that it consumes the rest of a page?. Some of that code might be published as part of the TeX.SX-TikZ bundle.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\currentsidemargin}{%
\ifodd\value{page}%
\oddsidemargin%
\else%
\evensidemargin%
\fi%
}

\newlength{\whatsleft}

\newcommand{\measureremainder}[1]{%
\begin{tikzpicture}[overlay,remember picture]
% Helper nodes
\path (current page.north west) ++(\hoffset, -\voffset)
node[anchor=north west, shape=rectangle, inner sep=0, minimum width=\paperwidth, minimum height=\paperheight]
(pagearea) {};

node[anchor=north west, shape=rectangle, inner sep=0, minimum width=\textwidth, minimum height=\textheight]
(textarea) {};

% Measure distance to right text border
\path let \p0 = (0,0), \p1 = (textarea.east) in
[/utils/exec={\pgfmathsetlength#1{\x1-\x0}\global#1=#1}];

\end{tikzpicture}%
}

\begin{document}
\section{test}

Some long paragraph of text \measureremainder{\whatsleft}\begin{minipage}[t]{\whatsleft}
\hrulefill
\end{minipage}

Some short text \measureremainder{\whatsleft}\begin{minipage}[t]{\whatsleft}
\hrulefill
\end{minipage}

Some long long long long long long long long long long long long long
long long long long long long long long long long long text \measureremainder{\whatsleft}\begin{minipage}[t]{\whatsleft}
\hrulefill
\end{minipage}

\end{document}


Result:

(The horizontal lines represent the width of the minipage.)

### Update 2011/09/15:

I just uploaded the new package tikzpagenodes to CTAN, which simplifies the above code as follows:

\usepackage{tikzpagenodes}
\usetikzlibrary{calc}

\newcommand{\measureremainder}[1]{%
\begin{tikzpicture}[overlay,remember picture]
% Measure distance to right text border
\path let \p0 = (0,0), \p1 = (current page text area.east) in
[/utils/exec={\pgfmathsetlength#1{\x1-\x0}\global#1=#1}];
\end{tikzpicture}%
}

-
Thanks! That seems to work for me, though I can get it to be slightly "wrong" for some \items in an itemize environment. Not sure what the minimal repro for that is, and it doesn't ultimately matter in the text I actually need to typeset, so this works for me. If I can minimize the test case, I'll post it... –  Ben Lerner May 10 '11 at 6:51
@Ben: You are welcome. Please make sure to also up-vote answers you accept or find to be good. –  Martin Scharrer May 10 '11 at 7:14
it seems the "slightly wrong" results occur for me when the \item winds up being the first text on a new page. I think @DanieEls explanation is relevant, that \item saves off a box which may snarl up zref. I'll add this comment here, so people reading your answer can have as much information as possible... –  Ben Lerner Jun 15 '11 at 23:05
I just noticed @AndrewStacey's \tikzmark macro -- your answer above seems to be closely related. Could it be simplified to something like \rlap{\tikzmark{left}\hfill\tikzmark{right}}\measureHdistancebetween{left}{righ‌​t}{\whatsleft}? (Unfortunately, I can't test it on the machine I'm on right now...) If so, might this be useful in the "best TikZ/PGF answers?" meta-question? –  Ben Lerner Jun 16 '11 at 20:28
@Ben: You can't use \hfill inside \rlap, but you could use \tikzmark or similar Tikz code between \hfill and then decide at the end marker what to draw , backwards I mean. However, this will consume the space. You could use \hskip-\whatsleft to compensate for it, though. –  Martin Scharrer Sep 15 '11 at 14:24

The zref, zref-savepos package has the option to save the position of a marker. In normal text it works quite well. Inside lists it is a different story. On c.t.t. it was explained as: \item doesn't actually print anything, nor does it start a new line. It saves the box containing the bullet, and arranges for \everypar to print it whenever the next paragraph starts, which is after you have have marked the current position (which is then just above the coming new line and at the left margin.

The problem is illustrated by using the linegoal package (it uses zref internaly)

\documentclass{article}
\usepackage{linegoal}
\begin{document}
This is a test \rlap{\rule[.5ex]{\linegoal}{0.5pt}}{}of line goal and all
kinds of everything else here and here again all kinds of everything else
here and here again
\begin{itemize}
\item This is a test \rlap{\rule[.5ex]{\linegoal}{0.5pt}}{}of line goal
and all kinds of everything else here and here again all kinds of
everything else here and here again
\end{itemize}
\end{document}

-

You can try the linegoal package.

-
Thanks -- that looks like the package I need, but it doesn't seem to be giving me the same results as appear in the package documentation. I still get overfull lines, even when I run pdflatex 5 times through -- The first three times it says references may have changed; the fourth time it's stable; the fifth was for good luck :) I'd still be curious if there's a purely-TeX based solution, that doesn't involve auxiliary files... –  Ben Lerner May 4 '11 at 9:03