% \iffalse meta-comment % % Package 'cleveref' to use with LaTeX2e % Copyright 2009 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} % [2009/11/02 v0.12 Intelligent cross-referencing] % %<*driver> \documentclass{ltxdoc} %\documentclass[draft]{ltxdoc} \usepackage{url} \usepackage{hyperref} \usepackage{cleveref} \EnableCrossrefs \CodelineIndex \RecordChanges %%\newcommand{\package}[1]{\texttt{#1.sty}} \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{3407} %% \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/05}{Renamed "cleveref" -- first public release} % \changes{v0.5}{2007/31/05}{Added poorman option} % \changes{v0.6}{2007/11/06}{Poorman no longer writes extra .tmp file} % \changes{v0.7}{2007/21/06}{Allow prevention of reference range % collapsing} % \changes{v0.8}{2007/10/07}% % {Made referencing commands robust, improved default formats, made % starred versions of referencing commands for hyperref, allowed % multiple consecutive empty references in list to prevent range % collapsing, and fixed bugs. Phew!} % \changes{v0.8.1}{2007/08/08}{Bug fixes.} % \changes{v0.9}{2007/29/10}% % {Added an extra conjunction and format component, used when a list % only contains a single pair of references or reference % sub-lists. Formats are now constructed from customisable % components, unless overridden using the old format definition % commands.} % \changes{v0.10}{2007/30/10}% % {Allow optional argument to \\label to override reference % type. Removed hyperref and ntheorem options; support for these and % amsmath is enabled automatically if those packages are loaded.} % \changes{v0.11}{2007/21/11}{Made referencing aware of appendices.} % \changes{v0.11.1}{2007/29/11}{Bug fixes.} % \changes{v0.12}{2009/11/02}{Restore working \\ref* when hyperref is % loaded -- first release mirrored on www.dr-qubit.org} % % % \GetFileInfo{cleveref.sty} % % \def\fileversion{0.12} % \def\filedate{11/02/2009} % % \title{The \package{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.) and the context in which the reference is used. 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 about his achievements! 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 probably valid when it comes 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 % facilities by allowing references to be formatted automatically % according to the type of object they refer to (chapter, section, % equation, theorem, etc.) and the context in which the reference is % used. It can also automatically format references to multiple labels, % automatically collapsing references to consecutive labels into a % reference range, and all kinds of other clever wizardry. % % In standard \LaTeX{}, you have almost certainly found yourself writing % things like |Eq.~(\ref{eq1})| and |Theorems~\ref{thm1} to~\ref{thm2}| % over and over again. Tedium isn't the only downside to this. 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|. % % The \package{cleveref} package 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 format of equation references, you only have % to change one preamble definition. If you xchange 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 avoiding % repetitively typing the same text for each and every reference. % % There are a number of other packages with similar goals, most notably % \package{varioref}, \package{fancyref}, \package{hyperref}'s |\autoref| % command, and (for theorem-like environments) \package{ntheorem} (with % the \option{thref} option). (There are many others, but these come % closest to providing similar features to \package{cleveref}.) 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}. Often 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. Not to mention missing out on % automatic collapsing of consecutive references, \package{ntheorem} % support, etc. % % The \package{hyperref} package's |\autoref| command typesets a name % before a reference, determined by the reference type. This is less % flexible than \package{cleveref}'s fully customisable reference % formatting but, when combined with \package{varioref}, the two packages % working together come close. However, even with \package{hyperref}, it % is impossible to customise precisely which part of the reference is % made into a hyper-link in PDF documents; this is very easy with % \package{cleveref}. And it still remains impossible to typeset multiple % references, have consecutive references collapsed automatically, etc. % % 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 that specifies the label type. \package{cleveref} % works equally well when referencing any type of object, as well as % fully supporting \package{ntheorem}. And again, \package{cleveref} % provides a number additional features, such as multiple references, % automatic collapsing of reference ranges, control over the placement of % hyper-links, etc. % % % % \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}). Basically, \package{cleveref} must be % loaded \emph{last}. % % If you just want to get going quickly with \package{cleveref}, and come % back later to read up on all the features it provides in more detail, % here's what you need to do. Wherever you would previously have used % |\ref|, use |\cref| instead. (Except at the beginning of a sentence, % where you should use |\Cref|.) You no longer need to put the name of % the thing you're referencing in front of the |\cref| command, because % \package{cleveref} will sort that out for you: i.e.\ use |\cref{eq1}| % instead of |eq.~(\ref{eq1})|. If you want to refer to a range of % labels, use |\crefrange|: |\crefrange{eq1}{eq5}| gives % |eqs.~(1)--(5)|. Finally, if you want to refer to multiple things at % once, you can now combine them all into one reference and leave % \package{cleveref} to sort it out: e.g.\ % |\cref{eq1,eq2,eq3,eq5,thm2,def1}| produces % |eqs.~(1)--(3) and~(5), theorem~5, and definition~1|. % % % \section{Typesetting References} % \label{sec:typesetting} % \DescribeMacro\cref % To automatically typeset a cross-reference according to the type of % object referred to, simply refer to it using |\cref{|\meta{label}|}|. % \package{cleveref} imposes just one extra restriction on the names of % labels: they are no longer allowed to contain commas ``,''. These are % instead used to typeset multiple references (see below). % % \DescribeMacro\Cref % As it is very difficult\footnote{Actually, very likely impossible!} % for \LaTeX{} to determine whether a cross-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 fully and independently customised, 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 original behaviour.}, % so you can still use it to typeset the formatted label counter alone, % without any additional text or formatting. % % \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 to 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} % (assuming you haven't customised the reference formats). % % To prevent a sequence of consecutive references from being collapsed to % a reference range, you can separate the references in the list by one % or more empty references, at the point at which you want to prevent % collapsing. For example, % \begin{quote} % |\cref{eq1,eq2,eq3,,eq4}| % \end{quote} % will be typeset as % \begin{quote} % eqs.~(1)--(3) and (4) % \end{quote} % or % \begin{quote} % |\cref{eq1,eq2,,eq3,eq4,eq5,,eq6,eq7,eq8}| % \end{quote} % will be typeset as % \begin{quote} % eqs.~(1), (2), (3)--(5) and (6)--(7) % \end{quote} % You can safely put an empty reference between references that would % never be collapsed anyway; it will simply be ignored. % % \DescribeMacro{\cref*} % \DescribeMacro{\Cref*} % \DescribeMacro{\crefrange*} % \DescribeMacro{\Crefrange*} % When \package{cleveref} is used along with the \package{hyperref} % package (see \cref{sec:customising,sec:other_packages}), additional % starred variants of all the referencing commands are available. The % standard referencing commands will make references into hyper-links; % the starred variants prevent this, producing the same typeset text but % without creating hyper-links. % % % \section{Customising the Reference Format} % \label{sec:customising} % 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 label types\footnote{For any pedantic % classics scholars out there: ``lemmas'' is recognised as a valid % plural form of ``lemma'' in all current versions of the Oxford % English Dictionary. ``Lemmata'' was last heard in a mathematical % debate that took place in a pub just around the corner from Hadrian's % wall\dots a few years before the Romans pulled out of % Britain. \package{cleveref} might have ``clever'' in its name, but % even that doesn't make it pretentious enough to use % ``lemmata''.}. But if you don't like them, or are writing in a % different language, or you need to cross-reference something for which % no default format is defined, then you can take charge and define your % own formats. % % 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. The error message indicates the name of the % unknown reference type, which you will then probably want to % define. (References to undefined labels still produce a ``reference % undefined'' warning and are typeset as a double question mark, as % usual.) % % The reference formats are usually constructed out of components: the % reference name (different for each type of reference), the label % formats, and the conjunctions used in reference ranges and lists of % multiple references. There are three levels of customisation: you can % customise the components globally, individually for each reference % type, or you can take full control and ignore the components entirely. % % % \subsection{Global Customisation} % \label{sec:global_customisation} % The global customisation commands can only be used in the preamble, and % \emph{must} come before any lower-level customisation commands if they % are to have any effect. % % \DescribeMacro\crefdefaultlabelformat % The format for the label counter itself can be customised globally % using % \begin{quote} % |\crefdefaultlabelformat{|\meta{format}|}| % \end{quote} % 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 in % that case no hyper-link will be created when \package{hyperref} is % used, and there are better ways to achieve this. See % \cref{sec:typesetting,sec:other_packages}.) % % \DescribeMacro\crefrangeconjunction % The conjunction used in a reference range can be customised by % redefining |\crefrangeconjunction|: % \begin{quote} % |\renewcommand{\crefrangeconjunction}{|\meta{conjunction}|}| % \end{quote} % It does not have to be an actual conjunction in the linguistic sense, % e.g.\ it is perfectly reasonable to define it to be an emdash % ``|--|''. |\crefrangeconjunction| is used directly between the start % and end references in a reference range, without any additional space % surrounding it, e.g.\ |\crefrange{thm1}{thm2}| is typeset as % \begin{quote} % |theorems~\ref{thm1}\crefrangeconjunction\ref{thm2}| % \end{quote} % (assuming the default theorem format hasn't been customised). So you % may or may not want to include surrounding space, depending on the % formatting you desire. For example, % \begin{quote} % |\renewcommand{\crefrangeconjunction}{ and~}| % \end{quote} % does require surrounding space, whereas % \begin{quote} % |\renewcommand{\crefrangeconjunction}{--}| % \end{quote} % does not. % % Note that customizing |\crefrangeconjunction| will \emph{not} work for % equations and figures because of the way the default formats for these % are defined. See |\crefrangeformat| in % \cref{sec:individual_customisation} for a way to change the conjunction % for these reference types. % % \DescribeMacro\crefpairconjunction % \DescribeMacro\crefmiddleconjunction % \DescribeMacro\creflastconjunction % The conjunctions used in lists of references can be customised by % redefining |\crefpairconjunction|, |\crefmiddleconjunction| and % |\creflastconjunction|: % \begin{quote} % |\renewcommand{\crefpairconjunction}{|\meta{conjunction}|}|\\ % |\renewcommand{\crefmiddleconjunction}{|\meta{conjunction}|}|\\ % |\renewcommand{\creflastconjunction}{|\meta{conjunction}|}| % \end{quote} % |\crefpairconjunction| is used when there are only two references in % the list, |\creflastconjunction| is used between the penultimate and % final reference in a list of more than two, and % |\crefmiddleconjunction| is used between all the others. Again, they do % not have to be conjunctions in the linguistic sense, and the same % comments about surrounding space apply as in the case of % |\crefrangeconjunction|. For example, the default definition of % |\crefmiddleconjunction| is: % \begin{quote} % |\renewcommand{\crefmiddleconjunction}{, }| % \end{quote} % % \DescribeMacro\crefpairgroupconjunction % \DescribeMacro\crefmiddlegroupconjunction % \DescribeMacro\creflastgroupconjunction % By default, the conjunctions used to separate sub-lists of different % reference types in a multi-reference are identical to those used to % separate references of the same type\footnote{More accurately, % redefining $\backslash$crefpairconjunction etc.\ automatically % redefines $\backslash$crefpairgroupconjunction etc.\ so that they % match. If you \emph{don't} redefine anything, the default definition % of $\backslash$creflastgroupconjunction has an additional comma % lacking in $\backslash$creflastconjunction.}. You can override this % by redefining |\crefpairgroupconjunction|, % |\crefmiddlegroupconjunction| and |\creflastgroupconjunction|. % % 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 as % \begin{quote} % eqs.~(1)|\crefrangeconjunction|(3)|\crefmiddlegroupconjunction|%\\ % theorems~1|\crefpairconjunction|2|\crefmiddlegroupconjunction|%\\ % fig.~1|\creflastgroupconjunction|theorem~3 % \end{quote} % % % \subsection{Customising Individual Reference Types} % \label{sec:individual_customisation} % \DescribeMacro\crefname % \DescribeMacro\Crefname % The reference name for a given reference type is customised using the % |\crefname| and |\Crefname| commands: % \begin{quote} % |\crefname{|\meta{type}|}{|\meta{singular}|}{|\meta{plural}|}|\\ % |\Crefname{|\meta{type}|}{|\meta{singular}|}{|\meta{plural}|}| % \end{quote} % used by the |\cref| and |\Cref| commands, respectively. You must supply % both \meta{singular} and \meta{plural} forms of the name. If the % corresponding |\Crefname| is undefined when |\crefname| is called, it % will define |\Crefname| to be a capitalised version of |\crefname|, % using |\MakeUppercase|. Conversely, if the corresponding |\crefname| is % undefined when |\Crefname| is called, it will define |\crefname| to be % a lower-case version of |\Crefname|, using |\MakeLowercase|. Obviously, % this will only work properly if the names begin with a letter. If the % first letter is a special character construct, such as an accented % character, you will need to surround it by braces. If the first thing % in the name is \emph{not} a letter at all (e.g.\ if it is a \LaTeX{} % command), you \emph{must} define both capitalisation variants % explicitly. Otherwise 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 % exceptions are appendices, for which \meta{type} should be ``appendix'' % (instead of chapter or section), and theorem-like environments when the % \package{ntheorem} package is loaded, for which \meta{type} should % instead be the environment name (lemma, corollary, definition, % etc.). \package{ntheorem} provides extra information about the % environment when different theorem-like environments use a common % counter, which \package{cleveref} makes use of to distinguish between % them automatically. % % \DescribeMacro\creflabelformat % You may want the label format for a particular reference type to differ % from the global format set by |\crefdefaultlabelformat| (see % \ref{sec:global_customisation}. You can do this using % \begin{quote} % |\creflabelformat{|\meta{type}|}{|\meta{format}|}| % \end{quote} % The \meta{type} argument is the reference type to customise, and the % \meta{format} argument defines the label format for references of that % type. As in the case of\linebreak[4] |\crefdefaultlabelformat|, the % latter should contain the three arguments |#1|, |#2| and |#3|, the % first being the formatted version of the label counter, the others % determining the beginning and end of the portion that becomes a % hyper-link when the \package{hyperref} package is loaded (see % \cref{sec:other_packages}). |#2| and |#3| must appear in that order. % % \DescribeMacro\crefrangelabelformat % Normally, the start and end references in a reference range are typeset % using using the usual label format (as defined by % |\crefdefaultlabelformat| or |\creflabelformat|) separated by % |\crefrangeconjunction| (\cref{sec:global_customisation}). You can % override this for a given reference type using % \begin{quote} % |\crefrangelabelformat{|\meta{type}|}{|\meta{format}|}| % \end{quote} % The \meta{format} argument should contain six arguments: |#1|, |#2|, % |#3|, |#4|, |#5|, |#6|. The first two (|#1| and |#2|) are the formatted % versions of the two label counters defining the reference range. The % next two (|#3| and |#4|) denote the beginning and end of the hyper-link % for the first reference, the final two (|#5| and |#6|) the hyper-link % for the second reference. The hyper-link arguments must appear in % order. For example, the default format for equations is defined as: % \begin{quote} % |\crefrangelabelformat{equation}{(#3#1#4)--(#5#2#6)}| % \end{quote} % % Note that the above default reference range format for equations (and % similarly for figures) already overrides the normal % |\crefrangelabelformat|, so customizing |\crefrangeconjunction| will % not affect these particular default formats. If you want to change the % conjunction used in equation and figure reference ranges, you have to % use |\crefrangelabelformat|. % % % \subsection{Taking Full Control} % \label{sec:full-control_customisation} % If you need more precise control over the reference format than is % possible by customising the individual components, then you can take % full control of the format for any given type, overriding the % component-derived format entirely. The formats for single references, % reference ranges and multi-references are customised separately. If you % only customise some of these, the other formats will still be % constructed from components, as usual. % % \subsubsection{Single References} % \label{sec:ref_format} % \DescribeMacro\crefformat % \DescribeMacro\Crefformat % Reference formats for \emph{single} references are defined or redefined % using the\linebreak[4] |\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} % The \meta{type} is usually the name of the counter, except for % theorem-like environments when \package{ntheorem} is loaded, in which % case it is the environment name,and appendices, when it is % ``appendix''. % % As in the case of the |\crefname| and |\Crefname| commands, 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, it will define % the |\crefformat| to produce a lower-case version of |\Crefformat|, % using |\MakeLowercase|. Obviously, this will only work properly if the % format starts with a letter, and letter constructs (such as accented % letter constructs) must be surrounded by braces (see % \cref{sec:global_customisation}). % % The \meta{format} argument can be any valid \LaTeX{} code, though you % will need to |\protect| fragile commands. It 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 % forms the hyper-link when the \package{hyperref} package is used, and % must appear in that order (see \cref{sec:other_packages}). % % 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-link. % % Note that the hyper-link arguments are \emph{not} letters, so if |#2| % appears at the beginning of \meta{format}, \package{cleveref} will not % be able to automatically define the other capitalisation variant % automatically using |\MakeUppercase| or |\MakeLowercase|. In this case, % you will have to define both variants separately. For example, if you % wanted to the ``Eq.'' to be part of the hyper-link, you would have to % define: % \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|. 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 as in the case of single references: the % \meta{type} is usually the name of the counter, except for theorem-like % environments when \package{ntheorem} is loaded, and if the % 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, the default % \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|. Multi-references also require \emph{all} the % other reference formats to be defined (see % \cref{sec:ref_format,sec:ref_range_format}), including the single % reference range formats, even if you never use the |\crefrange| and % |\Crefrange| commands. % % The commands all take five arguments: the reference type, the format % for the first reference in a list, the format for the second reference % in a list of two, the format for the middle references in a list of % more than two, and the format for the last reference in a list of more % than two. % \begin{quote} % |\crefmultiformat{|\meta{type}|}{|\meta{first}|}{|\meta{second}|}{|\meta{middle}|}{|\meta{last}|}|\\ % |\Crefmultiformat{|\meta{type}|}{|\meta{first}|}{|\meta{second}|}{|\meta{middle}|}{|\meta{last}|}|\\ % |\crefrangemultiformat{|\meta{type}|}{|\meta{first}|}{|\meta{second}|}{|\meta{middle}|}{|\meta{last}|}|\\ % |\Crefrangemultiformat{|\meta{type}|}{|\meta{first}|}{|\meta{second}|}{|\meta{middle}|}{|\meta{last}|}| % \end{quote} % % The \meta{type} is, as ever, the counter name, or environment name in % the case of \package{ntheorem} theorem-like environments. The same % considerations apply to the formatting arguments \meta{first}, % \meta{second}, \meta{middle} and \meta{last} as for the \meta{format} % argument of |\crefformat| or |\crefrangeformat|, including the meaning % of the arguments that should appear in the formatting code (|#1|, |#2| % and |#3| for |\crefmultiformat| and |\Crefmultiformat|, |#1|--|#6| for % |\crefmultiformat| and |\Crefmultiformat|). However, when the % corresponding other-capitalisation variant is automatically defined, % only the first letter of the \meta{first} argument is upper- or % lower-cased; the other arguments are defined to be identical for both % variants. % % Be careful to get the spaces at the beginning and end of the formatting % code correct: the \meta{first} and {|\meta{second}|}, or \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, in the default % equation format % \begin{quote} % |\crefmultiformat{equation}%|\\ % |{eqs.~(#2#1#3)}{ and~(#2#1#3)}{, (#2#1#3)}{ and~(#2#1#3)}| % \end{quote} % the \meta{middle} argument should \emph{not} have a space at the % beginning, whereas the \meta{second} and \meta{last} arguments % \emph{should} have a space. % % % % \section{Overriding the Reference Type} % As described previously, a label's reference type is usually determined % by its counter, or in the case of \package{ntheorem} theorem-like % environments by the environment name. Occasionally, you may want to % override the reference type for a particular label. You can do this by % supplying the desired type as an optional argument to the |\label| % command: % \begin{quote} % |\label[|\meta{type}|]{|\meta{label}|}| % \end{quote} % % One circumstance in which is useful is when you want to define a % special reference format for certain labels of a given type. By % specifying a type that doesn't already exist in the |\label|'s optional % argument, you can then define the reference format for that new type in % whatever way you like, without affecting other references of the same % type. For example, if a particular equation contains multiple % expressions and you want it to always be referred to in the plural, you % could use: % \begin{quote} % |\crefname{pluralequation}{eqs.}{eqs.}|\\ % \dots\\ % |\label[pluralequation]{eq1}| % \end{quote} % You can of course reuse this format for other plural equations, too. % % If you need to do this frequently, it can become tedious specifying the % label explicitly each time. An alternative is to use the % \package{aliascnt} package. This lets you define one counter to be an % alias for another, so that effectively the same counter has two % names. Since \package{cleveref} determines the label type from the % counter name, the two counter aliases can have different reference % formats whilst really being the same counter. You have to somehow % arrange for the correct counter alias to be used depending on which % reference format you want (probably by defining two variants of the % environment in question). But the effort involved might be worth the % convenience of not having to remember to pass an explicit optional % argument to a large number of labels. % % You can use this trick to get different reference formats for different % theorem-like environments, \emph{without} using the \package{ntheorem} % package\footnote{This trick seems to belong to \LaTeX{} mythology, and % certainly isn't my own idea! I haven't been able to definitively % track down who originally came up with it.}. For example, % \begin{quote} % |\usepackage{aliascnt}|\\ % |\usepackage{cleveref}|\\ % |\newaliascnt{lemma}{theorem}|\\ % |\newtheorem{lemma}[lemma]{Lemma}|\\ % |\aliascntresetthe{lemma}|\\ % |\crefname{lemma}{lemma}{lemmas}| % \end{quote} % % % % \section{Poor Man's \package{cleveref}} % Sometimes you may need to send your \LaTeX{} source to someone who % can't install the \package{cleveref} package themselves. For example, % many academic journals accept papers in \LaTeX{} format, but only % support a small subset of the packages available on CTAN. The % \option{poorman} option was designed specifically to help in this % situation. % % When the \option{poorman} option is supplied, your document will be % processed as normal. But in addition, a {\tt sed} script will % automatically be written, containing rules for replacing all the % \cmd{\cref} commands with the \LaTeX{} code that they would produce, % and using the standard \cmd{\ref} command to produce the % cross-references themselves. I.e.\ the script rewrites your document as % you would have done if you had had to do it manually! % % The advantage, of course, is that you \emph{don't} have to do it % manually. Instead, you can use all the features of \package{cleveref}, % and once you've created a version of your document that you want to % send elsewere, you can process it through the {\tt sed} script to % completely remove the \package{cleveref} dependency. The recipient % won't even realise you used \package{cleveref}! % % The {\tt sed} script is written to the same directory as the (main) % \LaTeX{} source file, and given the same name as that source file but % with the extension \file{.sed}. To process your document through the % script, all you need to do is run the following from your shell: % \begin{quote} % sed -f \meta{name}\file{.sed} \ % \meta{name}\file{.tex} \textgreater \meta{newname}\file{.tex} % \end{quote} % where \meta{name} is the name of the file containing your \LaTeX{} % source file minus the \file{.tex} extension, and \meta{newname} is % whatever you want to call the new version. \emph{Do not} make % \meta{newname} the same as \meta{name}. (It's in any case wise to keep % the original \LaTeX{} source file containing the \package{cleveref} % commands, in case you need to produce an updated version of your % document in the future. Think of the \meta{newname}\file{.tex} file as % being rather like a \file{DVI} file: something you can always reproduce % from the original source.) If your document is composed of a number of % separate \LaTeX{} source files, combined with |\include| commands, only % one {\tt sed} script will be generated, but you will need to run \emph % {each} source file through that \emph{same} script (and probably modify % the |\include| commands to match the new file names). % % % % \section{Interaction with Other Packages} % \label{sec:other_packages} % The \package{cleveref} package \emph{must} be loaded \emph{after} all % other packages that don't specifically support it\footnote{At the time % of writing, I'm not aware of any that do.}, i.e.\ the % \begin{quote} % |\usepackage{cleveref}| % \end{quote} % line should always be the last |\usepackage| command in your document's % preamble. % % Since \package{cleveref} redefines many internal commands involved in % \LaTeX{}'s referencing system, it can interact badly with other % packages that do the same. \package{varioref}'s enhanced referencing % features (the ones 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 packages' % 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} % In fact, \package{cleveref} does this for you automatically if % \package{ntheorem} was loaded with the \option{thref} option. Note that % you can still use the other features of \package{varioref} and % \package{ntheorem} whilst using \package{cleveref}, as long as % \package{cleveref} is loaded \emph{last}. % % Other packages which alter the \LaTeX{} referencing system are unlikely % to work properly with \package{cleveref}. % % % % \section{Known Bugs and Word-Arounds} % In no particular order. % \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 When both the \package{amsmath} \emph{and} \package{hyperref} % packages are loaded at the same time, the \package{cleveref} % cross-referencing commands will not work in section titles. If anyone % can figure out why, let me know! % \item \package{cleveref} provides no \package{babel} support. (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 The \option{poorman} sed script always uses |\ref| rather than % |\ref*|, even if the command it's replacing is a starred variant % |\cref*|, |\crefrange*| etc. (This should be fixed in a future % version.) % \item The \option{poorman} sed script uses |\ref| when replacing % \package{cleveref} cross-references, but this loses any custom % \package{cleveref} hyper-link formatting you might have defined. The % philosophy behind the \option{poorman} option is to replace % \package{cleveref}'s enhanced cross-referencing with standard % \LaTeX{} cross-reference commands that are guaranteed to work with % any standard \LaTeX{} installation. Although it would be simple to % fix this ``bug'', it's not obvious how to do it without compromising % this underlying philosophy, i.e.\ without using \LaTeX{} code that is % unlikely to be supported by journals. % \end{itemize} % % % % \section{Possible Future Improvements} % In no particular order. % \begin{itemize} % \item Allow reference-range collapsing to be disabled entirely via a % package option % \item Add an option to automatically sort references in a % multi-reference before typesetting them. % \item Enhance the \option{poorman} option to allow a choice of script % language rather than just sed (e.g.\ awk, perl, \dots?). % \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 \cmd{\cref} commands which use 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 type 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 \texttt{required} \LaTeX{} package). % % % \subsection{Redefinitions of \LaTeX{} kernel macros} % We store the original \cmd{\refstepcounter} in % \cmd{\cref@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\cref@old@refstepcounter\refstepcounter \def\refstepcounter{% \@ifnextchar[{\refstepcounter@optarg}{\refstepcounter@noarg}%] } \def\refstepcounter@noarg#1{% \cref@old@refstepcounter{#1}% \cref@resetby{#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{% \cref@old@refstepcounter{#2}% \cref@resetby{#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} % % We redefine the \cmd{\label} command to allow it to take an optional % argument that overrides the default reference type in % \cmd{\@currentlabel}. We have to postpone this redefinition of % \cmd{\label} until the beginning of the document because some other % packages do too, and we need to override their redefinitions. % \begin{macrocode} \def\cref@override@label@type[#1][#2][#3]#4\@nil#5{[#5][#2][#3]#4} \AtBeginDocument{% \let\cref@old@label\label \def\label{\@ifnextchar[\label@optarg\cref@old@label}%] \def\label@optarg[#1]{% \protected@edef\@currentlabel{% \expandafter\cref@override@label@type\@currentlabel\@nil{#1}}% \cref@old@label}% % \end{macrocode} % % The \package{amsmath} package redefines the \cmd{\label} command within % equation environments, so if it is loaded we have to extend the % behaviour to support the optional argument. With \package{amsmath}, the % original \cmd{\label} command in stored in \cmd{ltx@label}, and % \cmd{\label@in@display} replaces \cmd{label} inside % equations. \cmd{\label@in@display} just saves the label for later, and % defining it is left until the end of the equation, when % \cmd{\ltx@label} is finally called. % % To allow \cmd{label} within equations to support an optional argument, % we first store the original \cmd{\label@in@display} and the new % \cmd{\label} macro we defined above (since \cmd{\label} will be % clobbered inside equations). Then we redefine \cmd{label@in@display} so % that it wraps all its arguments, including any optional argument, in an % extra set of braces \{\}. These are stripped away again by % \cmd{\ltx@label} before calling the \cmd{\label} macro we defined above % (saved in \cmd{\cref@label}). % \begin{macrocode} \@ifpackageloaded{amsmath}{% \let\cref@label\label% \let\cref@old@label@in@display\label@in@display% \def\label@in@display{% \@ifnextchar[\label@in@display@optarg\label@in@display@noarg}%] \def\label@in@display@noarg#1{\cref@old@label@in@display{{#1}}} \def\label@in@display@optarg[#1]#2{% \cref@old@label@in@display{[#1]{#2}}} \def\ltx@label#1{\cref@label#1}% }{}% } % \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. We % add a level of redirection to make it easier in case we need to % redefine it for \package{hyperref} later. % \begin{macrocode} \def\cref@reflabel#1#2{\@result} \AtBeginDocument{% \DeclareRobustCommand{\ref}{\cref@ref} \def\cref@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@reflabel}{#1}}% } % \end{macrocode} % % The \cmd{\appendix} command causes the top-level sectioning commands % (\cmd{\chapter} or \cmd{\section}, depending on the document class) to % produce appendices instead. Since we want to be able to format % references to appendices separately from references to normal top-level % sections, we add to the tasks that \cmd{\appendix} does: it redefines % \cmd{\refstepcounter@noarg} to exceptionally override the label type % for chapters or sections, as appropriate, setting it to ``appendix'' % instead. % \begin{macrocode} \let\cref@old@appendix\appendix \renewcommand\appendix{% \cref@old@appendix% \@ifundefined{chapter}{% \def\refstepcounter@noarg##1{% \cref@old@refstepcounter{##1}% \cref@resetby{##1}{\@result}% \ifx\@result\relax\def\@result{}% \else\edef\@result{\csname the\@result\endcsname}\fi% \def\@tmpa{##1} \def\@tmpb{section}% \ifx\@tmpa\@tmpb% \protected@edef\@currentlabel{% [appendix][\arabic{##1}][\@result]\@currentlabel}% \else \protected@edef\@currentlabel{% [##1][\arabic{##1}][\@result]\@currentlabel} \fi} }{% \def\refstepcounter@noarg##1{% \cref@old@refstepcounter{##1}% \cref@resetby{##1}{\@result}% \ifx\@result\relax\def\@result{}% \else\edef\@result{\csname the\@result\endcsname}\fi% \def\@tmpa{##1} \def\@tmpb{chapter}% \ifx\@tmpa\@tmpb% \protected@edef\@currentlabel{% [appendix][\arabic{##1}][\@result]\@currentlabel}% \else \protected@edef\@currentlabel{% [##1][\arabic{##1}][\@result]\@currentlabel} \fi}% }% } % \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 other 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\@tmpa\csname r@#1\endcsname% \edef\@tmpa{\expandafter\@firstoftwo\@tmpa}% \expandafter\@cref@getlabel\@tmpa\@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\@tmpa\csname r@#1\endcsname% \edef\@tmpa{\expandafter\@firstoftwo\@tmpa}% \expandafter\@cref@gettype\@tmpa\@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\@tmpa\csname r@#1\endcsname% \edef\@tmpa{\expandafter\@firstoftwo\@tmpa}% \expandafter\@cref@getcounter\@tmpa\@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\@tmpa\csname r@#1\endcsname% \edef\@tmpa{\expandafter\@firstoftwo\@tmpa}% \expandafter\@cref@getprefix\@tmpa\@nil#2} \def\@cref@getprefix{\@ifnextchar[%] \@@cref@getprefix{\@@cref@getprefix[][][]}} \def\@@cref@getprefix[#1][#2][#3]#4\@nil#5{\def#5{#3}} % \end{macrocode} % % A basic utility macro for appending tokens to a token register. % \begin{macrocode} \def\cref@append@toks#1#2{\toks0={#2}% \edef\act{\noexpand#1={\the#1\the\toks0}}% \act}% % \end{macrocode} % % We treat 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\cref@stack@init#1{\def#1{\@nil}} \def\cref@stack@top#1{\expandafter\cref@stack@top@aux#1} \def\cref@stack@top@aux#1,#2\@nil{#1} \def\cref@stack@pop#1{\expandafter\cref@stack@pop@aux#1#1} \def\cref@stack@pop@aux#1,#2\@nil#3{\def#3{#2\@nil}} \def\cref@stack@push#1#2{% \expandafter\cref@stack@push@aux\expandafter{#2}{#1}{#2}} \def\cref@stack@push@aux#1#2#3{\def#3{#2,#1}} \def\cref@stack@pull#1#2{\expandafter\cref@stack@pull@aux#2{#1}{#2}} \def\cref@stack@pull@aux#1\@nil#2#3{\def#3{#1#2,\@nil}} \newif\if@cref@stackempty \newif\if@cref@stackfull \def\cref@isstackempty#1{% \def\@tmpa{\@nil}% \ifx#1\@tmpa\@cref@stackemptytrue% \else\@cref@stackemptyfalse\fi} \def\cref@isstackfull#1{% \def\@tmpa{\@nil}% \ifx#1\@tmpa\@cref@stackfullfalse% \else\@cref@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 (value is returned % by defining its second argument, which should be a macro name). % \begin{macrocode} \newif\if@cref@inresetlist \def\cref@isinresetlist#1#2{% \def\@counter{#1}% \begingroup% \def\@elt##1{##1,}% \expandafter\ifx\csname cl@#2\endcsname\relax% \gdef\cref@resetstack{,\@nil}% \else% \xdef\cref@resetstack{\csname cl@#2\endcsname\noexpand\@nil}% \fi% \endgroup% \cref@isstackfull{\cref@resetstack}% \@whilesw\if@cref@stackfull\fi{% \edef\@nextcounter{\cref@stack@top{\cref@resetstack}}% \ifx\@nextcounter\@counter% \@cref@stackfullfalse% \else% \let\@nextcounter\relax% \cref@stack@pop{\cref@resetstack}% \cref@isstackfull{\cref@resetstack}% \fi}% \ifx\@nextcounter\relax% \@cref@inresetlistfalse% \else% \@cref@inresetlisttrue% \fi} % \def\cref@resetby#1#2{% \cref@isinresetlist{#1}{subsubsubsection}% \if@cref@inresetlist% \def#2{subsubsubsection}% \else% \cref@isinresetlist{#1}{subsubsection}% \if@cref@inresetlist% \def#2{subsubsection}% \else% \cref@isinresetlist{#1}{subsection}% \if@cref@inresetlist% \def#2{subsection}% \else% \cref@isinresetlist{#1}{section}% \if@cref@inresetlist% \def#2{section}% \else% \cref@isinresetlist{#1}{chapter}% \if@cref@inresetlist% \def#2{chapter}% \else% \cref@isinresetlist{#1}{part}% \if@cref@inresetlist% \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} \DeclareRobustCommand{\cref}[1]{\@cref{cref}{#1}} \DeclareRobustCommand{\Cref}[1]{\@cref{Cref}{#1}} \DeclareRobustCommand{\crefrange}[2]{\@setcrefrange{#1}{#2}{cref}{}} \DeclareRobustCommand{\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% \def\@empty{}% \newif\if@firstgroup% \newif\if@secondgroup% \newif\if@secondref% \cref@stack@init{\@refstack}% \cref@stack@push{#2}{\@refstack}% \@firstgrouptrue% \@secondgroupfalse% \cref@isstackfull{\@refstack}% % \end{macrocode} % Loop until the reference stack is empty. % \begin{macrocode} \@whilesw\if@cref@stackfull\fi{% \cref@stack@init{\@refsubstack}% \edef\@nextref{\cref@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\cref@stack@pull\expandafter% {\@nextref}{\@refsubstack}% \cref@stack@pop{\@refstack}% \cref@isstackempty{\@refstack}% \if@cref@stackempty% \def\@nexttype{\relax}% \else% \edef\@nextref{\cref@stack@top{\@refstack}}% \ifx\@nextref\@empty% \let\@currenttype\@nexttype% \else% \expandafter\ifx\csname r@\@nextref\endcsname\relax% \def\@currenttype{\@undefined}% \else% \expandafter\cref@gettype\expandafter% {\@nextref}{\@currenttype}% \fi% \fi% \fi}% % \end{macrocode} % % Typeset appropriate conjunction between groups of reference types. % \begin{macrocode} \if@firstgroup% \@firstgroupfalse% \@secondgrouptrue% \else% \cref@isstackfull{\@refstack}% \if@cref@stackfull% \@setcref@middlegroupconjunction% \else% \if@secondgroup% \@setcref@pairgroupconjunction% \else% \@setcref@lastgroupconjunction% \fi% \fi% \@secondgroupfalse% \fi% % \end{macrocode} % % Process first group of consecutive references from substack. % \begin{macrocode} \edef\@nextref{\cref@stack@top{\@refsubstack}}% \cref@stack@pop{\@refsubstack}% % \end{macrocode} % If the substack only contains one reference, typeset it, % \begin{macrocode} \cref@isstackempty{\@refsubstack}% \if@cref@stackempty% \expandafter\@setcref\expandafter{\@nextref}{#1}{}% % \end{macrocode} % otherwise, find end of consecutive references. % \begin{macrocode} \else% \edef\@beginref{\@nextref}% \let\@endref\relax% \edef\@nextref{\cref@stack@top{\@refsubstack}}% \count@consecutive=1% \expandafter\ifx\csname r@\@beginref\endcsname\relax% \@cref@refconsecutivefalse% \else% % \end{macrocode} % If next reference in substack is empty, it indicates that no further % collapsing should take place. Having served its purpose, the empty % reference and any consecutive empty references are removed from the % substack. % \begin{macrocode} \ifx\@nextref\@empty% \@cref@refconsecutivefalse% \@whilesw\ifx\@nextref\@empty\fi{% \cref@stack@pop{\@refsubstack}% \cref@isstackempty{\@refsubstack}% \if@cref@stackempty% \let\@nextref\relax% \else% \edef\@nextref{\cref@stack@top{\@refsubstack}}% \fi% }% \ifnum\count@consecutive=2% \edef\@endref{\@endref,}% \fi% % \end{macrocode} % Otherwise, test whether next reference is consecutive or not. % \begin{macrocode} \else% \expandafter\ifx\csname r@\@nextref\endcsname\relax% \@cref@refconsecutivefalse% \else% \edef\@tmpa{{\@beginref}{\@nextref}}% \expandafter\cref@isrefconsecutive\@tmpa% \fi% \fi% \fi% \@whilesw\if@cref@refconsecutive\fi{% \advance\count@consecutive 1% \let\@endref\@nextref% \cref@stack@pop{\@refsubstack}% \cref@isstackempty{\@refsubstack}% \if@cref@stackempty% \@cref@refconsecutivefalse% \else% \edef\@nextref{\cref@stack@top{\@refsubstack}}% % \end{macrocode} % Test whether next reference is empty; % \begin{macrocode} \ifx\@nextref\@empty% \@cref@refconsecutivefalse% \@whilesw\ifx\@nextref\@empty\fi{% \cref@stack@pop{\@refsubstack}% \cref@isstackempty{\@refsubstack}% \if@cref@stackempty% \let\@nextref\relax% \else% \edef\@nextref{\cref@stack@top{\@refsubstack}}% \fi% }% \ifnum\count@consecutive=2% \edef\@endref{\@endref,}% \fi% % \end{macrocode} % otherwise, test whether next reference is consecutive or not. % \begin{macrocode} \else% \expandafter\ifx\csname r@\@nextref\endcsname\relax% \@cref@refconsecutivefalse% \else% \edef\@tmpa{{\@endref}{\@nextref}}% \expandafter\cref@isrefconsecutive\@tmpa% \fi% \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}% % \end{macrocode} % if there were only two consecutive references, typeset the first % one and return the second to the substack; % \begin{macrocode} \else% \ifnum\count@consecutive=2% \expandafter\@setcref\expandafter{\@beginref}{#1}{@first}% \expandafter\cref@stack@push\expandafter% {\@endref}{\@refsubstack}% % \end{macrocode} % otherwise, typeset a reference range. % \begin{macrocode} \else% \edef\@tmpa{{\@beginref}{\@endref}}% \if@cref@stackempty% \expandafter\@setcrefrange\@tmpa{#1}{}% \else% \expandafter\@setcrefrange\@tmpa{#1}{@first}% \fi% \fi% \fi% % \end{macrocode} % % Process further groups of consecutive references, until substack % is empty. % \begin{macrocode} \@secondreftrue% \cref@isstackfull{\@refsubstack}% \@whilesw\if@cref@stackfull\fi{% \edef\@beginref{\cref@stack@top{\@refsubstack}}% \cref@stack@pop{\@refsubstack}% \let\@endref\relax% % \end{macrocode} % If substack only contains only one reference, typeset it, % \begin{macrocode} \cref@isstackempty{\@refsubstack}% \if@cref@stackempty% \if@secondref% \expandafter\@setcref\expandafter{\@beginref}{#1}{@second}% \else% \expandafter\@setcref\expandafter{\@beginref}{#1}{@last}% \fi% % \end{macrocode} % otherwise, find end of consecutive references. % \begin{macrocode} \else% \edef\@nextref{\cref@stack@top{\@refsubstack}}% \count@consecutive=1% % \end{macrocode} % Test whether next reference is empty; % \begin{macrocode} \ifx\@nextref\@empty% \@cref@refconsecutivefalse% \@whilesw\ifx\@nextref\@empty\fi{% \cref@stack@pop{\@refsubstack}% \cref@isstackempty{\@refsubstack}% \if@cref@stackempty% \let\@nextref\relax% \else% \edef\@nextref{\cref@stack@top{\@refsubstack}}% \fi% }% \ifnum\count@consecutive=2% \edef\@endref{\@endref,}% \fi% % \end{macrocode} % otherwise, test whether next reference is consecutive or not. % \begin{macrocode} \else% \expandafter\ifx\csname r@\@nextref\endcsname\relax% \@cref@refconsecutivefalse% \else% \edef\@tmpa{{\@beginref}{\@nextref}}% \expandafter\cref@isrefconsecutive\@tmpa% \fi% \fi% \@whilesw\if@cref@refconsecutive\fi{% \advance\count@consecutive 1% \let\@endref\@nextref% \cref@stack@pop{\@refsubstack}% \cref@isstackempty{\@refsubstack}% \if@cref@stackempty% \@cref@refconsecutivefalse% \else% \edef\@nextref{\cref@stack@top{\@refsubstack}}% % \end{macrocode} % Test whether next reference is empty; % \begin{macrocode} \ifx\@nextref\@empty% \@cref@refconsecutivefalse% \@whilesw\ifx\@nextref\@empty\fi{% \cref@stack@pop{\@refsubstack}% \cref@isstackempty{\@refsubstack}% \if@cref@stackempty% \let\@nextref\relax% \else% \edef\@nextref{\cref@stack@top{\@refsubstack}}% \fi% }% \ifnum\count@consecutive=2% \edef\@endref{\@endref,}% \fi% % \end{macrocode} % otherwise, test whether next reference is consecutive or not. % \begin{macrocode} \else% \expandafter\ifx\csname r@\@nextref\endcsname\relax% \@cref@refconsecutivefalse% \else% \edef\@tmpa{{\@endref}{\@nextref}}% \expandafter\cref@isrefconsecutive\@tmpa% \fi% \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} \cref@isstackempty{\@refsubstack}% \if@cref@stackempty% \if@secondref% \def\@pos{@second}% \else% \def\@pos{@last}% \fi% \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% \expandafter\@setcref\expandafter% {\@beginref}{#1}{@middle}% \expandafter\cref@stack@push\expandafter% {\@endref}{\@refsubstack}% % \end{macrocode} % otherwise, typeset a reference range. % \begin{macrocode} \else% \edef\@tmpa{{\@beginref}{\@endref}{#1}{\@pos}}% \expandafter\@setcrefrange\@tmpa% \fi% \fi% \fi% \@secondreffalse% \cref@isstackfull{\@refsubstack}% }% end loop over reference substack \fi% \cref@isstackfull{\@refstack}% }% end loop over main reference stack \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\if@cref@refconsecutive% \def\cref@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{\@cref@refconsecutivefalse}% \ifx\refa@prefix\refb@prefix% \ifnum\refa@counter=\refb@counter% \def\@after{\@cref@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{% \begingroup% % \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 range 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% \expandafter\@@setcrefrange\expandafter{\@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% \endgroup} % \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} % % % The typesetting of conjunctions is also separated out into separate % macros, for the same reason. % \begin{macrocode} \def\@setcref@pairgroupconjunction{\crefpairgroupconjunction} \def\@setcref@middlegroupconjunction{\crefmiddlegroupconjunction} \def\@setcref@lastgroupconjunction{\creflastgroupconjunction} % \end{macrocode} % % % % \subsection{Reference Format Customisation Commands} % % \subsubsection{Format Component Commands} % The reference formats are usually constructed out of components defined % by the user-level \cmd{\crefname}, \cmd{\Crefname}, \cmd{\creflabel} % and \cmd{\crefrangelabel} commands. They simply use the supplied % arguments to define appropriately named macros containing the % formatting components. If the corresponding \cmd{\Crefname} or % \cmd{\crefname} variant is not already defined, \cmd{\crefname} and % \cmd{\Crefname} define it to be a version with the first letter % capitalised or lower-cased, respectively. \cmd{\@crefdefineallformats} % is then called to define all the formats from the new components. % \begin{macrocode} \newcommand{\crefdefaultlabelformat}[1]{% \def\cref@default@label##1##2##3{#1}} \newcommand{\crefname}[3]{% \@crefname{cref}{#1}{#2}{#3}% \@crefdefineallformats{#1}} \newcommand{\Crefname}[3]{% \@crefname{Cref}{#1}{#2}{#3}% \@crefdefineallformats{#1}} \newcommand{\creflabelformat}[2]{% \@creflabelformat{#1}{#2}% \@crefdefineallformats{#1}} \newcommand{\crefrangelabelformat}[2]{% \@crefrangelabelformat{#1}{#2}% \@crefdefineallformats{#1}} \def\@creflabelformat#1#2{% \expandafter\def\csname cref@#1@label\endcsname##1##2##3{#2}} \def\@crefrangelabelformat#1#2{% \expandafter\def\csname cref@#1@rangelabel\endcsname% ##1##2##3##4##5##6{#2}} % \end{macrocode} % % The \cmd{\@crefname} utility macro does the real work of defining % format names, by defining an appropriately named command to contain the % format component, and using the first argument (``cref'' of ``Cref'') % to determine how to define the corresponding command with the other % capitalisation. % \begin{macrocode} \def\@crefname#1#2#3#4{% \begingroup% \expandafter\gdef\csname #1@#2@name\endcsname{#3}% \expandafter\gdef\csname #1@#2@name@plural\endcsname{#4}% % \end{macrocode} % The following \cmd{\@tmpa} macro makes use of the fact that the first % character of \#1 is ``c'' for lower-case and ``C'' for upper-case, in % order to wrap the capitalisation-dependent parts in macros so that the % rest of the code can be capitalisation-variant agnostic. % \begin{macrocode} \def\@tmpa##1##2\@nil{% \if##1c% \def\@other{C##2}% \def\@changecase{\MakeUppercase}% \else% \def\@other{c##2}% \def\@changecase{\MakeLowercase}% \fi}% \@tmpa#1\@nil% % \end{macrocode} % If the other capitalisation variant is not already defined... % \begin{macrocode} \@ifundefined{\@other @#2@name}{% % \end{macrocode} % Define \cmd{\@tmpa} and \cmd{@tmpb} to be partial expansions (expanded % just once) of the macros for the capitalisation variant we've just % defined above. The \cmd{\@toska} token register just makes the code % less verbose. % \begin{macrocode} \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpa% \expandafter\expandafter\expandafter{% \csname#1@#2@name\endcsname}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpb% \expandafter\expandafter\expandafter{% \csname#1@#2@name@plural\endcsname}% % \end{macrocode} % Add the \cmd{\@changecase} command to the front of the definitions of % \cmd{\@tmpa} and \cmd{\@tmpb}. % \begin{macrocode} \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpa% \expandafter\expandafter\expandafter{% \expandafter\@changecase\@tmpa}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpb% \expandafter\expandafter\expandafter{% \expandafter\@changecase\@tmpb}% % \end{macrocode} % Define the other capitalisation variants to be the partial expansions % (expanded just once) of \cmd{\@tmpa} and \cmd{\@tmpb}. % \begin{macrocode} \toksdef\@toksa=0% \@toksa={% \expandafter\gdef\csname\@other @#2@name\endcsname}% \expandafter\the\expandafter\@toksa\expandafter{\@tmpa}% \@toksa={% \expandafter\gdef\csname\@other @#2@name@plural\endcsname}% \expandafter\the\expandafter\@toksa\expandafter{\@tmpb}% }{}% \endgroup} % \end{macrocode} % % % \cmd{\@crefconstructcomponents} utility macro puts the reference format % components for the specified reference type into temporary macros, for % use by later macros. The ridiculous number of ``\#'' characters ensure % that enough are left when they come to be used later (pairs ``\#\#'' % are collapsed to a single ``\#'' each time the code is expanded). % \begin{macrocode} \def\@crefconstructcomponents#1{% \@ifundefined{cref@#1@label}{% \let\@tmplabel\cref@default@label% }{% \expandafter\let\expandafter\@tmplabel% \csname cref@#1@label\endcsname% }% \@ifundefined{cref@#1@rangelabel}{% \expandafter\def\expandafter\@tmpa\expandafter{% \@tmplabel{####1}{####3}{####4}}% \expandafter\def\expandafter\@tmpb\expandafter{% \@tmplabel{####2}{####5}{####6}}% \toksdef\@toksa=0% \@toksa={\def\@tmprangelabel##1##2##3##4##5##6}% \expandafter\expandafter\expandafter\expandafter% \expandafter\expandafter\expandafter\the% \expandafter\expandafter\expandafter\expandafter% \expandafter\expandafter\expandafter\@toksa% \expandafter\expandafter\expandafter\expandafter% \expandafter\expandafter\expandafter{% \expandafter\expandafter\expandafter\@tmpa% \expandafter\crefrangeconjunction\@tmpb}% }{% \expandafter\let\expandafter\@tmprangelabel% \csname cref@#1@rangelabel\endcsname% }% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpname% \expandafter\expandafter\expandafter{% \csname cref@#1@name\endcsname}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpName% \expandafter\expandafter\expandafter{% \csname Cref@#1@name\endcsname}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpnameplural% \expandafter\expandafter\expandafter{% \csname cref@#1@name@plural\endcsname}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpNameplural% \expandafter\expandafter\expandafter{% \csname Cref@#1@name@plural\endcsname}% \expandafter\def\expandafter\@tmplabel\expandafter{% \@tmplabel{########1}{########2}{########3}}% \expandafter\def\expandafter\@tmprangelabel\expandafter{% \@tmprangelabel{########1}{########2}{########3}% {########4}{########5}{########6}}% } % \end{macrocode} % % The \cmd{\@crefdefineformat} et al.\ macros construct calls to % \cmd{\crefformat} et al.\ for the supplied reference type that define % the corresponding formats in terms of the format components. This is % mostly just an arduous exercise in controlling macro expansion order. % \begin{macrocode} \def\@crefdefineformat#1{% \begingroup% % \end{macrocode} % put format components into tmp macros % \begin{macrocode} \@crefconstructcomponents{#1}% % \end{macrocode} % Assemble the arguments for \cmd{\crefformat} and \cmd{\Crefformat} from % the components. % \begin{macrocode} \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpfirst% \expandafter\expandafter\expandafter{% \expandafter\@tmpname\expandafter~\@tmplabel}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpFirst% \expandafter\expandafter\expandafter{% \expandafter\@tmpName\expandafter~\@tmplabel}% % \end{macrocode} % Define \cmd{\crefformat} and \cmd{\Crefformat}. % \begin{macrocode} \toksdef\@toksa=0% \@toksa={\crefformat{#1}}% \expandafter\the\expandafter\@toksa\expandafter{\@tmpfirst}% \@toksa={\Crefformat{#1}}% \expandafter\the\expandafter\@toksa\expandafter{\@tmpFirst}% \endgroup} % \def\@crefrangedefineformat#1{% \begingroup% % \end{macrocode} % put format components into tmp macros % \begin{macrocode} \@crefconstructcomponents{#1}% % \end{macrocode} % Assemble the arguments for \cmd{\crefrangeformat} and % \cmd{\Crefrangeformat} from the components. % \begin{macrocode} \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpfirst% \expandafter\expandafter\expandafter{% \expandafter\@tmpnameplural\expandafter~\@tmprangelabel}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpFirst% \expandafter\expandafter\expandafter{% \expandafter\@tmpNameplural\expandafter~\@tmprangelabel}% % \end{macrocode} % Define \cmd{\crefrangeformat} and \cmd{\Crefrangeformat}. % \begin{macrocode} \toksdef\@toksa=0% \@toksa={\crefrangeformat{#1}}% \expandafter\the\expandafter\@toksa\expandafter{\@tmpfirst}% \@toksa={\Crefrangeformat{#1}}% \expandafter\the\expandafter\@toksa\expandafter{\@tmpFirst}% \endgroup} % \def\@crefdefinemultiformat#1{% \begingroup% % \end{macrocode} % put format components into tmp macros % \begin{macrocode} \@crefconstructcomponents{#1}% % \end{macrocode} % Assemble the arguments for \cmd{\crefmultiformat} and % \cmd{\Crefmultiformat} from the components. % \begin{macrocode} \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpfirst% \expandafter\expandafter\expandafter{% \expandafter\@tmpnameplural\expandafter~\@tmplabel}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpFirst% \expandafter\expandafter\expandafter{% \expandafter\@tmpNameplural\expandafter~\@tmplabel}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpsecond% \expandafter\expandafter\expandafter{% \expandafter\crefpairconjunction\@tmplabel}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpmiddle% \expandafter\expandafter\expandafter{% \expandafter\crefmiddleconjunction\@tmplabel}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmplast% \expandafter\expandafter\expandafter{% \expandafter\creflastconjunction\@tmplabel}% % \end{macrocode} % Bundle all four arguments for \cmd{\crefmultiformat} in token register % \cmd{\@toksb}, then call it. % \begin{macrocode} \toksdef\@toksa=0% \toksdef\@toksb=1% \@toksb={}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpfirst}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpsecond}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpmiddle}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmplast}}% \@toksa={\crefmultiformat{#1}}% \expandafter\the\expandafter\@toksa\the\@toksb% % \end{macrocode} % Bundle all four arguments for \cmd{\Crefmultiformat} in token register % \cmd{\@toksb}, then call it. % \begin{macrocode} \@toksb={}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpFirst}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpsecond}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpmiddle}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmplast}}% \@toksa={\Crefmultiformat{#1}}% \expandafter\the\expandafter\@toksa\the\@toksb% \endgroup} % \def\@crefrangedefinemultiformat#1{% \begingroup% % \end{macrocode} % put format components into tmp macros % \begin{macrocode} \@crefconstructcomponents{#1}% % \end{macrocode} % Assemble the arguments that need to be passed to % \cmd{\crefrangemultiformat} and \cmd{\Crefrangemultiformat} from the % reference components. % \begin{macrocode} \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpfirst% \expandafter\expandafter\expandafter{% \expandafter\@tmpnameplural\expandafter~\@tmprangelabel}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpFirst% \expandafter\expandafter\expandafter{% \expandafter\@tmpNameplural\expandafter~\@tmprangelabel}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpsecond% \expandafter\expandafter\expandafter{% \expandafter\crefpairconjunction\@tmprangelabel}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmpmiddle% \expandafter\expandafter\expandafter{% \expandafter\crefmiddleconjunction\@tmprangelabel}% \expandafter\expandafter\expandafter\def% \expandafter\expandafter\expandafter\@tmplast% \expandafter\expandafter\expandafter{% \expandafter\creflastconjunction\@tmprangelabel}% % \end{macrocode} % Bundle all four arguments for \cmd{\crefrangemultiformat} in token % register \cmd{\@toksb}, then call it. % \begin{macrocode} \toksdef\@toksa=0% \toksdef\@toksb=1% \@toksb={}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpfirst}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpsecond}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpmiddle}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmplast}}% \@toksa={\crefrangemultiformat{#1}}% \expandafter\the\expandafter\@toksa\the\@toksb% % \end{macrocode} % Bundle all four arguments for \cmd{\Crefrangemultiformat} in token % register \cmd{\@toksb}, then call it. % \begin{macrocode} \@toksb={}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpFirst}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpsecond}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmpmiddle}}% \expandafter\cref@append@toks\expandafter\@toksb\expandafter{% \expandafter{\@tmplast}}% \@toksa={\Crefrangemultiformat{#1}}% \expandafter\the\expandafter\@toksa\the\@toksb% \endgroup} % \end{macrocode} % % \cmd{\@crefdefineallformats} calls each of the above, to define all % formats for the given type from the corresponding components. % \begin{macrocode} \def\@crefdefineallformats#1{% \@crefdefineformat{#1}% \@crefrangedefineformat{#1}% \@crefdefinemultiformat{#1}% \@crefrangedefinemultiformat{#1}} % \end{macrocode} % % % \subsubsection{Format Definition Commands}\label{sec:crefformat} % \cmd{\crefformat} et al.\ are lower-level user commands that give % complete control over the format of different reference types. They % override the component-based formats, simply using the supplied % arguments to define appropriately named formatting macros, 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}[5]{% \@crefmultiformat{cref}{#1}{#2}{#3}{#4}{#5}} \newcommand{\Crefmultiformat}[5]{% \@crefmultiformat{Cref}{#1}{#2}{#3}{#4}{#5}} \newcommand{\crefrangemultiformat}[5]{% \@crefrangemultiformat{crefrange}{#1}{#2}{#3}{#4}{#5}} \newcommand{\Crefrangemultiformat}[5]{% \@crefrangemultiformat{Crefrange}{#1}{#2}{#3}{#4}{#5}} % \end{macrocode} % % The utility macros do the real work, by using the first argument % (``cref'' or ``Cref'', and ``crefrange'' or ``Crefrange'') to determine % how to define the corresponding command with the other capitalisation. % \begin{macrocode} \def\@crefformat#1#2#3{% \begingroup% \expandafter\gdef\csname #1@#2@format\endcsname##1##2##3{#3}% % \end{macrocode} % The following \cmd{\@tmpa} macro makes use of the fact that the first % character of \#1 is ``c'' for lower-case and ``C'' for upper-case, in % order to wrap the capitalisation-dependent parts in macros so that the % rest of the code can be capitalisation-variant agnostic. % \begin{macrocode} \def\@tmpa##1##2\@nil{% \if##1c% \def\@other{C##2}% \def\@changecase{\MakeUppercase}% \else% \def\@other{c##2}% \def\@changecase{\MakeLowercase}% \fi}% \@tmpa#1\@nil% % \end{macrocode} % If the other capitalisation variant is not already defined... % \begin{macrocode} \@ifundefined{\@other @#2@format}{% % \end{macrocode} % Define \cmd{\@tmpa} to be a partial expansion (expanded just once) of % the capitalisation variant we've just defined above. The \cmd{\@toska} % token register just makes the code less verbose. % \begin{macrocode} \toksdef\@toksa=0% \@toksa={\def\@tmpa##1##2##3}% \expandafter\expandafter\expandafter\the% \expandafter\expandafter\expandafter\@toksa% \expandafter\expandafter\expandafter{% \csname#1@#2@format\endcsname{##1}{##2}{##3}}% % \end{macrocode} % Add the \cmd{\@changecase} command to the front of the definition of % \cmd{\@tmpa}. % \begin{macrocode} \expandafter\expandafter\expandafter\the% \expandafter\expandafter\expandafter\@toksa% \expandafter\expandafter\expandafter{% \expandafter\@changecase\@tmpa{##1}{##2}{##3}}% % \end{macrocode} % Define the other capitalisation variant to be the partial expansion % (expanded just once) of \cmd{\@tmpa}. % \begin{macrocode} \@toksa={% \expandafter\gdef\csname\@other @#2@format\endcsname##1##2##3}% \expandafter\the\expandafter\@toksa\expandafter{% \@tmpa{##1}{##2}{##3}}% }{}% \endgroup} % \def\@crefrangeformat#1#2#3{% \begingroup% \expandafter\gdef\csname #1@#2@format\endcsname% ##1##2##3##4##5##6{#3}% % \end{macrocode} % The following \cmd{\@tmpa} macro makes use of the fact that the first % character of \#1 is ``c'' for lower-case and ``C'' for upper-case, in % order to wrap the capitalisation-dependent parts in macros so that the % rest of the code can be capitalisation-variant agnostic. % \begin{macrocode} \def\@tmpa##1##2\@nil{% \if##1c% \def\@other{C##2}% \def\@changecase{\MakeUppercase}% \else% \def\@other{c##2}% \def\@changecase{\MakeLowercase}% \fi}% \@tmpa#1\@nil% % \end{macrocode} % If the other capitalisation variant is not already defined... % \begin{macrocode} \@ifundefined{\@other @#2@format}{% % \end{macrocode} % Define \cmd{\@tmpa} to be a partial expansion (expanded just once) of % the capitalisation variant we've just defined above. The \cmd{\@toska} % token register just makes the code less verbose. % \begin{macrocode} \toksdef\@toksa=0% \@toksa={\def\@tmpa##1##2##3##4##5##6}% \expandafter\expandafter\expandafter\the% \expandafter\expandafter\expandafter\@toksa% \expandafter\expandafter\expandafter{% \csname#1@#2@format\endcsname{##1}{##2}{##3}{##4}{##5}{##6}}% % \end{macrocode} % Add the \cmd{\@changecase} command to the front of the definition of % \cmd{\@tmpa}. % \begin{macrocode} \expandafter\expandafter\expandafter\the% \expandafter\expandafter\expandafter\@toksa% \expandafter\expandafter\expandafter{% \expandafter\@changecase\@tmpa{##1}{##2}{##3}{##4}{##5}{##6}}% % \end{macrocode} % Define the other capitalisation variant to be the partial expansion % (expanded just once) of \cmd{\@tmpa}. % \begin{macrocode} \@toksa={\expandafter\gdef% \csname\@other @#2@format\endcsname##1##2##3##4##5##6}% \expandafter\the\expandafter\@toksa\expandafter{% \@tmpa{##1}{##2}{##3}{##4}{##5}{##6}}% }{}% \endgroup} % \def\@crefmultiformat#1#2#3#4#5#6{% \begingroup% \expandafter\gdef\csname #1@#2@format@first\endcsname##1##2##3{#3}% \expandafter\gdef\csname #1@#2@format@second\endcsname##1##2##3{#4}% \expandafter\gdef\csname #1@#2@format@middle\endcsname##1##2##3{#5}% \expandafter\gdef\csname #1@#2@format@last\endcsname##1##2##3{#6}% % \end{macrocode} % The following \cmd{\@tmpa} macro makes use of the fact that the first % character of \#1 is ``c'' for lower-case and ``C'' for upper-case, in % order to wrap the capitalisation-dependent parts in macros so that the % rest of the code can be capitalisation-variant agnostic. % \begin{macrocode} \def\@tmpa##1##2\@nil{% \if##1c% \def\@other{C##2}% \def\@changecase{\MakeUppercase}% \else% \def\@other{c##2}% \def\@changecase{\MakeLowercase}% \fi}% \@tmpa#1\@nil% % \end{macrocode} % If the other capitalisation variant of the first part of the % multi-format definition is not already defined... % \begin{macrocode} \@ifundefined{\@other @#2@format@first}{% % \end{macrocode} % Define \cmd{\@tmpa} to be a partial expansion (expanded just once) of % the capitalisation variant we've just defined above. The \cmd{\@toska} % token register just makes the code less verbose. % \begin{macrocode} \toksdef\@toksa=0% \@toksa={\def\@tmpa##1##2##3}% \expandafter\expandafter\expandafter\the% \expandafter\expandafter\expandafter\@toksa% \expandafter\expandafter\expandafter{% \csname#1@#2@format@first\endcsname{##1}{##2}{##3}}% % \end{macrocode} % Add the \cmd{\@changecase} command to the front of the definition of % \cmd{\@tmpa}. % \begin{macrocode} \expandafter\expandafter\expandafter\the% \expandafter\expandafter\expandafter\@toksa% \expandafter\expandafter\expandafter{% \expandafter\@changecase\@tmpa{##1}{##2}{##3}}% % \end{macrocode} % Define the other capitalisation variant to be the partial expansion % (expanded just once) of \cmd{\@tmpa}. % \begin{macrocode} \@toksa={% \expandafter\gdef\csname\@other @#2@format@first\endcsname% ##1##2##3}% \expandafter\the\expandafter\@toksa\expandafter{% \@tmpa{##1}{##2}{##3}}% }{}% % \end{macrocode} % The other parts of the multi-format definition are defined to be % identical for both capitalisation variants. % \begin{macrocode} \@ifundefined{\@other @#2@format@second}{% \@toksa={% \expandafter\global\expandafter\let% \csname\@other @#2@format@second\endcsname}% \expandafter\the\expandafter\@toksa% \csname #1@#2@format@second\endcsname% }{}% \@ifundefined{\@other @#2@format@middle}{% \@toksa={% \expandafter\global\expandafter\let% \csname\@other @#2@format@middle\endcsname}% \expandafter\the\expandafter\@toksa% \csname #1@#2@format@middle\endcsname% }{}% \@ifundefined{\@other @#2@format@last}{% \@toksa={% \expandafter\global\expandafter\let% \csname\@other @#2@format@last\endcsname}% \expandafter\the\expandafter\@toksa% \csname #1@#2@format@last\endcsname% }{}% \endgroup} % \def\@crefrangemultiformat#1#2#3#4#5#6{% \begingroup% \expandafter\gdef\csname #1@#2@format@first\endcsname% ##1##2##3##4##5##6{#3}% \expandafter\gdef\csname #1@#2@format@second\endcsname% ##1##2##3##4##5##6{#4}% \expandafter\gdef\csname #1@#2@format@middle\endcsname% ##1##2##3##4##5##6{#5}% \expandafter\gdef\csname #1@#2@format@last\endcsname% ##1##2##3##4##5##6{#6}% % \end{macrocode} % The following \cmd{\@tmpa} macro makes use of the fact that the first % character of \#1 is ``c'' for lower-case and ``C'' for upper-case, in % order to wrap the capitalisation-dependent parts in macros so that the % rest of the code can be capitalisation-variant agnostic. % \begin{macrocode} \def\@tmpa##1##2\@nil{% \if##1c% \def\@other{C##2}% \def\@changecase{\MakeUppercase}% \else% \def\@other{c##2}% \def\@changecase{\MakeLowercase}% \fi}% \@tmpa#1\@nil% % \end{macrocode} % If the other capitalisation variant of the first part of the % multi-format definition is not already defined... % \begin{macrocode} \@ifundefined{\@other @#2@format@first}{% % \end{macrocode} % Define \cmd{\@tmpa} to be a partial expansion (expanded just once) of % the capitalisation variant we've just defined above. The \cmd{\@toska} % token register just makes the code less verbose. % \begin{macrocode} \toksdef\@toksa=0% \@toksa={\def\@tmpa##1##2##3##4##5##6}% \expandafter\expandafter\expandafter\the% \expandafter\expandafter\expandafter\@toksa% \expandafter\expandafter\expandafter{% \csname#1@#2@format@first\endcsname% {##1}{##2}{##3}{##4}{##5}{##6}}% % \end{macrocode} % Add the \cmd{\@changecase} command to the front of the definition of % \cmd{\@tmpa}. % \begin{macrocode} \expandafter\expandafter\expandafter\the% \expandafter\expandafter\expandafter\@toksa% \expandafter\expandafter\expandafter{% \expandafter\@changecase\@tmpa{##1}{##2}{##3}{##4}{##5}{##6}}% % \end{macrocode} % Define the other capitalisation variant to be the partial expansion % (expanded just once) of \cmd{\@tmpa}. % \begin{macrocode} \@toksa={% \expandafter\gdef\csname\@other @#2@format@first\endcsname% ##1##2##3##4##5##6}% \expandafter\the\expandafter\@toksa\expandafter{% \@tmpa{##1}{##2}{##3}{##4}{##5}{##6}}% }{}% % \end{macrocode} % The other parts of the multi-format definition are defined to be % identical for both capitalisation variants. % \begin{macrocode} \@ifundefined{\@other @#2@format@second}{% \@toksa={% \expandafter\global\expandafter\let% \csname\@other @#2@format@second\endcsname}% \expandafter\the\expandafter\@toksa% \csname #1@#2@format@second\endcsname% }{}% \@ifundefined{\@other @#2@format@middle}{% \@toksa={% \expandafter\global\expandafter\let% \csname\@other @#2@format@middle\endcsname}% \expandafter\the\expandafter\@toksa% \csname #1@#2@format@middle\endcsname% }{}% \@ifundefined{\@other @#2@format@last}{% \@toksa={% \expandafter\global\expandafter\let% \csname\@other @#2@format@last\endcsname}% \expandafter\the\expandafter\@toksa% \csname #1@#2@format@last\endcsname% }{}% \endgroup} % \end{macrocode} % % % \subsection{Default Reference Formats} % We define default reference format components appropriate for % \LaTeX{} documents written in English.\\ % FIXME: add babel support % % The following must be defined before the user has the chance to % customise anything, otherwise the component commands will not work. % \begin{macrocode} \newcommand{\crefrangeconjunction}{ to~} \newcommand{\crefpairconjunction}{ and~} \newcommand{\crefmiddleconjunction}{, } \newcommand{\creflastconjunction}{ and~} \crefdefaultlabelformat{#2#1#3} % \end{macrocode} % % Define default format components. We want don't want these to be % defined during the document preamble in case the user defines them % themselves (automatic definition of the other capitalisation variant % would fail). Therefore, we postpone actual definition of the formats % until the beginning of the document, and only define those % that haven't already been defined.\\ % FIXME: add babel support % \begin{macrocode} \AtBeginDocument{% % \end{macrocode} % If the group conjunctions haven't been defined, define them to be % identical to the reference conjunctions. % \begin{macrocode} \@ifundefined{crefpairgroupconjunction}{% \let\crefpairgroupconjunction\crefpairconjunction}{}% \@ifundefined{crefmiddlegroupconjunction}{% \let\crefmiddlegroupconjunction\crefmiddleconjunction}{}% % \end{macrocode} % If the last reference conjunction hasn't been modified from its % default, define the last group conjunction to include an extra % comma. However, if the user has modified the last reference conjunction % but hasn't defined the last group conjunction, they will expect the % last group conjunction to be identical to their last reference % conjunction definition, so do that. % \begin{macrocode} \@ifundefined{creflastgroupconjunction}{% \def\@tmpa{ and~}% \ifx\creflastconjunction\@tmpa% \def\creflastgroupconjunction{, and~}% \else% \let\creflastgroupconjunction\creflastconjunction% \fi}{}% % \end{macrocode} % Define default names (and in the case of equations, also the label % format). We define the lowercase and capitalised versions separately, % rather than relying on the automatic definitions, because the code % produced by the poor man's sed script is then slightly tidier. % \begin{macrocode} \@ifundefined{cref@equation@name}{% \@crefname{cref}{equation}{eq.}{eqs.}% \@crefname{Cref}{equation}{Equation}{Equations}}{}% \@ifundefined{cref@equation@label}{% \@creflabelformat{equation}{\textup{(#2#1#3)}}% \@ifundefined{cref@equation@rangelabel}{% \@crefrangelabelformat{equation}{% \textup{(#3#1#4)}--\textup{(#5#2#6)}}}{}}{}% \@ifundefined{cref@chapter@name}{% \@crefname{cref}{chapter}{chapter}{chapters}% \@crefname{Cref}{chapter}{Chapter}{Chapters}}{}% \@ifundefined{cref@section@name}{% \@crefname{cref}{section}{section}{sections}% \@crefname{Cref}{section}{Section}{Sections}}{}% \@ifundefined{cref@subsection@name}{% \@crefname{cref}{subsection}{section}{sections}% \@crefname{Cref}{subsection}{Section}{Sections}}{}% \@ifundefined{cref@subsubsection@name}{% \@crefname{cref}{subsubsection}{section}{sections}% \@crefname{Cref}{subsubsection}{Section}{Sections}}{}% \@ifundefined{cref@subsubsubsection@name}{% \@crefname{cref}{subsubsubsection}{section}{sections}% \@crefname{Cref}{subsubsubsection}{Section}{Sections}}{}% \@ifundefined{cref@appendix@name}{% \@crefname{cref}{appendix}{appendix}{appendices}% \@crefname{Cref}{appendix}{Appendix}{Appendices}}{}% \@ifundefined{cref@figure@name}{% \@crefname{cref}{figure}{fig.}{figs.}% \@crefname{Cref}{figure}{Figure}{Figures}}{}% \@ifundefined{cref@figure@rangelabel}{% \@crefrangelabelformat{figure}{#3#1#4--#5#2#6}}{}% \@ifundefined{cref@table@name}{% \@crefname{cref}{table}{table}{tables}% \@crefname{Cref}{table}{Table}{Tables}}{}% \@ifundefined{cref@theorem@name}{% \@crefname{cref}{theorem}{theorem}{theorems}% \@crefname{Cref}{theorem}{Theorem}{Theorems}}{}% \@ifundefined{cref@enumi@name}{% \@crefname{cref}{enumi}{item}{items}% \@crefname{Cref}{enumi}{Item}{Items}}{}% \@ifundefined{cref@enumii@name}{% \@crefname{cref}{enumii}{item}{items}% \@crefname{Cref}{enumii}{Item}{Items}}{}% \@ifundefined{cref@enumiii@name}{% \@crefname{cref}{enumiii}{item}{items}% \@crefname{Cref}{enumiii}{Item}{Items}}{}% \@ifundefined{cref@enumiv@name}{% \@crefname{cref}{enumiv}{item}{items}% \@crefname{Cref}{enumiv}{Item}{Items}}{}% \@ifundefined{cref@enumv@name}{% \@crefname{cref}{enumv}{item}{items}% \@crefname{Cref}{enumv}{Item}{Items}}{}% % \end{macrocode} % Define any undefined formats using the components. % \begin{macrocode} \@ifundefined{cref@equation@format}{% \@crefdefineformat{equation}}{}% \@ifundefined{crefrange@equation@format}{% \@crefrangedefineformat{equation}}{}% \@ifundefined{cref@equation@format@first}{% \@crefdefinemultiformat{equation}}{}% \@ifundefined{crefrange@equation@format@first}{% \@crefrangedefinemultiformat{equation}}{}% \@ifundefined{cref@chapter@format}{% \@crefdefineformat{chapter}}{}% \@ifundefined{crefrange@chapter@format}{% \@crefrangedefineformat{chapter}}{}% \@ifundefined{cref@chapter@format@first}{% \@crefdefinemultiformat{chapter}}{}% \@ifundefined{crefrange@chapter@format@first}{% \@crefrangedefinemultiformat{chapter}}{}% \@ifundefined{cref@section@format}{% \@crefdefineformat{section}}{}% \@ifundefined{crefrange@section@format}{% \@crefrangedefineformat{section}}{}% \@ifundefined{cref@section@format@first}{% \@crefdefinemultiformat{section}}{}% \@ifundefined{crefrange@section@format@first}{% \@crefrangedefinemultiformat{section}}{}% \@ifundefined{cref@subsection@format}{% \@crefdefineformat{subsection}}{}% \@ifundefined{crefrange@subsection@format}{% \@crefrangedefineformat{subsection}}{}% \@ifundefined{cref@subsection@format@first}{% \@crefdefinemultiformat{subsection}}{}% \@ifundefined{crefrange@subsection@format@first}{% \@crefrangedefinemultiformat{subsection}}{}% \@ifundefined{cref@subsubsection@format}{% \@crefdefineformat{subsubsection}}{}% \@ifundefined{crefrange@subsubsection@format}{% \@crefrangedefineformat{subsubsection}}{}% \@ifundefined{cref@subsubsection@format@first}{% \@crefdefinemultiformat{subsubsection}}{}% \@ifundefined{crefrange@subsubsection@format@first}{% \@crefrangedefinemultiformat{subsubsection}}{}% \@ifundefined{cref@subsubsubsection@format}{% \@crefdefineformat{subsubsubsection}}{}% \@ifundefined{crefrange@subsubsubsection@format}{% \@crefrangedefineformat{subsubsubsection}}{}% \@ifundefined{cref@subsubsubsection@format@first}{% \@crefdefinemultiformat{subsubsubsection}}{}% \@ifundefined{crefrange@subsubsubsection@format@first}{% \@crefrangedefinemultiformat{subsubsubsection}}{}% \@ifundefined{cref@appendix@format}{% \@crefdefineformat{appendix}}{}% \@ifundefined{crefrange@appendix@format}{% \@crefrangedefineformat{appendix}}{}% \@ifundefined{cref@appendix@format@first}{% \@crefdefinemultiformat{appendix}}{}% \@ifundefined{crefrange@appendix@format@first}{% \@crefrangedefinemultiformat{appendix}}{}% \@ifundefined{cref@figure@format}{% \@crefdefineformat{figure}}{}% \@ifundefined{crefrange@figure@format}{% \@crefrangedefineformat{figure}}{}% \@ifundefined{cref@figure@format@first}{% \@crefdefinemultiformat{figure}}{}% \@ifundefined{crefrange@figure@format@first}{% \@crefrangedefinemultiformat{figure}}{}% \@ifundefined{cref@table@format}{% \@crefdefineformat{table}}{}% \@ifundefined{crefrange@table@format}{% \@crefrangedefineformat{table}}{}% \@ifundefined{cref@table@format@first}{% \@crefdefinemultiformat{table}}{}% \@ifundefined{crefrange@table@format@first}{% \@crefrangedefinemultiformat{table}}{}% \@ifundefined{cref@theorem@format}{% \@crefdefineformat{theorem}}{}% \@ifundefined{crefrange@theorem@format}{% \@crefrangedefineformat{theorem}}{}% \@ifundefined{cref@theorem@format@first}{% \@crefdefinemultiformat{theorem}}{}% \@ifundefined{crefrange@theorem@format@first}{% \@crefrangedefinemultiformat{theorem}}{}% \@ifundefined{cref@enumi@format}{% \@crefdefineformat{enumi}}{}% \@ifundefined{crefrange@enumi@format}{% \@crefrangedefineformat{enumi}}{}% \@ifundefined{cref@enumi@format@first}{% \@crefdefinemultiformat{enumi}}{}% \@ifundefined{crefrange@enumi@format@first}{% \@crefrangedefinemultiformat{enumi}}{}% \@ifundefined{cref@enumii@format}{% \@crefdefineformat{enumii}}{}% \@ifundefined{crefrange@enumii@format}{% \@crefrangedefineformat{enumii}}{}% \@ifundefined{cref@enumii@format@first}{% \@crefdefinemultiformat{enumii}}{}% \@ifundefined{crefrange@enumii@format@first}{% \@crefrangedefinemultiformat{enumii}}{}% \@ifundefined{cref@enumiii@format}{% \@crefdefineformat{enumiii}}{}% \@ifundefined{crefrange@enumiii@format}{% \@crefrangedefineformat{enumiii}}{}% \@ifundefined{cref@enumiii@format@first}{% \@crefdefinemultiformat{enumiii}}{}% \@ifundefined{crefrange@enumiii@format@first}{% \@crefrangedefinemultiformat{enumiii}}{}% \@ifundefined{cref@enumiv@format}{% \@crefdefineformat{enumiv}}{}% \@ifundefined{crefrange@enumiv@format}{% \@crefrangedefineformat{enumiv}}{}% \@ifundefined{cref@enumiv@format@first}{% \@crefdefinemultiformat{enumiv}}{}% \@ifundefined{crefrange@enumiv@format@first}{% \@crefrangedefinemultiformat{enumiv}}{}% \@ifundefined{cref@enumiv@format}{% \@crefdefineformat{enumiv}}{}% \@ifundefined{crefrange@enumiv@format}{% \@crefrangedefineformat{enumiv}}{}% \@ifundefined{cref@enumiv@format@first}{% \@crefdefinemultiformat{enumiv}}{}% \@ifundefined{crefrange@enumiv@format@first}{% \@crefrangedefinemultiformat{enumiv}}{}% } % \end{macrocode} % % % \subsection{\package{hyperref} Support} % If the \package{hyperref} package is loaded, we add hyper-link support % to \package{cleveref}. Since \package{hyperref} messes around with some % of the same \LaTeX{} internals as \package{cleveref}, we also have to % override some of its redefinitions so that they work with % \package{cleveref}. % \begin{macrocode} \@ifpackageloaded{hyperref}{% \PackageInfo{cleveref}{`hyperref' support loaded} \@ifpackagewith{hyperref}{backref}{% \PackageError{cleveref}{`cleveref' is currently incompatible with `hyperref's `backref' option}{Remove the `backref' option from `hyperref' if you want to use `cleveref'}}{} % \end{macrocode} % We redefine the utility macros to cope with the extra arguments % supplied by hyperref (via the aux file). % \begin{macrocode} \def\cref@reflabel#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\@tmpa\csname r@#1\endcsname% \edef\@tmpa{\expandafter\@firstoffive\@tmpa}% \expandafter\@cref@getlabel\@tmpa\@nil#2} \def\cref@gettype#1#2{% \expandafter\let\expandafter\@tmpa\csname r@#1\endcsname% \edef\@tmpa{\expandafter\@firstoffive\@tmpa}% \expandafter\@cref@gettype\@tmpa\@nil#2} \def\cref@getcounter#1#2{% \expandafter\let\expandafter\@tmpa\csname r@#1\endcsname% \edef\@tmpa{\expandafter\@firstoffive\@tmpa}% \expandafter\@cref@getcounter\@tmpa\@nil#2} \def\cref@getprefix#1#2{% \expandafter\let\expandafter\@tmpa\csname r@#1\endcsname% \edef\@tmpa{\expandafter\@firstoffive\@tmpa}% \expandafter\@cref@getprefix\@tmpa\@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}% \cref@resetby{#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{\cref@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{\cref@old@refstepcounter{#1}% } \def\refstepcounter@optarg[#1]#2{% \cref@old@refstepcounter{#2}% \expandafter\@cref@getlabel\@currentlabel\@nil{\@tmplabel}% \cref@resetby{#2}{\@tmpreset}% \ifx\@tmpreset\relax\def\@tmpreset{}% \else\edef\@tmpreset{\csname the\@tmpreset\endcsname}\fi% \protected@edef\@currentlabel{% [#1][\arabic{#2}][\@tmpreset]\@tmplabel}} % \end{macrocode} % % We again make \cmd{\appendix} redefine things so that the label type % for chapters or sections is exceptionally overridden and set to % ``appendix'' instead. But this time, it is \cmd{\H@refstepcounter} that % needs to be redefined. % \begin{macrocode} \renewcommand\appendix{% \cref@old@appendix% \@ifundefined{chapter}{% \def\H@refstepcounter##1{% \stepcounter{##1}% \cref@resetby{##1}{\@result}% \ifx\@result\relax\def\@result{}% \else\edef\@result{\csname the\@result\endcsname}\fi% \def\@tmpa{##1}% \def\@tmpb{section}% \ifx\@tmpa\@tmpb% \protected@edef\@currentlabel{% [appendix][\arabic{##1}][\@result]% \csname p@##1\endcsname\csname the##1\endcsname}% \else% \protected@edef\@currentlabel{% [##1][\arabic{##1}][\@result]% \csname p@##1\endcsname\csname the##1\endcsname}% \fi}% }{% \def\H@refstepcounter##1{% \stepcounter{##1}% \cref@resetby{##1}{\@result}% \ifx\@result\relax\def\@result{}% \else\edef\@result{\csname the\@result\endcsname}\fi% \def\@tmpa{##1}% \def\@tmpb{chapter}% \ifx\@tmpa\@tmpb% \protected@edef\@currentlabel{% [appendix][\arabic{##1}][\@result]% \csname p@##1\endcsname\csname the##1\endcsname}% \else% \protected@edef\@currentlabel{% [##1][\arabic{##1}][\@result]% \csname p@##1\endcsname\csname the##1\endcsname}% \fi}% }% } % \end{macrocode} % % Redefine \cmd{\cref} and all the others to allow starred variants, % which don't create hyper-links. The starred variants simply set a flag, % which is tested in \cmd{\@@setcref} and \cmd{\@@setrangeref} (below). % \begin{macrocode} \newif\if@crefstarred \DeclareRobustCommand{\cref}{% \@ifstar{\@crefstar{cref}}{\@crefnostar{cref}}} \DeclareRobustCommand{\Cref}{% \@ifstar{\@crefstar{Cref}}{\@crefnostar{Cref}}} \DeclareRobustCommand{\crefrange}{% \@ifstar{\@crefrangestar{cref}}{\@crefrangenostar{cref}}} \DeclareRobustCommand{\Crefrange}{% \@ifstar{\@crefrangestar{Cref}}{\@crefrangenostar{Cref}}} \def\@crefnostar#1#2{\@cref{#1}{#2}} \def\@crefstar#1#2{% \@crefstarredtrue\@crefnostar{#1}{#2}\@crefstarredfalse} \def\@crefrangenostar#1#2#3{\@setcrefrange{#2}{#3}{#1}{}} \def\@crefrangestar#1#2#3{% \@crefstarredtrue\@crefrangenostar{#1}{#2}{#3}\@crefstarredfalse} % \end{macrocode} % % Redefine \cmd{\@@setcref} and \cmd{\@@setrangeref} to create % hyper-links (unless the starred flag is set), 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}{\@tmplabel}% \if@crefstarred% #1{\@tmplabel}{}{}% \else% \edef\@tmplink{\cref@hyperref{#2}}% #1{\@tmplabel}{\hyper@linkstart{link}{\@tmplink}}{\hyper@linkend}% \fi} \def\@@setcrefrange#1#2#3{% \cref@getlabel{#2}{\@labela}% \cref@getlabel{#3}{\@labelb}% \if@crefstarred% #1{\@labela}{\@labelb}{}{}{}{}% \else% \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}% \fi} }{} % \end{macrocode} % % Redefine \cmd{\ref} command to provide a starred variant with the same % behaviour as \package{hyperref}'s \cmd{\ref*}. As before, we defer the % redefinition until the beginning of the document, to ensure it % `takes'. \package{hyperref} stores the original \cmd{\@setref} in % \cmd{real@setref}. % \begin{macrocode} \AtBeginDocument{% \DeclareRobustCommand{\ref}{\@ifstar\cref@refstar\cref@ref} \def\cref@refstar#1{% \expandafter\ifx\csname r@#1\endcsname\relax% \let\@result\relax% \else% \cref@getlabel{#1}{\@result}% \fi% \expandafter\real@setref\csname r@#1\endcsname{\cref@reflabel}{#1}}% } % \end{macrocode} % % % \subsection{\package{ntheorem} Support} % If \package{ntheorem} is loaded, we need to modify its theorem % referencing features so that they work with \package{cleveref}. % \begin{macrocode} \@ifpackageloaded{ntheorem}{% \PackageInfo{cleveref}{`ntheorem' support loaded} \@ifpackagewith{ntheorem}{thref}{% \PackageWarning{cleveref}{`cleveref' supersedes `ntheorem's `thref' option}% \renewcommand{\thref}{\cref}}{} % \end{macrocode} % % Newer versions of \package{ntheorem} require a call to % \cmd{\theorem@prework} when typesetting theorems. If an older version % of \package{ntheorem} is being used, we just \cmd{\let} it to % \cmd{\relax} to make sure it's defined. % \begin{macrocode} \@ifundefined{theorem@prework}{\let\theorem@prework\relax}{} % \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}% <<<<< \theorem@prework% \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} \AtBeginDocument{% \@ifundefined{cref@lemma@name}{% \@crefname{cref}{lemma}{lemma}{lemmas}% \@crefname{Cref}{lemma}{Lemma}{Lemmas}}{}% \@ifundefined{cref@corollary@name}{% \@crefname{cref}{corollary}{corollary}{corollaries}% \@crefname{Cref}{corollary}{Corollary}{Corollaries}}{}% \@ifundefined{cref@proposition@name}{% \@crefname{cref}{proposition}{proposition}{propositions}% \@crefname{Cref}{proposition}{Proposition}{Proposition}}{}% \@ifundefined{cref@definition@name}{% \@crefname{cref}{definition}{definition}{definitions}% \@crefname{Cref}{definition}{Definition}{Definitions}}{}% \@ifundefined{cref@result@name}{% \@crefname{cref}{result}{result}{results}% \@crefname{cref}{result}{Result}{Results}}{}% % \end{macrocode} % Define any undefined formats using the components. % \begin{macrocode} \@ifundefined{cref@lemma@format}{% \@crefdefineformat{lemma}}{}% \@ifundefined{crefrange@lemma@format}{% \@crefrangedefineformat{lemma}}{}% \@ifundefined{cref@lemma@format@first}{% \@crefdefinemultiformat{lemma}}{}% \@ifundefined{crefrange@lemma@format@first}{% \@crefrangedefinemultiformat{lemma}}{}% \@ifundefined{cref@corollary@format}{% \@crefdefineformat{corollary}}{}% \@ifundefined{crefrange@corollary@format}{% \@crefrangedefineformat{corollary}}{}% \@ifundefined{cref@corollary@format@first}{% \@crefdefinemultiformat{corollary}}{}% \@ifundefined{crefrange@corollary@format@first}{% \@crefrangedefinemultiformat{corollary}}{}% \@ifundefined{cref@definition@format}{% \@crefdefineformat{definition}}{}% \@ifundefined{crefrange@definition@format}{% \@crefrangedefineformat{definition}}{}% \@ifundefined{cref@definition@format@first}{% \@crefdefinemultiformat{definition}}{}% \@ifundefined{crefrange@definition@format@first}{% \@crefrangedefinemultiformat{definition}}{}% \@ifundefined{cref@result@format}{% \@crefdefineformat{result}}{}% \@ifundefined{crefrange@result@format}{% \@crefrangedefineformat{result}}{}% \@ifundefined{cref@result@format@first}{% \@crefdefinemultiformat{result}}{}% \@ifundefined{crefrange@result@format@first}{% \@crefrangedefinemultiformat{result}}{}% }% }{} % \end{macrocode} % % % \subsection{Poor Man's \package{cleveref}} % \begin{macrocode} \DeclareOption{poorman}{% \PackageInfo{cleveref}{option `poorman' loaded} % \end{macrocode} % % % Define global macro \cmd{\cref@text} to store the text produced by the % \cmd{\cref} commands, and open an output stream for writing the script % before starting to process to document body. % \begin{macrocode} \edef\cref@text{} \AtBeginDocument{% \newwrite\@crefscript% \immediate\openout\@crefscript=\jobname.sed% } % \end{macrocode} % % % After processing the document body, we re-read in the temporary script % file, and write it out again to the final sed script file, escaping % regexp special characters in the process. The escaping is carried out % by turning the regexp special characters into active characters, and % defining them to expand to their escaped form. This involves a lot of % juggling of catcodes and lccodes! % % Both \cmd{\DeclareOption} and \cmd{\AtEndDocument} store their % arguments in token lists, so all the following \TeX code is already % tokenised long before it is expanded and evaluated. Thus there is no % (easy) way to change the catcodes of the characters appearing here % before they are tokenised. In one way this is convenient: the catcode % changes we make don't ``take'' until evaluated, so we can continue to % use the standard \TeX characters ($\backslash$, \{, \} etc.) even after % the lines containing the catcode commands. But in another, more % significant, way, it is very inconvenient: it makes it difficult to % define the regexp special characters as active characters, since it's % impossible to directly create tokens with the correct char- and % catcodes. % % We get around this by creating the unusual charcode/catcode % combinations using the \cmd{\lowercase} trick (\cmd{\lowercase} changes % the charcodes of all characters in its argument to their lccodes, but % \emph{leaves} their catcodes alone). That way, the argument of % \cmd{\AtEndDocument} is tokenised correctly, and when it comes to be % expanded and evaluated, the \cmd{\lowercase} commands create tokens % with the correct char- and catcodes. % \begin{macrocode} \AtEndDocument{% \immediate\closeout\@crefscript% \newread\@crefscript% \immediate\openin\@crefscript=\jobname.sed% \begingroup% \newif\if@not@eof% \def\@eof{\par }% % \end{macrocode} % Change catcodes of regexp special characters to make them active % characters and define them to expand to their escaped forms. Change % those of \TeX special characters to make them normal letters. % \begin{macrocode} \catcode`.=13 \catcode`[=13 \catcode`]=13 \catcode`^=13 \catcode`$=13 %$ \catcode`\=0 \catcode`<=1 \catcode`>=2 \catcode`\\=13 \catcode`\{=12 \catcode`\}=12 \catcode`_=12 \lccode`/=92 \lccode`~=92\lowercase{\def~{\string/\string/}}% \lccode`~=46\lowercase{\def~{\string/\string.}}% \lccode`~=91\lowercase{\def~{\string/\string[}}% \lccode`~=93\lowercase{\def~{\string/\string]}}% \lccode`~=94\lowercase{\def~{\string/\string^}}% \lccode`~=36\lowercase{\def~{\string/\string$}}% $ \lccode`~=0 \lccode`/=0 \catcode`~=12 % \end{macrocode} % Read lines from the temporary script file, expand them to escape regexp % special characters, and store them in \cmd{\cref@text}. % \begin{macrocode} \def\cref@text{}% \immediate\read\@crefscript to \@tmpa% \ifx\@tmpa\@eof% \@not@eoffalse% \else% \@not@eoftrue% \edef\@tmpa{\@tmpa}% \fi% \@whilesw\if@not@eof\fi{% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \immediate\read\@crefscript to \@tmpa% \ifx\@tmpa\@eof% \@not@eoffalse% \else% \@not@eoftrue% \edef\@tmpa{\@tmpa}% \fi}% \endgroup% \immediate\closein\@crefscript% % \end{macrocode} % Add some rules to remove likely \package{cleveref} preamble % commands. We use the \cmd{\lowercase} trick again for writing the % $\backslash$, \{ and \} characters. (This could be done in other ways, % but since we're in \cmd{\lowercase} mood, why not go with it!) % \begin{macrocode} \begingroup% \lccode`|=92 \lccode`<=123 \lccode`>=125 \lccode`C=67 \lowercase{\edef\@tmpa{s/||usepackage|(|[.*|]|)|?//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{s/||[cC]refformat<.*><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{s/||[cC]refrangeformat<.*><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{s/||[cC]refmultiformat<.*><.*><.*><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{% s/||[cC]refrangemultiformat<.*><.*><.*><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{s/||[cC]refname<.*><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{s/||[cC]reflabelformat<.*><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{s/||[cC]refrangelabelformat<.*><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{s/||[cC]refdefaultlabelformat<.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{% s/||renewcommand<||crefpairconjunction><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{% s/||renewcommand<||crefpairgroupconjunction><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{% s/||renewcommand<||crefmiddleconjunction><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{% s/||renewcommand<||crefmiddlegroupconjunction><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{% s/||renewcommand<||creflastconjunction><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{% s/||renewcommand<||creflastgroupconjunction><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{s/||renewcommand<||[cC]ref><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \lowercase{\edef\@tmpa{s/||renewcommand<||[cC]refrange><.*>//g}}% \expandafter\g@addto@macro\expandafter\cref@text\expandafter{% \@tmpa^^J}% \endgroup% % \end{macrocode} % Overwrite the script file with the new, escaped regexp rules. % \begin{macrocode} \newwrite\@crefscript% \immediate\openout\@crefscript=\jobname.sed% \immediate\write\@crefscript{\cref@text}% \immediate\closeout\@crefscript% } % \end{macrocode} % % % Redefine the user-level referencing commands so that they write a % substitution rule for the reference to the script, as well as % typesetting the reference itself. % \begin{macrocode} \@ifpackageloaded{hyperref}{% \def\@crefnostar#1#2{% \edef\cref@text{}% \@cref{#1}{#2}% \cref@writescript{% \expandafter\string\csname#1\endcsname\string{#2\string}}} \def\@crefrangenostar#1#2#3{% \edef\cref@text{}% \@setcrefrange{#2}{#3}{#1}{}% \cref@writescript{% \expandafter\string\csname#1range\endcsname% \string{#2\string}\string{#3\string}}}% }{% \DeclareRobustCommand{\cref}[1]{% \edef\cref@text{}% \@cref{cref}{#1}% \cref@writescript{\string\cref\string{#1\string}}} \DeclareRobustCommand{\Cref}[1]{% \edef\cref@text{}% \@cref{Cref}{#1}% \cref@writescript{\string\Cref\string{#1\string}}} \DeclareRobustCommand{\crefrange}[2]{% \edef\cref@text{}% \@setcrefrange{#1}{#2}{cref}{}% \cref@writescript{% \string\crefrange\string{#1\string}\string{#2\string}}} \DeclareRobustCommand{\Crefrange}[2]{% \edef\cref@text{}% \@setcrefrange{#1}{#2}{Cref}{}% \cref@writescript{% \string\Crefrange\string{#1\string}\string{#2\string}}}% } % \end{macrocode} % % % The \cmd{\cref@writescript} utility macro does the actual writing of % the substitution rule to the script. % \begin{macrocode} \def\cref@writescript#1{% \edef\@tmpa{\cref@getmeaning{\cref@text}}% \immediate\write\@crefscript{s/#1/\@tmpa/g}} % \end{macrocode} % % % Redefine \cmd{\@@setcref} and \cmd{\@@setrangeref}, as well as the % conjunction macros \cmd{\@setcref@middlegroupconjunction}, % \cmd{\@setcref@lastgroupconjunction} and % \cmd{\@setcref@pairgroupconjunction}, to append text they typeset to % \cmd{\cref@text}, as well as actually doing the typesetting. % \begin{macrocode} \let\old@@setcref\@@setcref \let\old@@setcrefrange\@@setcrefrange \def\cref@getmeaning#1{\expandafter\@cref@getmeaning\meaning#1\@nil} \def\@cref@getmeaning#1->#2\@nil{#2} \def\@@setcref#1#2{% \old@@setcref{#1}{#2}% \expandafter\g@addto@macro\expandafter{% \expandafter\cref@text\expandafter}\expandafter{% #1{\ref{#2}}{}{}}} \def\@@setcrefrange#1#2#3{% \old@@setcrefrange{#1}{#2}{#3}% \expandafter\g@addto@macro% \expandafter{\expandafter\cref@text\expandafter}% \expandafter{#1{\ref{#2}}{\ref{#3}}{}{}{}{}}} \def\@setcref@pairgroupconjunction{% \crefpairgroupconjunction% \expandafter\g@addto@macro% \expandafter{\expandafter\cref@text\expandafter}% \expandafter{\crefpairgroupconjunction}} \def\@setcref@middlegroupconjunction{% \crefmiddlegroupconjunction% \expandafter\g@addto@macro% \expandafter{\expandafter\cref@text\expandafter}% \expandafter{\crefmiddlegroupconjunction}} \def\@setcref@lastgroupconjunction{% \creflastgroupconjunction% \expandafter\g@addto@macro% \expandafter{\expandafter\cref@text\expandafter}% \expandafter{\creflastgroupconjunction}} } % end of poorman 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: