summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/tools/xspace.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/tools/xspace.dtx')
-rw-r--r--Master/texmf-dist/source/latex/tools/xspace.dtx481
1 files changed, 417 insertions, 64 deletions
diff --git a/Master/texmf-dist/source/latex/tools/xspace.dtx b/Master/texmf-dist/source/latex/tools/xspace.dtx
index 1d3c2ff1642..5cb3b7cb2f1 100644
--- a/Master/texmf-dist/source/latex/tools/xspace.dtx
+++ b/Master/texmf-dist/source/latex/tools/xspace.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
+% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006
% The LaTeX3 Project and any individual authors listed elsewhere
% in this file.
%
@@ -8,19 +8,21 @@
% -------------------------------------------------------
%
% It may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
+% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
% http://www.latex-project.org/lppl.txt
-% and version 1.3 or later is part of all distributions of LaTeX
-% version 2003/12/01 or later.
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
%
% The list of all files belonging to the LaTeX `Tools Bundle' is
% given in the file `manifest.txt'.
%
% \fi
% \iffalse
-%% File: xspace.dtx Copyright (C) 1991-1996 David Carlisle
+%% File: xspace.dtx Copyright (C) 1991-1997 David Carlisle
+%% File: xspace.dtx Copyright (C) 2004-2006 David Carlisle,
+%% Morten H\o gholm
%
%<*dtx>
\ProvidesFile{xspace.dtx}
@@ -30,12 +32,17 @@
%<driver>\ProvidesFile{xspace.drv}
% \fi
% \ProvidesFile{xspace.dtx}
- [1997/10/13 v1.06 Space after command names (DPC)]
+ [2006/05/08 v1.12 Space after command names (DPC,MH)]
%
% \iffalse
%<*driver>
\documentclass{ltxdoc}
-\usepackage{xspace}
+\makeatletter
+\providecommand*\eTeX{{%
+ \if b\expandafter\@car\f@series\@nil\boldmath\fi$\m@th
+ \varepsilon$-\TeX}}
+\makeatother
+\usepackage{xspace}[2006/05/08]
\begin{document}
\DocInput{xspace.dtx}
\end{document}
@@ -46,49 +53,161 @@
% \title{The \textsf{xspace} package\thanks{This file
% has version number \fileversion, last
% revised \filedate.}}
-% \author{David Carlisle}
+% \author{David Carlisle \and Morten H\o gholm}
% \date{\filedate}
% \maketitle
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% \CheckSum{87}
+% \CheckSum{209}
%
% \changes{v1.00}{1991/08/30}{Initial version}
% \changes{v1.01}{1992/06/26}{Re-issue for the new doc and docstrip}
-% \changes{v1.02}{1994/01/31}{Re-issue for LaTeX2e (no change to code)}
+% \changes{v1.02}{1994/01/31}{Re-issue for LaTeX2e (no change to
+% code)}
+% \changes{v1.07}{2004/12/07}{Make extensible. tools/3712}
+% \changes{v1.07}{2004/12/07}{Fix active characters. tools/3747}
+% \changes{v1.07}{2004/12/07}{Update documentation}
+% \changes{v1.08}{2005/05/07}{Better fix for active characters}
+% \changes{v1.09}{2005/07/26}{Improve test by exiting if
+% \cs{@let@token} is a letter}
+% \changes{v1.10}{2005/10/04}{Use higher level functions for
+% conditional processing}
+% \changes{v1.10}{2005/10/04}{Improve expansion method}
%
% \begin{abstract}
-% |\xspace| should be used at the end of a macro designed to be used
-% mainly in text. It adds a space unless the macro is followed by
-% certain punctuation characters.
+% |\xspace| should be used at the end of a macro designed to
+% be used mainly in text. It adds a space unless the macro is
+% followed by certain punctuation characters.
% \end{abstract}
%
% \section{Introduction}
-% After |\newcommand{\gb}{Great Britain\xspace}|\\
-% \newcommand{\gb}{Great Britain\xspace}
-% |\gb is a very nice place to live.|\\
-% \gb is a very nice place to live.\\
-% |\gb, a small island off the coast of France.|\\
-% \gb, a small island off the coast of France.
-%
-% |\xspace| saves the user from having to type \verb*+\ + or |{}| after
-% most occurrences of a macro name in text. However if either of these
-% constructions follows |\xspace|, a space is not added by |\xspace|.
-% This means that it is safe to add |\xspace| to the end of an existing
-% macro without making too many changes in your document.
-%
-% Sometimes |\xspace| may make the wrong decision, and add a space when
-% it is not required. In these cases follow the macro with |{}|, as this
-% has the effect of suppressing the space.
-%
-% Note that this package must be loaded \emph{after} any language (or
-% other) packages that make punctuation characters `active'.
+% \newcommand{\gb}{Great Britain\xspace}\DescribeMacro{\xspace}
+% After defining |\newcommand{\gb}{Great Britain\xspace}|,
+% the command |\gb| will determine when to insert a space
+% after itself and when not. Thus the input
+% \begin{quote}
+% |\gb is a very nice place to live.\\| \\
+% |\gb, a small island off the coast of France.\\|\\
+% |\gb\footnote{The small island off the coast of France.}|\\
+% |is a very nice place to live.|
+% \end{quote}
+% results in the output
+% \begin{quote}
+% \gb is a very nice place to live. \\
+% \gb, a small island off the coast of France.\\
+% \gb\footnote{The small island off the coast of France.}
+% is a very nice place to live.
+% \end{quote}
+% |\xspace| saves the user from having to type \verb*+\ + or
+% |{}| after most occurrences of a macro name in text.
+% However if either of these constructions follows |\xspace|,
+% a space is not added by |\xspace|. This means that it is
+% safe to add |\xspace| to the end of an existing macro
+% without making too many changes in your document. In particular,
+% |\xspace| will always insert a space if the thing following it is
+% a normal letter which is the usual case.
+%
+% Sometimes |\xspace| may make the wrong decision, and add a
+% space when it is not required. There may be different
+% reasons for this behavior but it can always be handled by
+% following the macro with |{}|, as this has the effect of
+% suppressing the space.
+%
+%
+% \subsection{Adding new exceptions}
+%
+% One of the most common reasons for |\xspace| to add an
+% unwanted space is when it is followed by a macro not on its
+% list of exceptions.
+% \DescribeMacro{\xspaceaddexceptions}%
+% With |\xspaceaddexceptions| you can add new commands or
+% characters to be recognized by |\xspace|'s scanning
+% mechanism. Users of advanced footnote packages like
+% \textsf{manyfoot} will often define new footnote macros
+% that should not cause a command ``enhanced'' with |\xspace|
+% to insert a space. If you define the additional footnote
+% macros |\footnoteA| and |\footnoteB|, simply add the
+% following line to your preamble:
+% \begin{quote}
+% |\xspaceaddexceptions{\footnoteA \footnoteB}|
+% \end{quote}
+%
+%
+% \subsection{Support for active characters}
+%
+%
+% The other common instance of |\xspace| not working quite right
+% happens with active characters. Generally this package must be
+% loaded \emph{after} any language (or other) packages that make
+% punctuation characters `active'. This makes it difficult for
+% \textsf{xspace} to work flawlessly with the popular \textsf{babel}
+% package especially since the punctuation characters can switch
+% between being `active' and `other'. Starting at \textsf{xspace}
+% version~1.08 there are two different ways to handle this depending
+% on which engine your \LaTeX-format uses:
+% \begin{description}
+% \item[\TeX] The punctuation characters are added to the
+% exception list in both their normal and active states thus
+% ensuring that they are always recognized.
+% \item[\eTeX] The characters are re-read when going through
+% the exception list which means the internal comparison will test
+% against the current state of the character. This works for
+% whatever category code tricks some packages may use.
+% \end{description}
+%
+% At the time of writing all major \TeX\ distributions are using
+% \eTeX\ as engine for \LaTeX\ so usually everything should work out
+% of the box. If you find that you're running normal \TeX\ and
+% |\xspace| seems to be making the wrong choice then either use |{}|
+% as described above to fix it or add the character to the list but
+% with the desired category code. See the implementation for an example
+% of how to do that.
+%
+% \subsection{Still not satisfied?}
+%
+% Some people don't like the default list of exceptions so they can
+% remove one item at a time with the command
+% \DescribeMacro{\xspaceremoveexception}^^A
+% \cs{xspaceremoveexception}\marg{token}. Furthermore the command
+% \DescribeMacro{\@xspace@hook}\cs{@xspace@hook} can be redefined to
+% scan forward in the input stream in case you want to check more
+% tokens. It is called after \cs{xspace} has determined if it needed
+% to insert a space or if an exception was found (the default
+% definition is for \cs{@xspace@hook} to be empty). Hence you can use
+% \cs{unskip} to remove the space inserted if \cs{@let@token} matches
+% something special. Below is an example of how one can make sure an
+% endash gets a space inserted before it but a single dash not.
+% \begin{verbatim}
+% \xspaceremoveexception{-}
+% \makeatletter
+% \renewcommand*\@xspace@hook{%
+% \ifx\@let@token-%
+% \expandafter\@xspace@dash@i
+% \fi
+% }
+% \def\@xspace@dash@i-{\futurelet\@let@token\@xspace@dash@ii}
+% \def\@xspace@dash@ii{%
+% \ifx\@let@token-%
+% \else
+% \unskip
+% \fi
+% -%
+% }
+% \makeatother
+% \end{verbatim}
+%
%
% \StopEventually{}
%
% \section{The Macros}
%
+% |\xspace| peeks ahead for the next token. If the token is in our
+% exception list we break the loop and do nothing; else we try to
+% expand the token once and start over again. If this leads us to an
+% unexpandable token without finding one of the exceptions we insert a
+% space.
+%
% \begin{macrocode}
%<*package>
% \end{macrocode}
@@ -97,48 +216,282 @@
% |\xspace| just looks ahead, and then calls |\@xspace|.
% \changes{v1.03}{1994/11/15}{Make robust}
% \begin{macrocode}
-\DeclareRobustCommand\xspace{\futurelet\@let@token\@xspace}
+\DeclareRobustCommand\xspace{\@xspace@firsttrue
+ \futurelet\@let@token\@xspace}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if@xspace@first}
+% \changes{v1.11}{2006/02/12}{Added macro}
+% \begin{macro}{\@xspace@simple}
+% \changes{v1.11}{2006/02/12}{Added macro}
+% Some helpers to avoid multiple calls of |\@xspace@eTeX@setup|.
+% \begin{macrocode}
+\newif\if@xspace@first
+\def\@xspace@simple{\futurelet\@let@token\@xspace}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@xspace@exceptions@tlp}
+% \changes{v1.07}{2004/12/07}{Added macro}
+% The exception list. If the scanning mechanism finds one of
+% these, it won't insert a space after the command. The
+% \texttt{tlp} in the name means `token list pointer.'
+% \begin{macrocode}
+\def\@xspace@exceptions@tlp{%
+ ,.'/?;:!~-)\ \/\bgroup\egroup\@sptoken\space\@xobeysp
+ \footnote\footnotemark
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\xspaceaddexceptions}
+% \changes{v1.07}{2004/12/07}{Added macro}
+% The user command, which just adds tokens to the list.
+% \begin{macrocode}
+\newcommand*\xspaceaddexceptions{%
+ \g@addto@macro\@xspace@exceptions@tlp
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\xspaceremoveexception}
+% \changes{v1.10}{2005/10/04}{Use higher level functions for
+% conditional processing}
+% This command removes an exception globally.
+% \begin{macrocode}
+\newcommand*\xspaceremoveexception[1]{%
+% \end{macrocode}
+% First check that it is in the list at all.
+% \begin{macrocode}
+ \def\reserved@a##1#1##2##3\@@{%
+ \@xspace@if@q@nil@NF##2{%
+% \end{macrocode}
+% It's in the list, remove it.
+% \begin{macrocode}
+ \def\reserved@a####1#1####2\@@{%
+ \gdef\@xspace@exceptions@tlp{####1####2}}%
+ \expandafter\reserved@a\@xspace@exceptions@tlp\@@
+ }%
+ }%
+ \expandafter\reserved@a\@xspace@exceptions@tlp#1\@xspace@q@nil\@@
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@xspace@break@loop}
+% \changes{v1.08}{2005/04/28}{Added macro}
+% \changes{v1.10}{2005/10/04}{Use quark instead}
+% To stop the loop.
+% \begin{macrocode}
+\def\@xspace@break@loop#1\@nil{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@xspace@hook}
+% \changes{v1.09}{2005/07/26}{Added macro}
+% A hook for users with special needs.
+% \begin{macrocode}
+\providecommand*\@xspace@hook{}
+% \end{macrocode}
+% \end{macro}
+%
+% Now we check if we're running \eTeX. We can't use \cs{@ifundefined}
+% as that will lock catcodes and we need to change some of those.
+% As there is a small risk that someone already set \cs{eTeXversion}
+% to \cs{relax} by accident we make sure we check for that case but
+% without setting it to \cs{relax} if it wasn't already.
+% \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+ \expandafter\ifx\csname eTeXversion\endcsname\relax
+% \end{macrocode}
+% If we are running normal \TeX\ we add the most common cases of active
+% punctuation characters. First we make them active.
+% \begin{macrocode}
+ \begingroup
+ \catcode`\;=\active \catcode`\:=\active
+ \catcode`\?=\active \catcode`\!=\active
+% \end{macrocode}
+% The \texttt{alltt} environment also makes |,|, |'|, and |-| active
+% so we add them as well.
+% \begin{macrocode}
+ \catcode`\,=\active \catcode`\'=\active \catcode`\-=\active
+ \xspaceaddexceptions{;:?!,'-}
+ \endgroup
+ \let\@xspace@eTeX@setup\relax
+% \end{macrocode}
+% \begin{macro}{\@xspace@eTeX@setup}
+% \changes{v1.10}{2005/10/04}{Added macro}
+% \changes{v1.12}{2006/05/08}{Bug fix for verbatim in output routine}
+% When we're running \eTeX, we have the advantage of \cs{scantokens}
+% which will rescan tokens with current catcodes. This little
+% expansion trick makes sure that the exception list is redefined to
+% itself but with the contents of it exposed to the current catcode
+% regime. That is why we must make sure the catcode of space is 10,
+% since we have a \verb*|\ | inside the list.
+% \begin{macrocode}
+\else
+ \def\@xspace@eTeX@setup{%
+ \begingroup
+ \everyeof{}%
+ \endlinechar=-1\relax
+ \catcode`\ =10\relax
+ \makeatletter
+% \end{macrocode}
+% We may also be so unfortunate that the re-reading of the list takes
+% place when the catcodes of |\|, |{| and |}| are ``other,'' e.g., if
+% it takes place in a header and the output routine was called in the
+% middle of a \texttt{verbatim} environment.
+% \begin{macrocode}
+ \catcode`\\\z@
+ \catcode`\{\@ne
+ \catcode`\}\tw@
+ \scantokens\expandafter{\expandafter\gdef
+ \expandafter\@xspace@exceptions@tlp
+ \expandafter{\@xspace@exceptions@tlp}}%
+ \endgroup
+ }
+\fi
% \end{macrocode}
% \end{macro}
% \begin{macro}{\@xspace}
-% If the next token is one of a specified list of characters, do
-% nothing, otherwise add a space. If you often use a different
-% punctuation character, add the appropriate line (do not forget the
-% |\fi| at the end!)
% \changes{v1.03}{1994/11/15}{Add exclamation mark}
% \changes{v1.04}{1996/05/17}{Add slash}
% \changes{v1.05}{1996/12/06}{Add space for alltt etc. tools/2322}
% \changes{v1.06}{1997/10/13}{Add normal space. tools/2632}
+% \changes{v1.07}{2004/12/07}{Now runs through a list of exceptions}
+% \changes{v1.07}{2004/12/07}{Added \cs{footnote} and
+% \cs{footnotemark}}
+% \changes{v1.08}{2005/05/07}{Use recursive loop instead of \cs{@tfor}}
+% \changes{v1.09}{2005/07/26}{Only check non-letters and add hook}
+% \changes{v1.10}{2005/10/04}{Use higher level functions for
+% conditional processing}
+% \changes{v1.10}{2005/10/04}{Improve expansion method}
+% If the next token is one of a specified list of characters,
+% do nothing, otherwise add a space. With version~1.07 the
+% approach was altered dramatically to run through the
+% exception list |\@xspace@exceptions@tlp| and check each
+% token one at a time.
% \begin{macrocode}
\def\@xspace{%
- \ifx\@let@token\bgroup\else
- \ifx\@let@token\egroup\else
- \ifx\@let@token\/\else
- \ifx\@let@token\ \else
- \ifx\@let@token~\else
- \ifx\@let@token.\else
- \ifx\@let@token!\else
- \ifx\@let@token,\else
- \ifx\@let@token:\else
- \ifx\@let@token;\else
- \ifx\@let@token?\else
- \ifx\@let@token/\else
- \ifx\@let@token'\else
- \ifx\@let@token)\else
- \ifx\@let@token-\else
- \ifx\@let@token\@xobeysp\else
- \ifx\@let@token\space\else
- \ifx\@let@token\@sptoken\else
- \space
-% \end{macrocode}
-% When I first wrote this there were about half a dozen |\fi| here,
-% and I thought that was bad enough.
-% \begin{macrocode}
- \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
-%</package>
+% \end{macrocode}
+% Before we start checking the exception list it makes sense to
+% performe a quick check on the token in question. Most of the time
+% \cs{xspace} is used in regular text so \cs{@let@token} is set equal
+% to a letter. In that case there is no point in checking the list
+% because it will definitely not contain any tokens with catcode~11.
+%
+% You may wonder why there are special functions here instead of
+% simpler \cs{ifx} conditionals. The reason is that a)~this way we
+% don't have to add many, many \cs{expandafter}s to get the nesting
+% right and b)~we don't get into trouble when \cs{@let@token} has been
+% let equal to \cs{if} etc.
+% \begin{macrocode}
+ \@xspace@lettoken@if@letter@TF \space{%
+% \end{macrocode}
+% Otherwise we start testing after setting up a few things. If running
+% \eTeX{} we rescan the catcodes but only the first time around.
+% \begin{macrocode}
+ \if@xspace@first
+ \@xspace@firstfalse
+ \let\@xspace@maybespace\space
+ \@xspace@eTeX@setup
+ \fi
+ \expandafter\@xspace@check@token
+ \@xspace@exceptions@tlp\@xspace@q@nil\@nil
+% \end{macrocode}
+% If an exception was found \cs{@xspace@maybespace} is let to
+% \cs{relax} and we do nothing.
+% \begin{macrocode}
+ \@xspace@token@if@equal@NNT \space \@xspace@maybespace
+% \end{macrocode}
+% Otherwise we check to see if we found something expandable and try
+% again with that token one level expanded. If no expandable token is
+% found we insert a space and then execute the hook.
+% \begin{macrocode}
+ {%
+ \@xspace@lettoken@if@expandable@TF
+ {\expandafter\@xspace@simple}%
+ {\@xspace@maybespace\@xspace@hook}%
+ }%
+ }%
+}
% \end{macrocode}
% \end{macro}
%
-% \Finale
+% \begin{macro}{\@xspace@check@token}
+% \changes{v1.07}{2004/12/07}{Added macro}
+% \changes{v1.08}{2005/05/07}{Made function recursive}
+% \changes{v1.10}{2005/10/04}{Use higher level functions for
+% conditional processing}
+% \changes{v1.11}{2006/02/12}{Modified so the \cs{@let@token} can be
+% \cs{outer}}
+% This macro just checks the current item in the exception list
+% against the \cs{@let@token}. If they are equal we make sure that no
+% space is inserted and break the loop.
+% \begin{macrocode}
+\def\@xspace@check@token #1{%
+ \ifx\@xspace@q@nil#1%
+ \expandafter\@xspace@break@loop
+ \fi
+ \expandafter\ifx\csname @let@token\endcsname#1%
+ \let\@xspace@maybespace\relax
+ \expandafter\@xspace@break@loop
+ \fi
+ \@xspace@check@token
+}
+% \end{macrocode}
+% \end{macro}
+%
+% That's all, folks! That is, if we were running \LaTeX3. In that case
+% we would have had nice functions for all the conditionals but here
+% we must define them ourselves. We also optimize them here as
+% \cs{@let@token} will always be the argument in some cases.
+%
+% \begin{macro}{\@xspace@if@lettoken@letter@TF}
+% \begin{macro}{\@xspace@if@lettoken@expandable@TF}
+% \begin{macro}{\@xspace@cs@if@equal@NNF}
+% First a few comparisons.
+% \begin{macrocode}
+\def\@xspace@lettoken@if@letter@TF{%
+ \ifcat\noexpand\@let@token @% letter
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi}
+\def\@xspace@lettoken@if@expandable@TF{%
+ \expandafter\ifx\noexpand\@let@token\@let@token%
+ \expandafter\@secondoftwo
+ \else
+ \expandafter\@firstoftwo
+ \fi
+}
+\def\@xspace@token@if@equal@NNT#1#2{%
+ \ifx#1#2%
+ \expandafter\@firstofone
+ \else
+ \expandafter\@gobble
+ \fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\@xspace@q@nil}
+% \begin{macro}{\@xspace@if@q@nil@NF}
+% Some macros dealing with quarks.
+% \begin{macrocode}
+\def\@xspace@q@nil{\@xspace@q@nil}
+\def\@xspace@if@q@nil@NF#1{%
+ \ifx\@xspace@q@nil#1%
+ \expandafter\@gobble
+ \else
+ \expandafter\@firstofone
+ \fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
%
-
+% \Finale