% \iffalse meta-comment % % File: xpunctuate.dtx % % Copyright (C) 2023 by Philip G. Ratcliffe % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this % license or (at your option) any later version. % The latest version of this license is in the file % % http://www.latex-project.org/lppl.txt % % This file is part of the "xpunctuate package" (the Work in LPPL) % and all files in that package must be distributed together. % % The released version of this package is available from CTAN. % % This package has the LPPL maintenance status "maintained". % % The current maintainer of this package is Philip G. Ratcliffe. % % This work consists of the files xpunctuate.dtx and xpunctuate.ins % and the derived file xpunctuate.sty. % % \fi % % \iffalse % %\NeedsTeXFormat{LaTeX2e}[2020/10/01] %\ProvidesPackage{xpunctuate} % [2023/08/13 v2.0 punctuation after command names (PGR)] % %<*driver> \documentclass[british]{ltxdoc} \usepackage{xpunctuate} % \NewDocElement[macrolike=false]{Generic}{generic} \renewcommand\thefootnote{\color{red}{\emph{\alph{footnote}}}} \newenvironment{codelist} {\begin{list}{}{\setlength\leftmargin{3em}}\item[]}{\end{list}} \newcommand\eg{\xperiodafter{\emph{e}.\emph{g}}} \newcommand\ie{\xperiodafter{\emph{i}.\emph{e}}} % \CodelineIndex \EnableCrossrefs \RecordChanges \DoNotIndex{\def,\let,\futurelet} \DoNotIndex{\if,\else,\fi,\ifx,\fi,\iftrue,\fi,\iffalse,\fi} \DoNotIndex{\the,\csname,\endcsname,\expandafter,\noexpand,\protect} % \begin{document} \DocInput{xpunctuate.dtx} \end{document} % % \fi % % \CheckSum{154} % % \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} % \changes{v2.0}{2023/08/13}{general upgrade} % % \GetFileInfo{xpunctuate.sty} % % \DoNotIndex{\CodelineIndex,\EnableCrossrefs,\RecordChanges} % % \title{The \texttt{xpunctuate} package for \LaTeX2e % \\[1ex] \small (\fileversion, last revision \filedate)} % % \author{Philip G. Ratcliffe % \\[1ex] \small \textsf{philip.ratcliffe@uninsubria.it} % \\[2ex] \small Dipartimento di Scienza e Alta Tecnologia % \\ \small Universit\`a degli Studi dell'Insubria---Como % \\ \small and % \\ \small Istituto Nazionale di Fisica Nucleare % \\ \small Sezione di Milano Bicocca} % % \date{} % % \maketitle % % \begin{abstract} % The |xpunctuate| package provides package writers and ordinary users with % automatic post-macro punctuation insertion, \ie beyond (but similar to) that % of the |xspace| package, which is required here. Three new macros are % defined: |\xperiod|, |\xcomma| and |\xperiodcomma|, designed to insert the % required punctuation marks \emph{if and only if} necessary, following a % similar procedure to the |xspace| package. A further four macros % (|\xspaceafter|, |\xperiodafter|, |\xcommaafter| and |\xperiodcommaafter|) % are constructed to avoid the small superfluous space after possible font % changes (such as |\emph|) that involve the correction |\/|, which would % otherwise be hidden. % \end{abstract} % % \section{Introduction} % % The present package is mainly intended for package writers, but may also % serve the ordinary user; it provides additional post-macro punctuation % insertion, similar to that of the |xspace| package. Three new macros are % defined: |\xperiod|, |\xcomma| and |\xperiodcomma|, which, in an analogous % fashion to the standard |\xspace| macro, insert any relevant punctuation % where necessary. Four additional macros, of the form |\x|\dots|after|, avoid % the small superfluous space due to the following period or comma being % isolated from a preceding~|\/|. % % \section{Package call} % % \DescribeGeneric{package call} % The package is loaded via a standard call: % \begin{codelist} % |\usepackage{xpunctuate}| % \end{codelist} % % \subsection{User options} % % \DescribeGeneric{user options} % There are at present \emph{no} user options. % % \subsection{User macros} % % Three user macros are defined, each having a pre-punctuation space-correcting % variant, plus a similar extension of the |\xspace| macro. % % \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 \emph{accidental} % sentence-terminating full stop. If \emph{no} explicit period follows, one is % inserted, the occurrence is assumed to be mid-sentence and therefore normal % inter-word spacing is applied. However, if it \emph{is} followed by a period, % then this is considered to be a sentence terminator, it is left as is with no % further insertions and the appropriate trailing space will then naturally % ensue. % % After defining |\newcommand{\gb}{G.B\xperiod}|, the command |\gb| will % determine when to insert a period after itself and when not, with also the % correct mid-sentence or end-of-sentence spacing as required. Thus, the input % \newcommand{\gb}{G.B\@\xperiod} % \begin{codelist} % |\gb is a very nice place to live.\\|\\ % |I live in \gb. It is 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{codelist} % results in the output % \begin{codelist} % \gb is a very nice place to live.\\ % I live in \gb. It is 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{codelist} % % \DescribeMacro{\xcomma} % This macro similarly inserts a comma if not found as the next token. A % typical application might be following an abbreviation such as `eg' (\ie when % used \emph{without} periods), which according to different standard style % manuals should or should not be followed by a comma. It has no special % spacing behaviour. % % \DescribeMacro{\xperiodcomma} % This macro inserts a period \emph{and} a comma if not found as the next input % tokens. Typical use will be, as above, for abbreviations such as `e.g.'\ (\ie % \emph{with} periods) when they should be followed by a comma, but may also % occur fortuitously immediately preceding an explicit sentence-closing period % or indeed an explicit comma, the correct trailing space of which would then % ensue. Note that this action \emph{cannot} be reproduced via successive use % of the single macros, \ie the combination |\xperiod\xcomma|. % % \DescribeMacro{\xspaceafter} % \DescribeMacro{\xperiodafter} % \DescribeMacro{\xcommaafter} % \DescribeMacro{\xperiodcommaafter} % The variants |\x|\dots|after| are similar to the above except that they take % the object word or phrase to be spaced or punctuated as an argument; the % slight incorrect spacing adjustment between the word and following period or % comma is thus avoided when, for example, the word is |\emph|'asised. Other % punctuation marks do \emph{not} suffer from this problem. % % Note that although the action of |\xperiodcommaafter| may also be obtained % via suitable nesting of |\xperiodafter| and |\xcommaafter|, this combination % has not been thoroughly tested; the compound macro is thus included for both % safety and backwards compatibility. % % In the case of the macros that guarantee a trailing period (\emph{with} or % \emph{without} a comma), if the final letter of the word or phrase is a % capital (\eg `Ph.D.'), to guarantee the correct end-of-sentence trailing % spacing, it should be immediately followed by an explicit |\@|. That is, the % definition should be of the form % \begin{codelist} % |\newcommand\PhD{Ph.D\@\xperiod}|\\[-0.67ex] % \hspace*{-\leftmargin}\, or\\[-0.67ex] % |\newcommand\PhD{\xperiodafter{Ph.D\@}}| % \end{codelist} % N.B. If the ending capital letter or letters are \eg |\emph|'asised, the |\@| % should be placed \emph{inside} the |\emph|'asis:\footnote{It is for this % reason that it \emph{cannot} be incorporated directly into the |xpunctuate| % macros.} % \begin{codelist} % |\newcommand\PhD{\emph{Ph}.\emph{D\@}\xperiod}|\\[-0.67ex] % \hspace*{-\leftmargin}\, or\\[-0.67ex] % |\newcommand\PhD{\xperiodafter{\emph{Ph}.\emph{D\@}}}| % \end{codelist} % % The following are various other examples of possible usage: % \begin{codelist} % |\newcommand\etc{etc\xperiod}|\\ % |\newcommand\eg{i.e\xperiodcomma}|\\ % |\newcommand\etal{\xperiodafter{\emph{et al}}}|\\ % |\newcommand\ie{\xperiodcommaafter{\emph{e}.\emph{g}}}| % \end{codelist} % Note how the closing period in the above is \emph{not} explicitly present, % being inserted by the relevant macro as and when necessary, with too the % correct spacing. % % \subsection{Caveats} % % \begin{generic}{caveats} % No specific care should be necessary when employing the macros defined here; % in particular, they are all \emph{robust}. However, trailing punctuation % hidden inside or by other macro definitions may not always be correctly % interpreted. Moreover, the known limitations of |\xspace| remain. % \end{generic} % % \subsection{External package requirements} % % \begin{generic}{xspace} % The |xspace| package is required and is loaded automatically. Note that, in % the \emph{absence} of |\xspace|, the necessary presence of explicit trailing % backslashes for correct spacing following command strings, would frustrate % the functionality of all the macros defined here.\footnote{Users who shun the % use of |xspace| will probably not appreciate the present package either.} % \end{generic} % % \subsection{Package conflicts} % % \begin{generic}{conflicts} % There are no known conflicts with any standard \LaTeX2e\ packages. % \end{generic} % % \StopEventually{\PrintChanges\PrintIndex} % % \section{Implementation} % % \subsection{External packages} % \begin{generic}{packages} % First, load the |xspace| package, for automatic trailing-space insertion: % \begin{macrocode} \RequirePackage{xspace} % \end{macrocode} % \changes{v2.0}{2023/08/13}{useful \texttt{xspace} exceptions added} % \begin{generic}{exceptions} % and add some useful extra |xspace| exceptions relevant to the present % package. % \begin{macrocode} \xspaceaddexceptions{\xcomma\xperiod\xperiodcomma} % \end{macrocode} % \end{generic} % \end{generic} % % \subsection{User commands} % % \changes{v2.0}{2023/08/13}{revamped all macros} % \begin{macro}{\xspaceafter} % \changes{v2.0}{2023/08/13}{macro added} % This macro takes one argument, which it prints as is. It then inserts % |\xspace| immediately after, but nothing if followed by a comma or period. % \begin{macrocode} \NewDocumentCommand\xspaceafter{}{\xpnct@aux\xspace@aux} % \end{macrocode} % The correct spacing between the argument and any following comma or period is % thus maintained in the case of, say, an |\emph|'asised argument. The % necessity arises as the presence of |\xspace| `hides' any following % punctuation from a possible |\/| spacing-correction command. % \end{macro} % % \begin{macro}{\xperiod} % The following macro inserts a period if this is not found to be the next % character. % \begin{macrocode} \NewDocumentCommand\xperiod{}{\xpnct@aux\xperiod@aux{}} % \end{macrocode} % It may thus be used to construct common abbreviations (such as `etc.'). % \end{macro} % % \begin{macro}{\xperiodafter} % This macro takes one argument and inserts a period after it if this is not % found to be the next character. % \begin{macrocode} \NewDocumentCommand\xperiodafter{}{\xpnct@aux\xperiod@aux} % \end{macrocode} % The correct spacing between the argument and period is again thus maintained % in the case of, say, |\emph|, as in often \emph{italicised} abbreviations % (such as `\emph{etc}.'). % \end{macro} % % \begin{macro}{\xcomma} % The following macro inserts a comma if this is not found to be the next % character. % \begin{macrocode} \NewDocumentCommand\xcomma{}{\xpnct@aux\xcomma@aux{}} % \end{macrocode} % It may thus be used to construct those common abbreviations (without periods) % that might normally be followed by a comma, such as `eg' or `ie' according to % standard American-English usage. % \end{macro} % % \begin{macro}{\xcommaafter} % The following macro takes one argument and inserts a comma after it if this % is not found to be the next character. % \begin{macrocode} \NewDocumentCommand\xcommaafter{}{\xpnct@aux\xcomma@aux} % \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} \NewDocumentCommand\xperiodcomma{}{\xpnct@aux\xperiodcomma@aux{}} % \end{macrocode} % It may thus be used to construct those common abbreviations that might % normally be followed by a comma (such as `e.g.,'), the comma being inserted % \emph{if and only if} there is no following explicit sentence-ending period. % Here, there is of course no problem of spacing either preceding or following % the period. If only a period is found, it is treated as an end-of-sentence % and the correct spacing will ensue accordingly. A following period--comma % combination, if found, will be left as is. % \end{macro} % % \begin{macro}{\xperiodcommaafter} % This macro takes one argument and inserts a period and/or a comma after it if % these are not found to be the next characters. % \begin{macrocode} \NewDocumentCommand\xperiodcommaafter{}{\xpnct@aux\xperiodcomma@aux} % \end{macrocode} % It may thus be used to construct those common \emph{italicised} abbreviations % that should normally be followed by a comma (such as `\eg,'). % \end{macro} % % \subsection{Internal macros} % % \begin{macro}{\xpnct@tok} % A token register is defined to store a possible object word or phrase: % \begin{macrocode} \newtoks\xpnct@tok % \end{macrocode} % \end{macro} % % \begin{macro}{\xpnct@aux} % The general setup and call to the final output macros for the above user % commands is handled by the following auxiliary macro: % \begin{macrocode} \def\xpnct@aux#1#2{% \xpnct@tok{#2}% \futurelet\xpnct@nxt#1} % \end{macrocode} % \end{macro} % Note that all the user commands defined earlier terminate by inserting an % |\xspace| \emph{if} and \emph{only if} the required punctuation has actually % been inserted by the macro. % % \begin{macro}{\xspace@aux} % Testing and output for |\xspaceafter| are performed by the following macro: % \begin{macrocode} \def\xspace@aux{% \ifx\xpnct@nxt,\else \ifx\xpnct@nxt.\else \xpnct@tok\expandafter{\the\xpnct@tok\xspace}% \fi\fi \the\xpnct@tok} % \end{macrocode} % Only periods and commas need be excluded, as the spacing is correct for all % other punctuation marks. % \end{macro} % % \begin{macro}{\xperiod@aux} % Testing and output for |\xperiod| and |\xperiodafter| are performed by this % macro: % \begin{macrocode} \def\xperiod@aux{% \ifx\xpnct@nxt.\else \xpnct@tok\expandafter{\the\xpnct@tok.\@\xspace}% \fi \the\xpnct@tok} % \end{macrocode} % The approach adopted is to treat an explicit following period as an % end-of-sentence full stop; the trailing space is then handled accordingly. % However, when an explicit period is \emph{not} found), the placement of |\@| % immediately after the inserted period thus avoids standard end-of-sentence % spacing, assuming such an occurrence to be mid-sentence (as for % abbreviations). If, in contrast, an explicit period \emph{is} found, it is % retained as is and will thus generate the correct end-of-sentence spacing. % \end{macro} % % \begin{macro}{\xcomma@aux} % Testing and output for |\xcomma| and |\xcommaafter| are performed by the % following macro (shamelessly copied from an \emph{old} |xspace.sty| and % suitably hacked): % \begin{macrocode} \def\xcomma@aux{% \ifx\xpnct@nxt.\else \ifx\xpnct@nxt,\else \ifx\xpnct@nxt:\else \ifx\xpnct@nxt;\else \ifx\xpnct@nxt!\else \ifx\xpnct@nxt?\else \ifx\xpnct@nxt/\else \ifx\xpnct@nxt-\else \ifx\xpnct@nxt'\else \ifx\xpnct@nxt)\else \ifx\xpnct@nxt]\else \ifx\xpnct@nxt\}\else \ifx\xpnct@nxt\egroup\else \ifx\xpnct@nxt\/\else \xpnct@tok\expandafter{\the\xpnct@tok,\xspace}% \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \the\xpnct@tok} % \end{macrocode} % Note that certain of the default exceptions set by the |xspace| package are % missing here, for obvious reasons. % \end{macro} % % \begin{macro}{\xperiodcomma@aux} % Testing and output for |\xperiodcomma| and |\xperiodcommaafter| are performed % by the following: % \begin{macrocode} \def\xperiodcomma@aux{% \ifx\xpnct@nxt.\else \xpnct@tok\expandafter{\the\xpnct@tok.\@\xcomma}% \fi \the\xpnct@tok} % \end{macrocode} % The presence or absence of an explicit following period is again taken to % imply an end-of- or mid-sentence respectively, unless followed by an explicit % comma, other closing punctuation or brackets say, when it will be assumed % mid-sentence. Note, moreover, that |\@| is \emph{still} necessary here as the % period may not necessarily be immediately followed by a comma, \eg if it is % followed by a closing bracket or quotation marks. % \end{macro} % % \begin{macro}{\endinput} % Finally, explicitly terminate the package input here. % \begin{macrocode} \endinput % \end{macrocode} % \end{macro} % % \Finale % \endinput %% %% End of file `xpunctuate.dtx'.