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