\def\packageversion{0.2.0} \def\packagedate{2023-04-07} % \iffalse meta-comment % % Package `cleveref-usedon' to use with LaTeX2e % % Copyright (C) 2023 by Sven Pistre % % Written and maintained by Sven Pistre % % The development version of this package can be found at % % http://github.com/SvenPistre/cleveref-usedon % % for those people who are interested. Please report bugs by creating a % github issue or sending an email to cleveref-usedon@sven-pistre.com. % --------------------------------------------------------------------------- % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either % version 1.3 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.3 or later is part of all distributions of % LaTeX version 2005/12/01 or later. % ----------------------------------------------------------------------- % This work consists of the files cleveref-usedon.dtx and cleveref-usedon.ins % and the derived filebase cleveref-usedon.sty. % % \fi % % \iffalse %<*driver> \ProvidesFile{cleveref-usedon.dtx} % % %\NeedsTeXFormat{LaTeX2e}[2022/06/01] %\RequirePackage{expl3} %\ProvidesExplPackage{cleveref-usedon} % {\packagedate} % {\packageversion} % {Patches the cleveref package and adds forward-referencing functionality} % %<*driver> \documentclass{ltxdoc} \usepackage{thmtools} \usepackage{hyperref} \usepackage[capitalise]{cleveref-usedon}[2023/03/29] \declaretheorem[ numberwithin=section, name=Theorem]{theorem} \crefname{page}{page}{pages} % do NOT capitalise pages for more visual appeal \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{\jobname.dtx} \PrintChanges \PrintIndex \end{document} % % \fi % % \CheckSum{160} % % \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 \~} % % \DoNotIndex{\newcommand,\newenvironment} % % \changes{v0.1.0}{2023-03-29}{Initial version} % \changes{v0.2.0}{2023-04-07}{% % Manually \texttt{\textbackslash{}Require}'d the packages \pkg{expl3} and \pkg{xparse}% % for users of older \LaTeX{} installations.% % Added \texttt{@}-guards to the macros \texttt{\textbackslash{}origlabel},% % \texttt{\textbackslash{}origcref}, and \texttt{\textbackslash{}origCref} to prevent them from leaking.% % } % % \GetFileInfo{cleveref-usedon.dtx} % \title{The \pkg{cleveref-usedon} package% % \thanks{This document corresponds to % \pkg{cleveref-usedon}~v\packageversion, % dated~\packagedate.}} % \author{Sven Pistre% % \thanks{ % \href{mailto:cleveref-usedon@sven-pistre.com?subject=[cleveref-usedon]}{cleveref-usedon@sven-pistre.com}} % } % \date{\packagedate} % % \maketitle % % \begin{abstract} % This package adds ``forward-referencing'' to the \pkg{cleveref} package. % Any label can be referenced with the new optional argument ``|UsedOn|'' % passed to |\cref|. Doing so, will print an info message at the original label % location (in a theorem environment, say) which reads % ``\emph{Used on pages \meta{pagerange}.}''. % This functionality is complementary to \pkg{hyperref}'s |pagebackref| % or \pkg{biblatex}'s |backref| option for the bibliography. % It might be useful for authors of longer texts such as textbooks or theses, % where a lot of supplementary results and information are given in early % chapters, appendices or exercises. The message on which pages these % results will be used can be a helpful information for the reader of the final text. % Additionally, a bug in \pkg{cleveref v0.21.4} is patched. % \end{abstract} % % \section{Introduction} % \label{sec:introduction} % Imagine you are reading a long mathematical text such as a text book or % a thesis. There are plenty of supplementary lemmas, propositions, theorems % and/or exercises throughout the whole text. % You ask yourself ``Gosh, while Lemma 1.12 is certainly an interesting result % \emph{where} is this result used later on in this long text? I really would find % that helpful to decide \emph{why} I should read the proof.'' % You can, of course, use the PDF search function of your viewer to look up the % string ``Lemma 1.12'' but wouldn't it be more helpful if Lemma 1.12 already % indicates all or at least its most useful/crucial applications via an info message? % % This is what the package \pkg{cleveref-usedon} tries to address. % The info message ``\emph{Used on p. 40, 43-45 and 101.}'' would then be % printed to the header of Lemma 1.12. % For example, we have given the following theorem the label % \begin{quote} % |\label{thm:SqrtTwoIrrational}|. % \end{quote} % \begin{theorem} \label{thm:SqrtTwoIrrational} % The number $\sqrt{2}$ is irrational. % \end{theorem} % Now we can reference this theorem via % \begin{quote} % |\cref[UsedOn]{thm:SqrtTwoIrrational}|: % \end{quote} % A proof of \cref[UsedOn]{thm:SqrtTwoIrrational} can be traced back to Euclid. % \clearpage % Let's clear the page of this PDF, so that we can see the effects of % referencing \cref{thm:SqrtTwoIrrational} without the optional argument % |[UsedOn]|, i.e. % \begin{quote} % |\cref{thm:SqrtTwoIrrational}|. % \end{quote} % Note that the current page number \thepage{} is not included in the list of % page references in the header of \cref{thm:SqrtTwoIrrational}. % % % \section{Usage} % \label{sec:usage} % The \pkg{cleveref-usedon} package uses \pkg{cleveref v0.21.4} % as its base. % To freely cite from the \pkg{cleveref} documentation: \\ % The \pkg{cleveref-usedon} package is loaded in the usual way, by % putting the line % \begin{quote} % |\usepackage{cleveref-usedon}| % \end{quote} % in your document's preamble. However, care must be taken when using % \pkg{cleveref} in conjunction with other packages that modify % \LaTeX{}'s referencing system (see Section 13 of \pkg{cleveref}'s % documentation). Basically, \pkg{cleveref-usedon} must be loaded % \emph{last} but definitely AFTER \pkg{hyperref}. \\ % % \DescribeMacro{\cref} % \DescribeMacro{\Cref} % |\cref|\oarg{UsedOn}\marg{LabelName} \\ % The |\cref| macro can be called with option |UsedOn| or the short form % |uo|. This is case-insensitive, i.e. you could also write % \begin{quote} % |\cref[UsEdOn]|\marg{LabelName} \\ % |\cref[uO]|\marg{LabelName} % \end{quote} % --- but why would you? % % This additional option adds the text ``\emph{(Used on page(s) ... .)}'' % with an additional line break right after where the label has been originally % set. If \pkg{hyperref} has been loaded, there will also be hyperlinks % to the corresponding pages from where the label has been referenced. % % If the original label has been set in a theorem-style environment such as % \begin{quote} % \begin{verbatim} % \begin{theorem} \label{thm:SqrtTwoIrrational} % The number $\sqrt{2}$ is irrational. % \end{theorem} % \end{verbatim} % \end{quote} % then the info message is printed in the header of this theorem-style % environment. The same functionality can be used for |\Cref|. % % The package \pkg{cleveref-usedon} is implemented using |expl3|. % If you are interested, I have spent some time to document and comment % on the implementation in \cref{sec:implementation}. % % \section{Hints and tips} % \label{sec:tips} % If you use the |capitalise| option for \pkg{cleveref}, you might want % to revert this capitalisation for page references for more visual appeal by putting % \begin{quote} % |\crefname{page}{page}{pages}| % \end{quote} % in your document's preamble, after loading \pkg{cleveref-usedon}. % % It is recommended to not use the optional argument for equation-style % environments such as \cref[UsedOn]{eq:Stokes} because otherwise the % info message will --- unhelpfully --- be printed inside the equation % environment, like so: % \begin{equation} % \int_{M}\mathrm{d}\omega =\int_{\partial M}\omega. \label{eq:Stokes} % \end{equation} % So, for now, one should use this functionality only for theorem-style % environments such as theorems, lemmas and maybe exercises. % % \subsection{Editing the info message} % \label{subsec:edit_info_msg} % \DescribeMacro{\UsedOnMessage} % |\UsedOnMessage|\marg{PageNumberList from cpageref} \\ % The standard message which gets printed to the first line of the labelled % environment is ``\textit{(Used on \meta{PageNumberList}).}'' --- followed by % a line break --- where \meta{PageNumberList} is generated automatically % by \pkg{cleveref} via |\cpageref|. % You can change this behaviour by redefining the macro |\UsedOnMessage|, e.g. as % \begin{quote} % \begin{verbatim} % \RenewDocumentCommand{\UsedOnMessage}{m}{ % \emph{(Will be cited on #1.)} \\ % } % \end{verbatim} % \end{quote} % % \section{Interaction with other packages} % \label{sec:other_packages} % All interactions with other packages mentioned in Section 13 of % \pkg{cleveref}'s documentation also apply to \pkg{cleveref-usedon}. % In fact (if \pkg{cleveref-usedon} is loaded last), % \pkg{ntheorem}'s |\thref| and % \pkg{varioref}'s |\vref| also obtain the additional |UsedOn| % functionality because \pkg{cleveref} redefines these macros to % be aliases for |\cref|. % % \section{Future features} % \label{sec:future} % It is planned to include a package option that turns on the |UsedOn| % option for \emph{all} |\cref|'s calls. Additionally, a switch package option % might be included which reverses the standard behaviour, i.e. if one does % not want to use |UsedOn| functionality one needs to explicitly use % |\cref[NotUsedOn]|\marg{LabelName}. \\ % Let's just reference \cref[UsedOn]{thm:SqrtTwoIrrational} one last time for the fun of it, check \cpageref{thm:SqrtTwoIrrational} again to see the effect to the reference list in the header of \cref{thm:SqrtTwoIrrational}. % % \StopEventually{} % % \section{Implementation} % \label{sec:implementation} % % \iffalse %<*package> % \fi % % \subsection{Options and requirements} % The following package is included in the \LaTeX{} kernel since 2020/10/01. % Here, it is manually |\Require|'d for users with older \LaTeX{} versions. % Those users will get a package warning in the .log file. % \begin{macrocode} \RequirePackage{xparse} % \end{macrocode} % The following package options currently don't do anything. % \begin{macrocode} \bool_new:N \g_StandardBehaviour_bool \bool_gset_true:N \g_StandardBehaviour_bool \DeclareOption{usedon}{ \OptionNotUsed \bool_gset_true:N \g_StandardBehaviour_bool } \DeclareOption{notusedon}{ \OptionNotUsed \bool_gset_false:N \g_StandardBehaviour_bool } % \end{macrocode} % All other package options get passed on to \pkg{cleveref}. % \begin{macrocode} \DeclareOption*{ \PackageInfo{cleveref-usedon} {Passing~to~cleveref:~Option~`\CurrentOption'} \PassOptionsToPackage{\CurrentOption}{cleveref} } \ProcessOptions* \RequirePackage{cleveref}[2018/03/27] % \end{macrocode} % % \subsection{Patches of known bugs to \pkg{cleveref}} % % The following fixes the range bug for |\cpageref| in \pkg{cleveref v0.21.4} \par % See \url{https://tex.stackexchange.com/a/620066/267438} % % \begin{macrocode} \newcommand*{\@setcpagerefrange}[3]{% \@@setcpagerefrange{#1}{#2}{cref}{#3}} \newcommand*{\@setCpagerefrange}[3]{% \@@setcpagerefrange{#1}{#2}{Cref}{#3}} \newcommand*{\@setlabelcpagerefrange}[3]{% \@@setcpagerefrange{#1}{#2}{labelcref}{#3}} % \end{macrocode} % % \subsection{Overloading of label and cref} % % We need a branching variant of |\str_case:nn| % which expands the input string token. This will be used to match % options for the |\__UsedOn_Processor|. % % \begin{macrocode} \prg_generate_conditional_variant:Nnn \str_case:nn { x } { TF } % \end{macrocode} % %\begin{macro}{\g__UsedOn_k_seq} % Let's initialise a global key sequence for those label names that % have been referenced via |[UsedOn]|. % % \begin{macrocode} \seq_new:N \g__UsedOn_k_seq % \end{macrocode} %\end{macro} % %\begin{macro}{\g__UsedOn_kv_prop} % And we'll also create a global key-value property list with % label names as keys and the maximal amount of times they have % been referenced via |[UsedOn]| as values (possibly known from % the last pdflatex run). % % \begin{macrocode} \prop_new:N \g__UsedOn_kv_prop % \end{macrocode} %\end{macro} % %\begin{macro}{\UsedOnMessage} % The following is the standard text that gets printed in the first line % of the labelled environment which later gets referenced with |[UsedOn]|. % % \begin{macrocode} \NewDocumentCommand{\UsedOnMessage}{m}{ \emph{(Used~on~#1.)} \\ } % \end{macrocode} %\end{macro} % %\begin{macro}{\__UsedOn_PrintUsedOnLabel} % Given a \meta{LabelName}, the following command records all references % via |[UsedOn]| of this label in a temporary comma-separated list % (a |clist| in |expl3| speak). This |clist| is then passed to \pkg{cleveref}'s |cpageref| % and which in turn is passed to |\UsedOnMessage| to be printed after % the original label. % % \begin{macrocode} \NewDocumentCommand{\__UsedOn_PrintUsedOnLabel}{ m }{% % \end{macrocode} % First, we will check if the reference |UsedOn@|\meta{LabelName}|@1| % exists. Here, the |@1| means that \meta{LabelName} has been referenced % with option |[UsedOn]| at least once. If this reference does not exist, % nothing happens. %\iffalse %% % Check if the reference UsedOn@@1 exists %% % Here the @1 means that has been referenced %% % with option `UsedOn' at least once %\fi % \begin{macrocode} \cs_if_exist:cT {r@UsedOn@#1@1} { % \end{macrocode} % Next, we store all the references of the form % |UsedOn@|\meta{LabelName}|@|\meta{Number} in a temporary % comma-separated list (|clist|). We do this by looping from 1 to the value % of |LastRun@UsedOn@|\meta{LabelName} (if the latter value exists, % otherwise we set it to 1). Initially, this will need two consecutive runs of pdflatex. %\iffalse %% % In a tmp clist we store all the references of the form %% % `UsedOn@@` %% % where Number between 1 and \value{LastRun@UsedOn@} %% % if the latter exists, otherwise until 1 %% % Should/will normally need two consecutive runs of pdflatex %\fi % \begin{macrocode} \cs_if_free:cTF {c@LastRun@UsedOn@#1} { \int_set:Nn \l_tmpa_int { 1 } } { \int_set:Nn \l_tmpa_int { \value{LastRun@UsedOn@#1} } } \int_set:Nn \l_tmpb_int { 1 } \int_while_do:nn { \l_tmpb_int <= \l_tmpa_int } { \clist_put_right:Nx \l_tmpa_clist { UsedOn@#1@\int_use:N \l_tmpb_int } \int_incr:N \l_tmpb_int } % \end{macrocode} % Finally, we print the message that was set in the macro |\UsedOnMessage|. %\iffalse %% % Print `UsedOn` message by calling \cpageref with the parameter clist above %% % Uncomment the next two lines to see the contents of \l_tmpa_clist %% %% Arguments~of~cpageref~are: %% %% \par\clist_use:Nn \l_tmpa_clist {\par}\par %\fi % \begin{macrocode} \UsedOnMessage{\cpageref{\l_tmpa_clist}} } }% % \end{macrocode} %\end{macro} % %\begin{macro}{\__UsedOn_Processor} % This macro takes an optional argument % (a case-insensitive version of |[UsedOn]| or the shortform |[uo]|) % and a mandatory argument (a single \marg{LabelName} or a |clist| \{\meta{LabelName1},\meta{LabelName2},\ldots\}). % \begin{macrocode} \NewDocumentCommand{\__UsedOn_Processor}{ o m }{% \IfValueT{#1}{ % \end{macrocode} % First, we check if the option |[UsedOn]| or |[uo]| (case-insensitive) was used. % \begin{macrocode} \str_case:xnTF { \str_foldcase:n { #1 } } { % \end{macrocode} %\iffalse %% % check if option 'UsedOn' (case-insensitive) was used %% % in one of the following forms %\fi % \begin{macrocode} {usedon} {} {uo} {} } { { % \end{macrocode} % Loop through the (potential) label list in mandatory argument % of |\cref| (or |\Cref|) which gets passed as the mandatory argument % of the current macro. %\iffalse %% % Loop through (potential) label list in arg of \cref (or \Cref) %\fi % \begin{macrocode} \seq_set_from_clist:Nn \l_tmpa_seq {#2} \seq_map_inline:Nn \l_tmpa_seq { % \end{macrocode} % If the label has \emph{not} been referenced yet via |[UsedOn]|, create a % counter for the current run |ThisRun@UsedOn@##1|. % If we are not in the initial run anymore, there should be a counter % |LastRun@UsedOn@##1| which contains the maximal amount this % specific label has been referenced via |UsedOn|. % If we are in the initial run, we need to create this counter as well. % Then save the label in the global container |\g__UsedOn_k_seq|. %\iffalse %% % if the label has not been referenced yet, %% % create a counter for the current and last run and save the label in the %% % global container \g__UsedOn_k_seq %\fi % \begin{macrocode} \seq_if_in:NxF \g__UsedOn_k_seq {UsedOn@##1} { \newcounter{ThisRun@UsedOn@##1} \cs_if_free:cT {c@LastRun@UsedOn@##1} { \newcounter{LastRun@UsedOn@##1} } \seq_gput_right:Nx \g__UsedOn_k_seq {UsedOn@##1} } % \end{macrocode} % Increase the counter for the current run by 1 and set the counter % for last run (containing the maximal amount of |UsedOn|-|\cref|'s) % to...the maximal amount of |UsedOn|-|\cref|'s. %\iffalse %% % increase the counters and compare with max counter %\fi % \begin{macrocode} \stepcounter{ThisRun@UsedOn@##1} \setcounter{LastRun@UsedOn@##1}{% \fp_eval:n { max(% \value{ThisRun@UsedOn@##1},% \value{LastRun@UsedOn@##1} ) }% } % \end{macrocode} % Store the value of the max counter |LastRun@UsedOn@##1| in % the global container |\g__UsedOn_kv_prop|. %\iffalse %% % store the value in global key-value property list %\fi % \begin{macrocode} \prop_gput:Nxx \g__UsedOn_kv_prop {UsedOn@##1} {\arabic{LastRun@UsedOn@##1}} % \end{macrocode} % Now we create a numbered auxiliary label. This label is issued at the % location where we referenced the original label via % |\cref[UsedOn]|\meta{LabelName}. % The new auxiliary label has the prefix |UsedOn@| and % the suffix |@\arabic{ThisRun@UsedOn@##1}|, e.g. % |UsedOn@thm:Pythagoras@4| if it is the fourth time that we called \\ % |\cref[UsedOn]{thm:Pythagoras}|. %\iffalse %% % create a label for the UsedOn reference and number this label %\fi % \begin{macrocode} \__UsedOn_origlabel{UsedOn@##1@\arabic{ThisRun@UsedOn@##1}} } } } { % \end{macrocode} % Throw an error, if an unrecognised option was used for the % optional argument to this macro. %\iffalse %% % Throw an error, if an unrecognised option was used %% % for the optional argument to this macro. %\fi % \begin{macrocode} \msg_new:nnn {cleveref-usedon} { OptionSpellingError } { \\ Spelling~error~\msg_line_context: \\ Did~you~mean~to~pass~option\\ 'UsedOn'~to~cref~or~Cref? } \msg_fatal:nn { cleveref-usedon } { OptionSpellingError } } } }% % \end{macrocode} %\end{macro} % %\begin{macro}{\__UsedOn_cref} % This is just a wrapper around \pkg{cleveref}'s |\cref|. % Additionally the |\__UsedOn_Processor| gets called. % \begin{macrocode} \NewDocumentCommand{\__UsedOn_cref}{ s o m }{% \IfBooleanTF{#1}{ \__UsedOn_origcref*{#3} }{ \__UsedOn_origcref{#3} }% \__UsedOn_Processor[#2]{#3} }% % \end{macrocode} %\end{macro} % %\begin{macro}{\__UsedOn_Cref} % This is just a wrapper around \pkg{cleveref}'s |\Cref|. % Additionally the |\__UsedOn_Processor| gets called. % \begin{macrocode} \NewDocumentCommand{\__UsedOn_Cref}{ s o m }{% \IfBooleanTF{#1}{ \__UsedOn_origCref*{#3} }{ \__UsedOn_origCref{#3} }% \__UsedOn_Processor[#2]{#3} }% % \end{macrocode} %\end{macro} % %\begin{macro}{\__UsedOn_ReadFromAux} % From the .aux file we will read the contents of the % global container |\g__UsedOn_kv_prop|. % This is a key-value property list and we create and set a % for each label (key) and the maximal amount (value) it was called in the last run. % \begin{macrocode} \NewDocumentCommand{\__UsedOn_ReadFromAux}{ }{% \prop_map_inline:Nn \g__UsedOn_kv_prop { \newcounter{LastRun@##1} \setcounter{LastRun@##1}{##2} } }% % \end{macrocode} %\end{macro} % %\begin{macro}{\__UsedOn_WriteToAux} % For each label we write a line in the .aux file of the form: \\ % \meta{LabelName} == \meta{Maximal references via UsedOn in last run}.\\ % This information can be constructed from the global container |\g__UsedOn_k_seq| % and the counters with prefix |ThisRun@| we set earlier. % We need to wrap this in the on/off switch for |expl3| functionality. % \begin{macrocode} \NewDocumentCommand{\__UsedOn_WriteToAux}{ }{% % \end{macrocode} %% % First, we clear the global key-value prop list |\g__UsedOn_kv_prop| and %% % then we rebuild it with the information from the current run. % \begin{macrocode} \prop_clear:N \g__UsedOn_kv_prop \seq_map_inline:Nn \g__UsedOn_k_seq { \prop_gput:Nxx \g__UsedOn_kv_prop {##1}{\arabic{ThisRun@##1}} } % \end{macrocode} %\iffalse %% % Turn on |expl3| functionality in .aux file. %\fi % \begin{macrocode} \iow_now:cx { @auxout } { \token_to_str:N \ExplSyntaxOn } % \end{macrocode} %% % Loop through the key-val |proplist| and write contents to .aux file. % \begin{macrocode} \prop_map_inline:Nn \g__UsedOn_kv_prop { \iow_now:cx { @auxout } { \prop_gput_from_keyval:Nn \token_to_str:N \g__UsedOn_kv_prop {##1=##2} } } % \end{macrocode} %\iffalse %% % Turn off |expl3| functionality in .aux file. %\fi % \begin{macrocode} \iow_now:cx { @auxout } { \token_to_str:N \ExplSyntaxOff } }% % \end{macrocode} %\end{macro} % % At the hook |\AtBeginDocument| we read from the .aux file % and patch commands. % \begin{macrocode} \AtBeginDocument{% \__UsedOn_ReadFromAux % \end{macrocode} % Patch label and cref to include the new |[UsedOn]| capabilities. % \begin{macrocode} \NewCommandCopy{\__UsedOn_origlabel}{\label} \NewCommandCopy{\__UsedOn_origcref}{\cref} \NewCommandCopy{\__UsedOn_origCref}{\Cref} \RenewDocumentCommand{\label}{ m }{% \__UsedOn_origlabel{#1}\__UsedOn_PrintUsedOnLabel{#1} }% \RenewCommandCopy{\cref}{\__UsedOn_cref} \RenewCommandCopy{\Cref}{\__UsedOn_Cref} }% % \end{macrocode} % % At the hook |\AtEndDocument| we write to the .aux file. % \begin{macrocode} \AtEndDocument{% \__UsedOn_WriteToAux }% % \end{macrocode} % % \iffalse % % \fi % % \Finale \endinput