diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/locality |
Initial commit
Diffstat (limited to 'macros/latex/contrib/locality')
-rw-r--r-- | macros/latex/contrib/locality/README | 68 | ||||
-rw-r--r-- | macros/latex/contrib/locality/changes.txt | 10 | ||||
-rw-r--r-- | macros/latex/contrib/locality/locality.dtx | 634 | ||||
-rw-r--r-- | macros/latex/contrib/locality/locality.ins | 52 | ||||
-rw-r--r-- | macros/latex/contrib/locality/locality.pdf | bin | 0 -> 186910 bytes |
5 files changed, 764 insertions, 0 deletions
diff --git a/macros/latex/contrib/locality/README b/macros/latex/contrib/locality/README new file mode 100644 index 0000000000..ffe43d8436 --- /dev/null +++ b/macros/latex/contrib/locality/README @@ -0,0 +1,68 @@ +LaTeX Package: Locality 2010/06/29 v0.1 +---------------------------------------- +Various macros for keeping things local + +Copyright (C) 2010 +by Jason Gross <JasonGross9+locality@gmail.com> + +Abstract: + This package provides various macros to keep changes local to the current + group. This allows one to (re)define helper macros without worrying about + accidentally changing the functionality of another package's or the user's + definitions. Additionally, it allows recursive macros to have some + definitions persist between calls, and others be local. + +CTAN: macros/latex/contrib/locality + +Recent changes: + [Release 0.2] + * Switched the order of tests in \manyaftergroup, eliminating an infinite loop. + * Added \DeclareNonlocal*s, \pushvalues, \popvalues, \pushvalue, \popvalue, and a few others. + * Fixed \DeclareNonlocal* to work with \aftergroup. + * Added requirement for etoolbox, so that patching takes place at the end of the preamble. + [Release 0.1] + * Initial release. Some macros untested. + +EOF + + +Files: + * README - this file + * changes.txt - history of changes + * locality.ins - for installation to get .sty from .dtx + * locality.dtx - including sources and documentation + * locality.pdf - print-ready documentation + +Installation: +[manual installation] + * To get locality.sty out of locality.dtx + $ latex locality.ins + * To build documentation + $ latex locality.dtx + * Put the derived files in the proper directories: + - tex/latex/locality/locality.sty + - doc/latex/locality/locality.pdf + - source/latex/locality/locality.dtx + +[TeXLive] + * Use 'tlmgr' command + $ tlmgr show locality -- to check the package info + $ sudo tlmgr update locality -- to update the package + * You can use 'TeX Live Utility' instead of 'tlmgr', if on MacOSX. + +[MikTeX] + * Use the MikTeX Update Wizard to update locality package. + +License: + This work may be distributed and/or modified under the 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.3c or later is part of all distributions of LaTeX + version 2005/12/01 or later. + +-- +Happy TeXing! +Jason Gross + +EOF diff --git a/macros/latex/contrib/locality/changes.txt b/macros/latex/contrib/locality/changes.txt new file mode 100644 index 0000000000..fee40d7665 --- /dev/null +++ b/macros/latex/contrib/locality/changes.txt @@ -0,0 +1,10 @@ +2010/11/11 Release 0.2 + * Switched the order of tests in \manyaftergroup, eliminating an infinite loop. + * Added \DeclareNonlocal*s, \pushvalues, \popvalues, \pushvalue, \popvalue, and a few others. + * Fixed \DeclareNonlocal* to work with \aftergroup. + * Added requirement for etoolbox, so that patching takes place at the end of the preamble. + +2010-06-29 Release 0.1 + * Initial release. Some macros untested. + +EOF diff --git a/macros/latex/contrib/locality/locality.dtx b/macros/latex/contrib/locality/locality.dtx new file mode 100644 index 0000000000..f6fb404739 --- /dev/null +++ b/macros/latex/contrib/locality/locality.dtx @@ -0,0 +1,634 @@ +% \iffalse meta-comment +% +% Copyright (C) 2010 by Jason Gross (JasonGross9+locality@gmail.com) +% +% This file may be distributed and/or modified under the +% 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.3c or later is part of all distributions of +% LaTeX version 2005/12/01 or later. +% +% \fi +% +% +% \iffalse +%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] +%<package>\ProvidesPackage{locality} +%<package> [2010/11/11 v0.2 Various macros for keeping things local] +%<package>\RequirePackage{etoolbox}[2009/08/06] +% +%<*driver> +\documentclass{ltxdoc} +\usepackage{locality} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\begin{document} + \DocInput{locality.dtx} +\end{document} +%</driver> +% \fi +% +% \CheckSum{573} +% +% \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{v0.1}{2010/06/15}{Initial version. Please note that some macros +% have not yet been tested.} +% \changes{v0.2}{2010/11/11}{Switched the order of tests in \string +% \manyaftergroup, eliminating an infinite loop. Added \string +% \DeclareNonlocal*s\space, \string\pushvalues, \string\popvalues, +% \string\pushvalue, \string\popvalue, and a few others. Fixed +% \string\DeclareNonlocal*\space to work with \string\aftergroup. +% Added requirement for etoolbox, so that patching takes place at +% the end of the preamble.} +% +% \GetFileInfo{locality.sty} +% +% \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ } +% \DoNotIndex{} +% +% \title{The \textsf{locality} package\thanks{This document +% corresponds to \textsf{locality}~\fileversion, +% dated~\filedate.}} +% \author{Jason Gross \\ \texttt{JasonGross9+locality@gmail.com}} +% +% \maketitle +% +% \section{Introduction} +% +% The \textsf{locality} package provides various macros to keep changes local +% to the current group. This allows one to (re)define helper macros +% without worrying about accidentally changing the functionality of another +% package's or the user's definitions. Additionally, it allows recursive +% macros to have some definitions persist between calls, and others be local. +% +% \section{Usage} +% I give the usage and specification of every macro defined. I give bugs when +% I know them (please email me if you find other bugs, or have fixes for the +% bugs I list). I sometimes give extra description or justification. +% +% \DescribeMacro{\manyaftergroup} +% \noindent Usage: |\manyaftergroup|\marg{tokens} \par\noindent +% Specification: The \meta{tokens} get placed after the current group \par\noindent +% Bugs: No braces are permitted, spaces are stripped +% +% I've often wanted to use \TeX's |\aftergroup| with a variable-length +% argument. This macro allows this. It is expandable (may be used in +% |\edef|), but it gobbles spaces. +% +% ToDo: Write a version of this macro that preserves spaces, allows braces. +% +% \DescribeMacro{\locallydefine} +% \noindent Usage: |\locallydefine|\marg{macro}\marg{processing} \par\noindent +% Specification: Execute \meta{processing} inside of a group, and make +% the definition of |\macro| persist after the group ends. \par\noindent +% Bugs: Changes via |\let| to an unexpandable macro yield an infinite recursive +% loop. +% +% Normally, when you define a macro in a group, it's definition reverts after +% the group ends, unless you use |\global|. If you use |\global|, then the +% new definition replaces the current definition on all levels. This macro +% provides something in between. +% +% \DescribeMacro{\DeclareNonlocalMacro} +% \noindent Usage: |\DeclareNonlocalMacro|\marg{macro} \par\noindent +% Specification: Any changes to the definition of |\macro| persist +% after the end of the current group. \par\noindent +% Bugs: Changes via |\let| to an unexpandable macro yield an infinite recursive +% loop. Only works with |\begingroup| |\endgroup| (not with braces). +% +% This macro generalized |\locallydefine|. +% +% +% \DescribeMacro{\DeclareNonlocalMacros} +% \noindent Usage: |\DeclareNonlocalMacros|\marg{macro list} \par\noindent +% \noindent Example: |\DeclareNonlocalMacros{\macroi,\macroii}| \par\noindent +% Specification: \marg{macro list} Should be a comma-separated list of macros. +% This command will run |\DeclareNonlocalMacro| on each argument. +% +% +% \DescribeMacro{\DeclareNonlocalTheRegister}\DescribeMacro{\DeclareNonlocalCount} +% \DescribeMacro{\DeclareNonlocalDimen}\DescribeMacro{\DeclareNonlocalSkip} +% \DescribeMacro{\DeclareNonlocalMuskip}\DescribeMacro{\DeclareNonlocalToks} +% \noindent Usage: |\DeclareNonlocalCount|\marg{count} \par\noindent +% \phantom{Usage:} |\DeclareNonlocalDimen|\marg{dimen} \par\noindent +% \phantom{Usage:} |\DeclareNonlocalSkip|\marg{skip} \par\noindent +% \phantom{Usage:} |\DeclareNonlocalMuskip|\marg{muskip} \par\noindent +% \phantom{Usage:} |\DeclareNonlocalToks|\marg{toks} \par\noindent +% Specification: Any changes to the value in \meta{register} persist +% after the end of the current group. \par\noindent +% +% Registers for \meta{count}s, \meta{dimen}s, \meta{skip}s, and \meta{muskips}s +% can all be made nonlocal with |\DeclareNonlocalTheRegister|. +% +% Bugs: Only works with |\begingroup| |\endgroup| (not with braces). Only +% works if the argument is a single token. +% +% These do the same thing to registers (\meta{count}s, \meta{length}s, and +% \meta{tok}s) that |\DeclareNonlocalMacro| does to macros. +% +% +% \DescribeMacro{\DeclareNonlocalTheRegister}\DescribeMacro{\DeclareNonlocalCount} +% \DescribeMacro{\DeclareNonlocalDimen}\DescribeMacro{\DeclareNonlocalSkip} +% \DescribeMacro{\DeclareNonlocalMuskip}\DescribeMacro{\DeclareNonlocalToks} +% \noindent Usage: |\DeclareNonlocalCounts|\marg{list of counts (comma separated)} \par\noindent +% \phantom{Usage:} |\DeclareNonlocalDimens|\marg{list of dimens (comma separated)} \par\noindent +% \phantom{Usage:} |\DeclareNonlocalSkips|\marg{list of skips (comma separated)} \par\noindent +% \phantom{Usage:} |\DeclareNonlocalMuskips|\marg{list of muskips} \par\noindent +% \phantom{Usage:} |\DeclareNonlocalTokses|\marg{list of toks (comma separated)} \par\noindent +% Specification: Any changes to the value in \meta{register}s persist +% after the end of the current group. \par\noindent +% +% \DescribeMacro{\pushvalue}\DescribeMacro{\popvalue}\noindent +% Usage: |\pushvalue|\marg{macro} \par\noindent +% \phantom{Usage:} |\popvalue|\marg{macro} \par +% \noindent Specification: The argument \marg{macro} is backed up by +% |\pushvalue|, and the most recently backed up value is restored by +% |\popvalue|. The macro definitions are saved using a stack. +% +% +% \DescribeMacro{\savevalues}\DescribeMacro{\restorevalues} +% \noindent Usage: |\savevalues|\marg{list of macros (no separator)} \par\noindent +% \phantom{Usage:} |\restorevalues|\marg{list of macros (no separator)} \par\noindent +% Specification: Every token in the passed argument is backed up by +% |\savevalues|, and the most recently backed up values are restored by +% |\restorevalues|. +% +% +% \DescribeMacro{\pushvalues}\DescribeMacro{\popvalues}\noindent +% Usage: |\pushvalues|\marg{list of macros (comma separated)} \par\noindent +% \phantom{Usage:} |\popvalues|\marg{list of macros (comma separated)} \par +% \noindent Specification: Every macro in the passed argument is backed up by +% |\pushvalues|, and the most recently backed up values are restored by +% |\popvalues|. The macro definitions are saved using a stack. +% +% +% \DescribeMacro{\makecommandslocal} +% \noindent Usage: |\makecommandslocal|\marg{list of macros (no separator)}\marg{code} \par\noindent +% Specification: Every token in the first argument is made local to \meta{code}; +% changes made to their definitions do not perist outside of \meta{code}. +% +% This macro is the natural opposite of |\DeclareNonlocalMacro|; it allows +% some macros to behave as if \meta{code} was inside a group, while the rest +% of the macros behave as if they were not. +% +% +% \DescribeMacro{\ignoreglobal}\DescribeMacro{\obeyglobal}\DescribeMacro{\unignoreglobal} +% \noindent Usage: |\ignoreglobal| \par\noindent +% \noindent Usage: |\unignoreglobal| \par\noindent +% \noindent Usage: |\obeyglobal| \par\noindent +% Specification: The macro |\ignoreglobal| causes global changes, such as +% |\edef|, |\xdef|, and those prefaced by |\global|, to be local. The macro +% |\obeyglobal| causes these to be treated as global. The macro +% |\unignoreglobal| undoes the changes made by the last |\ignoreglobal|. If +% you call |\ignoreglobal| twice, then you must call |\unignoreglobal| twice to +% allow global changes. +% +% \DescribeMacro{\makecounterslocal} +% \noindent Usage: |\makecounterslocal| \par\noindent +% Specification: The macro |\makecounterslocal| redefines the \LaTeX{} +% \meta{counter} macros so that their changes are local, instead of global. +% At the end of the group in which |\makecounterslocal| is called, +% \meta{counter} macros revert to being global. +% +% \StopEventually{\PrintChanges\PrintIndex} +% +% \section{Implementation} +% \subsection{Helper functions} +% The following definitions are preliminary, to allow various tricks with |\def|. +% \begin{macrocode} +\def\@nil{\@nil\relax} % this way, I'll know if I've messed up; I'll get +% a stack overflow error. +\def\if@nil#1{\@if@nil#1\@@nil} +\def\@if@nil#1#2\@@nil{\ifx\@nil#1} +% We'll be messing with |\global|, so we better have a backup. +\let\locality@tex@global=\global +% \end{macrocode} +% +% \begin{macro}{\locality@global@non@collision@unique@count} +% At various places, I want to have a macro associated with a certain name +% which hasn't been used before. I use this count to number them. I use +% a count, instead of a counter, so that I can control whether or not it's +% global. The long name, with lots of |@|s, is to (hopefully) avoid +% collisions. +% \begin{macrocode} +\newcount\locality@global@non@collision@unique@count +\locality@global@non@collision@unique@count=0 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\manyaftergroup} +% +% The macro |\manyaftergroup| works by parsing it's argument one token at a +% time, and applying |\aftergroup| to each argument. It checks for the end +% with |\@nil|. +% \begin{macrocode} +\long\def\@manyaftergroup#1{\if@nil#1 \else \aftergroup#1 +\expandafter\@manyaftergroup\fi} +\newcommand{\manyaftergroup}[1]{\@manyaftergroup#1\@nil} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\locallydefine} +% Execute the second argument passed locally, and then preserve the definition +% of the first argument passed. +% \begin{macrocode} +\newcommand{\locallydefine}[2]{{#2\expandafter}% + \expandafter\def\expandafter#1\expandafter{#1}} +% \end{macrocode} +% +% \end{macro} +% +% The |\DeclareNonlocal| macros do some fancy stuff with |\begingroup| and +% |\endgroup|, so the old definitions must be saved. +% \begin{macrocode} +\let\locality@tex@begingroup=\begingroup +\let\locality@tex@endgroup=\endgroup +% \end{macrocode} +% These macros are extended versions of the |\locallydefine| macro; they +% redefine |\endgroup| to preserve definitions after the current group ends. +% +% Because |\aftergroup| would occur before definition restoration, we patch +% |\aftergroup| so that it instead appends tokens to the end of |\endgroup|. +% This doesn't fix all use cases, but it should fix a problem with the calc +% package. +% \begin{macrocode} +\newcount\locality@global@aftergroup@count +\locality@global@aftergroup@count=-1 +\newcommand\locality@patch@aftergroup{% + \def\aftergroup{% + \locality@tex@global\advance\locality@global@aftergroup@count by 1 + \afterassignment\locality@aftergroup\locality@tex@global + \expandafter\let\csname locality@nextchar\space\the + \locality@global@aftergroup@count\endcsname=% + }% +} +\newcommand\locality@aftergroup{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter\endgroup + \expandafter\expandafter\expandafter{\expandafter\endgroup + \csname locality@nextchar\space\the\locality@global@aftergroup@count + \endcsname}% +} +% \end{macrocode} +% +% +% \begin{macro}{\DeclareNonlocalMacro} +% This macro redefines |\endgroup| to do this for macro passed to it. +% +% First, back up |\endgroup| to a new macro. +% \begin{macrocode} +\newcommand{\DeclareNonlocalMacro}[1]{% + \locality@patch@aftergroup % first, patch |\aftergroup| + \expandafter\let + \csname endgroup \the\locality@local@group@non@local@macro@count + \endcsname=\endgroup +% \end{macrocode} +% Redefine |\endgroup| to, in order: revert it's definition, insert code to +% update the definition of the passed macro outside of the group, and call +% the (reverted) version of |\endgroup|. +% \begin{macrocode} + \expandafter\def\expandafter\endgroup\expandafter{% + \expandafter\expandafter\expandafter\let\expandafter + \expandafter\expandafter\endgroup\expandafter\expandafter + \csname endgroup \the\locality@local@group@non@local@macro@count + \endcsname\expandafter\endgroup + \expandafter\def\expandafter#1\expandafter{#1}}% + \advance\locality@local@group@non@local@macro@count by 1 +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\newcommand\locality@declarenonlocals[2]{% + \@for\locality@declarenonlocals@name:=#2\do{% + \expandafter #1\expandafter{\locality@declarenonlocals@name}% + }% +} +% \end{macrocode} +% +% \begin{macro}{\DeclareNonlocalMacros} +% \begin{macrocode} +\newcommand{\DeclareNonlocalMacros}[1]{\locality@declarenonlocals{\DeclareNonlocalMacro}{#1}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\DeclareNonlocalTheRegister} +% \begin{macro}{\DeclareNonlocalCount} +% \begin{macro}{\DeclareNonlocalDimen} +% \begin{macro}{\DeclareNonlocalSkip} +% \begin{macro}{\DeclareNonlocalMuskip} +% This works the same way as as |\DeclareNonlocalMacro|, but uses |\the| instead of +% |\def|. +% \begin{macrocode} +\newcommand{\DeclareNonlocalTheRegister}[1]{% + \locality@patch@aftergroup % first, patch |\aftergroup| + \expandafter\let + \csname endgroup \the\locality@local@group@non@local@macro@count + \endcsname=\endgroup + \expandafter\def\expandafter\endgroup\expandafter{% + \expandafter\expandafter\expandafter\let + \expandafter\expandafter\expandafter\endgroup + \expandafter\expandafter + \csname endgroup \the\locality@local@group@non@local@macro@count + \endcsname\expandafter\endgroup + \expandafter#1\expandafter=\the#1 }% Note the space. This is to +% prevent something like +% |\newcount\tempc\begingroup \DeclareNonlocalCount\tempc \tempc=1\endgroup1| +% from setting |\tempc| to 11. + \advance\locality@local@group@non@local@macro@count by 1 +}% +\let\DeclareNonlocalCount=\DeclareNonlocalTheRegister +\let\DeclareNonlocalDimen=\DeclareNonlocalTheRegister +\let\DeclareNonlocalSkip=\DeclareNonlocalTheRegister +\let\DeclareNonlocalMuskip=\DeclareNonlocalTheRegister +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\DeclareNonlocalTheRegisters} +% \begin{macro}{\DeclareNonlocalCounts} +% \begin{macro}{\DeclareNonlocalDimens} +% \begin{macro}{\DeclareNonlocalSkips} +% \begin{macro}{\DeclareNonlocalMuskips} +% \begin{macrocode} +\newcommand{\DeclareNonlocalTheRegisters}[1]{\locality@declarenonlocals{\DeclareNonlocalTheRegister}{#1}} +\let\DeclareNonlocalCounts=\DeclareNonlocalTheRegisters +\let\DeclareNonlocalDimens=\DeclareNonlocalTheRegisters +\let\DeclareNonlocalSkips=\DeclareNonlocalTheRegisters +\let\DeclareNonlocalMuskips=\DeclareNonlocalTheRegisters +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\DeclareNonlocalToks} +% This works the same way as as |\DeclareNonlocalCount|, but puts braces around +% the assigned value; |\toks0=1| fails, and should be |\toks0={1}|. +% \begin{macrocode} +\newcommand{\DeclareNonlocalToks}[1]{% + \locality@patch@aftergroup % first, patch |\aftergroup| + \expandafter\let + \csname endgroup \the\locality@local@group@non@local@macro@count + \endcsname=\endgroup + \expandafter\def\expandafter\endgroup\expandafter{% + \expandafter\expandafter\expandafter\let\expandafter\expandafter + \expandafter\endgroup\expandafter\expandafter + \csname endgroup \the\locality@local@group@non@local@macro@count' + \endcsname\expandafter\endgroup + \expandafter#1\expandafter=\expandafter{\the#1}}% + \advance\locality@local@group@non@local@macro@count by 1 +}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareNonlocalTokses} +% \begin{macrocode} +\newcommand{\DeclareNonlocalTokses}[1]{\locality@declarenonlocals{\DeclareNonlocalToks}{#1}} +% \end{macrocode} +% \end{macro} +% +% I redefine |\begingroup| to reset the locality macros, so nesting works. +% \begin{macrocode} +\newcount\locality@local@group@non@local@macro@count % Hopefully, this +% won't collide with anything. I hope putting this out here allows +% proper nesting of groups +\def\begingroup{\locality@tex@begingroup + \def\endgroup{\locality@tex@endgroup}% not \let, because + % that would break my |\aftergroup| patch + \locality@local@group@non@local@macro@count=0 +} +% \end{macrocode} +% +% +% +% \begin{macro}{\savevalues} +% \begin{macro}{\restorevalues} +% These macros parse their arguments token by token, renaming each |macro| to +% |@\macro backup|, or vice versa. +% \begin{macrocode} +\def\@savevalues#1{\ifx#1\@nil \else \expandafter\let + \csname @\string#1\space backup\endcsname=#1 + \expandafter\@savevalues\fi} +\newcommand{\savevalues}[1]{\@savevalues#1\@nil} + +\def\@restorevalues#1{% +\ifx + #1\@nil +\else + \expandafter\let\expandafter#1\expandafter + =\csname @\string#1\space backup\endcsname + \expandafter + \let\csname @\string#1\space backup\endcsname + =\relax + \expandafter\@restorevalues +\fi +} +\newcommand{\restorevalues}[1]{\@restorevalues#1\@nil} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\pushvalues} +% \begin{macro}{\popvalues} +% \begin{macro}{\pushvalue} +% \begin{macro}{\popvalue} +% \begin{macrocode} +\newcommand{\pushvalue}[1]{% + \@ifundefined{locality\space backup\space \string#1}{}{% + \expandafter\pushvalue\csname locality\space backup\space \string#1\endcsname% + }% + \expandafter\let\csname locality\space backup\space \string#1\endcsname=#1% +} +\newcommand{\pushvalues}[1]{% + \@for\locality@pushvalues@macroname:=#1\do{% + \expandafter\pushvalue\locality@pushvalues@macroname + }% +} +\newcommand{\popvalue}[1]{% + \@ifundefined{locality\space backup\space \string#1}{% + \let#1=\relax + }{% + \expandafter\let\expandafter#1\expandafter=\csname locality\space backup\space \string#1\endcsname + \expandafter\popvalue\csname locality\space backup\space \string#1\endcsname% + }% +} +\newcommand{\popvalues}[1]{% + \@for\locality@popvalues@macroname:=#1\do{% + \expandafter\popvalue\locality@popvalues@macroname + }% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\makecommandslocal} +% Save the macros, run the code, then restore the values. +% \begin{macrocode} +\newcommand{\makecommandslocal}[2]{\savevalues{#1}#2\restorevalues{#1}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\makecounterslocal} +% To make counters local without redefining them too badly (for example, this +% should work with the |calc| package, as long as you load |calc| first), +% we disable |\global|, and set |\gdef| and |\xdef| to |\def| and |\edef| +% respectively. +% +% \begin{macro}{\ignoreglobal} +% \begin{macro}{\obeyglobal} +% \begin{macro}{\unignoreglobal} +% We save the values of |\global|, |\gdef|, |\xdef|, globally, so +% that multiple calls don't fail. +% +% We also save the value of |\@cons|, a special macro used in counters, which +% uses |\xdef| to append something to a list. Since it must be redefined for +% counters, I'll redefine it here to do without |\xdef| fails. +% +% For reference, the original definition of |\@cons|, from |latex.ltx|, is \\ +% |\def\@cons#1#2{\begingroup\let\@elt\relax\xdef#1{#1\@elt #2}\endgroup}|. +% I try to make this forward-compatible, but if the definition of |\@cons| +% changes too badly, this'll break. +% \begin{macrocode} +\savevalues{\global\gdef\xdef\@cons} +{\def\begingroup{\begingroup\DeclareNonlocalMacro{##1}}% + \expandafter\expandafter\expandafter +}% +\expandafter\expandafter\expandafter\def +\expandafter\expandafter\expandafter\locality@cons +\expandafter\expandafter\expandafter#% +\expandafter\expandafter\expandafter1% +\expandafter\expandafter\expandafter#% +\expandafter\expandafter\expandafter2% +\expandafter\expandafter\expandafter{\@cons{#1}{#2}}% +\newcommand{\obeyglobal}{\restorevalues{\global\gdef\xdef\@cons}} +\newcommand{\unignoreglobal}{\popvalues{\global,\gdef,\xdef,\@cons}} +\newcommand{\ignoreglobal}{% + \pushvalues{\global,\gdef,\xdef,\@cons}% + \let\global=\relax \let\gdef=\def \let\xdef=\edef + \let\@cons=\locality@cons + \expandafter\def\expandafter\unignoreglobal\expandafter{\expandafter + \def\expandafter\unignoreglobal\expandafter{\unignoreglobal}% + \unignoreglobal}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% Now, the actual macro. +% +% We redefine |\stepcounter|, |\addtocounter|, |\refstepcounter|, +% |\setcounter|, |\@addtoreset|, and |\@definecounter|. +% +% Since |\newcounter| does everything with |\@addtoreset| and +% |\@definecounter|, it doesn't need and changes. +% \begin{macrocode} +\newcommand{\makecounterslocal}{% FIX, to make more robust + \expandafter\def\expandafter\stepcounter + \expandafter##\expandafter1\expandafter{% + \expandafter\ignoreglobal\stepcounter{##1}% + \unignoreglobal + }% + % + \expandafter\def\expandafter\refstepcounter + \expandafter##\expandafter1\expandafter{% + \expandafter\ignoreglobal\refstepcounter{##1}% + \unignoreglobal + }% + % + \expandafter\def\expandafter\setcounter + \expandafter##\expandafter1% + \expandafter##\expandafter2\expandafter{% + \expandafter\ignoreglobal\setcounter{##1}{##2}% + \unignoreglobal + }% + % + \expandafter\def\expandafter\addtocounter + \expandafter##\expandafter1% + \expandafter##\expandafter2\expandafter{% + \expandafter\ignoreglobal\addtocounter{##1}{##2}% + \unignoreglobal + }% + % + \expandafter\def\expandafter\@addtoreset + \expandafter##\expandafter1% + \expandafter##\expandafter2\expandafter{% + \expandafter\ignoreglobal\@addtoreset{##1}{##2}% + \unignoreglobal + }% + % + \expandafter\def\expandafter\@definecounter + \expandafter##\expandafter1\expandafter{% + \expandafter\ignoreglobal\@definecounter{##1}% + \unignoreglobal + }% + \locality@fix@for@amstext + \locality@fix@for@calc +} +% \end{macrocode} +% +% Following the example of the |calc| package, if the amstext package is loaded +% we must add the |\iffirstchoice@| switch as well. We patch the commands this +% way since it's good practice when we know how many arguments they take. +% +% We use |\AtEndPreamble| to ensure that we catch the other package loads. +% \begin{macrocode} +\AtEndPreamble{ + \@ifpackageloaded{amstext}{ + \newcommand{\locality@fix@for@amstext}{ + \expandafter\def\expandafter\stepcounter + \expandafter##\expandafter1\expandafter{% + \expandafter\iffirstchoice@\stepcounter{##1}\fi + } + \expandafter\def\expandafter\addtocounter + \expandafter##\expandafter1% + \expandafter##\expandafter2\expandafter{% + \expandafter\iffirstchoice@\addtocounter{##1}{##2}\fi + } + } + }{ + \let\locality@fix@for@amstext=\relax + } + \@ifpackageloaded{calc}{% + \def\locality@fix@for@calc{\expandafter\def\expandafter\begingroup\expandafter{\begingroup\DeclareNonlocalTheRegister{\calc@A}}} + }{ + \let\locality@fix@for@calc=\relax + } +} +% \end{macrocode} +% \end{macro} +% +% +% \Finale +\endinput diff --git a/macros/latex/contrib/locality/locality.ins b/macros/latex/contrib/locality/locality.ins new file mode 100644 index 0000000000..4944db3c3d --- /dev/null +++ b/macros/latex/contrib/locality/locality.ins @@ -0,0 +1,52 @@ +%% +%% Copyright (C) 2010 by Jason Gross +%% +%% 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. +%% +\input docstrip.tex +\keepsilent +\usedir{tex/latex/locality} + +\preamble + +This is a generated file. + +Copyright (C) 2010 by Jason Gross + +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. +\endpreamble + +\generate{\file{locality.sty}{\from{locality.dtx}{package}}} + +\obeyspaces +\Msg{****************************************************} +\Msg{* *} +\Msg{* To finish the installation you have to move the *} +\Msg{* following file into a directory searched by TeX: *} +\Msg{* *} +\Msg{* locality.sty *} +\Msg{* *} +\Msg{* To produce the documentation run the file *} +\Msg{* locality.dtx through LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{* *} +\Msg{****************************************************} + +\endbatchfile
\ No newline at end of file diff --git a/macros/latex/contrib/locality/locality.pdf b/macros/latex/contrib/locality/locality.pdf Binary files differnew file mode 100644 index 0000000000..21ac991b04 --- /dev/null +++ b/macros/latex/contrib/locality/locality.pdf |