chiark / gitweb /
Fix dates and version numbers in the package files.
[mdwtools] / mdwref.dtx
1 % \begin{meta-comment} <general public licence>
2 %%
3 %% mdwref package -- slightly fancy cross-referencing stuff
4 %% Copyright (c) 2007, 2019 Mark Wooding
5 %%
6 %% This program is free software; you can redistribute it and/or modify
7 %% it under the terms of the GNU General Public License as published by
8 %% the Free Software Foundation; either version 2 of the License, or
9 %% (at your option) any later version.
10 %%
11 %% This program is distributed in the hope that it will be useful,
12 %% but WITHOUT ANY WARRANTY; without even the implied warranty of
13 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 %% GNU General Public License for more details.
15 %%
16 %% You should have received a copy of the GNU General Public License
17 %% along with this program; if not, write to the Free Software
18 %% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 %%
20 % \end{meta-comment}
21 %
22 % \begin{meta-comment} <Package preambles>
23 %<+package>\NeedsTeXFormat{LaTeX2e}
24 %<+package>\ProvidesPackage{mdwref}
25 %<+package>                [2020/09/06 1.14.0 Cross-referencing]
26 % \end{meta-comment}
27 %
28 % ^^A\CheckSum{96}
29 %% \CharacterTable
30 %%  {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
31 %%   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
32 %%   Digits        \0\1\2\3\4\5\6\7\8\9
33 %%   Exclamation   \!     Double quote  \"     Hash (number) \#
34 %%   Dollar        \$     Percent       \%     Ampersand     \&
35 %%   Acute accent  \'     Left paren    \(     Right paren   \)
36 %%   Asterisk      \*     Plus          \+     Comma         \,
37 %%   Minus         \-     Point         \.     Solidus       \/
38 %%   Colon         \:     Semicolon     \;     Less than     \<
39 %%   Equals        \=     Greater than  \>     Question mark \?
40 %%   Commercial at \@     Left bracket  \[     Backslash     \\
41 %%   Right bracket \]     Circumflex    \^     Underscore    \_
42 %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
43 %%   Right brace   \}     Tilde         \~}
44 %%
45 %
46 % \begin{meta-comment}
47 %
48 %<*driver>
49 \input{mdwtools}
50 \describespackage{mdwref}
51 \usepackage{mdwtab}
52 \mdwdoc
53 %</driver>
54 %
55 % \end{meta-comment}
56 %
57 %^^A-------------------------------------------------------------------------
58 %
59 % \section{User guide}
60 %
61 % I always name my cross-reference labels with a prefix telling me what kind
62 % of thing they are.  A figure might be |fig:foo| or a table |tab:bar|.  When
63 % I refer to the thing, then, I basically have to repeat myself:
64 % `|see table~\ref{tab:bar}|'.  Kinda silly.
65 %
66 % \DescribeMacro\xref
67 % The |\xref| command understands my prefixing system.  I can say
68 % `|\xref{tab:bar}|' and it inserts a reference to `table~4', for example.
69 % This is, of course, useless if you want to put the reference at the
70 % beginning of a sentence: `Table~4 shows\dots'.
71 % \DescribeMacro\Xref
72 % The |\Xref| command (note the initial capital) handles this properly, so
73 % you just type `|\Xref{tab:bar} shows|\dots'.
74 %
75 % The full syntax of the |\xref| command is like this.
76 % \begin{grammar}
77 % <xref-command> ::= \[[
78 % "\\xref"
79 % \[ "[" <mangle> "]" \]
80 % "{" <reference> "}"
81 % \]]
82 % \end{grammar}
83 % The optional \<mangle> argument is a command to be applied to the generated
84 % text: it \emph{must} be a single token.  Rather than printing `table', or
85 % whatever, it prints \syntax{<mangle>"{table}"}.
86 % The most obvious application of this is the |\Xref| command, which uses a
87 % helper |\toupper|.
88 % \DescribeMacro\toupper
89 % The call \syntax{"\\toupper{"<stuff>"}"} typesets \<stuff> with the first
90 % character in uppercase.  So |\Xref| is defined simply as\footnote{Modulo
91 %   the fact that the author is a dreadful \TeX\ hacker.}
92 % \begin{listing}
93 %\newcommand{\Xref}[1]{\xref[\toupper]{#1}}
94 % \end{listing}
95 %
96 % \DescribeMacro\formatxref
97 % The reference itself is typeset by calling
98 % \syntax{"\\formatxref{"<mangle>"}{"<string>"}{"<label>"}"}, which can do as
99 % it pleases: the \<mangle> token is from the |\xref| invocation; the
100 % \<string> is category of thing being referred to (as established by
101 % |\defxref| below); and \<label> is the label, again from |\xref| .  The
102 % default behaviour is to print
103 % \syntax{<mangle>"{"<string>"}~\\ref{"<label>"}"}, but this can be
104 % overridden.
105 % (Not quite true: in fact, the default does something better if
106 % \package{hyperref} is detected, but the idea is basically the same.)
107 %
108 % All that remains is to define the strings to be typeset for various kinds
109 % of labels.
110 % \DescribeMacro\defxref
111 % For this, we use the |\defxref| command:
112 % \begin{grammar}
113 % <definition> ::= \[[
114 % "\\defxref"
115 % "{" <prefix> "}"
116 % "{" <string> "}"
117 % \]]
118 % \end{grammar}
119 % The \<prefix> is what you put on the front of your labels; the \<string> is
120 % the string to be typeset by |\xref|.
121 %
122 % A number of useful prefixes are already defined, following my usual
123 % preferences; they're shown in \xref{tab:defs}.
124 % \begin{table}
125 %   \def\i#1#2{\texttt{#1}&\texttt{#2}\\}
126 %   \begin{tabular}[C]{ll} \hlx*{hv}
127 %   \textbf{Prefix} & \textbf{Text} \\ \hlx{vhv}
128 %   \csname xref@defs\endcsname
129 %   \hlx*{vh}\end{tabular}
130 %   \caption{Predefined reference prefixes}
131 %   \label{tab:defs}
132 % \end{table}
133 %
134 % \implementation
135 % \section{Implementation}
136 %
137 %    \begin{macrocode}
138 %<*package>
139 %    \end{macrocode}
140 %
141 % The following quark will be useful.
142 %    \begin{macrocode}
143 \def\q@delim{\q@delim}
144 %    \end{macrocode}
145 %
146 % \begin{macro}{\defxref}
147 % Defining prefixes is easy.  We store the text for each prefix in a macro
148 % called \syntax{"\\xref$"<prefix>}.  The only catch is that, for the
149 % purposes of generating \xref{tab:defs}, we maintain a list of the prefixes
150 % which have been defined so far, but this is fairly easy.
151 %    \begin{macrocode}
152 \def\defxref#1#2{%
153   \toks@\expandafter{\xref@defs\i{#1}{#2}}\xdef\xref@defs{\the\toks@}%
154   \expandafter\def\csname xref$#1\endcsname{#2}%
155 }
156 %    \end{macrocode}
157 % The list is obviously empty initially.
158 %    \begin{macrocode}
159 \gdef\xref@defs{}
160 %    \end{macrocode}
161 % \end{macro}
162 %
163 % \begin{macro}{\formatxref}
164 % Output a cross-reference in the right way.
165 %    \begin{macrocode}
166 \def\formatxref#1#2#3{%
167   \ifx\hyperref\@@undefined #1{#2}~\ref{#3}%
168   \else \hyperref[#3]{#1{#2}~\ref*{#3}}\fi%
169 }
170 %    \end{macrocode}
171 % \end{macro}
172 %
173 % \begin{macro}{\xref}
174 % We're meant to typeset a reference.  The first job is to see whether
175 % there's an optional argument.  If so, grab it; otherwise |\relax| will do.
176 %    \begin{macrocode}
177 \def\xref{\@ifnextchar[\xref@{\xref@[\relax]}}
178 \def\xref@[#1]#2{\xref@@{#1}#2:\q@delim:\q@delim:\q@delim\q@delim}
179 %    \end{macrocode}
180 % Right; now we abuse \TeX's argument parser to pick apart the reference
181 % label, which ought to have the form \syntax{<prefix>":"<suffix>}.
182 %    \begin{macrocode}
183 \def\xref@@#1#2:#3:\q@delim#4\q@delim\q@delim{%
184 %    \end{macrocode}
185 % So, |#1| is the optional command, or |\relax|.  |#2| should be the
186 % prefix, and |#3| the suffix.  However, if the string doesn't have any
187 % colons in, then |#3| will be |\q@delim|.  This is easy to check for using
188 % |\ifx|.
189 %    \begin{macrocode}
190   \def\@tempa{#2}\def\@tempb{#3}%
191   \ifx\@tempb\q@delim%
192     \PackageError{xref}{Bad ref syntax}%
193   \else%
194     \expandafter\let\expandafter\@tempa\csname xref$#2\endcsname%
195     \ifx\@tempa\relax%
196       \PackageError{xref}{Unknown ref kind `#2'}%
197     \else%
198       \toks@\expandafter{\@tempa}%
199       \edef\next@##1{##1{\the\toks@}}%
200       \next@{\formatxref{#1}}{#2:#3}%
201     \fi%
202   \fi%
203 }
204 %    \end{macrocode}
205 % \end{macro}
206 %
207 % \begin{macro}{\toupper}
208 % That's the difficult stuff done.  Uppercasing is a matter of picking out
209 % the first letter and passing it to \TeX's |\uppercase| primitive.
210 %    \begin{macrocode}
211 \def\toupper#1{\toupper@#1}
212 \def\toupper@#1{\uppercase{#1}}
213 %    \end{macrocode}
214 % \end{macro}
215 %
216 % \begin{macro}{\Xref}
217 % As promised, |\Xref| is very easy.
218 %    \begin{macrocode}
219 \def\Xref{\xref[\toupper]}
220 %    \end{macrocode}
221 % \end{macro}
222 %
223 % Now all that remains is to initialize the table of prefix strings.
224 %    \begin{macrocode}
225 \defxref{ch}{chapter}
226 \defxref{app}{appendix}
227 \defxref{sec}{section}
228 \defxref{def}{definition}
229 \defxref{th}{theorem}
230 \defxref{lem}{lemma}
231 \defxref{prop}{proposition}
232 \defxref{cor}{corollary}
233 \defxref{fig}{figure}
234 \defxref{tab}{table}
235 \defxref{eq}{equation}
236 \defxref{i}{item}
237 \defxref{ex}{exercise}
238 %    \end{macrocode}
239 % And we're done!
240 %    \begin{macrocode}
241 %</package>
242 %    \end{macrocode}
243 % \nopagebreak
244 %
245 % \hfill Mark Wooding, \today
246 %
247 % \Finale
248 %
249 \endinput