From: Mark Wooding Date: Mon, 9 Apr 2007 17:57:59 +0000 (+0100) Subject: mdwref: New package for typesetting cross-references automagically. X-Git-Tag: 1.8.0~16^2 X-Git-Url: https://git.distorted.org.uk/~mdw/mdwtools/commitdiff_plain/e8f3554e4772f35bf1a7df96839bc2aeb3f0e028 mdwref: New package for typesetting cross-references automagically. --- diff --git a/Makefile.m4 b/Makefile.m4 index fd88bc8..f52c85c 100644 --- a/Makefile.m4 +++ b/Makefile.m4 @@ -34,7 +34,7 @@ pkgdocdir = ${texmfdir}/doc/latex/${PACKAGE} define(`addsuffix', `patsubst(`$1', `\>', `$2')') define(`BASE', `\ at centre cmtt colour crypto doafter exercise footnote mdwkey \ - mdwlist mdwmath mdwtab mdwthm poetry slowbox sverb syntax') + mdwlist mdwmath mdwref mdwtab mdwthm poetry slowbox sverb syntax') AUX = mdwtools.tex gpl.tex SRC = addsuffix(BASE, `.dtx') @@ -52,6 +52,7 @@ OBJ = \ mdwkey.sty \ mdwlist.sty \ mdwmath.sty \ + mdwref.sty \ mdwtab.sty mathenv.sty mtcolour.sty mtcolor.sty \ mdwthm.sty mdwmargin.thm \ poetry.sty \ diff --git a/mdwref.dtx b/mdwref.dtx new file mode 100644 index 0000000..f1da45c --- /dev/null +++ b/mdwref.dtx @@ -0,0 +1,237 @@ +% \begin{meta-comment} +% +% $Id: mdwref.dtx,v 1.3 2003/11/10 14:43:48 mdw Exp $ +% +% Slightly fancy cross-referencing stuff +% +% (c) 2007 Mark Wooding +% +% \end{meta-comment} +% +% \begin{meta-comment} +%% +%% mdwref package -- slightly fancy cross-referencing stuff +%% Copyright (c) 2007 Mark Wooding +%% +%% This program is free software; you can redistribute it and/or modify +%% it under the terms of the GNU General Public License as published by +%% the Free Software Foundation; either version 2 of the License, or +%% (at your option) any later version. +%% +%% This program is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%% GNU General Public License for more details. +%% +%% You should have received a copy of the GNU General Public License +%% along with this program; if not, write to the Free Software +%% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +%% +% \end{meta-comment} +% +% \begin{meta-comment} +%<+package>\NeedsTeXFormat{LaTeX2e} +%<+package>\ProvidesPackage{mdwref} +%<+package> [2007/04/09 1.01 Cross-referencing] +% \end{meta-comment} +% +% ^^A\CheckSum{96} +%% \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 \~} +%% +% +% \begin{meta-comment} +% +%<*driver> +\input{mdwtools} +\describespackage{mdwref} +\usepackage{mdwtab} +\mdwdoc +% +% +% \end{meta-comment} +% +%^^A------------------------------------------------------------------------- +% +% \section{User guide} +% +% I always name my cross-reference labels with a prefix telling me what kind +% of thing they are. A figure might be |fig:foo| or a table |tab:bar|. When +% I refer to the thing, then, I basically have to repeat myself: +% `|see table~\ref{tab:bar}|'. Kinda silly. +% +% \DescribeMacro\xref +% The |\xref| command understands my prefixing system. I can say +% `|\xref{tab:bar}|' and it inserts a reference to `table~4', for example. +% This is, of course, useless if you want to put the reference at the +% beginning of a sentence: `Table~4 shows\dots'. +% \DescribeMacro\Xref +% The |\Xref| command (note the initial capital) handles this properly, so +% you just type `|\Xref{tab:bar} shows|\dots'. +% +% The full syntax of the |\xref| command is like this. +% \begin{grammar} +% ::= \[[ +% "\\xref" +% \[ "[" "]" \] +% "{" "}" +% \]] +% \end{grammar} +% The optional \ argument is a command to be applied to the generated +% text: it \emph{must} be a single token. Rather than printing `table', or +% whatever, it prints \syntax{"{table}"}. +% The most obvious application of this is the |\Xref| command, which uses a +% helper |\toupper|. +% \DescribeMacro\toupper +% The call \syntax{"\\toupper{""}"} typesets \ with the first +% character in uppercase. So |\Xref| is defined simply as\footnote{Modulo +% the fact that the author is a dreadful \TeX\ hacker.} +% \begin{listing} +%\newcommand{\Xref}[1]{\xref[\toupper]{#1}} +% \end{listing} +% +% All that remains is to define the strings to be typeset for various kinds +% of labels. +% \DescribeMacro\defxref +% For this, we use the |\defxref| command: +% \begin{grammar} +% ::= \[[ +% "\\defxref" +% "{" "}" +% "{" "}" +% \]] +% \end{grammar} +% The \ is what you put on the front of your labels; the \ is +% the string to be typeset by |\xref|. +% +% A number of useful prefixes are already defined, following my usual +% preferences; they're shown in \xref{tab:defs}. +% \begin{table} +% \def\i#1#2{\texttt{#1}&\texttt{#2}\\} +% \begin{tabular}[C]{ll} \hlx*{hv} +% \textbf{Prefix} & \textbf{Text} \\ \hlx{vhv} +% \csname xref@defs\endcsname +% \hlx*{vh}\end{tabular} +% \caption{Predefined reference prefixes} +% \label{tab:defs} +% \end{table} +% +% \implementation +% \section{Implementation} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% The following quark will be useful. +% \begin{macrocode} +\def\q@delim{\q@delim} +% \end{macrocode} +% +% \begin{macro}{\defxref} +% Defining prefixes is easy. We store the text for each prefix in a macro +% called \syntax{"\\xref$"}. The only catch is that, for the +% purposes of generating \xref{tab:defs}, we maintain a list of the prefixes +% which have been defined so far, but this is fairly easy. +% \begin{macrocode} +\def\defxref#1#2{% + \toks@\expandafter{\xref@defs\i{#1}{#2}}\xdef\xref@defs{\the\toks@}% + \expandafter\def\csname xref$#1\endcsname{#2}% +} +% \end{macrocode} +% The list is obviously empty initially. +% \begin{macrocode} +\gdef\xref@defs{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\xref} +% We're meant to typeset a reference. The first job is to see whether +% there's an optional argument. If so, grab it; otherwise |\relax| will do. +% \begin{macrocode} +\def\xref{\@ifnextchar[\xref@{\xref@[\relax]}} +\def\xref@[#1]#2{\xref@@{#1}#2:\q@delim:\q@delim:\q@delim\q@delim} +% \end{macrocode} +% Right; now we abuse \TeX's argument parser to pick apart the reference +% label, which ought to have the form \syntax{":"}. +% \begin{macrocode} +\def\xref@@#1#2:#3:\q@delim#4\q@delim\q@delim{% +% \end{macrocode} +% So, |#1| is the optional command, or |\relax|. |#2| should be the +% prefix, and |#3| the suffix. However, if the string doesn't have any +% colons in, then |#3| will be |\q@delim|. This is easy to check for using +% |\ifx|. +% \begin{macrocode} + \def\@tempa{#2}\def\@tempb{#3}% + \ifx\@tempb\q@delim% + \PackageError{xref}{Bad ref syntax}% + \else% + \expandafter\let\expandafter\@tempa\csname xref$#2\endcsname% + \ifx\@tempa\relax% + \PackageError{xref}{Unknown ref kind `#2'}% + \else% + \toks@{#1}\toks\tw@\expandafter{\@tempa}% + \edef\next@{\the\toks@{\the\toks\tw@}}% + \next@~\ref{#2:#3}% + \fi% + \fi% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\toupper} +% That's the difficult stuff done. Uppercasing is a matter of picking out +% the first letter and passing it to \TeX's |\uppercase| primitive. +% \begin{macrocode} +\def\toupper#1{\toupper@#1} +\def\toupper@#1{\uppercase{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\Xref} +% As promised, |\Xref| is very easy. +% \begin{macrocode} +\def\Xref{\xref[\toupper]} +% \end{macrocode} +% \end{macro} +% +% Now all that remains is to initialize the table of prefix strings. +% \begin{macrocode} +\defxref{ch}{chapter} +\defxref{app}{appendix} +\defxref{sec}{section} +\defxref{def}{definition} +\defxref{th}{theorem} +\defxref{lem}{lemma} +\defxref{prop}{proposition} +\defxref{cor}{corollary} +\defxref{fig}{figure} +\defxref{tab}{table} +\defxref{eq}{equation} +\defxref{i}{item} +\defxref{ex}{exercise} +% \end{macrocode} +% And we're done! +% \begin{macrocode} +% +% \end{macrocode} +% \nopagebreak +% +% \hfill Mark Wooding, \today +% +% \Finale +% +\endinput diff --git a/mdwtools.ins b/mdwtools.ins index 0ad6ac2..e842fca 100644 --- a/mdwtools.ins +++ b/mdwtools.ins @@ -81,6 +81,7 @@ IMPORTANT NOTICE \mdwf {exercise.sty} {\from {exercise.dtx} {package}} \mdwf {slowbox.sty} {\from {slowbox.dtx} {package}} \mdwf {mdwmargin.thm} {\from {mdwthm.dtx} {thmstyle}} + \mdwf {mdwref.sty} {\from {mdwref.dtx} {package}} \mdwf {poetry.sty} {\from {poetry.dtx} {package}} }