From e94cc72c57a660f941e255ce8b3854ab00f7c76a Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 31 May 2007 18:42:38 +0000 Subject: new latex package cleveref (26may07) git-svn-id: svn://tug.org/texlive/trunk@4386 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/source/latex/cleveref/cleveref.dtx | 1559 ++++++++++++++++++++ .../texmf-dist/source/latex/cleveref/cleveref.ins | 34 + 2 files changed, 1593 insertions(+) create mode 100644 Master/texmf-dist/source/latex/cleveref/cleveref.dtx create mode 100644 Master/texmf-dist/source/latex/cleveref/cleveref.ins (limited to 'Master/texmf-dist/source') diff --git a/Master/texmf-dist/source/latex/cleveref/cleveref.dtx b/Master/texmf-dist/source/latex/cleveref/cleveref.dtx new file mode 100644 index 00000000000..995031bf2b5 --- /dev/null +++ b/Master/texmf-dist/source/latex/cleveref/cleveref.dtx @@ -0,0 +1,1559 @@ +% \iffalse meta-comment +% +% Package 'cleveref' to use with LaTeX2e +% Copyright 2007 by Toby Cubitt +% +% Written and maintained by Toby Cubitt +% +%% This file may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.2 +%% of this license or (at your option) any later version. +%% The latest version of this license is in: +%% +%% http://www.latex-project.org/lppl.txt +%% +%% and version 1.2 or later is part of all distributions of LaTeX +%% version 1999/12/01 or later. +% +% Please send bugreports and suggestions to toby-cleveref@dr-qubit.org +% \fi +% +% \iffalse +%\NeedsTeXFormat{LaTeX2e}[1999/12/01] +%\ProvidesPackage{cleveref} +% [2007/26/04 v0.4 Automatic cross-reference formatting] +% +%<*driver> +\documentclass[draft]{ltxdoc} +\usepackage{url} +\usepackage{cleveref} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +%%\newcommand{\package}[1]{\texttt{#1.sty}} +%\newcommand{\package}[1]{\texttt{#1}} +\newcommand{\package}[1]{\texttt{#1}} +\newcommand{\file}{\texttt} +\newcommand{\option}{\texttt} +\makeatletter +%% Command for writing code descriptions +\def\packeddescr{% + \begin{list}{}{\leftmargin0.5cm + \labelwidth\z@\itemindent-\leftmargin + \topsep=0pt\itemsep=0.05cm\parsep=0.05cm +% \let\makelabel\nlabel + }} +\def\endpackeddescr{\end{list}} +%% Commands for referring to code lines +\def\codelabel#1{\@bsphack + \protected@write\@auxout{}{\string\newlabel{#1}{{\number\the + \c@CodelineNo}{\thepage}}}\@esphack} +\newcounter{tmpcount} +\def\coderef#1#2{\setcounter{tmpcount}{0}\@ifundefined{r@#1}\relax + {\setcounter{tmpcount}{\ref{#1}}}\relax + \addtocounter{tmpcount}{#2}\arabic{tmpcount}} +\makeatother +\begin{document} + \DocInput{cleveref.dtx} +\end{document} +% +% \fi +% +% \CheckSum{1405} +%% \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 \~} +% +% \changes{v0.1}{2006/29/06}{Initial version} +% \changes{v0.2}{2007/18/04}{Complete rewrite} +% \changes{v0.3}{2007/26/04}{Added reference ranges} +% \changes{v0.4}{2007/26/04}{Renamed "cleveref"} +% +% \GetFileInfo{cleveref.sty} +% +% \def\fileversion{0.4} +% \def\filedate{26/05/2007} +% +% \title{The \textsf{cleveref} package\thanks{This document +% corresponds to \textsf{cleveref}~\fileversion, dated +% \filedate.}} +% \author{Toby Cubitt \\ \texttt{toby-cleveref@dr-qubit.org}} +% \date{\filedate} +% +% \maketitle +% +% \begin{abstract} +% The \package{cleveref} package enhances \LaTeX{}'s +% cross-referencing features, allowing the format of references to +% be determined automatically according to the type of reference +% (equation, section, etc.). The formatting for each reference type +% can be fully customised in the preamble of your document. In +% addition, \package{cleveref} can typeset references to lists of +% multiple labels, automatically formatting them according to their +% type, and collapsing sequences of numerically consecutive labels +% to a reference range. Again, the multiple-reference formatting is +% fully customisable. +% \end{abstract} +% +% \section{Introduction} +% +% When ``clever'' is used in the name of a computer program, it +% usually signifies that the programmer is overly smug! Or, to take a +% more charitable attitude, that the programmer is pleased with the +% sophisticated processing that he has managed to encapsulate in code, +% relieving the user of some complicated by tedious task. On the other +% hand, at the heart of the \LaTeX philosophy is the idea that it is +% clever to delegate as much of the typesetting as possible to the +% computer, in order to achieve a beautiful, but above all consistent, +% visual appearance. +% +% Both these points of view are valid with respect to the +% \package{cleveref} package. It's goals are two-fold: to use the +% information that \LaTeX inherently has about labels as +% intelligently as possible in order to type-set references to them +% (clever processing); and to enable you to produce an attractive, +% consistent formatting of references throughout your document, with +% the minimum of effort (you'd be clever to use it!). +% +% The \package{cleveref} package enhances \LaTeX's cross-referencing +% facility by allowing references to be formatted automatically +% according to the type of object they refer to (chapter, section, +% equation, theorem, etc.). It can also automatically format +% references to multiple labels. +% +% In standard \LaTeX, you have almost certainly found yourself +% writing things like |Eq.~(\ref{eq1})| and |Theorem~\ref{thm1}| over +% and over again. This isn't just tedious. What happens if you later +% decide you want equation references to be typeset as +% |Equation~\ref{eq1}| instead? What happens if you decide to change +% the theorem labelled |thm1| into a lemma? You have to search +% through the entire \LaTeX source of your document, modifying all +% references to equations, or changing all references to |thm1|. +% +% \package{cleveref} allows you to define the format for references +% once-and-for-all in the preamble of your document. If you later +% decide to change the typesetting of equation references, you only +% have to change one preamble definition. If you later decide to +% change a theorem into a lemma, you don't need to change any +% references at all, because \package{cleveref} will automatically +% typeset references to it using the appropriate formatting. This +% makes it far easier to typeset references uniformly across your +% whole document, as well as saving repetitively typing the same text +% for each and every reference. +% +% A number of other packages provide similar features, most notably +% \package{varioref}, \package{fancyref} and (for theorem-like +% environments) \package{ntheorem} (with the \option{thref} +% option). However, all have certain deficiencies which +% \package{cleveref} attempts to overcome. +% +% The \package{fancyref} package doesn't automatically determine the +% type of object being referred to. Instead, it relies on you adhering +% to a naming convention for labels. This is usually a good idea in +% any case, but it can be inconvenient. For example, if you change a +% theorem into a lemma, you have to change the label name, and +% therefore also all references to it. So you are back to searching +% and replacing through the entire document. +% +% The enhanced referencing feature provided by the \package{varioref} +% package decides how to format references when the label is +% \emph{defined}, rather than when it is \emph{referenced}. Most of +% the time, this isn't a problem. But it makes it impossible to format +% references differently according the context in which they are +% referenced, which can sometimes be very useful. For example, if you +% want references at the beginning of a sentence formatted any other +% way than by capitalising the first letter of the reference text, it +% is impossible using \package{varioref}. Perhaps even more +% significantly, it makes it impossible to typeset multiple references +% automatically; you are back typesetting +% |Eqs.~(\ref{eq1}) and~(\ref{eq2})| or +% |Eqs.~(\ref{eq1})--(\ref{eq3})| by hand. +% +% The \package{ntheorem} package (with the \option{thref} option) does +% things right\ldots except that it only works for theorem-like +% environments. It is possible to use it for other environments, but +% only in a bastardized form, by manually supplying an optional +% argument to |\label| commands telling it the label +% type. \package{cleveref} essentially extends the \package{ntheorem} +% theorem referencing feature to work for all objects. (Although the +% implementation details differ, and \package{cleveref} can be used +% independently of \package{ntheorem}.) \package{cleveref} provides a +% number extra features too, such as multiple references, automatic +% collapsing of reference ranges, and control over the placement of +% hyper-links. +% +% +% +% \section{Usage} +% +% The \package{cleveref} package is loaded in the usual way, by +% putting the line +% \begin{quote} +% |\usepackage{cleveref}| +% \end{quote} +% in your document's preamble. However, care must be taken when using +% \package{cleveref} in conjunction with other packages that modify +% \LaTeX's referencing system (see +% \cref{sec:other_packages}). +% +% +% \subsection{Typesetting References} +% +% \DescribeMacro\cref +% To automatically typeset a reference according to the type of object +% referred to, simply refer to it using |\cref{|\meta{label}|}|. +% \package{cleveref} imposes just one restriction on the names of +% labels: they are no longer allowed to contain commas ``,''. These +% can instead be used to typeset multiple references (see below). +% +% \DescribeMacro\Cref +% As it is very difficult for \LaTeX to determine whether a +% reference appears at the beginning of a sentence or not, a +% capitalised version exists: |\Cref{|\meta{label}|}|. By default, +% this typesets the reference with the first letter capitalised, +% though the formatting of the |\cref| and |\Cref| forms can be +% customised independently (see \cref{sec:customising}). +% +% \DescribeMacro\ref +% \package{cleveref} does \emph{not} modify the standard |\ref| +% command\footnote{This is not quite true. The original \cmd{\ref} +% command no longer works when \package{cleveref} is loaded, so +% \package{cleveref} redefines it to recover the correct +% behaviour.}, so you can still use it to typeset the formatted +% label counter alone, without any additional text or formatting. If +% you would like to use \package{cleveref}'s enhanced features, but +% want to continue to use |\ref| for referencing, simply redefine the +% |\ref| command in your document's preamble, thus: +% \begin{quote} +% |\renewcommand{\ref}{\cref}| +% \end{quote} +% Similarly, if you decide you would like all references capitalised, +% you can redefine the |\cref| command: +% \begin{quote} +% |\renewcommand{\cref}{\Cref}| +% \end{quote} +% +% \DescribeMacro\crefrange +% \DescribeMacro\Crefrange +% To typeset a reference range, e.g. |Eqs.~(1.1)--(1.5)|, use +% |\crefrange| or |\Crefrange| (depending on the capitalisation you +% require), which take the beginning and end of the range as +% arguments: +% \begin{quote} +% |\crefrange{|\meta{label1}|}{|\meta{label2}|}| +% \end{quote} +% +% \DescribeMacro\cref +% \DescribeMacro\Cref +% To typeset multiple references, simply list the lables inside the +% |\cref| or |\Cref| command, separated by commas (you are not allowed +% to use commas in label names when using \package{cleveref}): +% \begin{quote} +% |\cref{|\meta{label1}|,|\meta{label2}|,|\meta{label3}|,...}| +% \end{quote} +% The references will be typeset in the order in which they appear in +% the list, and sequences of consecutive references will be collapsed +% into a reference range. It is up to you to put the labels in the +% order you require. This is especially significant if the labels +% refer to different types of object, or to consecutive sequences of +% labels. For example, if |eq*| are equation labels, and |thm*| are +% theorem labels, +% \begin{quote} +% |\cref{eq1,eq2,eq3,thm1,thm2}| +% \end{quote} +% will be typeset as +% \begin{quote} +% Eqs.~(1)--(3), and Theorems~1 and~2 +% \end{quote} +% whereas +% \begin{quote} +% |\cref{eq1,eq2,thm1,thm2,eq3}| +% \end{quote} +% will be typeset as +% \begin{quote} +% Eqs.~(1) and~(2), Theorems~1 and~2, and Eq.~(3) +% \end{quote} +% +% +% \subsection{Customising the Reference Formats} +% \label{sec:customising} +% +% \subsubsection{Single References} +% \label{sec:ref_format} +% The \package{cleveref} package allows you to take full control of +% the typesetting of references. Defaults appropriate for English +% documents are provided for the standard reference types. But if you +% don't like them, or are writing in a different language, or you are +% using an environment for which no default format is defined, you +% will need to define your own. +% +% If \package{cleveref} encounters a reference to a type it does not +% know, it will produce a ``reference type undefined'' warning, and +% typeset the reference as +% \begin{quote} +% {\bf ??}~|\ref{|\meta{label}|}| +% \end{quote} +% i.e.\ it will typeset the reference as the label counter preceded by +% a double question mark. References to undefined labels still produce +% a ``reference undefined'' warning and are typeset as a double +% question mark, as usual. +% +% \DescribeMacro\crefformat +% \DescribeMacro\Crefformat +% Reference formats for \emph{single} references are defined or +% redefined using the |\crefformat| and |\Crefformat| commands, which +% are used by the |\cref| and |\Cref| commands respectively. These +% take two arguments: the reference type, and the formatting code: +% \begin{quote} +% |\crefformat{|\meta{type}|}{|\meta{format}|}|\\ +% |\Crefformat{|\meta{type}|}{|\meta{format}|}| +% \end{quote} +% +% If the corresponding |\Crefformat| is undefined when |\crefformat| +% is called, it will define the |\Crefformat| to produce a capitalised +% version of |\crefformat|, using |\MakeUppercase|. Conversely, if the +% corresponding |\crefformat| is undefined whe |\Crefformat| is +% called, if will define the |\Crefformat| to produce a lower-case +% version of |\Crefformat|, using |\MakeLowercase|. Obviously, this +% will only work properly if the formats have a letter at the +% start. If the first letter is a special construct, such as an +% accented character, you will need to surround everything whose case +% should be changed by braces. If the first thing in the format is not +% a letter (e.g.\ if it is a \LaTeX command, or a hyper-link +% argument, see below), you will get strange and fatal errors when +% processing the document. +% +% The reference \meta{type} is usually the name of the counter for the +% environment (equation, chapter, section, etc.). Currently, the only +% exception is theorem-like environments when the \package{ntheorem} +% package is loaded, for which \meta{type} should instead be the +% environment name (lemma, corollary, definition, etc.). This is +% because \package{ntheorem} allows different theorem-like +% environments to use a common counter. +% +% The \meta{format} argument can be any valid \LaTeX code, though +% you will need to |\protect| fragile commands. It can (and almost +% certainly should!) contain three arguments, |#1|, |#2| and |#3|. The +% first argument is the formatted version of the label counter (e.g.\ +% |\theequation|). The other two are used to mark the beginning and +% end of the part of the reference that should form the hyper-link +% when the \package{hyperref} package is used (see +% \cref{sec:other_packages}). The hyper-link arguments |#2| and |#3| +% \emph{must} appear in that order. Leaving them out completely will +% not cause an error, but will mean that no hyper-link will be created +% when \package{hyperref} is used. +% +% As an example, +% \begin{quote} +% |\crefformat{equation}{Eq.~(#2#1#3)}| +% \end{quote} +% will typeset equation references as +% \begin{quote} +% Eq.~(\meta{counter}) +% \end{quote} +% with the counter (excluding the brackets) forming the hyper-links. +% Note that the hyper-link arguments are \emph{not} letters, so if you +% want to make the ``Eq.'' part of the hyper-link by putting |#2| at +% the start of the formatting code, you will have to define both +% capitalisation variants independently: +% \begin{quote} +% |\crefformat{equation}{#2eq.~(#1)#3}|\\ +% |\Crefformat{equation}{#2Eq.~(#1)#3}| +% \end{quote} +% +% +% \subsubsection{Reference Ranges} +% \label{sec:ref_range_format} +% \DescribeMacro\crefrangeformat +% \DescribeMacro\Crefrangeformat +% The format for reference ranges is defined by |\crefrangeformat| +% and\linebreak[4] |\Crefrangeformat|. You do not have to define it if +% you don't plan to use any reference ranges, i.e. you never use the +% |\crefrange| and |\Crefrange| commands, and you never use multiple +% references (see \cref{sec:multiple_ref_format}). However, you will +% get ``reference format undefined'' errors if you later change your +% mind and forget to define the format. Like |\creformat| and +% |\Crefformat|, the commands take two arguments: the reference type, +% and the formatting code. +% \begin{quote} +% |\crefrangeformat{|\meta{type}|}{|\meta{format}|}|\\ +% |\Crefrangeformat{|\meta{type}|}{|\meta{format}|}| +% \end{quote} +% The same comments apply: the \meta{type} is usually the name of the +% counter, except for theorem-like environments, and if the +% corresponding other-capitalisation variant is not already defined, +% it will be defined automatically. +% +% The \meta{format} argument can again be any valid \LaTeX code, +% with fragile commands |\protect|ed. However, this time it should +% contain \emph{six} arguments, |#1|--|#6|. The first two (|#1| and +% |#2|) are the formatted versions of the label counters, the next two +% (|#3| and |#4|) are used to mark the beginning and end of the +% hyper-link for the first reference (|#1|), and the final two (|#5| +% and |#6|) mark the beginning and end of the second reference's +% hyper-link. +% +% As an example, +% \begin{quote} +% |\crefrangeformat{equation}{Eqs.~(#3#1#4)--(#5#2#6)}| +% \end{quote} +% will typeset equation reference ranges as +% \begin{quote} +% Eqs.~(\meta{counter1})--(\meta{counter2}) +% \end{quote} +% with the counters (excluding the brackets) forming the hyper-links. +% +% +% \subsubsection{Multiple References} +% \label{sec:multiple_ref_format} +% \DescribeMacro\crefmultiformat +% \DescribeMacro\Crefmultiformat +% \DescribeMacro\crefrangemultiformat +% \DescribeMacro\Crefrangemultiformat +% The format for multiple references is defined by |\crefmultiformat| +% and\linebreak[4] |\Crefmultiformat|, and that of reference ranges +% within multiple references by |\crefrangemultiformat| and +% |\Crefrangemultiformat|. If you don't use any multiple references +% for a particular reference type, you are not obliged to define the +% multi-formats. However, you will get ``reference format undefined'' +% errors if you later decide to use a multiple reference without +% ensuring the multi-formats are defined. You will also need to define +% \emph{all} the other reference formats (see +% \cref{sec:ref_format,sec:ref_range_format}), including the reference +% range formats, even if you never use the |\crefrange| and +% |\Crefrange| commands. +% +% The commands all take four arguments: the reference type, the format +% for the first reference in a list, the format for the middle +% references in a list, and the format for the last reference in a +% list. +% \begin{quote} +% |\crefmultiformat{|\meta{type}|}{|\meta{first}|}{|\meta{middle}|}{|\meta{last}|}|\\ +% |\Crefmultiformat{|\meta{type}|}{|\meta{first}|}{|\meta{middle}|}{|\meta{last}|}|\\ +% |\crefrangemultiformat{|\meta{type}|}{|\meta{first}|}{|\meta{middle}|}{|\meta{last}|}|\\ +% |\Crefrangemultiformat{|\meta{type}|}{|\meta{first}|}{|\meta{middle}|}{|\meta{last}|}| +% \end{quote} +% +% The same considerations apply to the \meta{type} and formatting +% arguments \meta{first}, \meta{middle} and \meta{last} as for the +% \meta{format} argument of |\crefformat| and |\Crefformat| or +% |\crefrangeformat| and |\Crefrangeformat|, including the meaning of +% the arguments that should appear in the formatting code. However, +% when the corresponding other-capitalisation variant is automatically +% defined, only the first letter of the \meta{first} argument is +% upper- or lower-cased. +% +% Be careful to get the spaces at the beginning and end of the +% formatting code correct: the \meta{first}, \meta{middle} and +% \meta{last} \LaTeX code is typeset one after another in a +% multi-reference, with no space separating them. You may or may not +% want spaces at the beginning and end of the formatting code, +% depending on the formatting you desire. For example, with the +% default format +% \begin{quote} +% |\crefmultiformat{equation}%|\\ +% |{Eqs.~(#2#1#3)}{, (#2#1#3)}{ and~(#2#1#3)}|\\ +% \end{quote} +% the \meta{middle} arguments should \emph{not} have a space at the +% beginning, whereas the \meta{last} arguments \emph{should} have a +% space. +% +% \DescribeMacro{\crefmiddleconjunction} +% \DescribeMacro{\creflastconjunction} +% The |\crefmiddleconjunction| and |\creflastconjunction| commands are +% used in between sub-lists of different types of references that +% occur in a multiple reference. If there are two or more reference +% types in the list, |\creflastconjunction| is used between the +% penultimate and final group of references, whereas +% |\crefmiddleconjunction| is used between all others. You can +% redefine them with |\renewcommand| in the usual way: +% \begin{quote} +% |\renewcommand{\crefmiddleconjunction}{|\meta{conjunction}|}|\\ +% |\renewcommand{\creflastconjunction}{|\meta{conjunction}|}| +% \end{quote} +% For example, if |eq*|, |thm*| and |fig*| are respectively equation, +% theorem and figure labels, +% \begin{quote} +% |\cref{eq1,eq2,eq3,thm1,thm2,fig1,thm3}| +% \end{quote} +% is typeset (assuming the default |\crefformat|s) as +% \begin{quote} +% Eqs.~(1)--(3)|\crefmiddleconjunction| Theorems~1\\ +% and~2|\crefmiddleconjunction| Fig.~1|\creflastconjunction| +% Theorem~3 +% \end{quote} +% +% +% \section{Interaction with Other Packages} +% \label{sec:other_packages} +% Since \package{cleveref} redefines many internal commands involved +% in \LaTeX's referencing system, it can interact badly with other +% packages that do the same. In general, \package{cleveref} should be +% loaded \emph{last}, and the appropriate options must be supplied if +% the \package{hyperref} and/or \package{ntheorem} packages are also +% used. E.g. +% \begin{quote} +% |\usepackage{hyperref}|\\ +% |\usepackage[hyperref]{cleveref}| +% \end{quote} +% or +% \begin{quote} +% |\usepackage{ntheorem}|\\ +% |\usepackage[ntheorem]{cleveref}| +% \end{quote} +% or +% \begin{quote} +% |\usepackage{hyperref}|\\ +% |\usepackage[hyperref]{ntheorem}|\\ +% |\usepackage[hyperref,ntheorem]{cleveref}| +% \end{quote} +% +% \package{varioref}'s enhanced referencing features (which you make +% use of by via the |\labelformat| command), the \package{fancyref} +% package, and \package{ntheorem}'s \option{thref} option are +% incompatible with \package{cleveref}. However, since +% \package{cleveref} implements an enhanced version of these features, +% this is not really a problem. For example, if you have a +% pre-existing document that uses \package{ntheorem}'s |\thref| +% command, you can simply redefine it to call |\cref| instead: +% \begin{quote} +% |\renewcommand{\thref}{\cref}| +% \end{quote} +% Note that you can still use the other features of \package{varioref} +% and \package{ntheorem} whilst using \package{cleveref}. +% +% Other packages which alter the \LaTeX referencing system are +% unlikely to work properly with \package{cleveref}. +% +% +% \section{Known Bugs} +% \begin{itemize} +% \item \package{cleveref} will not work properly with the standard +% \LaTeX |eqnarray| environment. The |eqnarray| environment is +% poorly implemented, making it somewhat difficult to get it to work +% properly with \package{cleveref}. You're better off using the +% \package{amsmath} replacements in any case, such as |gather|, +% |align|, |multine| and |split|, which \emph{do} work properly with +% \package{cleveref}. (See +% \url{http://www.tug.org/pracjourn/2006-4/madsen/}). +% \item \package{cleveref}'s referencing features currently may or may +% not work properly with references to list items. (This should be +% fixed in a future version.) +% \item \package{cleveref} breaks \package{hyperref}'s +% \option{backref} option, and probably also the \package{backref} +% package when used by itself. (This should be fixed in a future +% version.) +% \item \package{cleveref} assumes that counters are only ever reset +% by the standard sectioning commands (chapter, section, etc.). If +% this is not the case, the automatic collapsing of consecutive +% references into a reference range may be incorrect. +% \item \package{cleveref} provides no \package{babel} support. +% \end{itemize} +% +% +% \section{Future Improvements} +% \begin{itemize} +% \item Allow selective disabling of reference-range collapsing in +% multiple references, e.g.\ by the addition of an extra comma +% between the labels in the label list. +% \item Allow reference-range collapsing to be disabled entirely via a +% package option +% \item Implement a ``poor-man's'' \package{cleveref}, for situations +% in which you are able to install and use \package{cleveref} +% locally, but annother party can not (e.g.\ when submitting the +% \LaTeX source of a paper to a journal). When this option is set, +% \package{cleveref} would generate a sed or awk script through +% which the original source could be processed, generating a version +% of the source with all the \package{cleveref} references replaced +% by the text they would generate plus standard |\ref| commands. +% \end{itemize} +% +% +% +% \StopEventually{\PrintIndex} +% +% +% +% +% \section{Implementation} +% +% Essentially, the core of the implementation consists of causing an +% extra piece of information -- the label ``type'' -- to be written to +% the aux file, and defining an \cmd{\cref} command which uses this +% extra information to typeset the reference. +% +% The least invasive implementation seems to be that used by the +% \package{varioref} package. Namely, to redefine the +% \cmd{\refstepcounter} command so that the \cmd{\@currentlabel} +% macro, which usually just cotains the typeset version of the +% counter, now contains the additional information (in fact, we write +% three extra pieces of information: the type, the counter value +% itself, and the formatted version of the counter that causes the +% label's counter to be reset, which we call the ``prefix'' from now +% on). \cmd{\@currentlabel} eventually gets written to the aux file as +% an argument to \cmd{\newlabel} by the usual \LaTeX +% mechanisms. This involves less hacking to get everything else +% working again, since very few macros other than \cmd{\ref} use this +% particular \cmd{\newlabel} argument (nor are other packages likely +% to, given that \package{varioref} is a required package). +% +% +% \subsection{Redefinitions of \LaTeX kernel macros} +% We store the original \cmd{\refstepcounter} in +% \cmd{\old@refstepcounter}, then redefine \cmd{\refstepcounter} so +% that it first calls the old version and then adds the extra +% information to \cmd{\@currentlabel}. The new \cmd{\@refstepcounter} +% can take an optional argument, which overrides using the counter +% name as the ``type'' and instead uses whatever is supplied. +% \begin{macrocode} +\let\old@refstepcounter\refstepcounter +\def\refstepcounter% + {\@ifnextchar[{\refstepcounter@optarg}{\refstepcounter@noarg}}%] +\def\refstepcounter@noarg#1{% + \old@refstepcounter{#1}% + \reset@by{#1}{\@result}% + \ifx\@result\relax\def\@result{}% + \else\edef\@result{\csname the\@result\endcsname}\fi% + \protected@edef\@currentlabel{% + [#1][\arabic{#1}][\@result]\@currentlabel}} +\def\refstepcounter@optarg[#1]#2{% + \old@refstepcounter{#2}% + \reset@by{#2}{\@result}% + \ifx\@result\relax\def\@result{}% + \else\edef\@result{\csname the\@result\endcsname}\fi% + \protected@edef\@currentlabel{% + [#1][\arabic{#2}][\@result]\@currentlabel}} +% \end{macrocode} +% +% The standard \cmd{\ref} macro spits out whatever was in +% \cmd{\@currentlabel} when the label was written to the aux file, but +% this now contains the additional type information which we don't +% want. Therefore, we redefine \cmd{\cref} to recover the original +% behaviour. We have to defer redefinition of \cmd{\ref} till the +% beginning of the document, in case other packages (such as +% \package{ntheorem}) modify it after \package{cleveref} is loaded. +% \begin{macrocode} +\def\cref@label#1#2{\@result} +\AtBeginDocument{% + \def\ref#1{% + \expandafter\ifx\csname r@#1\endcsname\relax% + \let\@result\relax% + \else% + \cref@getlabel{#1}{\@result}% + \fi% + \expandafter\@setref\csname r@#1\endcsname{\cref@label}{#1}}% +} +% \end{macrocode} +% +% \subsection{Utility Macros} +% Define some utility macros for extracting label, type, and counter +% information from the contents of \cmd{\@currentlabel}, as written to +% the aux file and stored in \cmd{\r@\meta{label}} when this is re-read +% on the next pass. Some other packages commandeer the referencing +% system to write label information to the aux file for other +% purposes, and probably use \cmd{\ref} to recover it later. We still +% want them to work, so our utility macros must cope with the type +% information being absent. However, since we need them to be fully +% expandable in various places, and \cmd{\@ifnextchar} is definitely +% \emph{not} fully expandable, we use the work-around of having the +% macros store their result in another macro, whose name is passed as +% the second argument. This macro \emph{will} then be fully +% expandable, and can be used e.g.\ inside an \cmd{\edef} or +% \cmd{\csname}\ldots\cmd{\endcsname}. +% \begin{macrocode} +\def\cref@getlabel#1#2{% + \expandafter\let\expandafter\@tempa\csname r@#1\endcsname% + \edef\@tempa{\expandafter\@firstoftwo\@tempa}% + \expandafter\@cref@getlabel\@tempa\@nil#2} +\def\@cref@getlabel{\@ifnextchar[%] + \@@cref@getlabel{\@@cref@getlabel[][][]}} +\def\@@cref@getlabel[#1][#2][#3]#4\@nil#5{\def#5{#4}} +\def\cref@gettype#1#2{% + \expandafter\let\expandafter\@tempa\csname r@#1\endcsname% + \edef\@tempa{\expandafter\@firstoftwo\@tempa}% + \expandafter\@cref@gettype\@tempa\@nil#2} +\def\@cref@gettype{\@ifnextchar[%] + \@@cref@gettype{\@@cref@gettype[][][]}} +\def\@@cref@gettype[#1][#2][#3]#4\@nil#5{\def#5{#1}} +\def\cref@getcounter#1#2{% + \expandafter\let\expandafter\@tempa\csname r@#1\endcsname% + \edef\@tempa{\expandafter\@firstoftwo\@tempa}% + \expandafter\@cref@getcounter\@tempa\@nil#2} +\def\@cref@getcounter{\@ifnextchar[%] + \@@cref@getcounter{\@@cref@getcounter[][][]}} +\def\@@cref@getcounter[#1][#2][#3]#4\@nil#5{\def#5{#2}} +\def\cref@getprefix#1#2{% + \expandafter\let\expandafter\@tempa\csname r@#1\endcsname% + \edef\@tempa{\expandafter\@firstoftwo\@tempa}% + \expandafter\@cref@getprefix\@tempa\@nil#2} +\def\@cref@getprefix{\@ifnextchar[%] + \@@cref@getprefix{\@@cref@getprefix[][][]}} +\def\@@cref@getprefix[#1][#2][#3]#4\@nil#5{\def#5{#3}} +% \end{macrocode} +% +% We treate multiple references, supplied as a comma-separated list to +% \cmd{\cref} or \cmd{\Cref}, as a stack structure. So we define some +% utility macros for manipulating stacks (\cmd{\@nil} is used as an +% end-of-stack delimeter). +% \begin{macrocode} +\def\stack@init#1{\def#1{\@nil}} +\def\stack@top#1{\expandafter\stack@top@aux#1} +\def\stack@top@aux#1,#2\@nil{#1} +\def\stack@pop#1{\expandafter\stack@pop@aux#1#1} +\def\stack@pop@aux#1,#2\@nil#3{\def#3{#2\@nil}} +\def\stack@push#1#2{\expandafter\stack@push@aux\expandafter{#2}{#1}{#2}} +\def\stack@push@aux#1#2#3{\def#3{#2,#1}} +\def\stack@pull#1#2{\expandafter\stack@pull@aux#2{#1}{#2}} +\def\stack@pull@aux#1\@nil#2#3{\def#3{#1#2,\@nil}} +\newif\ifstackempty +\newif\ifstackfull +\def\isstackempty#1{% + \expandafter\ifx#1\@nil\stackemptytrue% + \else\stackemptyfalse\fi} +\def\isstackfull#1{% + \expandafter\ifx#1\@nil\stackfullfalse% + \else\stackfulltrue\fi} +% \end{macrocode} +% +% We need to be able to determine which counter is used to reset a +% given counter. Usually, resets are done by sectioning counters, and +% we assume that to be the case here. \cmd{\isinresetlist} searches +% through one counter's reset list, stored in +% \cmd{\cl@\meta{counter}}, to determine whether another counter +% appears there, and sets the new conditional +% appropriately. \cmd{\reset@by} searches through all the sectioning +% counters' reset lists, from lowest-level (subsubsection) to highest +% (part), checking whether the given counter is in the list, and +% returns the first sectioning counter whose list it appears in. +% \begin{macrocode} +\newif\ifinresetlist +\def\isinresetlist#1#2{% + \def\@counter{#1}% + \begingroup% + \def\@elt##1{##1,}% + \expandafter\ifx\csname cl@#2\endcsname\relax% + \gdef\@resetstack{,\@nil}% + \else% + \xdef\@resetstack{\csname cl@#2\endcsname\noexpand\@nil}% + \fi% + \endgroup% + \isstackfull{\@resetstack}% + \@whilesw\ifstackfull\fi{% + \edef\@nextcounter{\stack@top{\@resetstack}}% + \ifx\@nextcounter\@counter% + \stackfullfalse% + \else% + \let\@nextcounter\relax% + \stack@pop{\@resetstack}% + \isstackfull{\@resetstack}% + \fi}% + \ifx\@nextcounter\relax% + \inresetlistfalse% + \else% + \inresetlisttrue% + \fi} +% +\def\reset@by#1#2{% + \isinresetlist{#1}{subsubsubsection}% + \ifinresetlist% + \def#2{subsubsubsection}% + \else% + \isinresetlist{#1}{subsubsection}% + \ifinresetlist% + \def#2{subsubsection}% + \else% + \isinresetlist{#1}{subsection}% + \ifinresetlist% + \def#2{subsection}% + \else% + \isinresetlist{#1}{section}% + \ifinresetlist% + \def#2{section}% + \else% + \isinresetlist{#1}{chapter}% + \ifinresetlist% + \def#2{chapter}% + \else% + \isinresetlist{#1}{part}% + \ifinresetlist% + \def#2{part}% + \else% + \let#2\relax% + \fi% + \fi% + \fi% + \fi% + \fi% + \fi} +% \end{macrocode} +% +% +% \subsection{Referencing Commands} +% Define the main referencing macros \cmd{\cref} and the +% start-of-sentence variant \cmd{\Cref}. +% \begin{macrocode} +\newcommand{\cref}[1]{\@cref{cref}{#1}} +\newcommand{\Cref}[1]{\@cref{Cref}{#1}} +\newcommand{\crefrange}[2]{\@setcrefrange{#1}{#2}{cref}{}} +\newcommand{\Crefrange}[2]{\@setcrefrange{#1}{#2}{Cref}{}} +% \end{macrocode} +% To save duplicating code, the referencing macros pass an argument +% determining the variant to an auxilliary macro \cmd{\@cref}, which +% does the real work. The \cmd{\@cref} macro is the behemoth at the +% heart of all the smart referencing features. It deals with grouping +% references by type, typesetting the conjunctions between groups, +% choosing the right formatting macro to use for each reference, +% and collapsing consecutive references into ranges. +% \begin{macrocode} +\def\@cref#1#2{% + \begingroup% +% \end{macrocode} +% Initialise some things, and put all the references into a stack +% called \cmd{\@refstack}. +% \begin{macrocode} + \countdef\count@consecutive=0% + \newif\iffirstgroup% + \stack@init{\@refstack}% + \stack@push{#2}{\@refstack}% + \firstgrouptrue% + \isstackfull{\@refstack}% +% \end{macrocode} +% Loop until the reference stack is empty. +% \begin{macrocode} + \@whilesw\ifstackfull\fi{% + \stack@init{\@refsubstack}% + \edef\@nextref{\stack@top{\@refstack}}% + \expandafter\ifx\csname r@\@nextref\endcsname\relax% + \def\@currenttype{\@undefined}% + \else% + \expandafter\cref@gettype\expandafter{\@nextref}{\@currenttype}% + \fi% + \let\@nexttype\@currenttype% +% \end{macrocode} +% Move references from \cmd{\@refstack} into a different stack +% called \cmd{\@refsubstack}, until we encounter a reference that +% has a different type to those that came before. +% \begin{macrocode} + \@whilesw\ifx\@nexttype\@currenttype\fi{% + \expandafter\stack@pull\expandafter{\@nextref}{\@refsubstack}% + \stack@pop{\@refstack}% + \isstackempty{\@refstack}% + \ifstackempty% + \def\@nexttype{\relax}% + \else% + \edef\@nextref{\stack@top{\@refstack}}% + \expandafter\ifx\csname r@\@nextref\endcsname\relax% + \def\@currenttype{\@undefined}% + \else% + \expandafter\cref@gettype\expandafter{\@nextref}{\@currenttype}% + \fi% + \fi}% +% \end{macrocode} +% Typeset appropriate conjunction between groups of reference types. +% \begin{macrocode} + \iffirstgroup% + \else% + \isstackfull{\@refstack}% + \ifstackfull% + \crefmiddleconjunction% + \else% + \creflastconjunction% + \fi% + \fi% + \firstgroupfalse% +% \end{macrocode} +% Process first group of consecutive references from substack. +% \begin{macrocode} + \edef\@nextref{\stack@top{\@refsubstack}}% + \stack@pop{\@refsubstack}% +% \end{macrocode} +% If the substack only contains one reference, typeset it, +% \begin{macrocode} + \isstackempty{\@refsubstack}% + \ifstackempty% + \expandafter\@setcref\expandafter{\@nextref}{#1}{}% +% \end{macrocode} +% otherwise, find end of consecutive references. +% \begin{macrocode} + \else% + \edef\@beginref{\@nextref}% + \let\@endref\relax% + \edef\@nextref{\stack@top{\@refsubstack}}% + \count@consecutive=1% + \expandafter\ifx\csname r@\@beginref\endcsname\relax% + \refconsecutivefalse% + \else% + \expandafter\ifx\csname r@\@nextref\endcsname\relax% + \refconsecutivefalse% + \else% + \edef\@tmpa{{\@beginref}{\@nextref}}% + \expandafter\isrefconsecutive\@tmpa% + \fi% + \fi% + \@whilesw\ifrefconsecutive\fi{% + \advance\count@consecutive 1% + \let\@endref\@nextref% + \stack@pop{\@refsubstack}% + \isstackempty{\@refsubstack}% + \ifstackempty% + \refconsecutivefalse% + \else% + \edef\@nextref{\stack@top{\@refsubstack}}% + \expandafter\ifx\csname r@\@nextref\endcsname\relax% + \refconsecutivefalse% + \else% + \edef\@tmpa{{\@endref}{\@nextref}}% + \expandafter\isrefconsecutive\@tmpa% + \fi% + \fi}% +% \end{macrocode} +% If there were no consecutive references, typeset the first +% reference; +% \begin{macrocode} + \ifx\@endref\relax% + \expandafter\@setcref\expandafter{\@beginref}{#1}{@first}% + \else% +% \end{macrocode} +% if there were only two consecutive references, typeset the first +% one and return the second to the substack, +% \begin{macrocode} + \ifnum\count@consecutive=2% + \expandafter\@setcref\expandafter{\@beginref}{#1}{@first}% + \expandafter\stack@push\expandafter{\@endref}{\@refsubstack}% +% \end{macrocode} +% otherwise, typeset a reference range. +% \begin{macrocode} + \else + \edef\@tmpa{{\@beginref}{\@endref}}% + \ifstackempty% + \expandafter\@setcrefrange\@tmpa{#1}{}% + \else% + \expandafter\@setcrefrange\@tmpa{#1}{@first}% + \fi% + \fi% + \fi% +% \end{macrocode} +% Loop until substack is empty. +% \begin{macrocode} + \isstackfull{\@refsubstack}% + \@whilesw\ifstackfull\fi{% + \edef\@beginref{\stack@top{\@refsubstack}}% + \stack@pop{\@refsubstack}% + \let\@endref\relax% +% \end{macrocode} +% If substack only contains only one reference, typeset it, +% \begin{macrocode} + \isstackempty{\@refsubstack}% + \ifstackempty% + \expandafter\@setcref\expandafter{\@beginref}{#1}{@last}% +% \end{macrocode} +% otherwise, find end of consecutive references. +% \begin{macrocode} + \else% + \edef\@nextref{\stack@top{\@refsubstack}}% + \count@consecutive=1% + \expandafter\ifx\csname r@\@nextref\endcsname\relax% + \refconsecutivefalse% + \else% + \edef\@tmpa{{\@beginref}{\@nextref}}% + \expandafter\isrefconsecutive\@tmpa% + \fi% + \@whilesw\ifrefconsecutive\fi{% + \advance\count@consecutive 1% + \let\@endref\@nextref% + \stack@pop{\@refsubstack}% + \isstackempty{\@refsubstack}% + \ifstackempty% + \refconsecutivefalse% + \else% + \edef\@nextref{\stack@top{\@refsubstack}}% + \expandafter\ifx\csname r@\@nextref\endcsname\relax% + \refconsecutivefalse% + \else% + \edef\@tmpa{{\@endref}{\@nextref}}% + \expandafter\isrefconsecutive\@tmpa% + \fi% + \fi}% +% \end{macrocode} +% If the substack is now empty, we will need to typeset an +% ``end'' reference, otherwise we will need to typeset a +% ``middle'' reference. +% \begin{macrocode} + \isstackempty{\@refsubstack}% + \ifstackempty% + \def\@pos{@last}% + \else% + \def\@pos{@middle}% + \fi% +% \end{macrocode} +% If there were no consecutive references, just typeset the +% next reference; +% \begin{macrocode} + \ifx\@endref\relax% + \edef\@tmpa{{\@beginref}{#1}{\@pos}}% + \expandafter\@setcref\@tmpa% + \else% +% \end{macrocode} +% if there were only two consecutive references, typeset the +% first one, and return the second one to the substack, +% \begin{macrocode} + \ifnum\count@consecutive=2% + \edef\@tmpa{{\@beginref}{#1}{\@pos}}% + \expandafter\@setcref\@tmpa% +% \end{macrocode} +% otherwise, typeset a reference range. +% \begin{macrocode} + \else + \edef\@tmpa{{\@beginref}{\@endref}{#1}{\@pos}}% + \expandafter\@setcrefrange\@tmpa% + \fi% + \fi% + \fi% + \isstackfull{\@refsubstack}% + }% + \fi% + \isstackfull{\@refstack}% + }% + \endgroup} +% \end{macrocode} +% +% +% The internal \cmd{\@setcref} macro deals with actually typesetting +% the reference, by calling the appropriate type-dependent formatting +% macro defined by \cmd{\crefformat} etc. +% \begin{macrocode} +\def\@setcref#1#2#3{% + \expandafter\ifx\csname r@#1\endcsname\relax% + \protect\G@refundefinedtrue% + \nfss@text{\reset@font\bfseries ??}% + \@latex@warning{Reference `#1' on page \thepage \space undefined}% + \else% + \cref@gettype{#1}{\@temptype}% puts label type in \@temptype + \cref@getlabel{#1}{\@templabel}% puts label in \@templabel + \expandafter\ifx\csname #2@\@temptype @format#3\endcsname\relax% + \protect\G@refundefinedtrue% + \nfss@text{\reset@font\bfseries ??}~\@templabel% + \@latex@warning{\string\Cref \space reference format for label + type `\@temptype' undefined}% + \else% + \expandafter\@@setcref\expandafter% + {\csname #2@\@temptype @format#3\endcsname}{#1}% + \fi% + \fi} +% \end{macrocode} +% +% We separate out the very final typesetting step into a separate +% macro, in order to make it easier to redefine things later to make +% them work with the \package{hyperref} package. +% \begin{macrocode} +\def\@@setcref#1#2{\cref@getlabel{#2}{\@templabel}#1{\@templabel}{}{}} +% \end{macrocode} +% +% Define a new conditional to test whether two references are +% consecutive (needed when typesetting reference ranges). This uses +% the counter and prefix (i.e. formatted version of the counter that +% resets the label's counter) information provided by +% \cmd{\r@\meta{label}} (via the aux file) to check if the prefices are +% identical (i.e. the references come from the same chapter, section +% or whatever), and that the label counters differ by 1. +% \begin{macrocode} +\newif\ifrefconsecutive% +\def\isrefconsecutive#1#2{% + \begingroup% + \countdef\refa@counter=1% + \countdef\refb@counter=2% + \cref@getcounter{#1}{\@result}% + \refa@counter=\@result% + \advance\refa@counter 1% + \cref@getcounter{#2}{\@result}% + \refb@counter=\@result% + \cref@getprefix{#1}{\refa@prefix}% + \cref@getprefix{#2}{\refb@prefix}% + \def\@after{\refconsecutivefalse}% + \ifx\refa@prefix\refb@prefix% + \ifnum\refa@counter=\refb@counter% + \def\@after{\refconsecutivetrue}% + \fi% + \fi% + \expandafter\endgroup\@after} +% \end{macrocode} +% +% The internal \cmd{\@setcrefrange} macro deals with typesetting +% reference ranges, just as \cmd{\setcref} does for normal +% references. The actual typesetting is no more complicated in the +% range case; it's the error checking that makes the code so much +% longer. We now have to check whether \emph{two} references are +% undefined, whether \emph{two} reference formats are undefined, +% whether the reference types are consistent, and also combinations of +% these various errors. +% \begin{macrocode} +\def\@setcrefrange#1#2#3#4{% +% \end{macrocode} +% Check if both references are defined. +% \begin{macrocode} + \expandafter\ifx\csname r@#1\endcsname\relax% + \protect\G@refundefinedtrue% + \@latex@warning{Reference `#1' on page \thepage \space undefined}% + \expandafter\ifx\csname r@#2\endcsname\relax% + \nfss@text{\reset@font\bfseries ??}--% + \nfss@text{\reset@font\bfseries ??}% + \@latex@warning{Reference `#2' on page \thepage \space undefined}% + \else% + \cref@getlabel{#2}{\@labelb}% + \nfss@text{\reset@font\bfseries ??}--\@labelb% + \fi% + \else% + \expandafter\ifx\csname r@#2\endcsname\relax% + \protect\G@refundefinedtrue% + \cref@getlabel{#1}{\@labela}% + \@labela--\nfss@text{\reset@font\bfseries ??}% + \@latex@warning{Reference `#2' on page \thepage \space undefined}% +% \end{macrocode} +% If both references are defined, check that the reference format is +% defined. +% \begin{macrocode} + \else% + \cref@gettype{#1}{\@typea}% + \cref@gettype{#2}{\@typeb}% + \cref@getlabel{#1}{\@labela}% + \cref@getlabel{#2}{\@labelb}% + \edef\@formata{\expandafter\noexpand% + \csname #3range@\@typea @format#4\endcsname}% + \edef\@formatb{\expandafter\noexpand% + \csname #3range@\@typeb @format#4\endcsname}% + \expandafter\ifx\@formata\relax% + \protect\G@refundefinedtrue% + \nfss@text{\reset@font\bfseries ??}~\@labela--\@labelb% + \@latex@warning{#3 \space reference format for label + type `\@typea' undefined}% + \else% +% \end{macrocode} +% If reference types are identical, typeset reference range, +% otherwise display warning.\\ +% (Note: there's no need to check if reference format for second +% type is defined, since if it isn't it will be caught here as a +% non-identical type.) +% \begin{macrocode} + \ifx\formata\formatb% + \@@setcrefrange{\@formata}{#1}{#2}% + \else% + \protect\G@refundefinedtrue% + \nfss@text{\reset@font\bfseries ??}~\@labela--\@labelb% + \@latex@warning{Types inconsistent in reference range for + references `#1' and `#2' on page \thepage}% + \fi% + \fi% + \fi% + \fi} +% \end{macrocode} +% +% We again separate out the very final typesetting step into a +% separate macro, in order to make it easier to redefine things later +% to make them work with the \package{hyperref} package. +% \begin{macrocode} +\def\@@setcrefrange#1#2#3{% + \cref@getlabel{#2}{\@labela}% + \cref@getlabel{#3}{\@labelb}% + #1{\@labela}{\@labelb}{}{}{}{}} +% \end{macrocode} +% +% +% +% \subsection{Reference Format Customisation Commands} +% \cmd{\crefformat} et al.\ are user-level commands used to define the +% format of different reference types. They simply use the supplied +% argument(s) to define appropriately named formatting macro(s), which +% are called by \cmd{\@setcref}. The only moderately interesting part +% is that if the corresponding \cmd{\Crefformat} or \cmd{\crefformat} +% variant is not already defined, they define it to be a version with +% the first letter capitalised or lower-cased. +% \begin{macrocode} +\newcommand{\crefformat}[2]{\@crefformat{cref}{#1}{#2}} +\newcommand{\Crefformat}[2]{\@crefformat{Cref}{#1}{#2}} +\newcommand{\crefrangeformat}[2]{\@crefrangeformat{crefrange}{#1}{#2}} +\newcommand{\Crefrangeformat}[2]{\@crefrangeformat{Crefrange}{#1}{#2}} +\newcommand{\crefmultiformat}[4]{% + \@crefmultiformat{cref}{#1}{#2}{#3}{#4}} +\newcommand{\Crefmultiformat}[4]{% + \@crefmultiformat{Cref}{#1}{#2}{#3}{#4}} +\newcommand{\crefrangemultiformat}[4]{% + \@crefrangemultiformat{crefrange}{#1}{#2}{#3}{#4}} +\newcommand{\Crefrangemultiformat}[4]{% + \@crefrangemultiformat{Crefrange}{#1}{#2}{#3}{#4}} +% \end{macrocode} +% The utility macros do the real work, by using the first argument +% (``cref'', ``Cref'', ``crefrange'' or ``Crefrange'') to determine +% how to define the corresponding command with the other +% capitalisation. +% \begin{macrocode} +\def\@crefformat#1#2#3{% + \expandafter\def\csname #1@#2@format\endcsname##1##2##3{#3}% +% \end{macrocode} +% Note that the \cmd{@tmpa} macro makes use of the fact that the first +% character of \#1 is ``c'' for lower-case, ``C'' for upper-case. +% \begin{macrocode} + \def\@tmpa##1##2\@nil{% + \if##1c \def\@other{C##2}% + \else\def\@other{c##2}\fi}% + \@tmpa#1\@nil% +% \end{macrocode} +% Note that the \cmd{@tmpa} macro makes use of the fact that the first +% character of \#1 is ``c'' for lower-case, ``C'' for upper-case. +% \begin{macrocode} + \def\@tmpa##1##2\@nil{% + \if##1c\def\@changecase{\MakeUppercase}% + \else\def\@changecase{\MakeLowercase}\fi}% + \@tmpa#1\@nil% + \@ifundefined{\@other @#2@format}{% + \expandafter\edef\csname\@other @#2@format\endcsname##1##2##3{% + \expandafter\noexpand\@changecase\csname #1@#2@format\endcsname% + {##1}{##2}{##3}}}{}} +% +\def\@crefrangeformat#1#2#3{% + \expandafter\def\csname #1@#2@format\endcsname##1##2##3##4##5##6{#3}% +% \end{macrocode} +% Note that the \cmd{@tmpa} macro makes use of the fact that the first +% character of \#1 is ``c'' for lower-case, ``C'' for upper-case. +% \begin{macrocode} + \def\@tmpa##1##2\@nil{% + \if##1c \def\@other{C##2}% + \else\def\@other{c##2}\fi}% + \@tmpa#1\@nil% +% \end{macrocode} +% Note that the \cmd{@tmpa} macro makes use of the fact that the first +% character of \#1 is ``c'' for lower-case, ``C'' for upper-case. +% \begin{macrocode} + \def\@tmpa##1##2\@nil{% + \if##1c\def\@changecase{\MakeUppercase}% + \else\def\@changecase{\MakeLowercase}\fi}% + \@tmpa#1\@nil% + \@ifundefined{\@other @#2@format}{% + \expandafter\edef% + \csname\@other @#2@format\endcsname##1##2##3##4##5##6{% + \expandafter\noexpand\@changecase\csname #1@#2@format\endcsname% + {##1}{##2}{##3}{##4}{##5}{##6}}}{}} +% +\def\@crefmultiformat#1#2#3#4#5{% + \expandafter\def\csname #1@#2@format@first\endcsname##1##2##3{#3}% + \expandafter\def\csname #1@#2@format@middle\endcsname##1##2##3{#4}% + \expandafter\def\csname #1@#2@format@last\endcsname##1##2##3{#5}% +% \end{macrocode} +% Note that the \cmd{@tmpa} macros make use of the fact that the first +% character of \#1 is ``c'' for lower-case, ``C'' for upper-case. +% \begin{macrocode} + \def\@tmpa##1##2\@nil{% + \if##1c \def\@other{C##2}% + \else\def\@other{c##2}\fi}% + \@tmpa#1\@nil% + \def\@tmpa##1##2\@nil{% + \if##1c\def\@changecase{\MakeUppercase}% + \else\def\@changecase{\MakeLowercase}\fi}% + \@tmpa#1\@nil% + \@ifundefined{\@other @#2@format@first}{% + \expandafter\edef% + \csname\@other @#2@format@first\endcsname##1##2##3{% + \expandafter\noexpand\@changecase% + \csname #1@#2@format@first\endcsname% + {##1}{##2}{##3}}}{}% + \@ifundefined{\@other @#2@format@middle}{% + \expandafter\edef% + \csname\@other @#2@format@middle\endcsname##1##2##3{% + \csname #1@#2@format@middle\endcsname{##1}{##2}{##3}}}{}% + \@ifundefined{\@other @#2@format@last}{% + \expandafter\edef% + \csname\@other @#2@format@last\endcsname##1##2##3{% + \csname #1@#2@format@last\endcsname{##1}{##2}{##3}}}{}} +% +\def\@crefrangemultiformat#1#2#3#4#5{% + \expandafter\def\csname #1@#2@format@first\endcsname% + ##1##2##3##4##5##6{#3}% + \expandafter\def\csname #1@#2@format@middle\endcsname% + ##1##2##3##4##5##6{#4}% + \expandafter\def\csname #1@#2@format@last\endcsname% + ##1##2##3##4##5##6{#5}% +% \end{macrocode} +% Note that the \cmd{@tmpa} macros make use of the fact that the first +% character of \#1 is ``c'' for lower-case, ``C'' for upper-case. +% \begin{macrocode} + \def\@tmpa##1##2\@nil{% + \if##1c \def\@other{C##2}% + \else\def\@other{c##2}\fi}% + \@tmpa#1\@nil% + \def\@tmpa##1##2\@nil{% + \if##1c\def\@changecase{\MakeUppercase}% + \else\def\@changecase{\MakeLowercase}\fi}% + \@tmpa#1\@nil% + \@ifundefined{\@other @#2@format@first}{% + \expandafter\edef% + \csname\@other @#2@format@first\endcsname##1##2##3##4##5##6{% + \expandafter\noexpand\@changecase% + \csname #1@#2@format@first\endcsname% + {##1}{##2}{##3}{##4}{##5}{##6}}}{}% + \@ifundefined{\@other @#2@format@middle}{% + \expandafter\edef% + \csname\@other @#2@format@middle\endcsname##1##2##3##4##5##6{% + \csname #1@#2@format@middle\endcsname% + {##1}{##2}{##3}{##4}{##5}{##6}}}{}% + \@ifundefined{\@other @#2@format@last}{% + \expandafter\edef% + \csname\@other @#2@format@last\endcsname##1##2##3##4##5##6{% + \csname #1@#2@format@last\endcsname% + {##1}{##2}{##3}{##4}{##5}{##6}}}{}} +% \end{macrocode} +% +% +% \subsection{Default Reference Formats} +% Define the default reference formats, appropriate for \LaTeX +% documents written in English.\\ +% To-Do: add babel support +% \begin{macrocode} +\crefformat{equation}{eq.~#2(#1)#3} +\crefformat{chapter}{chapter~#2#1#3} +\crefformat{section}{section~#2#1#3} +\crefformat{subsection}{section~#2#1#3} +\crefformat{subsubsection}{section~#2#1#3} +\crefformat{subsubsubsection}{section~#2#1#3} +\crefformat{figure}{fig.~#2#1#3} +\crefformat{theorem}{theorem~#2#1#3} +\crefmultiformat{equation}% + {eqs.~#2(#1)#3}{, #2(#1)#3}{ and~#2(#1)#3} +\crefmultiformat{chapter}% + {chapters~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefmultiformat{section}% + {sections~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefmultiformat{subsection}% + {sections~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefmultiformat{subsubsection}% + {sections~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefmultiformat{subsubsubsection}% + {sections~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefmultiformat{figure}% + {figs.~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefmultiformat{theorem}% + {theorems~#2#1#3}{, #2#1#3}{ and~#2#1#3} +% +\crefrangeformat{equation}{eqs.~#3(#1)#4--#5(#2)#6} +\crefrangeformat{chapter}{chapters~#3#1#4--#5#2#6} +\crefrangeformat{section}{sections~#3#1#4--#5#2#6} +\crefrangeformat{subsection}{sections~#3#1#4--#5#2#6} +\crefrangeformat{subsubsection}{sections~#3#1#4--#5#2#6} +\crefrangeformat{subsubsubsection}{sections~#3#1#4--#5#2#6} +\crefrangeformat{figure}{figs.~#3#1#4--#5#2#6} +\crefrangeformat{theorem}{theorems~#3#1#4--#5#2#6} +\crefrangemultiformat{equation}% + {eqs.~#3(#1)#4--#5(#2)#6}% + {, #3(#1)#4--#5(#2)#6}% + { and~#3(#1)#4--#5(#2)#6} +\crefrangemultiformat{chapter}% + {chapters~#3#1#4--#5#2#6}% + {, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +\crefrangemultiformat{section}% + {sections~#3#1#4--#5#2#6}% + {, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +\crefrangemultiformat{subsection}% + {sections~#3#1#4--#5#2#6}% + {, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +\crefrangemultiformat{subsubsection}% + {sections~#3#1#4--#5#2#6}% + {, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +\crefrangemultiformat{subsubsubsection}% + {sections~#3#1#4--#5#2#6}% + {, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +\crefrangemultiformat{figure}% + {figs~#3#1#4--#5#2#6}% + {, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +\crefrangemultiformat{theorem}% + {theorems~#3#1#4--#5#2#6}% + {, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +% +\def\crefmiddleconjunction{, } +\def\creflastconjunction{, and } +% \end{macrocode} +% +% +% \subsection{\package{hyperref} Support} +% \begin{macrocode} +\DeclareOption{hyperref}{% +\PackageInfo{cleveref}{option `hyperref' loaded} +% \end{macrocode} +% We redefine the utility macros to cope with the extra arguments +% supplied by hyperref (via the aux file). +% \begin{macrocode} +\def\cref@label#1#2#3#4#5{\@result} +\def\cref@hyperref#1{\expandafter\expandafter\expandafter% + \@fourthoffive\csname r@#1\endcsname} +\def\cref@getlabel#1#2{% + \expandafter\let\expandafter\@tempa\csname r@#1\endcsname% + \edef\@tempa{\expandafter\@firstoffive\@tempa}% + \expandafter\@cref@getlabel\@tempa\@nil#2} +\def\cref@gettype#1#2{% + \expandafter\let\expandafter\@tempa\csname r@#1\endcsname + \edef\@tempa{\expandafter\@firstoffive\@tempa}% + \expandafter\@cref@gettype\@tempa\@nil#2} +\def\cref@getcounter#1#2{% + \expandafter\let\expandafter\@tempa\csname r@#1\endcsname + \edef\@tempa{\expandafter\@firstoffive\@tempa}% + \expandafter\@cref@getcounter\@tempa\@nil#2} +\def\cref@getprefix#1#2{% + \expandafter\let\expandafter\@tempa\csname r@#1\endcsname + \edef\@tempa{\expandafter\@firstoffive\@tempa}% + \expandafter\@cref@getprefix\@tempa\@nil#2} +% \end{macrocode} +% +% The \package{hyperref} package stores the original +% \cmd{\refstepcounter} definition as \cmd{\H@refstepcounter}, which +% we therefore need to modify so that it adds the extra information to +% \cmd{\@currentlabel}. +% \begin{macrocode} +\def\H@refstepcounter#1{% + \stepcounter{#1}% + \reset@by{#1}{\@result}% + \ifx\@result\relax\def\@result{}% + \else\edef\@result{\csname the\@result\endcsname}\fi% + \protected@edef\@currentlabel% + {[#1][\arabic{#1}][\@result]% + \csname p@#1\endcsname\csname the#1\endcsname}} +% \end{macrocode} +% +% The original \cmd{\refstepcounter}, as stored earlier in +% \cmd{\old@refstepcounter} already calls \H@refstepcounter if +% \package{hyperref} is loaded, and we just redefined it to store the +% type information. so we only need to change \cmd{\@currentlabel} in +% our \cmd{\refstepcounter} if an optional argument was supplied. +% \begin{macrocode} +\def\refstepcounter@noarg#1{\old@refstepcounter{#1}} +\def\refstepcounter@optarg[#1]#2{% + \old@refstepcounter{#2}% + \expandafter\@cref@getlabel\@currentlabel\@nil{\@templabel}% + \reset@by{#2}{\@tempreset}% + \ifx\@tempreset\relax\def\@tempreset{}% + \else\edef\@tempreset{\csname the\@tempreset\endcsname}\fi% + \protected@edef\@currentlabel{% + [#1][\arabic{#2}][\@tempreset]\@templabel}} +% \end{macrocode} +% +% Redefine \@@setcref and \@@setrangeref to create hyperlinks, using +% the extra arguments supplied in \cmd{r@\meta{label}} (via the aux +% file) by \package{hyperref}. +% \begin{macrocode} +\def\@@setcref#1#2{% + \cref@getlabel{#2}{\@templabel}% + \edef\@templink{\cref@hyperref{#2}}% + #1{\@templabel}{\hyper@linkstart{link}{\@templink}}{\hyper@linkend}} +\def\@@setcrefrange#1#2#3{% + \cref@getlabel{#2}{\@labela}% + \cref@getlabel{#3}{\@labelb}% + \edef\@linka{\cref@hyperref{#2}}% + \edef\@linkb{\cref@hyperref{#3}}% + #1{\@labela}{\@labelb}{\hyper@linkstart{link}{\@linka}}{\hyper@linkend}% + {\hyper@linkstart{link}{\@linkb}}{\hyper@linkend}} +} % end of hyperref option +% \end{macrocode} +% +% +% \subsection{\package{ntheorem} Support} +% \begin{macrocode} +\DeclareOption{ntheorem}{% +\PackageInfo{cleveref}{option `ntheorem' loaded} +% \end{macrocode} +% +% We modify \package{ntheorem}'s version of the \cmd{@thm} macro very +% slightly, to have it call \cmd{\refstepcounter} with an optional +% argument containing the theorem type. +% \begin{macrocode} +\gdef\@thm#1#2#3{% + \if@thmmarks + \stepcounter{end\InTheoType ctr}% + \fi + \renewcommand{\InTheoType}{#1}% + \if@thmmarks + \stepcounter{curr#1ctr}% + \setcounter{end#1ctr}{0}% + \fi + \refstepcounter[#1]{#2}% <<<<< + \thm@topsepadd \theorempostskipamount + \ifvmode \advance\thm@topsepadd\partopsep\fi + \trivlist + \@topsep \theorempreskipamount + \@topsepadd \thm@topsepadd + \advance\linewidth -\theorem@indent + \advance\@totalleftmargin \theorem@indent + \parshape \@ne \@totalleftmargin \linewidth + \@ifnextchar[{\@ythm{#1}{#2}{#3}}{\@xthm{#1}{#2}{#3}}%] + } +% \end{macrocode} +% +% Default formats for new theorem-like environments defined by ntheorem. +% \begin{macrocode} +\crefformat{lemma}{lemma~#2#1#3} +\crefformat{corrollary}{corrollary~#2#1#3} +\crefformat{proposition}{proposition~#2#1#3} +\crefformat{definition}{definition~#2#1#3} +\crefformat{result}{result~#2#1#3} +\crefrangeformat{lemma}{lemma~#3#1#4--#5#2#6} +\crefrangeformat{corrollary}{corrollary~#3#1#4--#5#2#6} +\crefrangeformat{proposition}{proposition~#3#1#4--#5#2#6} +\crefrangeformat{definition}{definition~#3#1#4--#5#2#6} +\crefrangeformat{result}{result~#3#1#4--#5#2#6} +\crefmultiformat{lemma}% + {lemmas~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefmultiformat{corrollary}% + {corrollaries~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefmultiformat{proposition}% + {propositions~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefmultiformat{definition}% + {definitions~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefmultiformat{result}% + {results~#2#1#3}{, #2#1#3}{ and~#2#1#3} +\crefrangemultiformat{lemma}% + {lemmas~#3#1#4--#5#2#6}{, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +\crefrangemultiformat{corrollary}% + {corrollaries~#3#1#4--#5#2#6}{, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +\crefrangemultiformat{proposition}% + {propositions~#3#1#4--#5#2#6}{, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +\crefrangemultiformat{definition}% + {definitions~#3#1#4--#5#2#6}{, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +\crefrangemultiformat{result}% + {results~#3#1#4--#5#2#6}{, #3#1#4--#5#2#6}% + { and~#3#1#4--#5#2#6} +} % end of ntheorem option +% \end{macrocode} +% +% +% Process options. +% \begin{macrocode} +\ProcessOptions\relax +% \end{macrocode} +% +% \Finale +\endinput +%% +%% End of file `cleveref.dtx'. + +%%% Local Variables: +%%% mode: doctex +%%% TeX-master: t +%%% End: diff --git a/Master/texmf-dist/source/latex/cleveref/cleveref.ins b/Master/texmf-dist/source/latex/cleveref/cleveref.ins new file mode 100644 index 00000000000..32278cc6f3b --- /dev/null +++ b/Master/texmf-dist/source/latex/cleveref/cleveref.ins @@ -0,0 +1,34 @@ +%% +%% cleveref.ins +%% Batch file, run through LaTeX. +%% +%% Copyright (C) 2006 Toby Cubitt +%% See the files README and COPYING. +%% +\def\batchfile{cleveref.ins} +\input docstrip.tex +\preamble + +LaTeX package for automatic cross-referencing text. + +Copyright (C) 2006 Toby Cubitt +See the files README and COPYING. + +\endpreamble +\keepsilent +\generateFile{cleveref.sty}{t}{\from{cleveref.dtx}{package}} +\Msg{**************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* files into a directory searched by LaTeX:} +\Msg{*} +\Msg{* \space\space cleveref.sty} +\Msg{*} +\Msg{* To produce the documentation run the following files} +\Msg{* through LaTeX:} +\Msg{*} +\Msg{* \space\space cleveref.dtx} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{**************************************************************} -- cgit v1.2.3