\documentclass[pagesize=auto]{scrartcl} \usepackage{fixltx2e} \usepackage{etex} \usepackage{lmodern} \usepackage[T1]{fontenc} \usepackage{textcomp} \usepackage{microtype} \usepackage{hyperref} \newcommand*{\mail}[1]{\href{mailto:#1}{\texttt{#1}}} \newcommand*{\pkg}[1]{\textsf{#1}} \newcommand*{\cs}[1]{\texttt{\textbackslash#1}} \makeatletter \newcommand*{\cmd}[1]{\cs{\expandafter\@gobble\string#1}} \makeatother \addtokomafont{title}{\rmfamily} \title{The \pkg{sphack} package\thanks{This manual corresponds to \pkg{sphack.sty}~v1.0, dated~22 May 1998.}} \author{Oliver Pretzel\thanks{\mail{o.pretzel@ic.ac.uk}}} \date{22 May 1998} \begin{document} \maketitle \noindent Standard \LaTeX\ uses the macros \cmd{\@bsphack}, \cmd{\@esphack}, and \cmd{\@Esphack}, for inserts into the text that should be invisible. So, for instance a space before and after a \cmd{\label} command should not result in two spaces in the output. \LaTeX\ deals with this as follows % \begin{itemize} \item in maths mode do nothing, \item in horizontal mode restore the space factor, \item if the last thing on the list was a space add \cmd{\ignorespaces} (and (\cmd{\global})\cmd{\ignore\-true} at the end of an environment), \item in vertical mode do nothing. \end{itemize} Doing nothing in maths mode is (nearly) harmless because maths mode does its own spacing (and anyway hidden commands will usually appear only at the start or end of maths). Doing nothing in vertical mode is not harmless. Many invisible commands such as \cmd{\index} may insert delayed write commands into \TeX's output (so that page numbers are correctly calculated). These commands can cause vertical space to accumulate, and may cause a page break; \cmd{\index} is a particular problem in \LaTeX2.09 since it inserts a delayed write if an index is actually being built (\cmd{\makeindex} in preamble) but does nothing otherwise. That can change the page breaks in a document. It is not possible to solve this problem completely in \LaTeX\ because \TeX\ does not remove things from the main vertical list once they have been contributed. So \LaTeXe\ makes \cmd{\index} insert something into the vertical list whether the index is being written or not. That has the virtue of consistancy, but is far from ideal. For instance, an \cmd{\index} immediately after an \cmd{\item} can cause the page to break between the item label and content. \pagebreak[2] The code in the \pkg{sphack} package remedies this fault and other common anomalies so that commands are nearly always invisible in vertical mode as well. It works as follows: % \begin{itemize} \item Rename \LaTeX's dimension \cmd{\@savsk} to \cmd{\@savdim} set a new skip \cmd{\@savsk} (because we need a true skip and a dimension in vertical mode) \item \cmd{\@bsphack} (at start of invisible command) \begin{itemize} \item in hmode (non-math) \begin{enumerate} \item store spacefactor in \cmd{\@savsf} \item store lastskip in \cmd{\@savsk} (used to test whether space already present) \end{enumerate} \item in vmode \begin{enumerate} \item store lastpenalty in \cmd{\@savsf} \item store lastskip in \cmd{\@savsk} (used for movement) \item store previous depth in \cmd{\@savdim} \item skip back \cmd{\lastskip} \end{enumerate} \end{itemize} \item \cmd{\@esphack} (at end of invisible command) \begin{itemize} \item in hmode (non-math) \begin{enumerate} \item set spacefactor = \cmd{\@savsf} \item if \cmd{\@savsk} > \cmd{\z@} \cmd{\ignorespaces} \end{enumerate} \item in vmode \begin{enumerate} \item if in a label, or just after section heading, or if \cmd{\@nobreak}\\ insert infinite penalty, (to prevent a page break)\\ else insert penalty \cmd{\@savsf}\\ endif \item set previous depth = \cmd{\@savdim} \item skip \cmd{\@savsk} \end{enumerate} \end{itemize} \end{itemize} % Just as in standard \LaTeX, \cmd{\@Esphack} is \cmd{\@esphack} + (\cmd{\global})\cmd{\@ignoretrue}. It is not necessary to change any of the label or index macros to fit with this code. \end{document}