2

Is there a reliable way to know in horizontal mode whether the current paragraph contributes to the main vertical list or to a box (vbox or vtop). The point is to know whether \lastbox, \unskip and \unpenalty are usable or not. The only way I found is to put

\newif\ifinsidebox
\everyvbox\expandafter{\the\everyvbox\insideboxtrue}

at the beginning of the document and test \ifinsidebox. But it works only as long as nobody changes \everyvbox.

To be more specific, I want to avoid some bad page break by increasing temporarily the \interlinepenalty, say inside some nopagebreak environment. For this, I essentially break the current paragraph, take the last box of the vertical list with \lastbox, set \interlinepenalty=10000, adjust some paragraph parameters and start a new paragraph by unhboxing the lastbox. At the end of my nopagebreak environment, I do the same, restoring the value of \interlinepenalty. Doing so, it seems that no line break occurred. But for this to work, I need to know before breaking the paragraph whether \lastbox, \unskip and \unpenalty will work.

5
  • Why do you need the test to happen in horizontal mode? Wouldn't you be able to use \lastbox etc. for the verical list in vertical mode anyway?
    – siracusa
    Nov 12, 2016 at 8:41
  • @siracusa ah no Eric wants to know in horizontal mode whether \par\setbox0=\lastbox would work or give an error. Nov 12, 2016 at 8:53
  • I’m afraid I don’t understand your intent: when you break a paragraph into lines and return to (outer) vertical mode, you also exercise the page builder; if the paragraph wasn’t empty, some boxes will be contributed to the main vertical list and immediately moved to the “current page”, where \lastbox can no longer retrieve them. So, the answer to the question “will \lastbox, \unskip, and \unpenalty work after breaking the paragraph” amounts to asking whether or not the paragraph occurred in inner vertical mode.
    – GuM
    Nov 12, 2016 at 14:11
  • @GustavoMezzetti I actually use this to prevent bad page breaks in footnotes. Especially to prevent page breaks in urls because in this case, hyperref puts the entire following page in the link. In this case, I know that the enclosing vertical list in in internal vertical mode. My intent was to design a general macro which would decide whether to activate or not, depending on the type of the englobing vertical list. Nov 14, 2016 at 23:08
  • It might nevertheless be possible to defer the test to vertical mode. If after breaking the paragraph I am in outer vertical mode, I can trigger the output routine by inserting some specific penalty. Then I could unbox \box255 inside a \vboxwhere I can use \lastbox and \unskip, and then recontribute the box to the page. Needs some more work... Nov 14, 2016 at 23:13

1 Answer 1

2

I don't think that you can really know in hmode, but you can defer an \ifinner test to whatever vertical list that you planned to do \lastbox on, whether that is via \par or \vadjust or however you get into vmode.

The following document removes the last line of the minipage paragraph, but gives no error, just a typeout with the paragraph on the main vertical list.

\documentclass{article}
\tracingonline1
\showboxdepth=10
\showboxbreadth=10
\scrollmode
\def\x{one two three four five six }
\def\y{Red \x green \x yellow \x}

\def\lastboxifposible{%
\ifvmode\ifinner
\setbox0=\lastbox
\showbox0
\else
\typeout{no lastbox here}%
\fi\fi}

\begin{document}

\y\par\lastboxifposible

\noindent
\begin{minipage}{\textwidth}
\y\par\lastboxifposible
\end{minipage}

\end{document}

enter image description here

2
  • @EricDomenjoud then I think you are doomed unless you use luatex (other than the code you already suggested in the question) possibly you should move your comment to your question (so it is not lost) then I'll delete this answer. Nov 12, 2016 at 10:49
  • @EricDomenjoud or failing that you still can defer the test, break the paragraph then test \ifinner and if that's true do as you say taking off lastbox and resetting the penalty, if it is false then just restart the paragraph with a \noindent or whatever is needed Nov 12, 2016 at 10:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .