1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
|
%%% ====================================================================
%%% @LaTeX-doc-source-file{
%%% filename = "pcatcode.dtx",
%%% version = "1.04",
%%% date = "2002/04/16",
%%% time = "09:20:52 EDT",
%%% author = "Michael J Downes",
%%% copyright = "Copyright 2001 American Mathematical Society",
%%% address = "American Mathematical Society,
%%% Publications Technical Group,
%%% PO Box 6248,
%%% Providence, RI 02940,
%%% USA",
%%% email = "tech-support@ams.org",
%%% URL = "http://www.ams.org/",
%%% abstract = "The pcatcode package changes LaTeX package loading
%%% internals so that all subsequently loaded packages
%%% can rely on having normal catcodes in effect.",
%%% license = "Artistic",
%%% checksum = "25118 359 1469 13319",
%%% docstring = "The checksum field, produced by Robert Solovay's
%%% checksum utility, gives CRC-16 checksum, lines,
%%% words, and characters.",
%%% }
%%% ====================================================================
% \iffalse
%<*driver>
\documentclass{amsdtx}
%\usepackage{pcatcode}\relax
\begin{document}
\title{The \pkg{pcatcode} package}
\author{Michael~J. Downes\\American Mathematical Society}
\date{Version \fileversion, \filedate}
\hDocInput{pcatcode.dtx}
\end{document}
%</driver>
% \fi
%
% \maketitle
% \section{Introduction}
%
% The \pkg{pcatcode} package provides mechanisms for robustly
% changing the catcode environment for the duration of a package and
% restoring it afterwards to whatever it was before the package was
% loaded.
%
% Motivation: The \pkg{amsmath} package (for example), makes a number
% of assignments using characters such as double-quote and
% left-quote, because these are hard-wired into the \tex/ syntax for
% numbers and other things. If a package that makes double-quote an
% active character is loaded before \pkg{amsmath}, all the
% statements that use double-quote turn into error messages.
%
% But now! Groan and grumble no more, ye package writers, for putting
% a magical invocation of the pcatcode package at the beginning of
% your package file, as shown here, will ensure that your
% package contents will be processed with completely normal catcodes.
%\begin{verbatim}
%\NeedsTeXFormat{LaTeX2e}[1995/12/01]
%\@ifundefined{PushCatcodes}{%
% \RequirePackage{pcatcode}\relax\PushCatcodes\NormalCatcodes
%}{}
%\ProvidesPackage{foo}[2002/04/16 v1.04]
%\end{verbatim}
%
% It must be followed by a matching \cs{PopCatcodes} command,
% typically used in conjunction with \cs{endinput}.
%
% WARNING: This functionality would work best if it were built into
% the \LaTeX{}2e kernel, but it cannot be usefully added to the
% kernel now without adversely affecting document compatibility
% across different systems. This package therefore modifies one or
% two of the low-level package-loading functions defined by the
% kernel. This means that there may be trouble if any other package,
% or some future version of \LaTeX{}, changes the definitions of
% those functions.
%
% NOTE: Packages that do not call \cs{PushCatcodes}
% \cs{NormalCatcodes} will remain transparent to the external catcode
% environment in the usual way (i.e., for all characters except the
% \verb'@' character).
%
% \StopEventually{}
%
% \section{Implementation}
% \subsection{Preliminary Remarks}
%
% At the document level, we assume that the following characters
% always have their standard catcode:
% \begin{center}
% \begin{tabular}{lp{.75\columnwidth}}
% \verb'\{}' & for commands and arguments\\
% \verb'%' & for comments\\
% \verb'#' & for use with \cn{newcommand}\\
% \verb'*' & cannot be changed without breaking star-form commands\\
% \verb'[]' & cannot be changed without breaking optional arguments\\
% \verb'~' & already active, no reason to change catcode
% \end{tabular}
% \end{center}
%
% One might think that we could assume hyphen, period (and comma, for
% European decimal notation) are always catcode 12. Experience has
% shown, however, that for just about every character there is some
% plausible application that would be facilitated by making that
% character active and giving it a complex definition. Surely hyphen
% and period must stay catcode 12 in order to work in statements like
% the following?
%\begin{verbatim}
%\addtocounter{section}{-1}
%\addtolength{\columnwidth}{-1.5cm}
%\end{verbatim}
% Yet hyphen and period are important constituents of ordinary text
% and therefore special applications arise. For example,
% what if you would like
% mdashes to be surrounded by extra space but your authors prefer to
% continue writing \verb'---' in the accustomed manner?
%
% Theoretically speaking, the \pkg{pcatcode} package itself has to
% guard against the kind of catcode problems that it is intended to
% circumvent. If you would like a nice little \tex/nician's
% exercise, try your hand, before looking at the code below, at the
% task that I set for myself: Find the minimal set of catcode
% assumptions that one has to make before attempting to establish
% normalcy, where normalcy is defined as the state at the end of
% \fn{latex.ltx}, just before the last \cs{makeatother}. This is the
% state that may normally be expected at the beginning of a
% documentclass file, if the \LaTeX{} format file does not have any
% extensions (e.g., babel) compiled in.
%
% Ready to look, now?
%
% In order for the following code to work it is only necessary that
% backslash, letters, and digits have their normal catcodes: 0, 11,
% 12 respectively. One could argue that if \fn{pcatcode.sty} is
% invoked through a standard \cs{RequirePackage} call, it can be
% assumed that curly braces also have their normal catcodes. But I
% suppose it is not utterly inconceivable that in some special
% circumstances one might want to load the package with the
% \cs{@@input} primitive, sans braces. And in any case the extra
% overhead to handle braces as well is trivial so for esthetic
% reasons I'm gonna put it in.
%
% If you look really hard you'll find one or two other assumptions,
% such as ``endlinechar is not a letter''. Wait, come to think of it,
% I can fix that \ldots
%
% The purpose of the group is chiefly to localize the temporarily
% changed definitions of \cs{e}, \cs{n}, etc.
% \begin{macrocode}
\begingroup\let\e\endlinechar\iffalse\
\fi\chardef\E\e\e13\chardef\n\catcode\e\catcode\e5\relax\relax
\chardef\s\catcode32\chardef\t10\catcode32\t
\chardef\c\catcode37 \catcode37 14 % percent
\chardef\=\catcode61 \catcode61 12 % equal sign
\chardef\l=\catcode123 \catcode123=1 % left brace
\chardef\r=\catcode125 \catcode125=2 % right brace
\chardef\[=\catcode91 \catcode91=12 % left bracket
\chardef\]=\catcode93 \catcode93=12 % right bracket
\chardef\^=\catcode94 \catcode94=7 % hat
\chardef\.=\catcode46 \catcode46=12 % period
\chardef\/=\catcode47 \catcode47=12 % slash
\edef\c{%
\endgroup
\def\noexpand\pcat@restore{%
\catcode\number\e=\number\n \catcode32=\number\s
\catcode123=\number\l \catcode125=\number\r
\catcode37=\number\c \catcode61=\number\=%
\catcode91=\number\[\catcode93=\number\]\catcode94=\number\^%
\catcode46=\number\.\catcode47=\number\/%
\endlinechar=\number\E \relax
}%
}
\c
\endlinechar13\catcode13\string=5\relax\relax
\catcode32\string=10 \catcode37 14\relax\relax
\catcode61 12\catcode123=1\catcode125=2\catcode91=12\catcode93=12\relax
\catcode46=12\catcode47=12\catcode94=7\relax
% \end{macrocode}
%
% This code was postponed until now to avoid all but the most
% essential assumptions.
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{pcatcode}[2002/04/16 v1.04]
% \end{macrocode}
%
% \begin{macrocode}
\def\NormalCatcodes{%
\endlinechar=13%
\catcode33=12\catcode34=12\catcode35=6\catcode36=3\catcode37=14%
\catcode38=4\catcode39=12\catcode40=12\catcode41=12\catcode42=12%
\catcode43=12\catcode44=12\catcode45=12\catcode46=12\catcode47=12%
\catcode58=12\catcode59=12\catcode60=12\catcode61=12\catcode62=12%
\catcode63=12\catcode91=12\catcode92=0\catcode93=12\catcode94=7%
\catcode95=8\catcode96=12\catcode123=1\catcode124=12\catcode125=2%
\catcode126=13\catcode32=10\catcode13=5\catcode9=10\catcode10=12%
\relax
}
% \end{macrocode}
%
% \begin{macrocode}
\def\CatcodeStack{}
% \end{macrocode}
%
% Notably absent from the following list: the \verb'@' character and
% whitespace characters. The former is already handled in the
% \LaTeX{} kernel, and I hesitate to interfere with its current
% catcode transitions.
% \begin{macrocode}
\begingroup \escapechar=\m@ne \let\s\string
\xdef\pcat@otherchars{%
\s\!\s\"\s\#\s\$\s\%\s\&\s\'\s\(\s\)\s\*\s +\s\,\s\-\s\.\s\/\s\:%
\s\;\s\<\s\=\s\>\s\?\s\[\s\\\s\]\s\^\s\_\s\`\s\{\s\|\s\}\s\~%
}
\endgroup
% \end{macrocode}
%
% \begin{macrocode}
\gdef\PushCatcodes{%
\xdef\CatcodeStack{%
\expandafter\PushCat@a\pcat@otherchars\ \
\^^I\^^J{T \@gobbletwo}\@empty
\relax
{\CatcodeStack}}%
}
\def\PushCat@a#1{\catcode\number`#1=\number\catcode`#1 \PushCat@a}
% \end{macrocode}
%
% \begin{macrocode}
\PushCatcodes \NormalCatcodes
% \end{macrocode}
%
% \begin{macrocode}
\def\PopCatcodes{\expandafter\PopCat@a\CatcodeStack}
\def\PopCat@a#1#{#1\xdef\CatcodeStack}
% \end{macrocode}
%
% \subsection{Checking current settings}
%
% This can be used to store a copy of the current settings. Or print
% it with \cs{typeout}.
% \begin{macrocode}
\def\CCSdo#1{ (\string#1\@iden{:\number\catcode`#1)\CCSdo}}
\def\CurrentCatcodesSubset{%
\romannumeral 0\CCSdo\^^I\^^J\^^L\^^M\ \!\"\#\$\%\&\'\(\)\*+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}{\~\@gobbletwo}:\number\catcode`\~)%
}
% \end{macrocode}
%
% \subsection{Futurelet support}
%
% For code that does futureletting to see if a punctuation character
% follows, it is distressing to handle the case when some characters
% might be made active (e.g., by the babel package).
%
% The \cs{FutureLetSetup} function attempts to minimize the
% difficulties by defining canonical control sequences to represent
% all the visible ASCII characters (i.e., ranging from space to
% \qc{\~}, 32--126, plus TAB) whose catcode could be changed without
% transgressing the limits of standard \LaTeX{} syntax.
% \begin{macrocode}
\begingroup\pcat@restore
\begingroup
\catcode`\3="3 \catcode`\4="4 \catcode`\7="7 \catcode`\8="8
\catcode`\A="A \catcode`\B="B \catcode`\C="C \catcode`\D="D
\gdef\fls@let#1#2{%
\ifx\@@undefined#1\else\errmessage{\string#1 already defined}\fi
\begingroup
\lccode`\3=`#2\lccode`\7=`#2\lccode`\8=`#2%
\lccode`\B=`#2\lccode`\C=`#2\lccode`\D=`#2\relax
\ifnum\catcode`#2=\active
\def\do##1{\noexpand\do\noexpand##1\noexpand}%
\lowercase{%
\xdef\fls@active@characters{%
\fls@active@characters
\do#1D}%
}%
\fi
\aftergroup\global \aftergroup\let \aftergroup#1\aftergroup=%
\lowercase{\aftergroup} %
\lowercase{\expandafter\endgroup
\ifcase\catcode`#2 %
0\or \bgroup\or \egroup\or 3\or 4\or 5\or 6\or 7\or 8\or 9\or
\@sptoken\or B\or C\else D\fi
}%
}
\endgroup
% \end{macrocode}
% \cs{dl@@dblquote} means ``document-level double quote'': a
% character token number 34 that has the catcode which is in effect
% at \verb'\begin{document}' for double quotes.
% \begin{macrocode}
\gdef\FutureLetSetup{%
\gdef\fls@active@characters{}%
% \end{macrocode}
% This will normally be the same as \cs{@sptoken}.
% \begin{macrocode}
\fls@let\dl@@space\ %
\fls@let\dl@@exclam\!%
\fls@let\dl@@dblquote\"%
\fls@let\dl@@hash\#%
\fls@let\dl@@dollar\$%
% \end{macrocode}
% At document level, this cannot occur as a separate token.
% \begin{macrocode}
% \fls@let\dl@@percent\%%
\fls@let\dl@@ampersand\&%
\fls@let\dl@@rquote\'%
\fls@let\dl@@lparen\(%
\fls@let\dl@@rparen\)%
\fls@let\dl@@star\*%
\fls@let\dl@@plus\+%
\fls@let\dl@@comma\,%
\fls@let\dl@@hyphen\-%
\fls@let\dl@@period\.%
\fls@let\dl@@slash\/%
\fls@let\dl@@colon\:%
\fls@let\dl@@semicolon\;%
\fls@let\dl@@less\<%
\fls@let\dl@@equal\=%
\fls@let\dl@@greater\>%
\fls@let\dl@@question\?%
\fls@let\dl@@lbracket\[%
% \end{macrocode}
% At document level, this cannot occur as a separate token.
% \begin{macrocode}
% \fls@let\dl@@backslash\\%
\fls@let\dl@@rbracket\]%
\fls@let\dl@@hat\^%
\fls@let\dl@@underscore\_%
\fls@let\dl@@lquote\`%
% \end{macrocode}
% Here one would normally use \cs{bgroup}.
% \begin{macrocode}
\fls@let\dl@@lbrace\{%
\fls@let\dl@@vert\|%
% \end{macrocode}
% Here one would normally use \cs{egroup}.
% \begin{macrocode}
\fls@let\dl@@rbrace\}%
\fls@let\dl@@tilde\~%
}
\AtBeginDocument{\FutureLetSetup}
% \end{macrocode}
%
% \begin{macrocode}
\gdef\FutureLetReset{%
\def\do##1##2{\let##1= ##2}%
\fls@active@characters
\let\do\relax
}
\endgroup
% \end{macrocode}
%
% \begin{macrocode}
\endinput \PopCatcodes\pcat@restore
% \end{macrocode}
%
% \CheckSum{530}
% \Finale
|