Re: How to make custom linked cross-references?
- From: "Ulrich Diez" <eu_angelion@xxxxxxxxxxxxxx>
- Date: Wed, 3 May 2006 19:25:27 +0200
The previous "improvement" introduced a bug.
Shame on me. Sorry.
Ulrich
=========================<start of file `custref.sty'>=========================
%
% Manual/macro-description can be found after \endinput so that it
% won't be read when loading the package. Also you don't need
% these '%'-characters all the time...
%
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{custref}
[2006/05/03 v0.04 customize the appearance of ref-erenced counters]
\@ifdefinable\if@extractnum{%
\newif\if@extractnum
\global\@extractnumfalse
}%
\@ifdefinable\extractnum{%
\long\gdef
\extractnum\setrefphrases\refleadphrase#1\reftrailphrase{#1}%
}%
\newcommand*\nolinkref[1]{%
{%
\@ifundefined{@refstar}%
{{\resetrefphrases\ref{#1}}}%
{{\resetrefphrases\ref*{#1}}}%
}%
}%
\newcommand*\nolinkpageref[1]{%
{%
\@ifundefined{@pagerefstar}%
{{\resetrefphrases\pageref{#1}}}%
{{\resetrefphrases\pageref*{#1}}}%
}%
}%
\@ifdefinable\@innerextractpagerefnum{%
\def\@innerextractpagerefnum#1#2#3#4\@nil{%
\@expandtwoargs\@tempa{\noexpand#1}{#3}%
}%
}%
\newcommand*\extractpagerefnum[3][\newcommand*]{%
\begingroup
\expandafter\ifx\csname r@#3\endcsname\relax
\protect\G@refundefinedtrue
\@latex@warning{Reference `#3' on page \thepage\space
undefined}%
\endgroup
#1#2{0}%
\else
\def\@tempa{%
\def\@tempa####1{%
\endgroup#1####1%
}%
\@innerextractpagerefnum{#2}%
}%
\@extractnumtrue
\expandafter\expandafter
\expandafter\@tempa
\csname r@#3\endcsname\empty\empty\empty\empty\@nil
\fi
}%
\@ifdefinable\@innerextractrefnum{%
\def\@innerextractrefnum#1#2#3#4\@nil{%
\@expandtwoargs\@tempa{\noexpand#1}{#2}%
}%
}%
\newcommand*\extractrefnum[3][\newcommand*]{%
\begingroup
\expandafter\ifx\csname r@#3\endcsname\relax
\protect\G@refundefinedtrue
\@latex@warning{Reference `#3' on page \thepage\space
undefined}%
\endgroup
#1#2{0}%
\else
\def\@tempa{%
\def\@tempa####1{%
\endgroup#1####1%
}%
\@innerextractrefnum{#2}%
}%
\@extractnumtrue
\expandafter\expandafter
\expandafter\@tempa
\csname r@#3\endcsname\empty\empty\empty\empty\@nil
\fi
}%
\newcommand*\nolinkcustomizeref[3]{%
{%
\@ifundefined{@pagerefstar}%
{{\resetrefphrases\customizeref{#1}{#2}{#3}}}%
{{\resetrefphrases\customizeref*{#1}{#2}{#3}}}%
}%
}%
\newcommand*\refleadphrase{}%
\newcommand*\reftrailphrase{}%
\newcommand*\setrefphrases{}%
\newcommand*\resetrefphrases{%
\def\setrefphrases{}%
}%
\newcommand*\makerefcustomizeable[3]{%
\AtBeginDocument{%
\expandafter\renewcommand\expandafter*\csname p@#1\endcsname{%
\csname innerp@#1\expandafter\endcsname
}%
\expandafter\newcommand\expandafter*\csname innerp@#1\endcsname[1]{%
\expandafter\protect\csname setstandardphrases@#1\endcsname
\protect\setrefphrases
\protect\refleadphrase##1\protect\reftrailphrase
}%
\expandafter\newcommand
\expandafter*%
\csname setstandardphrases@#1\endcsname{%
\if@extractnum
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\extractnum}%
{%
\toks@{#2}\edef\refleadphrase{\the\toks@}%
\toks@{#3}\edef\reftrailphrase{\the\toks@}%
}%
}%
}%
}%
\@onlypreamble\makerefcustomizeable
\newcommand*\customizerefatnostar[3]{%
{%
\renewcommand*\setrefphrases{%
\toks@{#2}\edef\refleadphrase{\the\toks@}%
\toks@{#3}\edef\reftrailphrase{\the\toks@}%
}%
\ref{#1}%
}%
}%
\newcommand*\customizerefatstar[3]{%
{%
\renewcommand*\setrefphrases{%
\toks@{#2}\edef\refleadphrase{\the\toks@}%
\toks@{#3}\edef\reftrailphrase{\the\toks@}%
}%
\ref*{#1}%
}%
}%
\newcommand*\customizeref{\@ifstar\customizerefatstar\customizerefatnostar}%
\endinput
%%
%%
!!!! Here's the promised manual'n stuff !!!!
1. Legal stuff
==============
What is it?: A .sty-file for LaTeX2e, loadable via \usepackage
in the preamble.
Copyright: custref.sty [2006/05/03 v0.04] (C) Ulrich Diez
Author: Ulrich Diez (ulrich.diez@xxxxxxxxxxxxxxxxxxxxxxx)
Licence: LPPL
Submitted to CTAN: No. If somebody wants the package on CTAN,
please contact the author/current maintainer
via e-mail.
Maintenance-status: At may 03, 2006 this sty-file was maintained by
Ulrich Diez.
If somebody wants to overtake maintenance of
the file custref.sty, please contact the author/
current maintainer via e-mail.
Warranties: None. Usage is atyour own risk. If something breaks,
you may keep the pieces.
This file came into being due to a "feature-request" of Ted Pavlic
at comp.text.tex (usenet). For more details google the initial-message's
ID: <1146244592.766091.42210@xxxxxxxxxxxxxxxxxxxxxxxxxxxx> .
2. Changes to LaTeX-internals
=============================
Each <counter> defined by LaTeX2e's \newcounter-macro provides
a macro \p@<counter> which is intended for providing some
referencing-prefix. Usually it is empty. This package provides
means for redefining these \p@-macros and thus might break when
being used together with other packages which do the same.
3. Compatibility to other packages
==================================
I assume that this package will break some features of e.g. the
ifthen-package. The reason is: You cannot extract plain
"hyperlinkless" reference- or pagenumbers from the labels
with common methods any more as done e.g. by the ifthen-package
when it comes to comparing e.g. page-number-values of references/
labels.
In order to work around this restriction, this package provides
the macros \extractrefnum and \extractpagerefnum. Usage of these
macros is described in the "Usage"-section.
4. Change-History
=================
2006/05/01 v0.01 - Initial release
2006/05/02 v0.02 - Package: Support for extracting plain numerical values
------- from labels for numerical comparing / Added
macros \extractrefnum and \extractpagerefnum.
Documentation: Fixed some typo and added some
------------- \extract(page)refnum-examples.
2006/05/03 v0.03 - Package: Removed and changed some unnecessary grouping
------- in order to better preserve implicite kerning.
Also removed unnecessary \reset...-macros.
2006/05/03 v0.04 - Package: Restored erroneously removed \reset...-macros.
-------
5. Usage
========
Intro
-----
People often wish to customize the way in which counters appear when
referencing takes place. E.g., when referencing a section-counter,
\ref{sec-bla} should deliver something like "section~23", but when
referencing figures, \ref{fig} should deliver something like
"Fig.~(7)".
When looking at these examples, you can find that actually the
reference-text is made of three parts:
1. Some leading phrase, e.g. "Fig.~("
2. The reference-number as "spit out" by \the<counter>
3. Some trailing-phrase, e.g. ")"
package-loading
---------------
in the preamble via \usepackage{custref}
preamble-macro \makerefcustomizable
-----------------------------------
This package provides a preamble-macro
\makerefcustomizable{<counter>}
{<standard-leading-phrase>}
{<standard-trailing-phrase>}
by means of which you can specify the appearance for single counters
when they get referred by means of the \ref-macro.
That means:
You can -after package-loading- write in the preamble e.g.,
...
\makerefcustomizable{section}
{section~(}
{) of this book}
...
When writing in the document
...
% fifth-section
\section{some section}\label{thissection}
...
A reference to \ref{thissection}
, you will get:
A reference to section~(5) of this book
and in case of using hyperref, the hyperlinked phrase is
"section~(5) of this book"
macro \customizeref
-------------------
There is another macro \customizeref for usage within the document.
\customizeref takes 3 arguments:
\customizeref{<label>}
{<this time's-leading-phrase>}
{<this time's-trailing-phrase>}
When applying \customizeref to a label instead of \ref, the leading- and
trailing-phrase of the reference will be formed from \customizeref's
second and third argument _instead_ of what was provided to
\makerefcustomizeable as second and third argument.
You can -after package-loading- write in the preamble e.g.,
...
\makerefcustomizeable{section}
{section~(}
{) of this book}
...
When writing in the document
...
% fifth-section
\section{some section}\label{thissection}
...
A reference to \ref{thissection}
A reference to \customizeref{thissection}{A}{B}
, you will get:
A reference to section~(5) of this book
A reference to A5B
and in case of using hyperref, the first hyperlinked phrase
is "section~(5) of this book", the second is "A5B".
\nolinkref, \nolinkpageref, \nolinkcustomizeref
-----------------------------------------------
A weird but nonetheless existing problem/case is:
You might wish to take reference to yet another label within
\customizeref's second argument (<this time's-leading-phrase>)
or tird argument (<this time's-trailing-phrase>),
e.g. in order to create a hyperlink to only the fifth section of
your book from a phrase like
"chapter 7, section~(5), page 11 of this book".
Simply nesting \ref, \pageref or \customizeref won't work as this
would mean to create hyperlinks in hyperlinks which is not
supported by any driver/viewer yet. Therefore the macros
\nolinkref, \nolinkpageref, \nolinkcustomizeref are provided.
You can use them within the arguments of \customizeref.
\extractrefnum and \extractpagerefnum
-------------------------------------
Sometimes you might wish to extract the plain page- or reference-
number which is associated to a label. Just the numerical
value, no hyperlink or the like. The macros
\extractrefnum and \extractpagerefnum are intended for
facilitating this task.
[In the intro was said that a reference is made of 3 parts:
1. Some leading phrase (e.g. "Fig.~(")
2. The reference-number as "spit out" by \the<counter>
3. Some trailing-phrase (e.g. ")")
So the phrase "just the numerical value" means the second part
"The reference-number as spit out by \the<counter>." Thus
if \the<counter> was not defined to "spit out" a plain
arabic number, the "numerical value" won't be a plain number
either and you cannot use it sucessfully for e.g.
\ifnum-comparison!]
\extractrefnum[<defining-command>]{<macro>}{<label>}
\extractpagerefnum[<defining-command>]{<macro>}{<label>}
The macro \extractrefnum takes one optional and two mandatory
arguments: The first mandatory argument is the name of a newly
to be defined <macro>. The second mandatory argument is the name
of an existing <label>.
The <macro> will be defined to expand to the specified <label>'s
"reference-number as spit out by \the<counter>."
\extractpagerefnum works in the same way but delivers the
page-number-value instead.
Usually defining the <macro> will take place in terms of
\newcommand* . Within the optional argument you can specify
otherwise (e.g., [\def], [\global\def], [\providecommand],
[\DeclareRobustCommand],...) Useful when applying
\extract(page)refnum in a loop where always the same temporary
<macro> is to be (re)defined and thus \newcommand* cannot be
applied as that would lead to an unwanted 'already-defined-error'.
If numerical comparison to references , e.g. , via the
ifthen-package fails, you can try to work around this by first
putting the reference-numbers via \extract(page)refnum into
temporary macros and afterwards performing numerical comparison
to them. If you don't want to have temporary macros defined
permanently, you can write something like e.g.,
{% <-open group
\extractrefnum{\tempa}{<labelA>}%
\extractrefnum{\tempb}{<labelB>}
\expandafter}% closing the group and thus destroying the
% temporary macros will due to \expandafter happen
% right after evaluating the expression, before
% acting on one of the branches.
\ifnum\tempa<\tempb\relax
bla bla
\else
blu blu
\fi
IN CASE THAT LABEL IS UNDEFINED, A WARNING-MESSAGE OCCURS AND
<macro> WILL BE DEFINED TO EXPAND TO "0". During the very first
LaTeX-run no label is defined as labels get defined when reading
the aux-file which is not available yet during that run.
Another issue is:
-----------------
If you did not apply the macro \makerefcustomizeable to a
counter in the preamble, but take reference to it via
\customizeref{<label>}
{<this time's-leading-phrase>}
{<this time's-trailing-phrase>}
, the effect will be the same as if you had just written
\ref{<label>} into your source-code instead.
This is because \customizeref heavily uses and relies on
the p@-macros associated to the counters being (re)defined by
\makerefcustomizable in a special way.
6. hyperlinks across long lines
===============================
You can create very long link-phrases by means of this package.
If you do so, make sure that your viewer/driver supports hyper-
links with linebreaks. pdf(e)(La)TeX does. Most DVI-viewers do
not.
7. Usage-example
================
You can copy-paste the following example to some separate-file,
run it through (pdf)LaTeX and see how the package works:
\documentclass{article}
\usepackage{hyperref} % Actually hyperref is not a requirement
% but we want to see the hyperlinks.
\usepackage{custref}
\makerefcustomizeable{subsection}
{std-lead-phrase-for-sub-section~}
{~std-trail-phrase-for-sub-section}
\makerefcustomizeable{figure}
{std-lead-phrase-for-figure~}
{~std-trail-phrase-for-figure}
\begin{document}
\setcounter{page}{20}%
\parskip=\medskipamount\relax
\parindent=0pt\relax
\section{first section}
\label{firstsection}
This is first section.
\begin{figure}
This is a figure in first section.
\caption{figure's caption}
\label{fig}
\end{figure}
\subsection{first sub-section}
\label{firstsubsection}
This is first sub-section.
\newpage
\section{referencing}
subsection and figure are made ``customizeable''.
section is not.
This is reference to first sub-section:
\ref{firstsubsection}
This is customize-reference to first sub-section:
\customizeref{firstsubsection}
{customize~}
{~customize}
This is reference to first section:
\ref{firstsection}
This is (effectless) customize-reference to first section:
\customizeref{firstsection}
{customize~}
{~customize}
This is reference to figure:
\ref{fig}
This is customize-reference to figure:
\customizeref{fig}
{customize~}
{~customize}
This is customize-reference to figure with other references
in the arguments:
\customizeref{fig}%
{see page~\nolinkpageref{fig} for figure~}%
{ of the \nolinkcustomizeref{firstsection}{}{}$^{st}$ section}%
Plain reference-number of the label \emph{fig} is now in
\texttt{%
\string\tempa~=
\extractrefnum{\tempa}{fig}%
\meaning\tempa
}%
% Now \tempa is defined.
% We now have to use "\def" or something like
% "\let\tempa\relax\newcommand*" in order to prevent
% "already-defined-errors":
Plain reference-number of the label \emph{firstsubsection} is now in
\texttt{%
\string\tempa~=
\extractrefnum[\def]{\tempa}{firstsubsection}%
\meaning\tempa
}%
Plain reference-number of the label \emph{firstsection} is now in
\texttt{%
\string\tempa~=
\extractrefnum[\let\tempa\relax\newcommand]{\tempa}{firstsection}%
\meaning\tempa
}%
Plain page-number of the label \emph{fig} is now in protected
\def\spacereplace#1 #2 #3\nil{#1 #2\char`\ #3}%
\texttt{%
\extractpagerefnum[\DeclareRobustCommand]{\tempa}{fig}%
\string\tempa~=
\expandafter\spacereplace\meaning\tempa;\nil
\spacereplace{} \string\tempa{} ~=~\nil
\expandafter\meaning\csname tempa \endcsname
}%
Plain page-number of the label \emph{firstsubsection} is now in
\texttt{%
\string\tempa~=
\extractpagerefnum[\def]{\tempa}{firstsubsection}%
\meaning\tempa
}%
Plain page-number of the label \emph{firstsection} is now in
\texttt{%
\string\tempa~=
\extractpagerefnum[\def]{\tempa}{firstsection}%
\meaning\tempa
}%
\end{document}
%%
%% End of file `custref.sty'.
==========================<end of file `custref.sty'>==========================
.
- References:
- Re: How to make custom linked cross-references?
- From: Ted Pavlic
- Re: How to make custom linked cross-references?
- From: Ulrich Diez
- Re: How to make custom linked cross-references?
- From: Ted Pavlic
- Re: How to make custom linked cross-references?
- From: Ulrich Diez
- Re: How to make custom linked cross-references?
- From: Ted Pavlic
- Re: How to make custom linked cross-references?
- From: Ulrich Diez
- Re: How to make custom linked cross-references?
- From: Ulrich Diez
- Re: How to make custom linked cross-references?
- Prev by Date: Re: footnotes in section titles with KOMA
- Next by Date: Re: Whitespace Characters
- Previous by thread: Re: How to make custom linked cross-references?
- Next by thread: Re: How to make custom linked cross-references?
- Index(es):
Relevant Pages
|