summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/saferef/saferef.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/saferef/saferef.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/saferef/saferef.dtx')
-rw-r--r--macros/latex/contrib/saferef/saferef.dtx478
1 files changed, 478 insertions, 0 deletions
diff --git a/macros/latex/contrib/saferef/saferef.dtx b/macros/latex/contrib/saferef/saferef.dtx
new file mode 100644
index 0000000000..f09502d608
--- /dev/null
+++ b/macros/latex/contrib/saferef/saferef.dtx
@@ -0,0 +1,478 @@
+% \changes{v1.0}{1997/2/2}{First Release}
+%
+% \iffalse % this is a METACOMMENT !
+%
+% Package `indxcite' for use with LaTeX2e
+% Copyright (C) 1997 James Ashton (email `James.Ashton@anu.edu.au').
+% All rights reserved. You may not alter the contents of this file
+% unless you also change its name.
+%
+% \fi
+%
+% \MakeShortVerb{\+}
+%
+% \title{Safer cross-referencing with \texttt{saferef}}
+% \author{James Ashton}
+% \maketitle
+% \begin{abstract}
+% The \texttt{saferef} package replaces +\ref+ with +\figureref+,
+% +\sectionref+, +\eqref+, etc.\ so that you're forced to specify the
+% kind of label you're using. Each reference command also generates
+% appropriate text automatically so that instead of typing
+% `+See Figure~\ref{figure:key}+' only `+See \figureref{key}+' is necessary.
+% The +\label+ command is redefined so that it records the type of label
+% with the key. In this way each type of label has its own name-space.
+% \end{abstract}
+%
+% \section{Introduction}
+%
+% This package is designed to help avoid cross-referencing errors.
+% In a large work it can be difficult to keep track of the keys used
+% with \LaTeX's automatic cross-referencing. It's possible for the output
+% to say `as in Corollary 3' when in fact there is no `Corollary 3' but
+% instead `Lemma 3'. Also it can be taxing to come up with
+% different keys when the keys used for every label share the same
+% name-space. The \texttt{saferef} package gives every type of label its
+% own key name-space and defines a separate variant of +\ref+ to access each
+% type of label. Use of +\ref+ is an error.
+%
+% \section{Compatibility with other packages}
+%
+% The +saferef+ package takes care to be compatible with other packages
+% as much as possible. Where commands are redefined, the new definition
+% is in terms of the existing definition where possible so that new
+% features can be added without disrupting existing ones. For this
+% strategy to work, +saferef+ must be read \emph{after} other packages
+% which may interact with the features it provides. In particular
+% +saferef+ works with AMS-\LaTeX{} 1.1 and~1.2 or with the +theorem+
+% package when read after them in the preamble.
+%
+% \pagebreak
+% \section{User interface}
+%
+% \DescribeMacro{\label}
+% \noindent
+% The +\label+ command is used exactly as in plain \LaTeX, i.e.,\ a single
+% key is supplied as the only argument.
+% Its definition has been changed so that the key is modified by prepending
+% the name of the type of label followed by a colon.
+% If the label follows a +\chapter+ command then +\label{key}+ will
+% behave as +\label{chapter:key}+ does in plain \LaTeX.
+%
+% The types of things that can be labelled each have their own counter
+% and, in general, the name of the counter is used as the name of the
+% label type, i.e.,\ chapters have the label type +chapter+ because that
+% is the name of the \LaTeX{} counter used to number them.
+% There are exceptions to this rule however:
+%
+% \begin{itemize}
+%
+% \item
+% Subsections and subsubsections are both of type +section+ since their numbers
+% usually include the section number so that it's possible to tell what
+% level of section is being referenced by the number itself.
+%
+% \item
+% Subparagraphs are of type +paragraph+.
+%
+% \item
+% Every level of list item is of type +item+, i.e.,\ items numbered using
+% any of the counters +enumi+, +enumii+, +enumiii+ or +enumiv+, are all
+% of type +item+.
+%
+% \item
+% Minipage footnotes use the +mpfootnote+ counter but are of type +footnote+.
+%
+% \item
+% Of course appendices use the +chapter+ counter but (after the +\appendix+
+% command is executed) they are of type +appendix+.
+% \end{itemize}
+%
+% \DescribeMacro{\pageref}
+% \noindent
+% The +\pageref+ command is not modified by \texttt{saferef} but the key
+% used must be modified to match the new definition of +\label+ described
+% above.
+%
+% \DescribeMacro{\ref}
+% \noindent
+% The +\ref+ command is withdrawn so that using it will cause an error.
+% It is replaced by the commands described below.
+%
+% \DescribeMacro{\appendixref}
+% \DescribeMacro{\chapterref}
+% \DescribeMacro{\figureref}
+% \DescribeMacro{\footnoteref}
+% \DescribeMacro{\itemref}
+% \DescribeMacro{\partref}
+% \DescribeMacro{\sectionref}
+% \DescribeMacro{\tableref}
+% \noindent
+% Each of these commands is used to make a cross-reference to a particular
+% kind of label. In each case exactly one argument is required which
+% should be a comma separated list of the label keys to be referenced.
+% These keys are modified by prepending the label type followed by a colon
+% so that they will work with the modified +\label+ command.
+%
+% These commands also provide the text describing the
+% type of label being referenced. The input:
+% \begin{verbatim}
+% See \chapterref{first}.
+% See \chapterref{first,second}.
+% See \chapterref{first,second,third}.
+% \end{verbatim}
+% is equivalent to the following plain \LaTeX{} input:
+% \begin{verbatim}
+% See Chapter~\chapterref{chapter:first}.
+% See Chapters \ref{chapter:first} and~\ref{chapter:second}.
+% See Chapters \ref{chapter:first}, \ref{chapter:second} and~\ref{chapter:third}.
+% \end{verbatim}
+%
+% \DescribeMacro{\eqref}
+% \noindent
+% +\eqref+ is based on the command of the same name provided by
+% AMS-\LaTeX{}\@. It is used to reference labels of the +equation+ type
+% and it produces the equation numbers as displayed with the referenced
+% equation(s). It does not generate the word `Equation' since this is
+% not usually required.
+%
+% Note that all of the environments that share the
+% equation numbering should be referenced with +\eqref+. Apart from
+% +equation+ and +eqnarray+, this includes the +align+, +gather+,
+% +multline+, etc.\ environments from AMS-\LaTeX{} and possibly other similar
+% enviroments from other packages.
+%
+% \DescribeMacro{\refname}
+% \noindent
+% This command will (re)define a referencing command for a label type.
+% The three arguments required are the label type name, the singular
+% form used to refer to it and the plural form,
+% e.g.,\ +\refname{chapter}{Chapter}{Chapters}+.
+%
+% \DescribeMacro{\itemname}
+% \noindent
+% Sometimes it may be desirable to be more descriptive about items in lists.
+% The +\itemname+ command can be used to cause items to be of aribrary type,
+% e.g.,\ if you were using an +enumerate+ environment to list problems, then
+% then +\itemname{problem}+ would require them to be referenced like
+% +\problemref{key}+. Of course, it would also be necessary to
+% specify
+% \begin{verbatim}
+% \refname{problem}{Problem}{Problems}
+% \end{verbatim}
+% for this to work.
+%
+% \DescribeMacro{\newtheorem}
+% \noindent
+% The +\newtheorem+ is redefined so that an extra
+% argument is required. Specify the plural form of the environment's
+% name as an argument immediately following the singular form, e.g.:
+% \begin{verbatim}
+% \newtheorem{theorem}{Theorem}{Theorems}[section]
+% \newtheorem{lemma}[theorem]{Lemma}{Lemmas}
+% \end{verbatim}
+% The above would define +\theoremref+ and +\lemmaref+ and cause labels
+% in the new `theorem-like' environments to have label types identical
+% to their environment names (+theorem+ and +lemma+ in this case).
+%
+% \pagebreak
+% \section{An example}
+%
+% The following is a small example which illustrates a few of the
+% features of the package.
+% Just run it through \LaTeX{} twice, then use +makeindex+ (with the
+% arguments noted in the comment in the file, and finally run \LaTeX{} again.
+% \begin{macrocode}
+%<*example>
+\documentclass{article}
+\usepackage{amsmath}
+\usepackage{amsthm}
+\usepackage{saferef}
+\newtheorem{theorem}{Theorem}{Theorems}
+\newtheorem{lemma}[theorem]{Lemma}{Lemmas}
+\begin{document}
+\section{The first section}
+\label{zero}
+We'll use the following in \theoremref{one}.
+\begin{equation}
+a = b\label{two}
+\end{equation}
+\begin{theorem}
+\label{one}
+Equation \eqref{two} has nothing to do with \eqref{three} or \eqref{four}.
+See also \lemmaref{six}.
+\begin{align}
+a^2&=b^2+c^2\label{three}\\
+a&=\sqrt{b^2+c^2-2bc\cos A}\label{four}
+\end{align}
+\end{theorem}
+Having had this pointless theorem, why not try for a lemma of similar
+class.
+\section{Another section}
+\label{five}
+\begin{lemma}
+\label{six}
+\theoremref{one} (in \sectionref{zero}) contains two equations.
+While both are simple, \eqref{four} is more complex than \eqref{three}.
+\end{lemma}
+\section{The final section}
+\label{seven}
+This document includes \sectionref{zero,five,seven}.
+\lemmaref{six} is on page \pageref{lemma:six}.
+\end{document}
+%</example>
+% \end{macrocode}
+%
+% \StopEventually{}
+%
+% \pagebreak
+% \section{The code}
+% This package is titled \texttt{saferef} and it requires \LaTeX2e{} to run.
+% \begin{macrocode}
+%<*package>
+\def\fileversion{1.0}
+\def\filedate{1997/2/2}
+\def\docdate{1997/2/2}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{saferef}[\filedate\space\fileversion\space A Safer Cross-referencing package]
+\typeout{Package `saferef' \fileversion\space<\filedate>}
+% \end{macrocode}
+%
+% The +\refstepcounter+ command is used by \LaTeX to increment counters that
+% may be referenced. First we remember its existing definition.
+% \begin{macrocode}
+\let\sr@refstepcounter=\refstepcounter
+% \end{macrocode}
+% Now we redefine it to remember the name of the counter (in +\sr@name+).
+% \begin{macrocode}
+\def\refstepcounter#1{%
+ \xdef\sr@name{#1}
+% \end{macrocode}
+% We also call +\sr@nm@counter-name+ if it's defined. This is the
+% mechanism used to allow special behaviour for some counters.
+% \begin{macrocode}
+ \csname sr@nm@#1\endcsname
+% \end{macrocode}
+% Finally we call the remembered original definition of +\refstepcounter+.
+% \begin{macrocode}
+ \sr@refstepcounter{#1}}
+% \end{macrocode}
+%
+% +\eqnarray+ doesn't use +\refstepcounter+ directly so we have to
+% modify it as well.
+% \begin{macrocode}
+\let\sr@eqnarray=\eqnarray
+\def\eqnarray{\def\sr@name{equation}\sr@eqnarray}
+% \end{macrocode}
+%
+% Our redefinition of +\label+ involves just the obvious prepending of the
+% label type (as saved in +\sr@label+) to the key.
+% \begin{macrocode}
+\let\sr@label=\label
+\def\label#1{\sr@label{\sr@name:#1}}
+% \end{macrocode}
+%
+% AMS-\LaTeX\ uses +\ltx@label+ internally instead of +\label+ so we
+% need to make these identical in case we're using AMS-\LaTeX.
+% \begin{macrocode}
+\let\ltx@label=\label
+% \end{macrocode}
+%
+% It wouldn't be safe if we could just use the old +\ref+ command so
+% we remember its definition and then define it to generate an error message.
+% \begin{macrocode}
+\let\sr@ref=\ref
+\def\ref{\@latex@error{\string\ref\space disallowed with the saferef package.}}
+% \end{macrocode}
+%
+% \pagebreak
+% The command +\sr@refs+ is called by the various +\ref+ variants to do
+% the hard work. It determines whether there's more than one key and
+% generates the singular or plural form of the label type name as
+% appropriate. It also handles the first key by prepending the label type
+% and a colon and passing the result to the original definition of +\ref+.
+% Finally, it calls +\sr@rest+ if there are more keys to handle.
+% \begin{macrocode}
+\def\sr@refs<#1,#2>#3#4#5{%
+ \ifx\relax#2\relax
+ #4~\sr@ref{#3:#1}%
+ \else%
+ #5 \sr@ref{#3:#1}%
+ \sr@rest<#2>{#3}%
+ \fi%
+}
+% \end{macrocode}
+% +\sr@rest+ handles every key but the first; prepending the label type
+% and a colon to each one and passing each result to the original
+% definition of +\ref+. It also generates any required commas and the
+% word `and' between the last two references.
+% \begin{macrocode}
+\def\sr@rest<#1,#2>#3{%
+ \ifx\relax#2\relax
+ \ and~\sr@ref{#3:#1}%
+ \else%
+ , \sr@ref{#3:#1}%
+ \sr@rest<#2>{#3}%
+ \fi%
+}
+% \end{macrocode}
+%
+% Some base definition of +\eqref+ is required since the later
+% redefinition will depend on an existing one. If there isn't an
+% existing one we provide one based on the AMS-\LaTeX 1.2 version.
+% \begin{macrocode}
+\ifx\eqref\@undefined
+ \def\eqref#1{\textup{\hbox{\m@th\normalfont(\ignorespaces\ref{#1}\unskip\@@italiccorr)}}}
+\fi
+% \end{macrocode}
+% Now we modify +\eqref+ to avoid the use of the forbidden +\ref+ command
+% \begin{macrocode}
+\let\sr@eqref=\eqref
+\def\eqref#1{{\let\ref=\sr@ref\sr@eqref{equation:#1}}}
+% \end{macrocode}
+%
+% The following provides the command which maps label type names to the text
+% to appear in references. Both a singular and plural version must be provided.
+% \begin{macrocode}
+\def\refname#1#2#3{%
+ \expandafter\def\csname#1ref\endcsname##1{\sr@refs<##1,>{#1}{#2}{#3}}}
+% \end{macrocode}
+% We use the above command to provide names for the standard LaTeX counters.
+% \begin{macrocode}
+\refname{appendix}{Appendix}{Appendices}
+\refname{chapter}{Chapter}{Chapters}
+\refname{figure}{Figure}{Figures}
+\refname{footnote}{Footnote}{Footnotes}
+\refname{item}{Item}{Items}
+\refname{paragraph}{Paragraph}{Paragraphs}
+\refname{part}{Part}{Parts}
+\refname{section}{Section}{Sections}
+\refname{table}{Table}{Tables}
+% \end{macrocode}
+%
+% We now arrange for some label types to have different names from their
+% counters. This is done by defining a command +\sr@nm@counter-name+
+% which is called by +\label+ and which will redefine +\sr@name+ as required.
+%
+% `subsection' and `subsubsection' are renamed `section'.
+% \begin{macrocode}
+\def\sr@nm@subsection{\xdef\sr@name{section}}
+\def\sr@nm@subsubsection{\xdef\sr@name{section}}
+% \end{macrocode}
+%
+% `subparagraph' is renamed `paragraph'.
+% \begin{macrocode}
+\def\sr@nm@subparagraph{\xdef\sr@name{paragraph}}
+% \end{macrocode}
+%
+% `mpfootnote' is renamed `footnote'.
+% \begin{macrocode}
+\def\sr@nm@mpfootnote{\xdef\sr@name{footnote}}
+% \end{macrocode}
+%
+% Add to the definition of +\appendix+ so that it causes the +chapter+
+% label type to be renamed +appendix+.
+% \begin{macrocode}
+\let\sr@appendix=\appendix
+\def\appendix{\sr@appendix\def\sr@nm@chapter{\xdef\sr@name{appendix}}}
+% \end{macrocode}
+%
+% We want to be able to have list items called something other than just
+% `item' so we'll arrange for the command +\sr@item+ to be used to
+% specify the label type of items.
+% \begin{macrocode}
+\def\sr@nm@enumi{\xdef\sr@name{\sr@item}}
+\def\sr@nm@enumii{\xdef\sr@name{\sr@item}}
+\def\sr@nm@enumiii{\xdef\sr@name{\sr@item}}
+\def\sr@nm@enumiv{\xdef\sr@name{\sr@item}}
+% \end{macrocode}
+% Now we define a command to set +\sr@item+ and use it to set the initial value.
+% \begin{macrocode}
+\def\itemname#1{\def\sr@item{#1}}
+\itemname{item}
+% \end{macrocode}
+%
+% We need to redefine +\newtheorem+ for two reasons. Firstly we need to
+% know the plural form of the name for use in multiple references.
+% Secondly, where several `theorem-like' environments are numbered alike,
+% they all use the same counter. We need to hack the generated
+% environment so that it tells us which environment it is even though it
+% increments a different counter.
+%
+% The redefinition of +\newtheorem+ uses the existing definition so it
+% will work with any existing definition that's compatible with the
+% standard \LaTeX{} +\newtheorem+. In particular, it will work with the
+% `theorem' or `amsthm' packages---provided, of course, that these are
+% loaded first.
+% \begin{macrocode}
+\let\sr@newtheorem=\newtheorem
+% \end{macrocode}
+%
+% The following is based on the +amsthm+ package. The routines just
+% parse the various forms of +\newtheorem+ with two possible optional
+% argument forms and a starred form (+amsthm+ only). Having gathered
+% up the arguments, they call the remembered original +\newtheorem+ and
+% then add a call to +\refname+ to the newly defined environment.
+% \begin{macrocode}
+\def\newtheorem{\@ifstar{\sr@xnthm*}{\sr@xnthm\relax}}
+%
+\def\sr@oparg#1[#2]{\@ifnextchar[{#1}{#1[#2]}}
+%
+\def\sr@unthm#1#2{\sr@newtheorem*{#1}{#2}}
+%
+\def\sr@xnthm#1#2{%
+ \let\sr@t\relax
+ \ifx *#1% Handle the amsthm starred form of \newtheorem
+ \def\sr@t{\sr@unthm{#2}}%
+ \else
+ \def\sr@t{\sr@oparg{\sr@ynthm{#2}}[]}%
+ \fi
+ \sr@t
+}
+%
+\def\sr@ynthm#1[#2]#3#4{%
+ \ifx\relax#2\relax
+ \def\sr@t{\sr@oparg{\sr@xthm{#1}{#3}{#4}}[]}%
+ \else
+ \let\sr@t=\relax
+ \sr@newtheorem{#1}[#2]{#3}
+ \refname{#1}{#3}{#4}
+ \expandafter\let\expandafter\sr@th\csname #1\endcsname
+ \expandafter\let\csname sr@th@#1\endcsname\sr@th
+ \let\sr@th\relax
+ \expandafter\def\csname #1\endcsname{
+ \expandafter\def\csname sr@nm@#2\endcsname{\xdef\sr@name{#1}}
+ \csname sr@th@#1\endcsname
+ }
+ \fi
+ \sr@t
+}
+%
+\def\sr@xthm#1#2#3[#4]{
+ \ifx\relax#4\relax
+ \sr@newtheorem{#1}{#2}
+ \refname{#1}{#2}{#3}
+ \else
+ \sr@newtheorem{#1}{#2}[#4]
+ \refname{#1}{#2}{#3}
+ \fi
+}
+%</package>
+% \end{macrocode}
+%
+% \pagebreak
+%\section{The documentation driver}
+% This will generate the documentation root file.
+% \begin{macrocode}
+%<*driver>
+\documentclass{article}
+\usepackage{doc}
+\OnlyDescription
+\setlength{\parindent}{0pt}
+\begin{document}
+\DocInput{saferef.dtx}
+\PrintIndex
+\PrintChanges
+\end{document}
+%</driver>
+% \end{macrocode}