2

I need a macro for a test if a page has no text, means the current point is the upper left corner of the text area. This does not work:

\documentclass{article}

\makeatletter \newcommand*\isOnTopOfPage{% \ifdim \pagetotal > \pagegoal \expandafter@secondoftwo \else \expandafter@firstoftwo \fi } \makeatother

\begin{document} foo bar \par \isOnTopOfPage{>> On top of the page}% {>> not on top of the page}

\clearpage \isOnTopOfPage{>> On top of the page}% {>> not on top of the page}

\end{document}

Edit 1: Problems are still lines without a \par and empty boxes. Only the second one is correct:

\documentclass{article}

\makeatletter \providecommand@secondofthree[3]{#2} \newcommand*\isOnTopOfPage{% \ifdim\pagetotal=\z@ \unless\ifdim\pagegoal=\maxdimen \expandafter@gobbletwo \fi \expandafter@secondofthree \fi @secondoftwo } \makeatother

\begin{document} f \isOnTopOfPage{>> On top of the page}% {>> not on top of the page}

\clearpage \isOnTopOfPage{>> On top of the page}% {>> not on top of the page}

\clearpage \null% empty box \isOnTopOfPage{>> On top of the page}% {>> not on top of the page}

\end{document}

user187802
  • 16,850
  • While it is nice to have a short example and a focused question, maybe it would help to add a bit of context why you want to test for an empty page. Possibly existing/alternative solutions exist for what you want to do. – Marijn May 29 '21 at 12:56
  • The first line on a page is usually formatted before the previous page is shipped, which means that you really need to be testing for a full page, not an empty one. Preface your test with \needspace. – John Kormylo May 29 '21 at 13:45
  • 1
    This is essentially not possible in tex, as page breaking happens asynchronouslly with line breaking and macro expansion. You need a two pass system, you can write the vertical position with \pdfsavepos and check it on the next run. – David Carlisle May 29 '21 at 14:00
  • The third example doesn't yield the wrong output. If you put \null the following will not end up at the top of the page (you could use the showframe package to see this). But @DavidCarlisle is right, this is not really possible for each and every case. – Skillmon May 29 '21 at 16:07
  • @DavidCarlisle: ah yes, I forgot about it. Will see if it is possible with \pdfsavepos – user187802 May 29 '21 at 17:58

1 Answers1

4

From the TeX book:

When the current page contains no boxes, \pagetotal and its relatives are zero and \pagegoal is 16383.99998 pt (TeX’s largest ⟨dimen⟩);

So the following test does what you want:

\documentclass{article}

\makeatletter \providecommand@secondofthree[3]{#2} \newcommand*\isOnTopOfPage{% \ifdim\pagetotal=\z@ \unless\ifdim\pagegoal=\maxdimen \expandafter@gobbletwo \fi \expandafter@secondofthree \fi @secondoftwo } \makeatother

\begin{document} foo bar \par \isOnTopOfPage{>> On top of the page}% {>> not on top of the page}

\clearpage \isOnTopOfPage{>> On top of the page}% {>> not on top of the page}

\end{document}

Skillmon
  • 60,462
  • thanks, but there is still a problem without a par in a first line or a an empty box.I modified my question. – user187802 May 29 '21 at 13:30
  • the quote at the top is true, but the condition it states isn't the same as "the text at this position will end up at the top of a page" especially as the question (now) includes some tests mid-paragraph where you don't even know what page it will be on, let alone whetehr it will be at the top. – David Carlisle May 29 '21 at 14:52
  • @DavidCarlisle well, the first MWE was different. I know that this doesn't work mid paragraph. – Skillmon May 29 '21 at 16:04
  • @Skillmon sure I know you know, the comment wasn't aimed at you:-) – David Carlisle May 29 '21 at 16:54