\documentclass[a4paper,12pt]{article}

\usepackage[vmargin=1in]{geometry}
\usepackage{parskip}
\usepackage{verbatim}
\usepackage[ascii]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}

\makeatletter
\g@addto@macro\maketitle{%
  \thispagestyle{empty}%
}
\providecommand*{\cs}[1]{%
  \texttt{\textbackslash #1}%
}
\providecommand*{\eTeX}{%
  $\m@th\varepsilon$-\TeX
}
\providecommand*{\xpackage}[1]{%
  \textsf{#1}%
}
\newenvironment{code}{%
  \quote
  \verbatim
}{%
  \endverbatim
  \endquote
}
\makeatother

\title{%
  Safe redefinition of \cs{shipout} (II)
  using \cs{lastkern} without \eTeX
}
\author{Heiko Oberdiek}
\date{27th April 2007}

\begin{document}
\maketitle

Goal: Redefine \cs{shipout} to do something with its box.

First we catch its box by \cs{setbox} and \cs{afterassignment}:
\begin{code}
\shipout := \afterassignment\@Test
            \setbox\@Box=
\end{code}
There are two different cases:
\begin{code}
(a) \shipout\box0      -> \setbox\@Box=\box0 \@Test
(b) \shipout\vbox{...} -> \setbox\@Box=\vbox{\@Test ...}
\end{code}
In the latter case we want to postpone macro \cs{@Test} after the
\cs{vbox} group by \cs{aftergroup}.
But how can we differentiate between these cases?

In case (b) we are at the start of a new box. Here \cs{lastkern}
always returns 0pt.
\begin{code}
\shipout := \begingroup
              \setbox0=\hbox\bgroup
                \kern1pt
                \afterassignment\@Test
                \global\setbox\@Box= % \global is necessary
\@Test   :=     \ifdim\lastkern=0pt
                  \expandafter\aftergroup
                \fi
                \@Output
\@Output :=   \egroup
            \endgroup
            \ifvoid\@Box
              % original \shipout ignores void boxes
            \else
              % do something with box \@Box
            \fi
            \@OrigShipout\box\@Box
\end{code}
This is one of the methods implemented by package \xpackage{atbegshi}.
\end{document}
