% \iffalse meta-comment
%
% Copyright (C) 2012 by Philip G. Ratcliffe <philip.ratcliffe@uninsubria.it>
%
% This file may be distributed and/or modified under the conditions of
% the LaTeX Project Public License, either version 1.2 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.2 or later is part of all distributions of LaTeX
% version 1999/12/01 or later.
%
% \fi
%
% \iffalse
%
%<package>\NeedsTeXFormat{LaTeX2e}[1995/12/01]
%<package>\ProvidesPackage{xpunctuate}
%<package>   [2012/05/21 v1.0 trailing punctuation package (PGR)]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{xpunctuate}
\CodelineIndex
\EnableCrossrefs
\RecordChanges
%
\begin{document}
  \DocInput{xpunctuate.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{144}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
% \changes{v1.0}{2012/05/21}{first public release}
%
% \GetFileInfo{xpunctuate.sty}
%
% \DoNotIndex{\CodelineIndex,\EnableCrossrefs,\RecordChanges}
%
% \title{
%   The \textsf{xpunctuate}\relax
%   \thanks{
%     This file has version number \fileversion, and revision date \filedate.}
%   \space
%   package for \LaTeX2e
% }
% \author{
%   Philip G. Ratcliffe\thanks{E-mail: \textsf{philip.ratcliffe@uninsubria.it}}
% \\
%   Dipartimento di Scienze e Alta Tecnologia
% \\
%   Universit\`{a} degli Studi dell'Insubria---Como
% }
%
% \date{}
%
% \maketitle
%
% \begin{abstract}
% This package affords the user or package writer post-macro punctuation
% insertion, \emph{i.e.}, beyond (but similar to) that of the |xspace| package.
% Three new commands are defined: |\xperiod|, |\xcomma| and |\xperiodcomma|,
% which, following a similar procedure to the standard |\xspace| macro, are
% designed to insert the relevant punctuation \emph{if and only if} necessary.
% \end{abstract}
%
% \section{Introduction}
%
% The present package is mainly intended for package writers and provides
% additional post-macro punctuation insertion, similar to that of the |xspace|
% package. Three new commands are defined: |\xperiod|, |\xcomma| and
% |\xperiodcomma|, which, in an analogous fashion to the standard |\xspace|
% macro, insert the relevant punctuation where necessary.
%
% \section{Usage}
%
% The package is loaded via a standard package call: |\usepackage{xpunctuate}|.
% There are at present no user options.
%
% \subsection{User commands}
%
% The package defines three user commands, each having two variants.
%
% \DescribeMacro{\xperiod}
% The purpose of this macro is to insert a period if not found as the
% successive \LaTeX\ input token. Typical use will be in defining
% abbreviations, where there may or may not be a following ``accidental''
% sentence-terminating period. The definition of |\xperiod| is such that if it
% is followed by a period, then this is considered as a sentence terminator and
% the appropriate trailing space is inserted. However, when no explicit period
% follows, the occurrence is assumed to be mid-sentence and therefore normal
% inter-word spacing is used.
%
% \DescribeMacro{\xcomma}
% The purpose of this macro is to insert a comma if not found as the next
% token. Typical use will be following an object such as ``\emph{e.g.}'', which
% according to certain standard style manuals should be followed by a comma.
% This command has no special spacing behaviour.
%
% \DescribeMacro{\xperiodcomma}
% The purpose of this macro is to insert a period \emph{and} comma if not found
% as the next input tokens. Typical use will be, as above, following an object
% such as ``\emph{e.g.}'', which, according to certain style manuals, should be
% followed by a comma, but may also occur fortuitously immediately preceding an
% explicit sentence-closing period, the correct trailing space of which would
% then be inserted.
%
% \DescribeMacro{\xperiodafter}
% \DescribeMacro{\xcommaafter}
% \DescribeMacro{\xperiodcommaafter}
% These variants are similar to the above macros except that they take the word
% or words to be punctuated as an argument; this avoids incorrect spacing
% adjustment when the word is, for example, |\emph|'asised.
%
% Note that the action of |\xperiodcommaafter| may also obtained by suitably
% nesting |\xperiodafter| and |\xcommaafter| though this has not been
% thoroughly tested; it is thus included for safety and backward compatibility.
%
% The following are examples of possible usage:\\[2ex]
% |\DeclareRobustCommand\etal{\xperiodafter{\emph{et al}}}| \\
% |\DeclareRobustCommand\eg{e.g\xperiodcomma}| \\
% |\DeclareRobustCommand\eg{\xcommaafter{\xperiodafter{\emph{e.g}}}}|
%
% \subsection{Caveats}
%
% No particular care should be necessary in using the commands defined by this
% package. However, trailing punctuation hidden inside macro definitions may
% not be correctly interpreted.
%
% \subsection{External package requirements}
%
% The |xspace| package is required and is loaded automatically.
%
% \subsection{Package conflicts}
%
% There are no known conflicts with any standard \LaTeX2e\ packages.
%
% \StopEventually{\PrintChanges\PrintIndex}
%
% \section{Implementation}
%
% \subsection{External package requirements}
%
% Load the |xspace| package for automatic trailing space:
%    \begin{macrocode}
\RequirePackage{xspace}
%    \end{macrocode}
%
% \subsection{User commands}
%
% \begin{macro}{\xperiod}
% The following macro inserts a period if this is not found to be the next
% character. It may thus be used to construct common abbreviations (such as
% ``\emph{etc}.'').
%    \begin{macrocode}
\DeclareRobustCommand\xperiod{\xprd@Set{}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xperiodafter}
% This macro takes one argument and places a period after it if this is not
% found to be the next character. The correct spacing between the word and
% period is thus maintained in the case of, say, |\emph|.
%    \begin{macrocode}
\DeclareRobustCommand\xperiodafter[1]{\xprd@Set{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xcomma}
% The following macro inserts a comma if this is not found to be the next
% character. Thus, it may be used to construct common abbreviations and
% expressions that should normally be followed by a comma (such as
% ``\emph{e.g.}'').
%    \begin{macrocode}
\DeclareRobustCommand\xcomma{\xcmm@Set{}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xcommaafter}
% The following macro takes one argument and places a comma after it if this is
% not found to be the next character. 
%    \begin{macrocode}
\DeclareRobustCommand\xcommaafter[1]{\xcmm@Set{#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xperiodcomma}
% The following macro first adds a period and then a comma if these are not
% found to be the next characters.
%    \begin{macrocode}
\DeclareRobustCommand\xperiodcomma{\xpcm@Set{}}
%    \end{macrocode}
% It may thus be used to construct common abbreviations that should normally be
% followed by a comma (such as ``\emph{e.g.}''). The comma is inserted if only
% and if the following character does not imply the end of a period. Here, of
% course, there is no problem of spacing either preceding or following the
% period. If only a period is found this is treated as an end-of-sentence and
% the spacing is handled accordingly.
% \end{macro}
%
% \begin{macro}{\xperiodcommaafter}
% This macro takes one argument and places a period and a comma after it if
% these are not found to be the next characters:
%    \begin{macrocode}
\DeclareRobustCommand\xperiodcommaafter[1]{\xpcm@Set{#1}}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Internal macros}
%
% \begin{macro}{\xprd@Set}
% The setup for |\xperiod| and |\xperiodafter| is performed by the following
% auxiliary macro:
%    \begin{macrocode}
\newcommand\xprd@Set[1]{\def\xprd@Obj{#1}\futurelet\xprd@Nxt\xprd@Fin}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xprd@Fin}
% The testing and final output for |\xperiod| and |\xperiodafter| is made by
% the following auxiliary macro:
%    \begin{macrocode}
\newcommand\xprd@Fin{%
  \ifx\xprd@Nxt.\relax
    \let\xprd@Out\xprd@Obj
  \else
    \def\xprd@Out{\xprd@Obj.\@\xspace}%
  \fi
  \xprd@Out
}
%    \end{macrocode}
% Note the insertion of ``|\@|'' following the period when this last is not
% found; this avoids the standard default end-of-sentence spacing, assuming the
% occurrence in such a case to be mid-sentence.
% \end{macro}
%
% \begin{macro}{\xcmm@Set}
% The setup for |\xcomma| and |\xcommaafter| is performed by the following
% auxiliary macro:
%    \begin{macrocode}
\newcommand\xcmm@Set[1]{\def\xcmm@Obj{#1}\futurelet\xcmm@Nxt\xcmm@Fin}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xcmm@Fin}
% The testing and final output for |\xcomma| and |\xcommaafter| is made by the
% following auxiliary macro (shamelessly copied from an \emph{old} |xspace| and
% hacked):
%    \begin{macrocode}
\newcommand\xcmm@Fin{%
  \let\xcmm@Out\xcmm@Obj
  \ifx\xcmm@Nxt\bgroup\else
  \ifx\xcmm@Nxt\egroup\else
  \ifx\xcmm@Nxt\/\else
  \ifx\xcmm@Nxt~\else
  \ifx\xcmm@Nxt.\else
  \ifx\xcmm@Nxt!\else
  \ifx\xcmm@Nxt,\else
  \ifx\xcmm@Nxt:\else
  \ifx\xcmm@Nxt;\else
  \ifx\xcmm@Nxt?\else
  \ifx\xcmm@Nxt/\else
  \ifx\xcmm@Nxt'\else
  \ifx\xcmm@Nxt)\else
  \ifx\xcmm@Nxt]\else
  \ifx\xcmm@Nxt-\else
    \def\xcmm@Out{\xcmm@Obj,\xspace}%
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
  \xcmm@Out
}
%    \end{macrocode}
% Note that there are fewer options than in the |xspace| package, for obvious
% reasons.
% \end{macro}
%
% \begin{macro}{\xpcm@Set}
% The setup for |\xperiodcomma| and |\xperiodcommaafter| is performed by the
% following auxiliary macro:
%    \begin{macrocode}
\newcommand\xpcm@Set[1]{\def\xpcm@Obj{#1}\futurelet\xpcm@Nxt\xpcm@Fin}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xpcm@Fin}
% The testing and final output for |\xperiodcomma| and |\xperiodcommaafter| is
% made by the following auxiliary macro:
%    \begin{macrocode}
\newcommand\xpcm@Fin{%
  \ifx\xpcm@Nxt.\relax
    \let\xpcm@Out\xpcm@Obj
  \else
    \def\xpcm@Out{\xpcm@Obj.\xcomma}%
  \fi
  \xpcm@Out
}
%    \end{macrocode}
% The choice made is that if only a following period is found, then it is
% treated as an end-of-sentence and the trailing space is handled accordingly.
% \end{macro}
%
% \Finale
%
\endinput
%%
%% End of file `xpunctuate.dtx'.