Commit | Line | Data |
---|---|---|
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 |