% \iffalse meta-comment % % Copyright (C) 1993-2024 % The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. % ------------------------------------------- % % It may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % https://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions of LaTeX % version 2008 or later. % % This file has the LPPL maintenance status "maintained". % % The list of all files belonging to the LaTeX base distribution is % given in the file `manifest.txt'. See also `legal.txt' for additional % information. % % The list of derived (unpacked) files belonging to the distribution % and covered by LPPL is defined by the unpacking scripts (with % extension .ins) which are part of the distribution. % % \fi % % \iffalse %%% From File: ltxref.dtx % %<*driver> % \fi \ProvidesFile{ltxref.dtx} [2023/05/16 v1.1q LaTeX Kernel (Cross Referencing)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltxref.dtx} \title{\filename} \date{\filedate} \author{% Johannes Braams\and David Carlisle\and Alan Jeffrey\and Leslie Lamport\and Frank Mittelbach\and Chris Rowley\and Rainer Sch\"opf} \begin{document} \MaintainedByLaTeXTeam{latex} \maketitle \DocInput{\filename} \end{document} % % \fi % % % \changes{v1.0c}{1994/03/29} % {Create file ltcntlen from parts of ltmiscen and ltherest.} % \changes{v1.1a}{1994/05/19} % {Extract file ltxref from ltcntlen.} % \changes{v1.1b}{1994/05/21}{Use new warning commands} % \changes{v1.1c}{1994/05/25}{Modify documentation} % \changes{v1.1p}{2022/04/12}{Add starred variants for the ref commands} % % \section{Cross Referencing} % The user writes |\label|\marg{foo} to define the following % cross-references: % % |\ref|*\marg{foo}: value of most recently incremented referenceable % counter. in the current environment. (Chapter, section, % theorem, footnote and enumeration counters and other counters % stepped with \cs{refstepcounter} are % referenceable.) % % |\pageref|*\marg{foo}: page number at which |\label{foo}| command % appeared. where foo can be any string of characters not % containing `|\|', `|{|' or `|}|'. % % Note: The scope of the |\label| command is delimited by environments, % so\\ % |\begin{theorem} \label{foo} ... \end{theorem} \label{bar}|\\ % defines |\ref{foo}| to be the theorem number and |\ref{bar}| to be % the current section number. % % Note: |\label| does the right thing in terms of spacing -- i.e., % leaving a space on both sides of it is equivalent to leaving % a space on either side. % % Note: the starred versions |\ref*| and |\pageref*| are provided % to align with the use of \pkg{hyperref}. Without \pkg{hyperref} (or some % other package using the starred form) the star is simply ignored. % % Note: starting with 2023-06-01 |\label| stores also the current value % of |\@currentlabelname| which should typically contain a (sanitized) title. % (A reference command |\nameref| is provided by the \pkg{nameref} package.) % |\label| also stores |\@currentHref| which if set should refer to a target name % for links. This value is set and used by \pkg{hyperref}. Unlike the other values % |\@currentHref| should be set globally. A fifth value |\@kernel@reserved@label@data| % is reserved for the kernel to allow future extensions of the cross-reference % system. % % % \MaybeStop{} % % \subsection{Cross Referencing} % % \begin{oldcomments} % \begin{macrocode} %<*2ekernel> \message{x-ref,} % \end{macrocode} % % This is implemented as follows. A referenceable counter CNT is % incremented by the command \refstepcounter{CNT} , which sets % \@currentlabel == {CNT}{eval(\p@cnt\theCNT)}. The command % \label{FOO} then writes the following on file \@auxout : % \newlabel{FOO}{{eval(\@currentlabel)}{eval(\thepage)}% % {eval(\@currentlabelname)}{eval(\@currentHref)}{eval(\@kernel@reserved@label@data)}} % % \ref{FOO} == % BEGIN % if \r@foo undefined % then @refundefined := G T % ?? % Warning: 'reference foo on page ... undefined' % else \@car \eval(\r@FOO)\@nil % fi % END % % \pageref{foo} = % BEGIN % if \r@foo undefined % then @refundefined := G T % ?? % Warning: 'reference foo on page ... undefined' % else \@cdr \eval(\r@FOO)\@nil % fi % END % % \end{oldcomments} % % \DescribeMacro\labelformat % A reference via |\ref| produces by default the data associated with % the corresponding |\label| command (typically a number); any % additional formatting has to be provided by the user. If, for % example, references to equations are always to be typeset as % ``equation (\textit{number})'', one has to code % ``\verb=equation (\ref{=\textit{key}\verb=})=''. With |\labelformat| % there is a possibility to generate such % frills automatically without resorting to low-level coding. % The command takes two arguments: the first is % the name of a counter and the second is its representation when % referenced. This means that for a successful usage, one has to know % the counter name being used for generating the label, though in % practice this should not pose a problem. The current counter number % is picked up as an argument. % Here are two examples: %\begin{verbatim} % \labelformat{section}{section~#1} % \labelformat{equation}{equation~(#1)}} %\end{verbatim} % % \DescribeMacro\Ref % A side effect of using |\labelformat| is that, depending on the % defined formatting, it becomes impossible to use |\ref| at the % beginning of a sentence (if its replacement text starts with a % lowercase letter). To overcome this problem we % introduce the command |\Ref| that behave like % |\ref| except that it uppercases the first token % of the generated string. % % To make |\Ref| work properly the very first token in the second % argument of |\labelformat| has to be a simple \textsc{ascii} or % UTF-8 letter, otherwise the capitalization will fail or worse, you % will end up with some error messages. If you actually need something % more complicated in this place (e.g., an accented letter not written % as a UTF-8 character) you have to explicitly surround it with % braces, to identify the part that needs to be capitalized. For % example, for figure references in the Hungarian language you might % want to write |\labelformat{figure}{{\'a}bra~\thefigure}| or use % |\labelformat{figure}{ábra~\thefigure}| which avoids the brace % problem. % % % \begin{macro}{\G@refundefinedtrue} % \changes{v1.1i}{1995/12/07}{Renamed (back) from \cs{G@refundefined}} % \begin{macro}{\@refundefined} % \changes{v1.1h}{1995/10/24}{Switch for refundefined replaced} % This does not save on name-space (since \cs{G@refundefinedfalse} % was never needed) but it does make the implementation of such % one-way switches more consistent. The extra macro to make the % change is used since this change appears several times. % % \textbf{Note} despite its name, |\G@refundefinedtrue| does % \emph{not} correspond to an |\if| command, and there is no % matching \ldots|false|. It would be more natural to call the % command |\G@refundefined| (as inspection of the change log will % reveal) but unfortunately such a change would break any package % that had defined a |\ref|-like command that mimicked the % definition of |\ref|, calling |\G@refundefinedtrue|. Inspection % of the \TeX\ archives revealed several such packages, and so this % command has been named \ldots|true| so that the definition of % |\ref| need not be changed, and the packages will work without % change. % \begin{macrocode} % \newif\ifG@refundefined % \def\G@refundefinedtrue{\global\let\ifG@refundefined\iftrue} % \def\G@refundefinedfalse{\global\let\ifG@refundefined\iffalse} \def\G@refundefinedtrue{% \gdef\@refundefined{% \@latex@warning@no@line{There were undefined references}}} \let\@refundefined\relax % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macrocode} % \end{macrocode} % \begin{macro}{\ref} % \changes{LaTeX2e}{1993/12/11}{Macro reimplemented} % \changes{LaTeX2e}{2022/04/12}{Macro reimplemented with a starred version} % \begin{macro}{\pageref} % \changes{LaTeX2e}{1993/12/11}{Macro reimplemented} % \changes{LaTeX2e}{2022/04/12}{Macro reimplemented with a starred version} % \begin{macro}{\@setref} % \changes{LaTeX2e}{1993/12/11}{Macro added} % \changes{v1.1h}{1995/10/24}{Switch for refundefined renamed} % \changes{v1.1i}{1995/12/07}{Switch for refundefined restored} % Referencing a |\label|. % RmS 91/10/25: added a few extra |\reset@font|, % as suggested by Bernd Raichle % % RmS 92/08/14: made |\ref| and |\pageref| robust % % RmS 93/09/08: Added setting of refundefined switch. % \begin{macrocode} % %<*2ekernel|latexrelease> %\IncludeInRelease{2023/06/01}% % {\@kernel@sref}{store five arguments}% \def\@setref#1#2#3{% \ifx#1\relax \protect\G@refundefinedtrue \nfss@text{\reset@font\bfseries ??}% \@latex@warning{Reference `#3' on page \thepage \space undefined}% \else \expandafter#2#1\@empty\@empty\@empty\null \fi} % \end{macrocode} % \begin{macrocode} \long\def\@firstoffive#1#2#3#4#5{#1} \long\def\@secondoffive#1#2#3#4#5{#2} \def\@kernel@sref#1{\expandafter\@setref\csname r@#1\endcsname\@firstoffive{#1}} \def\@kernel@spageref#1{\expandafter\@setref\csname r@#1\endcsname \@secondoffive{#1}} %\EndIncludeInRelease %\IncludeInRelease{2022/06/01}% % {\@kernel@sref}{store five arguments}% %\def\@setref#1#2#3{% % \ifx#1\relax % \protect\G@refundefinedtrue % \nfss@text{\reset@font\bfseries ??}% % \@latex@warning{Reference `#3' on page \thepage \space % undefined}% % \else % \expandafter#2#1\null % \fi} %\let\@firstoffive\undefined %\let\@secondoffive\undefined %\def\@kernel@sref#1{\expandafter\@setref\csname r@#1\endcsname\@firstoftwo{#1}} %\def\@kernel@spageref#1{\expandafter\@setref\csname r@#1\endcsname % \@secondoftwo{#1}} %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% % {\@kernel@sref}{store five arguments}% %\def\@setref#1#2#3{% % \ifx#1\relax % \protect\G@refundefinedtrue % \nfss@text{\reset@font\bfseries ??}% % \@latex@warning{Reference `#3' on page \thepage \space % undefined}% % \else % \expandafter#2#1\null % \fi} %\let\@firstoffive\undefined %\let\@secondoffive\undefined %\let\@kernel@sref\undefined %\let\@kernel@spageref\undefined %\EndIncludeInRelease %\IncludeInRelease{2022/06/01}% % {\ref}{Add starred reference commands}% % \end{macrocode} % \begin{macrocode} \let\@kernel@ref\@kernel@sref \let\@kernel@pageref\@kernel@spageref \NewDocumentCommand\ref{s} {\IfBooleanTF{#1}{\@kernel@sref}{\@kernel@ref}} \NewDocumentCommand\pageref{s} {\IfBooleanTF{#1}{\@kernel@spageref}{\@kernel@pageref}} % \end{macrocode} % As the commands are now protected we also need expandable versions for use % in \cs{ifthenelse}: % \begin{macrocode} \def\@kernel@pageref@exp#1{\csname cs_if_exist:cTF\endcsname {r@#1}{\csname tl_item:cn\endcsname{r@#1}{2}}{0}} \def\@kernel@ref@exp#1{\csname cs_if_exist:cTF\endcsname {r@#1}{\csname tl_item:cn\endcsname{r@#1}{1}}{0}} % \end{macrocode} % \begin{macrocode} % %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% % {\ref}{Add starred reference commands}% %\def\ref#1{\expandafter\@setref\csname r@#1\endcsname\@firstoftwo{#1}} %\def\pageref#1{\expandafter\@setref\csname r@#1\endcsname % \@secondoftwo{#1}} % %\EndIncludeInRelease %<*2ekernel> % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\newlabel} % \changes{v1.1b}{1994/05/21}{Use new warning commands} % \changes{v1.1e}{1995/04/24}{Make \cs{@onlypreamble} for /1388.} % \changes{v1.1e}{1995/06/19} % {Use \cs{@newl@bel} to share code with \cs{bibcite}} % \changes{v1.1g}{1995/07/14} % {Remove \cs{@onlypreamble} so still defined in new \cs{enddocument}} % This command will be written to the \texttt{.aux} file to % pass label information from one run to another. % \begin{macro}{\@newl@bel} % The internal form of |\newlabel| and |\bibcite|. Note that this % macro does it's work inside a group. That way the local % assignments it needs to do don't clutter the save stack. This % prevents large documents with many labels to run out of save % stack. % \changes{v1.1h}{1995/10/24}{Switch for multiplelabels replaced by % inline code} % \changes{v1.1k}{2001/02/16}{Added an extra grouplevel (PR3250), jlb} % \begin{macrocode} \def\@newl@bel#1#2#3{{% \@ifundefined{#1@#2}% \relax {\gdef \@multiplelabels {% \@latex@warning@no@line{There were multiply-defined labels}}% \@latex@warning@no@line{Label `#2' multiply defined}}% \global\@namedef{#1@#2}{#3}}} % \end{macrocode} % % \begin{macrocode} \def\newlabel{\@newl@bel r} % \end{macrocode} % % \begin{macrocode} \@onlypreamble\@newl@bel % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\if@multiplelabels} % \changes{v1.1h}{1995/10/24}{Macro removed} % \begin{macro}{\@multiplelabels} % \changes{v1.1h}{1995/10/24}{Switch for multiplelabels removed} % This is redefined to produce a warning if at least one label is % defined more than once. It is executed by the |\enddocument| % command. % \begin{macrocode} \let \@multiplelabels \relax % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\label} % \changes{v1.1d}{1994/11/04}{(ASAJ)Added \cs{protected@write}} % \changes{v1.1d}{1994/11/04}{(ASAJ)Added \cs{protected@edef}} % \changes{v1.1q}{2023/05/12}{(UFi)extended to store five arguments} % \changes{v1.1q}{2023/05/12}{(UFi)added a hook with argument} % The commands |\label| and |\refstepcounter| have been changed to % allow |\protect|'ed commands to work properly. For example, %\begin{verbatim} % \def\thechapter{\protect\foo{\arabic{chapter}.\roman{section}}} %\end{verbatim} % will cause a |\label{bar}| command to define |\ref{bar}| to expand % to something like |\foo{4.d}|. Change made 20 Jul 88. % % \begin{macrocode} % %<*2ekernel|latexrelease> %\IncludeInRelease{2023/06/01}% % {\label}{store five label arguments}% \providecommand\@currentlabelname{} \providecommand\@currentHref{} \providecommand\@kernel@reserved@label@data{} \NewHookWithArguments{label}{1} \def\label#1{\@bsphack \begingroup \UseHookWithArguments{label}{1}{#1}% \protected@write\@auxout{}% {\string\newlabel{#1}{{\@currentlabel}{\thepage}% {\@currentlabelname}{\@currentHref}{\@kernel@reserved@label@data}}}% \endgroup \@esphack} %\EndIncludeInRelease % \end{macrocode} % \end{macro} % % \begin{macrocode} %\IncludeInRelease{2022/06/01}% % {\Ref}{Add starred version}% % \end{macrocode} % % \begin{macro}{\refstepcounter} % Step the counter and allow for labels to point to its current value. % \changes{v1.1n}{2020/05/05}{record the counter name in \cs{@currentcounter}} % \changes{v1.1o}{2020/08/23}{add default definition of \cs{@currentcounter}} % \begin{macrocode} \def\@currentcounter{} \def\refstepcounter#1{\stepcounter{#1}% \edef\@currentcounter{#1}% \protected@edef\@currentlabel % \end{macrocode} % By generating the second csname first the |\p@...| command can % grab it as an argument which can be helpful for more complicated % typesetting arrangements. % % The trick is to ensure that |\csname the#1\endcsname| is turned % into a single token before |\p@...| is expanded further. This % way, if the |\p@...| command is a macro with one argument it will % receive |\the...|. With the original kernel code (i.e., without the % |\expandafter|) it will instead pick up |\csname| which would be % disastrous. % % Using |\expandafter| instead of braces delimiting the argument is % better because, assuming that the |\p@...| command is not defined % as a macro with one argument, the braces will stay and prohibit % kerning that might otherwise happen between the glyphs generated % by |\the...| and surrounding glyphs. % % \changes{v1.1l}{2019/08/22}{Allow \cs{p@...} to have an % argument} % \begin{macrocode} {\csname p@#1\expandafter\endcsname\csname the#1\endcsname}% } % \end{macrocode} % \end{macro} % % \begin{macro}{\labelformat} % A shortcut to set the |\p@...| macro for a counter. It will pick % up the counter representation as an argument so that it can be % specially formatted. % \changes{v1.1l}{2019/08/22}{Commanded moved from \texttt{varioref.sty}} % \begin{macrocode} \def\labelformat#1{\expandafter\def\csname p@#1\endcsname##1} % \end{macrocode} % \end{macro} % % \begin{macro}{\Ref} % This macro expands the result of |\ref| and then uppercases the % first token. Only useful if the label was generated via % |\labelformat| and contains some lower case letter at its start. If % the label starts with a complicated construct (e.g., an accented % letter that is provided via a command, e.g., \verb=\"a= instead % of a UTF-8 character like ä) one has to surround everything that % needs uppercasing in % a brace group in the definition of |\labelformat|.\footnote{There % is one problem with this approach: the braces are kept in a % normal \texttt{\textbackslash ref} which might spoil kerning. % Perhaps one day this needs redoing.} % \changes{v1.1l}{2019/08/22}{Commanded moved from \texttt{varioref.sty}} % \changes{v1.1p}{2022/04/12}{Macro reimplemented with a starred version}% % \begin{macrocode} \def\@kernel@Ref#1{\protected@edef\@tempa{\@kernel@ref{#1}}% \expandafter\MakeUppercase\@tempa} \def\@kernel@sRef#1{\protected@edef\@tempa{\@kernel@sref{#1}}% \expandafter\MakeUppercase\@tempa} \NewDocumentCommand\Ref{s} {\IfBooleanTF{#1}{\@kernel@sRef}{\@kernel@Ref}} % \end{macrocode} % \end{macro} % % % % \changes{v1.1m}{2019/09/16}{Correctly revert the \cs{p@...} change} % \begin{macrocode} % %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% % {\label}{store five label arguments}% %\let\@currenttitle\@undefined %\let\@currenttarget\@undefined %\let\@kernel@currentdata\@undefined %\def\label#1{\@bsphack % \protected@write\@auxout{}% % {\string\newlabel{#1}{{\@currentlabel}{\thepage}}}% % \@esphack} %\EndIncludeInRelease %\IncludeInRelease{2020/10/01}% % {\Ref}{Add starred version}% %\def\@currentcounter{} %\def\refstepcounter#1{\stepcounter{#1}% % \edef\@currentcounter{#1}% % \protected@edef\@currentlabel % {\csname p@#1\expandafter\endcsname\csname the#1\endcsname}% %} %\def\labelformat#1{\expandafter\def\csname p@#1\endcsname##1} %\DeclareRobustCommand\Ref[1]{\protected@edef\@tempa{\ref{#1}}% % \expandafter\MakeUppercase\@tempa} %\EndIncludeInRelease %\IncludeInRelease{2019/10/01}% % {\refstepcounter}{Add \labelformat and \Ref}% %\let\@currentcounter\@undefined %\def\refstepcounter#1{\stepcounter{#1}% % \protected@edef\@currentlabel % {\csname p@#1\expandafter\endcsname\csname the#1\endcsname}% %} %\def\labelformat#1{\expandafter\def\csname p@#1\endcsname##1} %\DeclareRobustCommand\Ref[1]{\protected@edef\@tempa{\ref{#1}}% % \expandafter\MakeUppercase\@tempa} %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% % {\refstepcounter}{Add \labelformat and \Ref}% % %\def\refstepcounter#1{\stepcounter{#1}% % \protected@edef\@currentlabel % {\csname p@#1\endcsname\csname the#1\endcsname}% %} %\let\labelformat\@undefined %\let\Ref\@undefined % %\EndIncludeInRelease %<*2ekernel> % \end{macrocode} % % % % % % % % \begin{macro}{\@currentlabel} % Default for |\label| commands that come before any environment. % \begin{macrocode} \def\@currentlabel{} % \end{macrocode} % \end{macro} % % \begin{macrocode} % % \end{macrocode} % % % \Finale %